2024-10-14 14:56:40 +02:00
|
|
|
// Copyright (C) 2021-present sam (starshines.gay)
|
|
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU Affero General Public License as published
|
|
|
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
2024-08-14 16:05:43 +02:00
|
|
|
using System.ComponentModel;
|
2024-10-15 01:32:59 +02:00
|
|
|
using Catalogger.Backend.Cache;
|
2024-08-19 16:12:28 +02:00
|
|
|
using Catalogger.Backend.Cache.InMemoryCache;
|
2024-08-14 16:05:43 +02:00
|
|
|
using Catalogger.Backend.Database;
|
2024-10-28 02:14:41 +01:00
|
|
|
using Catalogger.Backend.Database.Dapper.Repositories;
|
2024-08-14 16:05:43 +02:00
|
|
|
using Catalogger.Backend.Database.Queries;
|
|
|
|
|
using Catalogger.Backend.Extensions;
|
|
|
|
|
using Catalogger.Backend.Services;
|
|
|
|
|
using Remora.Commands.Attributes;
|
|
|
|
|
using Remora.Commands.Groups;
|
2024-10-15 01:32:59 +02:00
|
|
|
using Remora.Discord.API;
|
2024-08-14 16:05:43 +02:00
|
|
|
using Remora.Discord.API.Abstractions.Objects;
|
|
|
|
|
using Remora.Discord.API.Objects;
|
|
|
|
|
using Remora.Discord.Commands.Attributes;
|
|
|
|
|
using Remora.Discord.Commands.Feedback.Messages;
|
|
|
|
|
using Remora.Discord.Commands.Feedback.Services;
|
|
|
|
|
using Remora.Discord.Commands.Services;
|
2024-10-15 01:32:59 +02:00
|
|
|
using Remora.Discord.Extensions.Embeds;
|
2024-08-14 16:05:43 +02:00
|
|
|
using Remora.Discord.Interactivity;
|
|
|
|
|
using Remora.Discord.Interactivity.Services;
|
|
|
|
|
using Remora.Rest.Core;
|
|
|
|
|
using Remora.Results;
|
|
|
|
|
using DbGuild = Catalogger.Backend.Database.Models.Guild;
|
|
|
|
|
using IResult = Remora.Results.IResult;
|
|
|
|
|
|
|
|
|
|
namespace Catalogger.Backend.Bot.Commands;
|
|
|
|
|
|
|
|
|
|
public class ChannelCommands(
|
|
|
|
|
ILogger logger,
|
2024-10-15 01:32:59 +02:00
|
|
|
Config config,
|
2024-10-28 02:14:41 +01:00
|
|
|
GuildRepository guildRepository,
|
2024-08-19 16:12:28 +02:00
|
|
|
GuildCache guildCache,
|
|
|
|
|
ChannelCache channelCache,
|
2024-10-15 01:32:59 +02:00
|
|
|
IMemberCache memberCache,
|
2024-08-14 16:05:43 +02:00
|
|
|
IFeedbackService feedbackService,
|
|
|
|
|
ContextInjectionService contextInjection,
|
2024-10-15 01:32:59 +02:00
|
|
|
InMemoryDataService<Snowflake, ChannelCommandData> dataService,
|
|
|
|
|
PermissionResolverService permissionResolver
|
2024-10-09 17:35:11 +02:00
|
|
|
) : CommandGroup
|
2024-08-14 16:05:43 +02:00
|
|
|
{
|
|
|
|
|
private readonly ILogger _logger = logger.ForContext<ChannelCommands>();
|
|
|
|
|
|
2024-10-15 01:32:59 +02:00
|
|
|
private static readonly DiscordPermission[] RequiredGuildPermissions =
|
|
|
|
|
[
|
|
|
|
|
DiscordPermission.ManageGuild,
|
|
|
|
|
DiscordPermission.ViewAuditLog,
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// TODO: i hate this
|
2024-10-14 21:28:34 +02:00
|
|
|
[Command("check-permissions")]
|
|
|
|
|
[Description(
|
|
|
|
|
"Check for any permission issues that would prevent Catalogger from sending logs."
|
|
|
|
|
)]
|
|
|
|
|
[DiscordDefaultMemberPermissions(DiscordPermission.ManageGuild)]
|
|
|
|
|
public async Task<IResult> CheckPermissionsAsync()
|
|
|
|
|
{
|
2024-10-15 01:32:59 +02:00
|
|
|
var (userId, guildId) = contextInjection.GetUserAndGuild();
|
|
|
|
|
if (!guildCache.TryGet(guildId, out var guild))
|
|
|
|
|
throw new CataloggerError("Guild not in cache");
|
|
|
|
|
|
|
|
|
|
var embed = new EmbedBuilder().WithTitle($"Permission check for {guild.Name}");
|
|
|
|
|
|
|
|
|
|
var botUser = await memberCache.TryGetAsync(
|
|
|
|
|
guildId,
|
|
|
|
|
DiscordSnowflake.New(config.Discord.ApplicationId)
|
|
|
|
|
);
|
|
|
|
|
var currentUser = await memberCache.TryGetAsync(guildId, userId);
|
|
|
|
|
if (botUser == null || currentUser == null)
|
|
|
|
|
throw new CataloggerError("Bot member or invoking member not found in cache");
|
|
|
|
|
|
|
|
|
|
// We don't want to check categories or threads
|
|
|
|
|
var guildChannels = channelCache
|
|
|
|
|
.GuildChannels(guildId)
|
|
|
|
|
.Where(c =>
|
|
|
|
|
c.Type
|
|
|
|
|
is not (
|
|
|
|
|
ChannelType.GuildCategory
|
|
|
|
|
or ChannelType.PublicThread
|
|
|
|
|
or ChannelType.PrivateThread
|
|
|
|
|
or ChannelType.AnnouncementThread
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
// We'll only check channels the user can see, to not leak any information.
|
|
|
|
|
var checkChannels = guildChannels
|
|
|
|
|
.Where(c =>
|
|
|
|
|
{
|
|
|
|
|
var perms = permissionResolver.GetChannelPermissions(guildId, currentUser, c);
|
|
|
|
|
return perms.HasPermission(DiscordPermission.ViewChannel)
|
|
|
|
|
|| perms.HasPermission(DiscordPermission.Administrator);
|
|
|
|
|
})
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
var ignoredChannels = guildChannels.Count - checkChannels.Count;
|
|
|
|
|
if (ignoredChannels != 0)
|
|
|
|
|
embed = embed.WithFooter(
|
|
|
|
|
$"{ignoredChannels} channel(s) were ignored as you do not have access to them"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
var guildPerms = permissionResolver.GetGuildPermissions(guildId, botUser);
|
|
|
|
|
// If the bot has admin perms, we can ignore the rest--we'll never get permission errors
|
|
|
|
|
if (guildPerms.HasPermission(DiscordPermission.Administrator))
|
|
|
|
|
{
|
|
|
|
|
return await feedbackService.ReplyAsync(
|
|
|
|
|
embeds:
|
|
|
|
|
[
|
|
|
|
|
embed
|
|
|
|
|
.WithColour(DiscordUtils.Green)
|
|
|
|
|
.WithDescription("No issues found, all channels can be logged to and from!")
|
|
|
|
|
.Build()
|
|
|
|
|
.GetOrThrow(),
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var missingGuildPerms = string.Join(
|
|
|
|
|
", ",
|
|
|
|
|
RequiredGuildPermissions.Where(p => !guildPerms.HasPermission(p))
|
|
|
|
|
);
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(missingGuildPerms))
|
|
|
|
|
embed.AddField("Server-level permissions", missingGuildPerms);
|
|
|
|
|
|
|
|
|
|
var missingManageChannel = new List<Snowflake>();
|
|
|
|
|
var missingSendMessages = new List<Snowflake>();
|
|
|
|
|
var missingViewChannel = new List<Snowflake>();
|
|
|
|
|
var missingReadMessageHistory = new List<Snowflake>();
|
|
|
|
|
var missingManageWebhooks = new List<Snowflake>();
|
|
|
|
|
|
|
|
|
|
foreach (var channel in checkChannels)
|
|
|
|
|
{
|
|
|
|
|
var channelPerms = permissionResolver.GetChannelPermissions(guildId, botUser, channel);
|
|
|
|
|
if (!channelPerms.HasPermission(DiscordPermission.ManageChannels))
|
|
|
|
|
missingManageChannel.Add(channel.ID);
|
|
|
|
|
if (!channelPerms.HasPermission(DiscordPermission.SendMessages))
|
|
|
|
|
missingSendMessages.Add(channel.ID);
|
|
|
|
|
if (!channelPerms.HasPermission(DiscordPermission.ViewChannel))
|
|
|
|
|
missingViewChannel.Add(channel.ID);
|
|
|
|
|
if (!channelPerms.HasPermission(DiscordPermission.ReadMessageHistory))
|
|
|
|
|
missingReadMessageHistory.Add(channel.ID);
|
|
|
|
|
if (!channelPerms.HasPermission(DiscordPermission.ManageWebhooks))
|
|
|
|
|
missingManageWebhooks.Add(channel.ID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (missingManageChannel.Count != 0)
|
|
|
|
|
embed.AddField(
|
|
|
|
|
"Manage Channel",
|
|
|
|
|
string.Join("\n", missingManageChannel.Select(id => $"<#{id}>"))
|
|
|
|
|
);
|
|
|
|
|
if (missingSendMessages.Count != 0)
|
|
|
|
|
embed.AddField(
|
|
|
|
|
"Send Messages",
|
|
|
|
|
string.Join("\n", missingSendMessages.Select(id => $"<#{id}>"))
|
|
|
|
|
);
|
|
|
|
|
if (missingReadMessageHistory.Count != 0)
|
|
|
|
|
embed.AddField(
|
|
|
|
|
"Read Message History",
|
|
|
|
|
string.Join("\n", missingReadMessageHistory.Select(id => $"<#{id}>"))
|
|
|
|
|
);
|
|
|
|
|
if (missingViewChannel.Count != 0)
|
|
|
|
|
embed.AddField(
|
|
|
|
|
"View Channel",
|
|
|
|
|
string.Join("\n", missingViewChannel.Select(id => $"<#{id}>"))
|
|
|
|
|
);
|
|
|
|
|
if (missingManageWebhooks.Count != 0)
|
|
|
|
|
embed.AddField(
|
|
|
|
|
"Manage Webhooks",
|
|
|
|
|
string.Join("\n", missingManageWebhooks.Select(id => $"<#{id}>"))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (embed.Fields.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
embed = embed
|
|
|
|
|
.WithColour(DiscordUtils.Green)
|
|
|
|
|
.WithDescription("No issues found, all channels can be logged to and from!");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
embed = embed
|
|
|
|
|
.WithColour(DiscordUtils.Red)
|
|
|
|
|
.WithDescription("Permission issues found, please fix them and try again.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await feedbackService.ReplyAsync(embeds: [embed.Build().GetOrThrow()]);
|
2024-10-14 21:28:34 +02:00
|
|
|
}
|
|
|
|
|
|
2024-08-14 16:05:43 +02:00
|
|
|
[Command("configure-channels")]
|
|
|
|
|
[Description("Configure log channels for this server.")]
|
|
|
|
|
[DiscordDefaultMemberPermissions(DiscordPermission.ManageGuild)]
|
|
|
|
|
public async Task<IResult> ConfigureChannelsAsync()
|
|
|
|
|
{
|
2024-09-02 15:06:10 +02:00
|
|
|
var (userId, guildId) = contextInjection.GetUserAndGuild();
|
2024-10-09 17:35:11 +02:00
|
|
|
if (!guildCache.TryGet(guildId, out var guild))
|
|
|
|
|
throw new CataloggerError("Guild not in cache");
|
2024-08-14 16:05:43 +02:00
|
|
|
var guildChannels = channelCache.GuildChannels(guildId).ToList();
|
2024-10-28 02:14:41 +01:00
|
|
|
var guildConfig = await guildRepository.GetAsync(guildId);
|
2024-08-14 16:05:43 +02:00
|
|
|
|
|
|
|
|
var (embeds, components) = BuildRootMenu(guildChannels, guild, guildConfig);
|
|
|
|
|
|
2024-10-09 17:35:11 +02:00
|
|
|
var msg = await feedbackService
|
|
|
|
|
.SendContextualAsync(
|
|
|
|
|
embeds: embeds,
|
|
|
|
|
options: new FeedbackMessageOptions(MessageComponents: components)
|
|
|
|
|
)
|
|
|
|
|
.GetOrThrow();
|
2024-08-14 16:05:43 +02:00
|
|
|
|
|
|
|
|
dataService.TryAddData(msg.ID, new ChannelCommandData(userId, CurrentPage: null));
|
|
|
|
|
|
|
|
|
|
return Result.Success;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-09 17:35:11 +02:00
|
|
|
public static (List<IEmbed>, List<IMessageComponent>) BuildRootMenu(
|
|
|
|
|
List<IChannel> guildChannels,
|
|
|
|
|
IGuild guild,
|
|
|
|
|
DbGuild guildConfig
|
|
|
|
|
)
|
2024-08-14 16:05:43 +02:00
|
|
|
{
|
|
|
|
|
List<IEmbed> embeds =
|
|
|
|
|
[
|
|
|
|
|
new Embed(
|
|
|
|
|
Title: $"Log channels for {guild.Name}",
|
|
|
|
|
Description: "Press one of the buttons below to change the channel for that log type.",
|
|
|
|
|
Colour: DiscordUtils.Purple,
|
|
|
|
|
Fields: new[]
|
|
|
|
|
{
|
2024-10-09 17:35:11 +02:00
|
|
|
new EmbedField(
|
|
|
|
|
"Server changes",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildUpdate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Emoji changes",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildEmojisUpdate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"New roles",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildRoleCreate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Edited roles",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildRoleUpdate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Deleted roles",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildRoleDelete),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"New channels",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.ChannelCreate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Edited channels",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.ChannelUpdate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Deleted channels",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.ChannelDelete),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Members joining",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildMemberAdd),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Members leaving",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildMemberRemove),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Member role changes",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildMemberUpdate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Key role changes",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildKeyRoleUpdate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Member name changes",
|
2024-08-14 16:05:43 +02:00
|
|
|
PrettyChannelString(guildConfig.Channels.GuildMemberNickUpdate),
|
2024-10-09 17:35:11 +02:00
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Member avatar changes",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildMemberAvatarUpdate),
|
|
|
|
|
true
|
|
|
|
|
),
|
2024-10-11 20:38:53 +02:00
|
|
|
new EmbedField(
|
|
|
|
|
"Timeouts",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildMemberTimeout),
|
|
|
|
|
true
|
|
|
|
|
),
|
2024-10-09 17:35:11 +02:00
|
|
|
new EmbedField(
|
|
|
|
|
"Kicks",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildMemberKick),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Bans",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildBanAdd),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Unbans",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.GuildBanRemove),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"New invites",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.InviteCreate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Deleted invites",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.InviteDelete),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Edited messages",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.MessageUpdate),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Deleted messages",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.MessageDelete),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
new EmbedField(
|
|
|
|
|
"Bulk deleted messages",
|
|
|
|
|
PrettyChannelString(guildConfig.Channels.MessageDeleteBulk),
|
|
|
|
|
true
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
),
|
2024-08-14 16:05:43 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
List<IMessageComponent> components =
|
|
|
|
|
[
|
2024-10-09 17:35:11 +02:00
|
|
|
new ActionRowComponent(
|
|
|
|
|
[
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Server changes",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Emoji changes",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildEmojisUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "New roles",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildRoleCreate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Edited roles",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildRoleUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Deleted roles",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildRoleDelete)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
new ActionRowComponent(
|
|
|
|
|
[
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "New channels",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.ChannelCreate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Edited channels",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.ChannelUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Deleted channels",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.ChannelDelete)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Members joining",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildMemberAdd)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Members leaving",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildMemberRemove)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
new ActionRowComponent(
|
|
|
|
|
[
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Member role changes",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildMemberUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Key role changes",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildKeyRoleUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Member name changes",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildMemberNickUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
2024-10-11 20:38:53 +02:00
|
|
|
Label: "Member avatar changes",
|
2024-10-09 17:35:11 +02:00
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildMemberAvatarUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
2024-10-11 20:38:53 +02:00
|
|
|
Label: "Timeouts",
|
2024-10-09 17:35:11 +02:00
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
2024-10-11 20:38:53 +02:00
|
|
|
nameof(LogChannelType.GuildMemberTimeout)
|
2024-10-09 17:35:11 +02:00
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
new ActionRowComponent(
|
|
|
|
|
[
|
2024-10-11 20:38:53 +02:00
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Kicks",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildMemberKick)
|
|
|
|
|
)
|
|
|
|
|
),
|
2024-10-09 17:35:11 +02:00
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Bans",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildBanAdd)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Unbans",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.GuildBanRemove)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "New invites",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.InviteCreate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Deleted invites",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.InviteDelete)
|
|
|
|
|
)
|
|
|
|
|
),
|
2024-10-11 20:38:53 +02:00
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
new ActionRowComponent(
|
|
|
|
|
[
|
2024-10-09 17:35:11 +02:00
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Edited messages",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.MessageUpdate)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Deleted messages",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.MessageDelete)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Primary,
|
|
|
|
|
Label: "Bulk deleted messages",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
nameof(LogChannelType.MessageDeleteBulk)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
new ButtonComponent(
|
|
|
|
|
ButtonComponentStyle.Secondary,
|
|
|
|
|
Label: "Close",
|
|
|
|
|
CustomID: CustomIDHelpers.CreateButtonIDWithState(
|
|
|
|
|
"config-channels",
|
|
|
|
|
"close"
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
),
|
2024-08-14 16:05:43 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (embeds, components);
|
|
|
|
|
|
|
|
|
|
string PrettyChannelString(ulong id)
|
|
|
|
|
{
|
2024-10-09 17:35:11 +02:00
|
|
|
if (id == 0)
|
|
|
|
|
return "Not set";
|
|
|
|
|
if (guildChannels.All(c => c.ID != id))
|
|
|
|
|
return $"unknown channel {id}";
|
2024-08-14 16:05:43 +02:00
|
|
|
return $"<#{id}>";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-09 17:35:11 +02:00
|
|
|
public static string PrettyLogTypeName(LogChannelType type) =>
|
|
|
|
|
type switch
|
|
|
|
|
{
|
|
|
|
|
LogChannelType.GuildUpdate => "Server changes",
|
|
|
|
|
LogChannelType.GuildEmojisUpdate => "Emoji changes",
|
|
|
|
|
LogChannelType.GuildRoleCreate => "New roles",
|
|
|
|
|
LogChannelType.GuildRoleUpdate => "Edited roles",
|
|
|
|
|
LogChannelType.GuildRoleDelete => "Deleted roles",
|
|
|
|
|
LogChannelType.ChannelCreate => "New channels",
|
|
|
|
|
LogChannelType.ChannelUpdate => "Edited channels",
|
|
|
|
|
LogChannelType.ChannelDelete => "Deleted channels",
|
|
|
|
|
LogChannelType.GuildMemberAdd => "Members joining",
|
2024-10-11 20:38:53 +02:00
|
|
|
LogChannelType.GuildMemberUpdate => "Member role changes",
|
2024-10-09 17:35:11 +02:00
|
|
|
LogChannelType.GuildKeyRoleUpdate => "Key role changes",
|
|
|
|
|
LogChannelType.GuildMemberNickUpdate => "Member name changes",
|
|
|
|
|
LogChannelType.GuildMemberAvatarUpdate => "Member avatar changes",
|
2024-10-11 20:38:53 +02:00
|
|
|
LogChannelType.GuildMemberTimeout => "Timeouts",
|
2024-10-09 17:35:11 +02:00
|
|
|
LogChannelType.GuildMemberRemove => "Members leaving",
|
|
|
|
|
LogChannelType.GuildMemberKick => "Kicks",
|
|
|
|
|
LogChannelType.GuildBanAdd => "Bans",
|
|
|
|
|
LogChannelType.GuildBanRemove => "Unbans",
|
|
|
|
|
LogChannelType.InviteCreate => "New invites",
|
|
|
|
|
LogChannelType.InviteDelete => "Deleted invites",
|
|
|
|
|
LogChannelType.MessageUpdate => "Edited messages",
|
|
|
|
|
LogChannelType.MessageDelete => "Deleted messages",
|
|
|
|
|
LogChannelType.MessageDeleteBulk => "Bulk deleted messages",
|
|
|
|
|
_ => throw new ArgumentOutOfRangeException(
|
|
|
|
|
nameof(type),
|
|
|
|
|
type,
|
|
|
|
|
"Invalid LogChannelType value"
|
|
|
|
|
),
|
|
|
|
|
};
|
|
|
|
|
}
|