From 56fae83f03692848a363e6df6deae0ca618a9f0f Mon Sep 17 00:00:00 2001 From: Marro64 Date: Sun, 23 Nov 2025 16:55:44 +0100 Subject: [PATCH] Splitting up, doesn't work --- FluxPoseDiscordBot/ActionsBase.cs | 7 + FluxPoseDiscordBot/Experimenting/Actions.cs | 32 +++ .../Experimenting/ButtonCommands.cs | 16 ++ .../Experimenting/SlashCommands.cs | 107 +++++++++ FluxPoseDiscordBot/FluxPoseDiscordBot.csproj | 2 +- FluxPoseDiscordBot/GlobalSetup.cs | 10 + FluxPoseDiscordBot/Program.cs | 211 ++---------------- FluxPoseDiscordBot/Roles/Actions.cs | 15 ++ FluxPoseDiscordBot/Roles/SlashCommands.cs | 5 + FluxPoseDiscordBot/Users/Actions.cs | 15 ++ FluxPoseDiscordBot/appsettings.json | 2 +- 11 files changed, 225 insertions(+), 197 deletions(-) create mode 100644 FluxPoseDiscordBot/ActionsBase.cs create mode 100644 FluxPoseDiscordBot/Experimenting/Actions.cs create mode 100644 FluxPoseDiscordBot/Experimenting/ButtonCommands.cs create mode 100644 FluxPoseDiscordBot/Experimenting/SlashCommands.cs create mode 100644 FluxPoseDiscordBot/GlobalSetup.cs create mode 100644 FluxPoseDiscordBot/Roles/Actions.cs create mode 100644 FluxPoseDiscordBot/Roles/SlashCommands.cs create mode 100644 FluxPoseDiscordBot/Users/Actions.cs diff --git a/FluxPoseDiscordBot/ActionsBase.cs b/FluxPoseDiscordBot/ActionsBase.cs new file mode 100644 index 0000000..a1c11ed --- /dev/null +++ b/FluxPoseDiscordBot/ActionsBase.cs @@ -0,0 +1,7 @@ +namespace FluxPose.DiscordBot +{ + public abstract class ActionsBase(TContext context) where TContext : IInteractionContext + { + public ulong GuildId => context.Interaction.Guild?.Id ?? throw new InvalidOperationException("Action cannot be performed outside of a server."); + } +} diff --git a/FluxPoseDiscordBot/Experimenting/Actions.cs b/FluxPoseDiscordBot/Experimenting/Actions.cs new file mode 100644 index 0000000..3b8fc95 --- /dev/null +++ b/FluxPoseDiscordBot/Experimenting/Actions.cs @@ -0,0 +1,32 @@ +namespace FluxPose.DiscordBot.Experimenting; + +public class Actions(Users.Actions usersActions, GatewayClient client, TContext context) : ActionsBase(context) where TContext : IInteractionContext +{ + public async Task GetRandomUserFromGuild() + { + var users = await usersActions.GetAllUsersFromGuild(); + + var index = new Random().Next(users.Count); + return users[index]; + } + + public async Task RemoveRoleFromAllUsers(ulong roleId) + { + var users = await usersActions.GetAllUsersFromGuild(); + + foreach (var user in users) + { + if (user.RoleIds.Contains(roleId)) + { + continue; + } + + await client.Rest.RemoveGuildUserRoleAsync(GuildId, user.Id, roleId); + } + } + + public async Task> GetAllGuildEmoji() + { + return await client.Rest.GetGuildEmojisAsync(GuildId); + } +} diff --git a/FluxPoseDiscordBot/Experimenting/ButtonCommands.cs b/FluxPoseDiscordBot/Experimenting/ButtonCommands.cs new file mode 100644 index 0000000..fb14ea1 --- /dev/null +++ b/FluxPoseDiscordBot/Experimenting/ButtonCommands.cs @@ -0,0 +1,16 @@ +using NetCord.Services.ComponentInteractions; + +namespace FluxPose.DiscordBot.Experimenting; + +public class ButtonCommands : ComponentInteractionModule +{ + [ComponentInteraction("testButton")] + public async Task RespondToTestButton() + { + await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); + + await Context.Message.ModifyAsync(message => message.WithContent($"{Context.Message.Content}a")); + + await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Clicked!")); + } +} \ No newline at end of file diff --git a/FluxPoseDiscordBot/Experimenting/SlashCommands.cs b/FluxPoseDiscordBot/Experimenting/SlashCommands.cs new file mode 100644 index 0000000..0a02fd9 --- /dev/null +++ b/FluxPoseDiscordBot/Experimenting/SlashCommands.cs @@ -0,0 +1,107 @@ +namespace FluxPose.DiscordBot.Experimenting; + +public class SlashCommands(Actions experimentingActions, Users.Actions usersActions, Roles.Actions rolesActions, GatewayClient client) : ApplicationCommandModule +{ + [SlashCommand("randomuser", "Get a random user from the server")] + public async Task GetRandomUserCommand() + { + await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); + var randomUser = await experimentingActions.GetRandomUserFromGuild(); + + if (randomUser == null) + { + return $"Found no users :("; + } + + return $"Here's a random user: {randomUser.Username}"; + } + + [SlashCommand("getroles", "Get all roles on the server")] + public async Task GetRolesCommand() + { + await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); + + var roles = await rolesActions.GetRolesFromGuild(); + + roles = [.. roles.Where(role => !role.Name.StartsWith('@'))]; + + if (roles.Count == 0) + { + return $"Found no roles :("; + } + + return $"Roles in the server:\n{String.Join("\n", roles.Select(role => $"- {role.Id}: {role.Name}"))}"; + } + + [SlashCommand("giveroletouser", "Give a role")] + public async Task GiveRoleToAllUsersCommand(string userId, string roleId) + { + await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); + + var parsed = ulong.TryParse(userId, out ulong userIdParsed); + if (!parsed) + { + return "Invalid roleId"; + } + + parsed = ulong.TryParse(roleId, out ulong roleIdParsed); + if (!parsed) + { + return "Invalid roleId"; + } + + await rolesActions.GiveRoleToUser(userIdParsed, roleIdParsed); + + return "Done."; + } + + [SlashCommand("removerolefromallusers", "Remove role from all users on the server")] + public async Task RemoveRoleFromAllUsersCommand(string roleId) + { + await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); + + var parsed = ulong.TryParse(roleId, out ulong roleIdParsed); + if (!parsed) + { + return "Invalid roleId"; + } + + await experimentingActions.RemoveRoleFromAllUsers(roleIdParsed); + + return "Done."; + } + + [SlashCommand("defer", "Defer")] + public async Task DeferCommand() + { + await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); + + Thread.Sleep(2000); + + await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Sup")); + + Thread.Sleep(1000); + + await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Sup bitches")); + } + + [SlashCommand("button", "Gives a button")] + public async Task ButtonCommand() + { + await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); + + var emojis = await experimentingActions.GetAllGuildEmoji(); + + EmojiProperties? emoji = null; + if (emojis.Count > 0) + { + emoji = EmojiProperties.Custom(emojis[new Random().Next(emojis.Count)].Id); + } + + var button = new ButtonProperties("testButton", "Click Me!", emoji!, ButtonStyle.Primary); + + var component = new ActionRowProperties([button]); + + await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Here's a button").WithComponents([component])); + } +} diff --git a/FluxPoseDiscordBot/FluxPoseDiscordBot.csproj b/FluxPoseDiscordBot/FluxPoseDiscordBot.csproj index 50b864a..2f3866e 100644 --- a/FluxPoseDiscordBot/FluxPoseDiscordBot.csproj +++ b/FluxPoseDiscordBot/FluxPoseDiscordBot.csproj @@ -5,6 +5,7 @@ net9.0 enable enable + FluxPose.DiscordBot @@ -20,5 +21,4 @@ PreserveNewest - \ No newline at end of file diff --git a/FluxPoseDiscordBot/GlobalSetup.cs b/FluxPoseDiscordBot/GlobalSetup.cs new file mode 100644 index 0000000..fdee568 --- /dev/null +++ b/FluxPoseDiscordBot/GlobalSetup.cs @@ -0,0 +1,10 @@ +global using NetCord; +global using NetCord.Gateway; +global using NetCord.Rest; +global using NetCord.Services.ApplicationCommands; +global using NetCord.Services; +global using System; +global using System.Collections.Generic; +global using System.Linq; +global using System.Text; +global using System.Threading.Tasks; \ No newline at end of file diff --git a/FluxPoseDiscordBot/Program.cs b/FluxPoseDiscordBot/Program.cs index 4e97f0f..f062ed6 100644 --- a/FluxPoseDiscordBot/Program.cs +++ b/FluxPoseDiscordBot/Program.cs @@ -1,20 +1,15 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.VisualBasic; -using NetCord; -using NetCord.Gateway; using NetCord.Hosting.Gateway; using NetCord.Hosting.Services; using NetCord.Hosting.Services.ApplicationCommands; using NetCord.Hosting.Services.ComponentInteractions; -using NetCord.Rest; -using NetCord.Services.ApplicationCommands; using NetCord.Services.ComponentInteractions; -using System.ComponentModel; -using System.Linq; -public static class Program +namespace FluxPose.DiscordBot; + +internal static class Program { public static void Main(string[] args) { @@ -28,204 +23,30 @@ public static class Program .AddApplicationCommands() .AddComponentInteractions(); + AddActions(builder.Services); + var host = builder.Build(); var configuration = host.Services.GetRequiredService(); - //configuration["Discord:Token"] = Environment.GetEnvironmentVariable("BOT_TOKEN"); + var token = Environment.GetEnvironmentVariable("BOT_TOKEN"); + if (token != null) + { + configuration["Discord:Token"] = token; + } host.AddModules(typeof(Program).Assembly); host.RunAsync().GetAwaiter().GetResult(); } -} -public class SlashCommands(GatewayClient client) : ApplicationCommandModule -{ - private ulong GuildId => GetGuildId() ?? throw new InvalidOperationException("Command cannot be used outside of a server."); - - [SlashCommand("randomuser", "Get a random user from the server")] - public async Task GetRandomUserCommand() + private static void AddActions(IServiceCollection services) { - await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); - var randomUser = await GetRandomUserFromGuild(); + services.AddScoped(); + services.AddScoped(); - if (randomUser == null) - { - return $"Found no users :("; - } - - return $"Here's a random user: {randomUser.Username}"; - } - - [SlashCommand("getroles", "Get all roles on the server")] - public async Task GetRolesCommand() - { - await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); - - var roles = await GetRolesFromGuild(); - - roles = [.. roles.Where(role => !role.Name.StartsWith('@'))]; - - if (roles.Count == 0) - { - return $"Found no roles :("; - } - - return $"Roles in the server:\n{String.Join("\n", roles.Select(role => $"- {role.Id}: {role.Name}"))}"; - } - - [SlashCommand("giveroletoallusers", "Give role to all users on the server")] - public async Task GiveRoleToAllUsersCommand(string roleId) - { - await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); - - var parsed = ulong.TryParse(roleId, out ulong roleIdParsed); - if (!parsed) - { - return "Invalid roleId"; - } - - await GiveRoleToAllUsers(roleIdParsed); - - return "Done."; - } - - [SlashCommand("removerolefromallusers", "Remove role from all users on the server")] - public async Task RemoveRoleFromAllUsersCommand(string roleId) - { - await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); - - var parsed = ulong.TryParse(roleId, out ulong roleIdParsed); - if (!parsed) - { - return "Invalid roleId"; - } - - await RemoveRoleFromAllUsers(roleIdParsed); - - return "Done."; - } - - [SlashCommand("defer", "Defer")] - public async Task DeferCommand() - { - await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); - - Thread.Sleep(2000); - - await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Sup")); - - Thread.Sleep(1000); - - await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Sup bitches")); - } - - //[SlashCommand("button", "Gives a button")] - //public async Task ButtonCommand() - //{ - // await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); - - // var emojis = await client.Rest.GetGuildEmojisAsync(GuildId); - - // EmojiProperties? emoji = null; - // if (emojis.Count > 0) - // { - // emoji = EmojiProperties.Custom(emojis[new Random().Next(emojis.Count)].Id); - // } - - // var button = new ButtonProperties(TestButtonId, "Click Me!", emoji!, ButtonStyle.Primary); - - // var component = new ActionRowProperties([button]); - - // await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Here's a button").WithComponents([component])); - //} - - [SlashCommand("button", "Gives a button")] - public async Task ButtonCommand() - { - await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); - - var emojis = await client.Rest.GetGuildEmojisAsync(GuildId); - - EmojiProperties? emoji = null; - if (emojis.Count > 0) - { - emoji = EmojiProperties.Custom(emojis[new Random().Next(emojis.Count)].Id); - } - - var button = new ButtonProperties("testButton", "Click Me!", emoji!, ButtonStyle.Primary); - - var component = new ActionRowProperties([button]); - - await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Here's a button").WithComponents([component])); - } - - private ulong? GetGuildId() - { - return Context.Guild?.Id; - } - - private async Task GetRandomUserFromGuild() - { - var users = await GetAllUsersFromGuild(); - - var index = new Random().Next(users.Count); - return users[index]; - } - - private async Task> GetAllUsersFromGuild() - { - var users = await client.Rest.GetGuildUsersAsync(GuildId).ToListAsync(); - if (users == null) - { - return []; - } - - return users; - } - - private async Task> GetRolesFromGuild() - { - var roles = (await client.Rest.GetGuildRolesAsync(GuildId)).ToList(); - return roles; - } - - private async Task GiveRoleToAllUsers(ulong roleId) - { - var users = await GetAllUsersFromGuild(); - - foreach (var user in users) - { - await client.Rest.AddGuildUserRoleAsync(GuildId, user.Id, roleId); - } - } - - private async Task RemoveRoleFromAllUsers(ulong roleId) - { - var users = await GetAllUsersFromGuild(); - - foreach (var user in users) - { - if (user.RoleIds.Contains(roleId)) - { - continue; - } - - await client.Rest.RemoveGuildUserRoleAsync(GuildId, user.Id, roleId); - } + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); } } - -public class ButtonCommands : ComponentInteractionModule -{ - [ComponentInteraction("testButton")] - public async Task RespondToTestButton() - { - await Context.Interaction.SendResponseAsync(InteractionCallback.DeferredMessage()); - - await Context.Message.ModifyAsync(message => message.WithContent($"{Context.Message.Content}a")); - - await Context.Interaction.ModifyResponseAsync(message => message.WithContent("Clicked!")); - } -} \ No newline at end of file diff --git a/FluxPoseDiscordBot/Roles/Actions.cs b/FluxPoseDiscordBot/Roles/Actions.cs new file mode 100644 index 0000000..5f605c8 --- /dev/null +++ b/FluxPoseDiscordBot/Roles/Actions.cs @@ -0,0 +1,15 @@ +namespace FluxPose.DiscordBot.Roles; + +public class Actions(Users.Actions usersActions, GatewayClient client, TContext context) : ActionsBase(context) where TContext : IInteractionContext +{ + public async Task> GetRolesFromGuild() + { + var roles = (await client.Rest.GetGuildRolesAsync(GuildId)).ToList(); + return roles; + } + + public async Task GiveRoleToUser(ulong userId, ulong roleId) + { + await client.Rest.AddGuildUserRoleAsync(GuildId, userId, roleId); + } +} diff --git a/FluxPoseDiscordBot/Roles/SlashCommands.cs b/FluxPoseDiscordBot/Roles/SlashCommands.cs new file mode 100644 index 0000000..59b8cc2 --- /dev/null +++ b/FluxPoseDiscordBot/Roles/SlashCommands.cs @@ -0,0 +1,5 @@ +namespace FluxPose.DiscordBot.Roles; + +public class SlashCommands +{ +} diff --git a/FluxPoseDiscordBot/Users/Actions.cs b/FluxPoseDiscordBot/Users/Actions.cs new file mode 100644 index 0000000..bdf7eab --- /dev/null +++ b/FluxPoseDiscordBot/Users/Actions.cs @@ -0,0 +1,15 @@ +namespace FluxPose.DiscordBot.Users; + +public class Actions(GatewayClient client, TContext context) : ActionsBase(context) where TContext : IInteractionContext +{ + public async Task> GetAllUsersFromGuild() + { + var users = await client.Rest.GetGuildUsersAsync(GuildId).ToListAsync(); + if (users == null) + { + return []; + } + + return users; + } +} diff --git a/FluxPoseDiscordBot/appsettings.json b/FluxPoseDiscordBot/appsettings.json index a45fb6d..8f9175c 100644 --- a/FluxPoseDiscordBot/appsettings.json +++ b/FluxPoseDiscordBot/appsettings.json @@ -1,5 +1,5 @@ { "Discord": { - "Token": "Token from Discord Developer Portal" + "Token": "MTQzOTk1MjIzMzAxMjY1ODI2Ng.GePLJF.ljh--yyvzz3Os5t8kZlhNnHnJuT-gQxpjGAgyA" } } \ No newline at end of file