|
| 1 | +using System.Text.RegularExpressions; |
| 2 | +using DSharpPlus; |
| 3 | +using DSharpPlus.Entities; |
| 4 | +using DSharpPlus.SlashCommands; |
| 5 | +using EmbedBot.Interactivity; |
| 6 | + |
| 7 | +namespace EmbedBot.Commands; |
| 8 | + |
| 9 | +internal sealed partial class EmbedCommand |
| 10 | +{ |
| 11 | + private static readonly Regex MessageLinkRegex = GetMessageLinkRegex(); |
| 12 | + |
| 13 | + [SlashCommand("edit", "Edits an existing embed.", false)] |
| 14 | + public async Task EditAsync(InteractionContext context, |
| 15 | + [Option("message", "The link to the message to edit.")] |
| 16 | + string messageLink) |
| 17 | + { |
| 18 | + var response = new DiscordInteractionResponseBuilder(); |
| 19 | + Match match = MessageLinkRegex.Match(messageLink); |
| 20 | + |
| 21 | + if (!match.Success) |
| 22 | + { |
| 23 | + response.WithContent("Invalid message link."); |
| 24 | + await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, response).ConfigureAwait(false); |
| 25 | + return; |
| 26 | + } |
| 27 | + |
| 28 | + ulong guildId = ulong.Parse(match.Groups[1].Value); |
| 29 | + ulong channelId = ulong.Parse(match.Groups[2].Value); |
| 30 | + ulong messageId = ulong.Parse(match.Groups[3].Value); |
| 31 | + |
| 32 | + if (guildId != context.Guild.Id) |
| 33 | + { |
| 34 | + response.WithContent("The message must be in this guild."); |
| 35 | + await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, response).ConfigureAwait(false); |
| 36 | + return; |
| 37 | + } |
| 38 | + |
| 39 | + DiscordChannel? channel = context.Guild.GetChannel(channelId); |
| 40 | + if (channel is null) |
| 41 | + { |
| 42 | + response.WithContent($"The channel {channelId} does not exist."); |
| 43 | + await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, response).ConfigureAwait(false); |
| 44 | + return; |
| 45 | + } |
| 46 | + |
| 47 | + DiscordMessage? message = await channel.GetMessageAsync(messageId).ConfigureAwait(false); |
| 48 | + if (message is null) |
| 49 | + { |
| 50 | + response.WithContent($"The message {messageId} does not exist."); |
| 51 | + await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, response).ConfigureAwait(false); |
| 52 | + return; |
| 53 | + } |
| 54 | + |
| 55 | + if (message.Author.Id != context.Client.CurrentUser.Id) |
| 56 | + { |
| 57 | + response.WithContent("The message must be sent by this bot."); |
| 58 | + await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, response).ConfigureAwait(false); |
| 59 | + return; |
| 60 | + } |
| 61 | + |
| 62 | + if (message.Embeds.Count == 0) |
| 63 | + { |
| 64 | + response.WithContent("The message must contain an embed to edit."); |
| 65 | + await context.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, response).ConfigureAwait(false); |
| 66 | + return; |
| 67 | + } |
| 68 | + |
| 69 | + var builder = new DiscordEmbedBuilder(message.Embeds[0]); |
| 70 | + |
| 71 | + var modal = new DiscordModalBuilder(context.Client); |
| 72 | + modal.WithTitle("Edit Embed"); |
| 73 | + |
| 74 | + DiscordModalTextInput titleInput = modal.AddInput("Title", "The title of the embed.", maxLength: 256, isRequired: true, initialValue: builder.Title); |
| 75 | + DiscordModalTextInput colorInput = modal.AddInput("Color", "e.g. #007EC6", maxLength: 7, isRequired: false, initialValue: builder.Color.HasValue ? builder.Color.Value.ToString() : null); |
| 76 | + DiscordModalTextInput descriptionInput = modal.AddInput("Description", "The body of the embed.", isRequired: true, maxLength: 2048, inputStyle: TextInputStyle.Paragraph, initialValue: builder.Description); |
| 77 | + |
| 78 | + DiscordModalResponse modalResponse = await modal.Build().RespondToAsync(context.Interaction, TimeSpan.FromMinutes(5)).ConfigureAwait(false); |
| 79 | + if (modalResponse == DiscordModalResponse.Timeout) |
| 80 | + return; |
| 81 | + |
| 82 | + DiscordColor color = builder.Color.HasValue ? builder.Color.Value : DiscordColor.CornflowerBlue; |
| 83 | + |
| 84 | + if (!string.IsNullOrWhiteSpace(colorInput.Value)) |
| 85 | + color = new DiscordColor(colorInput.Value); |
| 86 | + |
| 87 | + builder.WithColor(color); |
| 88 | + builder.WithTitle(titleInput.Value); |
| 89 | + builder.WithDescription(descriptionInput.Value); |
| 90 | + |
| 91 | + await message.ModifyAsync(embed: builder.Build()).ConfigureAwait(false); |
| 92 | + await context |
| 93 | + .FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"Embed edited for {message.JumpLink}")) |
| 94 | + .ConfigureAwait(false); |
| 95 | + } |
| 96 | + |
| 97 | + [GeneratedRegex("^https://discord(?:canary)?\\.com/channels/(\\d+)/(\\d+)/(\\d+)$", RegexOptions.Compiled)] |
| 98 | + private static partial Regex GetMessageLinkRegex(); |
| 99 | +} |
0 commit comments