C
C#13mo ago
Immortal

❔ Need help with discord command to toggle a task

using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;

namespace self_bot.commands
{
internal class TestCommand : ApplicationCommandModule
{
private DiscordClient _clientInstance;

public TestCommand(DiscordClient client)
{
_clientInstance = client;
}

private static bool IsOn = false;

[SlashCommand("ToggleTest", "Toggle test messages to be sent at user after every message")]
public async Task Toggle(InteractionContext ctx, [Option("user", "Specified user")] DiscordUser user)
{
IsOn=!IsOn;

if (IsOn==true)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle online"));
_clientInstance.MessageCreated += TestMessage(user, e);
}

if (IsOn==false)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle shutting down"));
_clientInstance.MessageCreated -= TestMessage(user, e);
}
}
public async Task TestMessage(DiscordUser user, MessageCreateEventArgs e)
{
if (e.Message.Author.Id == user.Id)
{
await e.Message.RespondAsync("Test success");
}
}
}
}
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;

namespace self_bot.commands
{
internal class TestCommand : ApplicationCommandModule
{
private DiscordClient _clientInstance;

public TestCommand(DiscordClient client)
{
_clientInstance = client;
}

private static bool IsOn = false;

[SlashCommand("ToggleTest", "Toggle test messages to be sent at user after every message")]
public async Task Toggle(InteractionContext ctx, [Option("user", "Specified user")] DiscordUser user)
{
IsOn=!IsOn;

if (IsOn==true)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle online"));
_clientInstance.MessageCreated += TestMessage(user, e);
}

if (IsOn==false)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle shutting down"));
_clientInstance.MessageCreated -= TestMessage(user, e);
}
}
public async Task TestMessage(DiscordUser user, MessageCreateEventArgs e)
{
if (e.Message.Author.Id == user.Id)
{
await e.Message.RespondAsync("Test success");
}
}
}
}
So I'm trying to make a command that takes a user as an input and toggles a task that uses that user as an input parameter for the toggled task. So you do something like: /ToggleTest user1 Then anytime user1 sends a message the bot will respond with "Test success" Then you can do /ToggleTest user1 to toggle it off.
80 Replies
Matt
Matt13mo ago
So basically you want each user to have their own IsOwn value - that can be done using a Dictionary or HashSet for example What a dictionary does is map a certain key (what would identify a Discord user uniquely?) to a value (in your case, a boolean) - that way you can have multiple "variables" at once
Immortal
Immortal13mo ago
Eventually yes, but right now just trying to get it to work in general as I'm getting errors and I'm not sure how to solve them
Matt
Matt13mo ago
Does your current code not send messages? 🤔
Immortal
Immortal13mo ago
Getting 2 errors each on the Ifs: The name 'e' does not exist in the current context Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'DSharpPlus.AsyncEvents.AsyncEventHandler<DSharpPlus.DiscordClient, DSharpPlus.EventArgs.MessageCreateEventArgs>' Been looking at the discord.MessageCreated += async (s, e) => part in the "Your First Bot" in the DSharpPlus documentation and took that as a guide for something like this Nope, because of the errors I can't run it, If I remove the _clientInstance.MessageCreated += TestMessage(user, e); and _clientInstance.MessageCreated -= TestMessage(user, e); then I can run it and get the messages that the toggle is on because there's no errors
Matt
Matt13mo ago
I'll have to look into that library as I have never used it, brb
Immortal
Immortal13mo ago
Here's the part I'm looking at: https://dsharpplus.github.io/DSharpPlus/articles/basics/first_bot.html Scroll down to bottom and you'll see the Finished Product part with the discord.MessageCreated += async (s, e) =>
Matt
Matt13mo ago
From those docs, it looks like MessageCreated is an event handler - you use that to detect messages are coming instead of adding a hook to that event handler every time the command is run, I'd suggest adding a hook once in your application and then using a variable to figure out if the user should be replied to or not
Immortal
Immortal13mo ago
Something like this?
if (IsOn==true)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle online"));
_clientInstance.MessageCreated += async (s, e) =>
{
if (e.Message.Author==user.Id)
await e.Message.RespondAsync("Test success");
}
if (IsOn==true)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle online"));
_clientInstance.MessageCreated += async (s, e) =>
{
if (e.Message.Author==user.Id)
await e.Message.RespondAsync("Test success");
}
Matt
Matt13mo ago
hmm, nope here's the thing: your bot is always receiving Discord messages, adding a hook to MessageCreated only forwards them to your code instead of voiding so there's pretty much no extra cost in always listening to Discord messages ^
Immortal
Immortal13mo ago
I'm not sure how to do what you're suggesting
Matt
Matt13mo ago
where do you create _clientInstance? that's only created once, right?
Immortal
Immortal13mo ago
At the top of the code yeah
internal class TestCommand : ApplicationCommandModule
{
private DiscordClient _clientInstance;

public TestCommand(DiscordClient client)
{
_clientInstance = client;
}
internal class TestCommand : ApplicationCommandModule
{
private DiscordClient _clientInstance;

public TestCommand(DiscordClient client)
{
_clientInstance = client;
}
Matt
Matt13mo ago
right, but you're just assigning client to it where do you create the instance that goes into client?
Immortal
Immortal13mo ago
In my Bot.cs:
using System.Text.Json;
using DSharpPlus;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;
using JsonConfig;

namespace self_bot
{
public class Bot
{
public DiscordClient Client { get; private set; }
public SlashCommandsExtension Slash { get; private set; }

public async Task RunAsync()
{
try
{
var config = InitializeConfig();

Client = new DiscordClient(config);

Client.Ready += OnClientReady;

var slashConfig = new SlashCommandsConfiguration
{

};

Slash = Client.UseSlashCommands(slashConfig);

SlashRegistry.RegisterCommands(Slash);

await Client.ConnectAsync();
await Task.Delay(-1);

}
catch (Exception ex)
{
Console.WriteLine($"Error running bot..\n------- EXCEPTION -------\n {ex.Message}\n------- EXCEPTION -------");
}
}

private Task OnClientReady(DiscordClient sender, ReadyEventArgs e)
{
return Task.CompletedTask;
}

private static DiscordConfiguration InitializeConfig()
{
var jsonString = File.ReadAllText("config.json");

var configJson = JsonSerializer.Deserialize<ConfigJson>(jsonString);

var config = new DiscordConfiguration
{
Token = configJson.Token,
TokenType = TokenType.Bot,
AutoReconnect = true
};

return config;
}
}
}
using System.Text.Json;
using DSharpPlus;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;
using JsonConfig;

namespace self_bot
{
public class Bot
{
public DiscordClient Client { get; private set; }
public SlashCommandsExtension Slash { get; private set; }

public async Task RunAsync()
{
try
{
var config = InitializeConfig();

Client = new DiscordClient(config);

Client.Ready += OnClientReady;

var slashConfig = new SlashCommandsConfiguration
{

};

Slash = Client.UseSlashCommands(slashConfig);

SlashRegistry.RegisterCommands(Slash);

await Client.ConnectAsync();
await Task.Delay(-1);

}
catch (Exception ex)
{
Console.WriteLine($"Error running bot..\n------- EXCEPTION -------\n {ex.Message}\n------- EXCEPTION -------");
}
}

private Task OnClientReady(DiscordClient sender, ReadyEventArgs e)
{
return Task.CompletedTask;
}

private static DiscordConfiguration InitializeConfig()
{
var jsonString = File.ReadAllText("config.json");

var configJson = JsonSerializer.Deserialize<ConfigJson>(jsonString);

var config = new DiscordConfiguration
{
Token = configJson.Token,
TokenType = TokenType.Bot,
AutoReconnect = true
};

return config;
}
}
}
Matt
Matt13mo ago
perfect :) you're doing this here:
Client = new DiscordClient(config);
Client.Ready += OnClientReady;
Client = new DiscordClient(config);
Client.Ready += OnClientReady;
that tells your function OnClientReady that the bot is connected to Discord and ready for using why not have the MessageCreated hook added there aswell? that way you're always getting Discord's messages to process yourself, and don't have to deal with adding or removing that hook when a command is run
Immortal
Immortal13mo ago
I'm not sure I understand what you mean here? You want me to add Client.Ready += TestMessage; ? Sorry, I know must be frustrating trying to help me
Matt
Matt13mo ago
nah it's fine! :) I just don't want to give you copy-pasteable code because that would most likely not teach anything 😂
Immortal
Immortal13mo ago
Yeah that's fair
Matt
Matt13mo ago
Client.Ready is an event handler, when you use += you're adding a hook (a function that listens to events) to it - that's the same as saying "whenever this event happens, make sure my hook function is called"
Immortal
Immortal13mo ago
Also try to keep all code relating to a command inside the same class, Idk if it's good or bad practice but I feel like it's more organized
Matt
Matt13mo ago
that's actually a pretty interesting topic in more advanced architectures xD there's a big debate on how to divide code, and what you described is pretty close to what VSA (Vertical Slice Architecture) would suggest
Immortal
Immortal13mo ago
I understand that part, I come from Python background only started playing around with C# like 2 days ago
Matt
Matt13mo ago
I don't have an IDE with me at the moment so can you try switching _clientInstance.MessageCreated += TestMessage(user, e); to _clientInstance.MessageCreated += TestMessage;? same thing for -= trying to go with your suggestion of having everything in the same file :p
Immortal
Immortal13mo ago
This is what my first approach was but didn't work, will try again though Yeah this was the error I was getting: No overload for 'TestMessage' matches delegate 'AsyncEventHandler<DiscordClient, MessageCreateEventArgs>'
Matt
Matt13mo ago
that error tells me the compiler wants DiscordClient as first parameter
Immortal
Immortal13mo ago
From reading it I thought it's because I didn't pass anything in as parameters so I tried adding them
Matt
Matt13mo ago
but here you're asking for DiscordUser:
public async Task TestMessage(DiscordUser user, MessageCreateEventArgs e)
public async Task TestMessage(DiscordUser user, MessageCreateEventArgs e)
Immortal
Immortal13mo ago
I don't know why though, I don't ask for a DiscordClient in my TestMessage Task
Matt
Matt13mo ago
https://dsharpplus.github.io/DSharpPlus/api/DSharpPlus.DiscordClient.MessageCreated.html those are the arguments actually being declared by DSharpPlus
public event AsyncEventHandler<DiscordClient, MessageCreateEventArgs> MessageCreated
public event AsyncEventHandler<DiscordClient, MessageCreateEventArgs> MessageCreated
your hook function has to match those, as there's no way to go from DiscordClient (what DSharpPlus passes) to DiscordUser (what your hook function is asking for)
Immortal
Immortal13mo ago
So I need something like this? _clientInstance.MessageCreated += TestMessage(_clientInstance, e); Is this bad practice or something? I thought it was good because of being more modular 😅
Matt
Matt13mo ago
if you write TestMessage(_clientInstance, e) you're calling TestMessage with those arguments, but you want the event handler to be calling the function instead 🤔 _clientInstance.MessageCreated += TestMessage; would be the correct with you changing TestMessage to public async Task TestMessage(DiscordClient client, MessageCreateEventArgs e)
Immortal
Immortal13mo ago
But how am I going to pass the user into the task to check against if I do that?
Matt
Matt13mo ago
well, those arguments are what DSharpPlus' API sends so you don't have control over that MessageCreateEventArgs will contain the user that sent the message you're receiving the event of
Immortal
Immortal13mo ago
That's what I'm using to check against for the input user of the command though, I'll just end up checking against the same thing which will means it will always be true
Matt
Matt13mo ago
I think you're misunderstanding how event handlers work 😅 they're defined in code somewhere and when triggered cause all listening hooks to be executed if an event handler passes DiscordClient instead of DiscordUser, you have to accept DiscordClient - there's no way to force it to pass DiscordUser you'll have the user that sent the message inside MessageCreateEventArgs, so what you can do is create another place to store if an user should be replied to or not - then compare those two what I mean with this is DSharpPlus defines what the parameters in your function should be, not you
Immortal
Immortal13mo ago
So there's no way for me to pass on the user variable in this code to the TestMessage Task? public async Task Toggle(InteractionContext ctx, [Option("user", "Specified user")] DiscordUser user)
Matt
Matt13mo ago
correct you could actually create another lambda function to pass the user variable that way, but then you're doing the same thing as using a variable in the class
Immortal
Immortal13mo ago
Sorry, I'm just so confused how there's no way for me to just pass on a variable to my function 😅
Matt
Matt13mo ago
no worries :) it's because in this case DSharpPlus is what will be calling your function, not you that's why the arguments are defined by it and you can't have different ones 🤔
Immortal
Immortal13mo ago
I think I understand this part now, but I still don't get how there isn't a simple way to pass it on to the function Wait I think I have something that Might work?
Matt
Matt13mo ago
seems fun
Immortal
Immortal13mo ago
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;

