| @@ -0,0 +1,16 @@ | |||||
| | |||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediatRSample", "MediatRSample\MediatRSample.csproj", "{CE066EE5-7ED1-42A0-8DB2-862D44F40EA7}" | |||||
| EndProject | |||||
| Global | |||||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
| Debug|Any CPU = Debug|Any CPU | |||||
| Release|Any CPU = Release|Any CPU | |||||
| EndGlobalSection | |||||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
| {CE066EE5-7ED1-42A0-8DB2-862D44F40EA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
| {CE066EE5-7ED1-42A0-8DB2-862D44F40EA7}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
| {CE066EE5-7ED1-42A0-8DB2-862D44F40EA7}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
| {CE066EE5-7ED1-42A0-8DB2-862D44F40EA7}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
| EndGlobalSection | |||||
| EndGlobal | |||||
| @@ -0,0 +1,48 @@ | |||||
| using Discord.WebSocket; | |||||
| using MediatR; | |||||
| using MediatRSample.Notifications; | |||||
| using Microsoft.Extensions.DependencyInjection; | |||||
| namespace MediatRSample; | |||||
| public class DiscordEventListener | |||||
| { | |||||
| private readonly CancellationToken _cancellationToken; | |||||
| private readonly DiscordSocketClient _client; | |||||
| private readonly IServiceScopeFactory _serviceScope; | |||||
| public DiscordEventListener(DiscordSocketClient client, IServiceScopeFactory serviceScope) | |||||
| { | |||||
| _client = client; | |||||
| _serviceScope = serviceScope; | |||||
| _cancellationToken = new CancellationTokenSource().Token; | |||||
| } | |||||
| private IMediator Mediator | |||||
| { | |||||
| get | |||||
| { | |||||
| var scope = _serviceScope.CreateScope(); | |||||
| return scope.ServiceProvider.GetRequiredService<IMediator>(); | |||||
| } | |||||
| } | |||||
| public Task StartAsync() | |||||
| { | |||||
| _client.Ready += OnReadyAsync; | |||||
| _client.MessageReceived += OnMessageReceivedAsync; | |||||
| return Task.CompletedTask; | |||||
| } | |||||
| private Task OnMessageReceivedAsync(SocketMessage arg) | |||||
| { | |||||
| return Mediator.Publish(new MessageReceivedNotification(arg), _cancellationToken); | |||||
| } | |||||
| private Task OnReadyAsync() | |||||
| { | |||||
| return Mediator.Publish(ReadyNotification.Default, _cancellationToken); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| using MediatR; | |||||
| using MediatRSample.Notifications; | |||||
| namespace MediatRSample.Handlers; | |||||
| public class MessageReceivedHandler : INotificationHandler<MessageReceivedNotification> | |||||
| { | |||||
| public async Task Handle(MessageReceivedNotification notification, CancellationToken cancellationToken) | |||||
| { | |||||
| Console.WriteLine($"MediatR works! (Received a message by {notification.Message.Author.Username})"); | |||||
| // Your implementation | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,20 @@ | |||||
| <Project Sdk="Microsoft.NET.Sdk"> | |||||
| <PropertyGroup> | |||||
| <OutputType>Exe</OutputType> | |||||
| <TargetFramework>net6.0</TargetFramework> | |||||
| <ImplicitUsings>enable</ImplicitUsings> | |||||
| <Nullable>enable</Nullable> | |||||
| <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <PackageReference Include="Discord.Net" Version="3.4.1" /> | |||||
| <PackageReference Include="MediatR" Version="10.0.1" /> | |||||
| <PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" /> | |||||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" /> | |||||
| <PackageReference Include="Serilog" Version="2.10.0" /> | |||||
| <PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" /> | |||||
| </ItemGroup> | |||||
| </Project> | |||||
| @@ -0,0 +1,14 @@ | |||||
| using Discord.WebSocket; | |||||
| using MediatR; | |||||
| namespace MediatRSample.Notifications; | |||||
| public class MessageReceivedNotification : INotification | |||||
| { | |||||
| public MessageReceivedNotification(SocketMessage message) | |||||
| { | |||||
| Message = message ?? throw new ArgumentNullException(nameof(message)); | |||||
| } | |||||
| public SocketMessage Message { get; } | |||||
| } | |||||
| @@ -0,0 +1,13 @@ | |||||
| using MediatR; | |||||
| namespace MediatRSample.Notifications; | |||||
| public class ReadyNotification : INotification | |||||
| { | |||||
| public static readonly ReadyNotification Default | |||||
| = new(); | |||||
| private ReadyNotification() | |||||
| { | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,73 @@ | |||||
| using Discord; | |||||
| using Discord.Interactions; | |||||
| using Discord.WebSocket; | |||||
| using MediatR; | |||||
| using Microsoft.Extensions.DependencyInjection; | |||||
| using Serilog; | |||||
| using Serilog.Events; | |||||
| namespace MediatRSample; | |||||
| public class Bot | |||||
| { | |||||
| private static ServiceProvider ConfigureServices() | |||||
| { | |||||
| return new ServiceCollection() | |||||
| .AddMediatR(typeof(Bot)) | |||||
| .AddSingleton(new DiscordSocketClient(new DiscordSocketConfig | |||||
| { | |||||
| AlwaysDownloadUsers = true, | |||||
| MessageCacheSize = 100, | |||||
| GatewayIntents = GatewayIntents.AllUnprivileged, | |||||
| LogLevel = LogSeverity.Info | |||||
| })) | |||||
| .AddSingleton<DiscordEventListener>() | |||||
| .AddSingleton(x => new InteractionService(x.GetRequiredService<DiscordSocketClient>())) | |||||
| .BuildServiceProvider(); | |||||
| } | |||||
| public static async Task Main() | |||||
| { | |||||
| await new Bot().RunAsync(); | |||||
| } | |||||
| private async Task RunAsync() | |||||
| { | |||||
| Log.Logger = new LoggerConfiguration() | |||||
| .MinimumLevel.Verbose() | |||||
| .Enrich.FromLogContext() | |||||
| .WriteTo.Console() | |||||
| .CreateLogger(); | |||||
| await using var services = ConfigureServices(); | |||||
| var client = services.GetRequiredService<DiscordSocketClient>(); | |||||
| client.Log += LogAsync; | |||||
| var listener = services.GetRequiredService<DiscordEventListener>(); | |||||
| await listener.StartAsync(); | |||||
| await client.LoginAsync(TokenType.Bot, "OTI1ODAxMDI1OTcyMDgwNzMx.YcyZZQ.qDD8EHfF9ZMefjT-qVcwAEpDXvg"); | |||||
| await client.StartAsync(); | |||||
| await Task.Delay(Timeout.Infinite); | |||||
| } | |||||
| private static Task LogAsync(LogMessage message) | |||||
| { | |||||
| var severity = message.Severity switch | |||||
| { | |||||
| LogSeverity.Critical => LogEventLevel.Fatal, | |||||
| LogSeverity.Error => LogEventLevel.Error, | |||||
| LogSeverity.Warning => LogEventLevel.Warning, | |||||
| LogSeverity.Info => LogEventLevel.Information, | |||||
| LogSeverity.Verbose => LogEventLevel.Verbose, | |||||
| LogSeverity.Debug => LogEventLevel.Debug, | |||||
| _ => LogEventLevel.Information | |||||
| }; | |||||
| Log.Write(severity, message.Exception, "[{Source}] {Message}", message.Source, message.Message); | |||||
| return Task.CompletedTask; | |||||
| } | |||||
| } | |||||