rebuild discord bot to better user interactions

This commit is contained in:
rootdarkarchon
2023-09-17 00:05:57 +02:00
parent 56b27e5ee8
commit 7e90187822
13 changed files with 1409 additions and 7 deletions

View File

@@ -13,6 +13,7 @@ using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using StackExchange.Redis;
using System.Text;
using System.Threading.Channels;
namespace MareSynchronosServices.Discord;
@@ -54,7 +55,9 @@ internal class DiscordBot : IHostedService
if (!string.IsNullOrEmpty(token))
{
_interactionModule = new InteractionService(_discordClient);
_interactionModule.Log += Log;
await _interactionModule.AddModuleAsync(typeof(MareModule), _services).ConfigureAwait(false);
await _interactionModule.AddModuleAsync(typeof(MareWizardModule), _services).ConfigureAwait(false);
await _discordClient.LoginAsync(TokenType.Bot, token).ConfigureAwait(false);
await _discordClient.StartAsync().ConfigureAwait(false);
@@ -64,10 +67,10 @@ internal class DiscordBot : IHostedService
_discordClient.InteractionCreated += async (x) =>
{
var ctx = new SocketInteractionContext(_discordClient, x);
await _interactionModule.ExecuteCommandAsync(ctx, _services);
await _interactionModule.ExecuteCommandAsync(ctx, _services).ConfigureAwait(false);
};
await _botServices.Start();
await _botServices.Start().ConfigureAwait(false);
_ = UpdateStatusAsync();
}
}
@@ -78,7 +81,7 @@ internal class DiscordBot : IHostedService
{
_discordClient.ButtonExecuted -= ButtonExecutedHandler;
await _botServices.Stop();
await _botServices.Stop().ConfigureAwait(false);
_processReportQueueCts?.Cancel();
_updateStatusCts?.Cancel();
_vanityUpdateCts?.Cancel();
@@ -197,16 +200,100 @@ internal class DiscordBot : IHostedService
private async Task DiscordClient_Ready()
{
var guild = (await _discordClient.Rest.GetGuildsAsync()).First();
var guild = (await _discordClient.Rest.GetGuildsAsync().ConfigureAwait(false)).First();
await _interactionModule.RegisterCommandsToGuildAsync(guild.Id, true).ConfigureAwait(false);
await CreateOrUpdateModal(guild).ConfigureAwait(false);
_ = RemoveUsersNotInVanityRole();
_ = ProcessReportsQueue();
_ = UpdateVanityRoles(guild);
}
private async Task UpdateVanityRoles(RestGuild guild)
{
while (!_updateStatusCts.IsCancellationRequested)
{
var vanityRoles = _configurationService.GetValueOrDefault(nameof(ServicesConfiguration.VanityRoles), Array.Empty<ulong>());
if (vanityRoles.Length != _botServices.VanityRoles.Count)
{
_botServices.VanityRoles.Clear();
foreach (var role in vanityRoles)
{
var restrole = guild.GetRole(role);
if (restrole != null) _botServices.VanityRoles.Add(restrole);
}
}
await Task.Delay(TimeSpan.FromSeconds(30), _updateStatusCts.Token).ConfigureAwait(false);
}
}
private async Task CreateOrUpdateModal(RestGuild guild)
{
_logger.LogInformation("Creating Wizard: Getting Channel");
var discordChannelForCommands = _configurationService.GetValue<ulong?>(nameof(ServicesConfiguration.DiscordChannelForCommands));
if (discordChannelForCommands == null)
{
_logger.LogWarning("Creating Wizard: No channel configured");
return;
}
IUserMessage? message = null;
var socketchannel = await _discordClient.GetChannelAsync(discordChannelForCommands.Value).ConfigureAwait(false) as SocketTextChannel;
var pinnedMessages = await socketchannel.GetPinnedMessagesAsync().ConfigureAwait(false);
foreach (var msg in pinnedMessages)
{
_logger.LogInformation("Creating Wizard: Checking message id {id}, author is: {author}, hasEmbeds: {embeds}", msg.Id, msg.Author.Id, msg.Embeds.Any());
if (msg.Author.Id == _discordClient.CurrentUser.Id
&& msg.Embeds.Any())
{
message = await socketchannel.GetMessageAsync(msg.Id).ConfigureAwait(false) as IUserMessage;
break;
}
}
_logger.LogInformation("Creating Wizard: Found message id: {id}", message?.Id ?? 0);
await GenerateOrUpdateWizardMessage(socketchannel, message).ConfigureAwait(false);
}
private async Task GenerateOrUpdateWizardMessage(SocketTextChannel channel, IUserMessage? prevMessage)
{
EmbedBuilder eb = new EmbedBuilder();
eb.WithTitle("Mare Services Bot Interaction Service");
eb.WithDescription("Press \"Start\" to interact with this bot!" + Environment.NewLine + Environment.NewLine
+ "You can handle all of your Mare account needs in this server through the easy to use interactive bot prompt. Just follow the instructions!");
eb.WithThumbnailUrl("https://raw.githubusercontent.com/Penumbra-Sync/repo/main/MareSynchronos/images/icon.png");
var cb = new ComponentBuilder();
cb.WithButton("Start", style: ButtonStyle.Primary, customId: "wizard-home:true", emote: Emoji.Parse("➡️"));
if (prevMessage == null)
{
var msg = await channel.SendMessageAsync(embed: eb.Build(), components: cb.Build()).ConfigureAwait(false);
await msg.PinAsync().ConfigureAwait(false);
}
else
{
await prevMessage.ModifyAsync(p =>
{
p.Embed = eb.Build();
p.Components = cb.Build();
}).ConfigureAwait(false);
}
}
private Task Log(LogMessage msg)
{
_logger.LogInformation("{msg}", msg);
switch (msg.Severity)
{
case LogSeverity.Critical:
case LogSeverity.Error:
_logger.LogError(msg.Exception, msg.Message); break;
case LogSeverity.Warning:
_logger.LogWarning(msg.Exception, msg.Message); break;
default:
_logger.LogInformation(msg.Message); break;
}
return Task.CompletedTask;
}