Skip to content

Instantly share code, notes, and snippets.

@manbeardgames
Created March 4, 2021 20:14
Show Gist options
  • Select an option

  • Save manbeardgames/c2ff8e03ce4917c152894546e4404507 to your computer and use it in GitHub Desktop.

Select an option

Save manbeardgames/c2ff8e03ce4917c152894546e4404507 to your computer and use it in GitHub Desktop.
Discord Bot Group Not Working
using System.Threading.Tasks;
using Discord.Commands;
namespace Rena.Modules
{
public class AboutModule : BaseModule
{
[Command("about")]
public async Task AboutAsync()
{
Discord.EmbedBuilder embed = new Discord.EmbedBuilder();
embed.Title = "Hi! I'm Rena";
embed.Description = "Nice To Meet You! ";
embed.AddField("About Me", "I'm a discord bot. I'm not ready for use yet, but I will be soon.");
embed.ThumbnailUrl = _renaThumbnail;
await ReplyAsync(null, false, embed.Build());
}
}
}
using Discord.Commands;
namespace Rena.Modules
{
public abstract class BaseModule : ModuleBase<SocketCommandContext>
{
protected readonly string _renaThumbnail = @"https://vignette.wikia.nocookie.net/starocean/images/f/fb/Tales_Rena_default.png/revision/latest?cb=20190624002000";
}
}
using System;
using System.Reflection;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Rena.Utils;
namespace Rena.Handlers
{
public class DiscordCommandHandler
{
private readonly DiscordSocketClient _client;
private readonly CommandService _commandService;
private readonly IServiceProvider _serviceProvider;
public DiscordCommandHandler(DiscordSocketClient client, IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_client = client;
CommandServiceConfig config = new CommandServiceConfig();
config.CaseSensitiveCommands = false;
config.DefaultRunMode = RunMode.Async;
config.IgnoreExtraArgs = true;
config.SeparatorChar = ',';
_commandService = new CommandService(config);
}
public async Task InitializeAsync()
{
await _commandService.AddModulesAsync(Assembly.GetEntryAssembly(), _serviceProvider);
_commandService.CommandExecuted += OnCommandExecutedAsync;
}
public async Task OnCommandExecutedAsync(Optional<CommandInfo> command, ICommandContext context, IResult result)
{
// We have access ot the information of the command executed,
// the context of the command, and the result returned from the
// execution in this event.
// We can tell the user what went wrong
if(!string.IsNullOrEmpty(result?.ErrorReason))
{
await context.Channel.SendMessageAsync(result.ErrorReason);
}
// ... or even log the result (themethod used should fit into
// your existing log handler)
var commandName = command.IsSpecified ? command.Value.Name : "A command";
Logger.Message($"CommandExecution {commandName} was executed");
if(!string.IsNullOrEmpty(result?.ErrorReason))
{
Logger.Error(result.ErrorReason);
}
}
public async Task HandleCommandsAsync(SocketMessage socketMessage)
{
if (!(socketMessage is SocketUserMessage message)) { return; }
if (message.Author.IsBot) { return; }
// Create a number to track where the prefix ends and the command begins
int argPos = 0;
if (!message.HasStringPrefix("!rena ", ref argPos)) { return; }
Logger.Message($"Command Given: {message}");
Logger.Message($"argPos: {argPos}");
// Create a WebSocket-based command context based on the message
SocketCommandContext context = new SocketCommandContext(_client, message);
// Execute the command with the command context we just created, along with
// the service provider for precondition checks.
//
// Keep in mind that result does not indicate a return value
// rather an object stating if the command executed successfully
var result = await _commandService.ExecuteAsync(context, argPos, _serviceProvider);
}
}
}
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using Rena.Utils;
namespace Rena.Handlers
{
public class DiscordEventHandler
{
private readonly DiscordSocketClient _client;
private readonly DiscordCommandHandler _commandHandler;
public DiscordEventHandler(DiscordSocketClient client, DiscordCommandHandler commandHandler)
{
_client = client;
_commandHandler = commandHandler;
}
public void InitializeEvents()
{
_client.Log += OnClientLog;
_client.MessageReceived += OnClientMessageReceived;
}
private Task OnClientLog(LogMessage log)
{
switch (log.Severity)
{
case LogSeverity.Critical:
case LogSeverity.Error:
Logger.Error(log.Message);
break;
case LogSeverity.Warning:
Logger.Warning(log.Message);
break;
case LogSeverity.Info:
case LogSeverity.Verbose:
case LogSeverity.Debug:
default:
Logger.Message(log.Message);
break;
}
return Task.CompletedTask;
}
private async Task OnClientMessageReceived(SocketMessage message) => await _commandHandler.HandleCommandsAsync(message);
}
}
using System;
using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Rena.Utils;
namespace Rena.Modules
{
[Group("poll")]
public class PollModule : BaseModule
{
[Command("create")]
public async Task CreatePollAsync(string question, params string[] answers)
{
if (string.IsNullOrWhiteSpace(question))
{
await InvalidAsync("You must add a question for the poll");
return;
}
if (answers.Length < 2)
{
await InvalidAsync("You must supply at minimum 2 answers");
}
if (answers.Length > 10)
{
await InvalidAsync("No more than 10 answers are allowed");
}
StringBuilder responseBuilder = new StringBuilder();
for (int i = 0; i < answers.Length; i++)
{
responseBuilder.Append(i switch
{
0 => Reactions.Standard.Symbols.one,
1 => Reactions.Standard.Symbols.two,
2 => Reactions.Standard.Symbols.three,
3 => Reactions.Standard.Symbols.four,
4 => Reactions.Standard.Symbols.five,
5 => Reactions.Standard.Symbols.six,
6 => Reactions.Standard.Symbols.seven,
7 => Reactions.Standard.Symbols.eight,
8 => Reactions.Standard.Symbols.nine,
9 => Reactions.Standard.Symbols.keycap_ten,
_ => string.Empty
});
responseBuilder.AppendLine($" {answers[i]}");
}
Discord.EmbedBuilder embed = new Discord.EmbedBuilder();
embed.Title = "New Poll";
embed.Description = $"{Context.User.Username} created the following poll. To Vote in the poll, click the appropriate discord reaction at the bottom of the post";
embed.AddField("Poll Question", question);
embed.AddField("Available Responses", responseBuilder.ToString());
embed.ThumbnailUrl = _renaThumbnail;
IUserMessage message = await ReplyAsync(null, false, embed.Build());
IEmote[] reactions = new IEmote[answers.Length];
for (int i = 0; i < reactions.Length; i++)
{
reactions[i] = i switch
{
0 => new Emoji(Reactions.Standard.Symbols.one),
1 => new Emoji(Reactions.Standard.Symbols.two),
2 => new Emoji(Reactions.Standard.Symbols.three),
3 => new Emoji(Reactions.Standard.Symbols.four),
4 => new Emoji(Reactions.Standard.Symbols.five),
5 => new Emoji(Reactions.Standard.Symbols.six),
6 => new Emoji(Reactions.Standard.Symbols.seven),
7 => new Emoji(Reactions.Standard.Symbols.eight),
8 => new Emoji(Reactions.Standard.Symbols.nine),
9 => new Emoji(Reactions.Standard.Symbols.keycap_ten),
_ => throw new Exception("Unknown reaction to add to poll message")
};
}
await message.AddReactionsAsync(reactions);
}
[Command("help")]
public async Task HelpAsync()
{
Discord.EmbedBuilder embed = new Discord.EmbedBuilder();
embed.Title = "Poll Help";
embed.Description = $"To create a poll, use the following command\n`!rena poll <\"Question\"> <\"Response 1\"> <\"Response 2\"> ....[\"Response 10\"]`{Environment.NewLine}{Environment.NewLine}";
embed.Description += "A minimum of 2 answers must be supplied and no more than 10 answers can be given.";
embed.ThumbnailUrl = _renaThumbnail;
await ReplyAsync(null, false, embed.Build());
}
private async Task InvalidAsync(string reason)
{
Discord.EmbedBuilder embed = new Discord.EmbedBuilder();
embed.Title = "Poll error";
embed.Description = $"{reason}{Environment.NewLine}";
embed.Description += "For more information use the command `!rena poll help`";
embed.ThumbnailUrl = _renaThumbnail;
await ReplyAsync(null, false, embed.Build());
}
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using Microsoft.Extensions.DependencyInjection;
using Rena.Handlers;
using Rena.Utils;
namespace Rena
{
public class Program
{
// The Discord client used to communicate with the discord services.
private static DiscordSocketClient _client;
// Service provider used for dependency injection.
public static IServiceProvider _serviceProvider;
/// <summary>
/// Application entry point, provides immediate async context for
/// entire application from the start.
/// </summary>
/// <param name="args">
/// Arguments provided from the command line. Currently non supported.
/// </param>
public static void Main(string[] args)
{
new Program().MainAsync().GetAwaiter().GetResult();
}
/// <summary>
/// The main async entry point for the application.
/// </summary>
/// <returns>
/// Task.Completed.
/// </returns>
public async Task MainAsync()
{
// -------------------------------------------
// Initialize services for dependency injection
// -------------------------------------------
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<DiscordEventHandler>();
serviceCollection.AddSingleton<DiscordCommandHandler>();
serviceCollection.AddSingleton<DiscordSocketClient>();
_serviceProvider = serviceCollection.BuildServiceProvider();
// -------------------------------------------
// Login the client
// -------------------------------------------
using (_client = _serviceProvider.GetRequiredService<DiscordSocketClient>())
{
_serviceProvider.GetRequiredService<DiscordEventHandler>().InitializeEvents();
await _serviceProvider.GetRequiredService<DiscordCommandHandler>().InitializeAsync();
bool loggedIn = false;
try
{
await _client.LoginAsync(TokenType.Bot, "Token Removed, Use Your Own");
loggedIn = true;
}
catch (Exception ex)
{
Logger.Error($"The following exception occurred while attempting to log in the discord client. \"{ex.Message}\"");
}
if (loggedIn)
{
await _client.StartAsync();
await Task.Delay(-1);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment