@@ -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; | |||||
} | |||||
} |