namespace self_bot.commands
{
internal class TestCommand : ApplicationCommandModule
{
private DiscordClient _clientInstance;
private DiscordUser _user;

public TestCommand(DiscordClient Client)
{
_clientInstance = Client;
}

private static bool IsOn = false;

[SlashCommand("ToggleTest", "Toggle test messages to be sent at user after every message")]
public async Task Toggle(InteractionContext ctx, [Option("user", "Specified user")] DiscordUser user)
{
IsOn=!IsOn;
_user = user;

if (IsOn==true)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle online"));
_clientInstance.MessageCreated += TestMessage;

if (IsOn==false)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle shutting down"));
_clientInstance.MessageCreated += TestMessage;
}
}
}
public async Task TestMessage(DiscordClient client, MessageCreateEventArgs e)
{
if (e.Message.Author.Id == _user.Id)
{
await e.Message.RespondAsync("Test success");
}
}
}
}
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;

namespace self_bot.commands
{
internal class TestCommand : ApplicationCommandModule
{
private DiscordClient _clientInstance;
private DiscordUser _user;

public TestCommand(DiscordClient Client)
{
_clientInstance = Client;
}

private static bool IsOn = false;

[SlashCommand("ToggleTest", "Toggle test messages to be sent at user after every message")]
public async Task Toggle(InteractionContext ctx, [Option("user", "Specified user")] DiscordUser user)
{
IsOn=!IsOn;
_user = user;

if (IsOn==true)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle online"));
_clientInstance.MessageCreated += TestMessage;

if (IsOn==false)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle shutting down"));
_clientInstance.MessageCreated += TestMessage;
}
}
}
public async Task TestMessage(DiscordClient client, MessageCreateEventArgs e)
{
if (e.Message.Author.Id == _user.Id)
{
await e.Message.RespondAsync("Test success");
}
}
}
}
This is what I did
Matt
Matt13mo ago
looks pretty good :)
Immortal
Immortal13mo ago
I declared a _user variable outside the command made it equal to user when the command is executed and that can be used by the TestMessage function without being a parameter of the function, not sure if it will work
Matt
Matt13mo ago
that's what I was going for yep 😂 you can't change hook function arguments... so add variables to your class and use them inside it xD I don't think that code will work the way you want it to yet, but that was some progress
Immortal
Immortal13mo ago
Is my methodology good practice? cx
Matt
Matt13mo ago
having everything needed to handle a feature inside the same code file? I honestly like it Vertical Slice Architecture is all about that, but probably not worth for you researching it rn 😂
Immortal
Immortal13mo ago
using DSharpPlus.SlashCommands;
using self_bot.commands;

namespace self_bot
{
internal static class SlashRegistry
{
//Register commands by adding the class that the commands belong to (all commands within a class will be added if multiple exist)
internal static void RegisterCommands(SlashCommandsExtension slash)
{
slash.RegisterCommands<Test_command>();
slash.RegisterCommands<Test_command2>();
slash.RegisterCommands<SimpleCommands>();
}
}
}
using DSharpPlus.SlashCommands;
using self_bot.commands;

namespace self_bot
{
internal static class SlashRegistry
{
//Register commands by adding the class that the commands belong to (all commands within a class will be added if multiple exist)
internal static void RegisterCommands(SlashCommandsExtension slash)
{
slash.RegisterCommands<Test_command>();
slash.RegisterCommands<Test_command2>();
slash.RegisterCommands<SimpleCommands>();
}
}
}
Then all I do is register the commands into this SlashRegistry commands which is then used by my Bot.cs, I thought it made it super easy to manage and very modular
Matt
Matt13mo ago
yeah that's fine in my opinion
Immortal
Immortal13mo ago
The bot doesn't respond lol, but yeah it's progress
Matt
Matt13mo ago
should that check be inside the other if?
if (IsOn==false)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle shutting down"));
_clientInstance.MessageCreated += TestMessage;
}
if (IsOn==false)
{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle shutting down"));
_clientInstance.MessageCreated += TestMessage;
}
Immortal
Immortal13mo ago
Whoops nope it should not Thanks for catching that
Matt
Matt13mo ago
can you add a Console.WriteLine call to your code to check if your Toggle function is being run?
Immortal
Immortal13mo ago
Wait nvm Not getting any Console.Writelines getting this error
Immortal
Immortal13mo ago
This is where I've added them
Matt
Matt13mo ago
hmmm... when doing /toggletest are you passing an user? does Discord give you that option?
Immortal
Immortal13mo ago
Yeah It does
Immortal
Immortal13mo ago
Matt
Matt13mo ago
perhaps your bot doesn't have the permission to send messages?
Immortal
Immortal13mo ago
It does, it works with other commands
Immortal
Immortal13mo ago
Immortal
Immortal13mo ago
I gave it all intents and perms in the dev portal
Matt
Matt13mo ago
alright I'll look into it then
Immortal
Immortal13mo ago
Thank you very much I'm thinking it might be to do with the client variable I have in the TestCommand class not being the same as the one in my Bot class
Matt
Matt13mo ago
I didn't spot anything wrong with your code 🤔
Slash commands can be registered either globally or for a certain guild. However, if you try to register them globally, they can take up to an hour to cache across all guilds. So, it is recommended that you only register them for a certain guild for testing, and only register them globally once they're ready to be used.
Slash commands can be registered either globally or for a certain guild. However, if you try to register them globally, they can take up to an hour to cache across all guilds. So, it is recommended that you only register them for a certain guild for testing, and only register them globally once they're ready to be used.
from https://dsharpplus.github.io/DSharpPlus/articles/slash_commands.html I don't think that would be the cause of the issue though, as the command shows in your Discord client
Immortal
Immortal13mo ago
Here's the updated TestCommand:
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;

namespace self_bot.commands
{
internal class TestCommand : ApplicationCommandModule
{
private DiscordClient _clientInstance;
private DiscordUser _user;

public TestCommand(DiscordClient Client)
{
_clientInstance = Client;
}

private static bool IsOn = false;

[SlashCommand("ToggleTest", "Toggle test messages to be sent at user after every message")]
public async Task Toggle(InteractionContext ctx, [Option("user", "Specified user")] DiscordUser user)
{
Console.WriteLine("1");
IsOn=!IsOn;
_user = user;

if (IsOn==true)
{
Console.WriteLine("2");
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle online"));
_clientInstance.MessageCreated += TestMessage;
}

if (IsOn==false)

{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle shutting down"));
_clientInstance.MessageCreated += TestMessage;
}
}
public async Task TestMessage(DiscordClient client, MessageCreateEventArgs e)
{
if (e.Message.Author.Id == _user.Id)
{
await e.Message.RespondAsync("Test success");
}
}
}
}
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;

namespace self_bot.commands
{
internal class TestCommand : ApplicationCommandModule
{
private DiscordClient _clientInstance;
private DiscordUser _user;

public TestCommand(DiscordClient Client)
{
_clientInstance = Client;
}

private static bool IsOn = false;

[SlashCommand("ToggleTest", "Toggle test messages to be sent at user after every message")]
public async Task Toggle(InteractionContext ctx, [Option("user", "Specified user")] DiscordUser user)
{
Console.WriteLine("1");
IsOn=!IsOn;
_user = user;

if (IsOn==true)
{
Console.WriteLine("2");
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle online"));
_clientInstance.MessageCreated += TestMessage;
}

if (IsOn==false)

{
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Test toggle shutting down"));
_clientInstance.MessageCreated += TestMessage;
}
}
public async Task TestMessage(DiscordClient client, MessageCreateEventArgs e)
{
if (e.Message.Author.Id == _user.Id)
{
await e.Message.RespondAsync("Test success");
}
}
}
}
And here's my Bot.cs:
using System.Text.Json;
using DSharpPlus;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;
using JsonConfig;

namespace self_bot
{
public class Bot
{
public DiscordClient Client { get; private set; }
public SlashCommandsExtension Slash { get; private set; }

public async Task RunAsync()
{
try
{
var config = InitializeConfig();

Client = new DiscordClient(config);

Client.Ready += OnClientReady;

var slashConfig = new SlashCommandsConfiguration
{

};

Slash = Client.UseSlashCommands(slashConfig);

SlashRegistry.RegisterCommands(Slash);

await Client.ConnectAsync();
await Task.Delay(-1);

}
catch (Exception ex)
{
Console.WriteLine($"Error running bot..\n------- EXCEPTION -------\n {ex.Message}\n------- EXCEPTION -------");
}
}

private Task OnClientReady(DiscordClient sender, ReadyEventArgs e)
{
return Task.CompletedTask;
}

private static DiscordConfiguration InitializeConfig()
{
var jsonString = File.ReadAllText("config.json");

var configJson = JsonSerializer.Deserialize<ConfigJson>(jsonString);

var config = new DiscordConfiguration
{
Token = configJson.Token,
TokenType = TokenType.Bot,
AutoReconnect = true
};

return config;
}
}
}
using System.Text.Json;
using DSharpPlus;
using DSharpPlus.EventArgs;
using DSharpPlus.SlashCommands;
using JsonConfig;

namespace self_bot
{
public class Bot
{
public DiscordClient Client { get; private set; }
public SlashCommandsExtension Slash { get; private set; }

public async Task RunAsync()
{
try
{
var config = InitializeConfig();

Client = new DiscordClient(config);

Client.Ready += OnClientReady;

var slashConfig = new SlashCommandsConfiguration
{

};

Slash = Client.UseSlashCommands(slashConfig);

SlashRegistry.RegisterCommands(Slash);

await Client.ConnectAsync();
await Task.Delay(-1);

}
catch (Exception ex)
{
Console.WriteLine($"Error running bot..\n------- EXCEPTION -------\n {ex.Message}\n------- EXCEPTION -------");
}
}

private Task OnClientReady(DiscordClient sender, ReadyEventArgs e)
{
return Task.CompletedTask;
}

private static DiscordConfiguration InitializeConfig()
{
var jsonString = File.ReadAllText("config.json");

var configJson = JsonSerializer.Deserialize<ConfigJson>(jsonString);

var config = new DiscordConfiguration
{
Token = configJson.Token,
TokenType = TokenType.Bot,
AutoReconnect = true
};

return config;
}
}
}
Matt
Matt13mo ago
silly thing... the docs always use [SlashCommand] with lowercase name - maybe that's a requirement? can you try changing SlashCommand("ToggleTest" to SlashCommand("toggletest"? Discord client is showing that command in lowercase too
Immortal
Immortal13mo ago
Didn't work, I'd be super surprised if that was the case though
Matt
Matt13mo ago
yeah me too lol
Immortal
Immortal13mo ago
I think it's to do with this. 1st picture is from TestCommand, 2nd is from Bot.cs. I'm thinking the _clientInstance is being set to the Client variable in the Bot.cs like I thought it was
Matt
Matt13mo ago
any reason why you create a blank config here?
var slashConfig = new SlashCommandsConfiguration {};
var slashConfig = new SlashCommandsConfiguration {};
Immortal
Immortal13mo ago
Haven't gotten around to filling that out yet
Matt
Matt13mo ago
doc doesn't pass that
Matt
Matt13mo ago
so maybe passing it blank is not expected, idk though
Immortal
Immortal13mo ago
My other slash commands have worked fine
Matt
Matt13mo ago
yeah I'm not sure why your first Console.WriteLine isn't being hit 😅 I use Disnake for my bots and when developing slash commands I always add the guild ID as that updates a lot faster than no guild ID... doubt that's the issue here though
Slash commands can be registered either globally or for a certain guild. However, if you try to register them globally, they can take up to an hour to cache across all guilds. So, it is recommended that you only register them for a certain guild for testing, and only register them globally once they're ready to be used.
Slash commands can be registered either globally or for a certain guild. However, if you try to register them globally, they can take up to an hour to cache across all guilds. So, it is recommended that you only register them for a certain guild for testing, and only register them globally once they're ready to be used.
D#+ has the same thing in their docs https://dsharpplus.github.io/DSharpPlus/articles/slash_commands.html#setup
Immortal
Immortal13mo ago
I just tried to do a try catch on it and it's not giving me anything either
Immortal
Immortal13mo ago
I GOT IT WORKING
Immortal
Immortal13mo ago
Now I need to figure out how I'm going to make it work for multiple users Thank you so much for all your help
Accord
Accord13mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.