discord-net / Discord.Net

An unofficial .Net wrapper for the Discord API (https://discord.com/)
https://discordnet.dev
MIT License
3.32k stars 737 forks source link

[Feature Request] Allow hot-removing individual modules from individual guilds #2536

Closed GNUGradyn closed 1 year ago

GNUGradyn commented 1 year ago

Say you have a bot startup process that adds a bunch of "public" (global) commands from modules like this

await _handler.RegisterCommandsGloballyAsync();

Later, a guild is opted into a development module (a module with [DontAutoRegister] intended for development scenarios). This can easily be handled without restarting the bot by simply doing

await _handler.AddModulesToGuildAsync(guild, false, module);

Finally, say this guild is opted back out of this development module. Now there is a problem. Discord.net does not allow removing a single module from a single guild. There are 2 options to circumvent this:

1: Run AddModulesToGuildAsync again, specifying every module you still want enabled, including normal public modules This isn't really a good option, because after doing this all the normal global commands would become development commands in that server. Also you would have to manually re-work out which modules should be included. You would have to manually go through every module adding all the modules that are either public or private but opted in.

2: Restart the bot and let it automatically reregister all the public commands and readd all the private commands This is obviously not a good option either because it would require restarting the production bot every time a server is opted out of a development command

At the moment there is currently no good way to de-register a single module from a single server. There are many scenarios where this would be useful

GNUGradyn commented 1 year ago

I dug into this as I was suspicious this might not be possible at an API level. Turns out it's not, but neither is adding a single module to a server. Discord.net is currently working around this by simply replacing all the global commands in that server with dev commands, and also adding the added modules. The same procedure in reverse is possible to remove a module. PR coming soon

cjbonn commented 1 year ago

I fail to why you can't just iterate through the interaction handler to select the modules you want to register, from what I remember it includes everything, including assigned attributes. I use this to put a bot administration command into a single bot management server. Don't see why you can't control what's selected during runtime.

GNUGradyn commented 1 year ago

My original reasoning was I wanted the global commands to remain as global commands. Turns out they are replaced with dev commands under the hood as soon as you run addModulesToGuildAsync anyway so what you described would work.

However I'm still going to make a pr from my branch in the morning because it's alot more convinient to be able to just have the interaction handler do it for you

cjbonn commented 1 year ago

Keep in mind the API limit of 200 command creates per day. If a server opts in and opts out repeatedly, they will entirely lock your bot for 24h.

GNUGradyn commented 1 year ago

Thanks. I'll keep that in mind. Luckily in my case only developers are able to opt a server in or out

BobVul commented 1 year ago

https://discord.com/developers/docs/interactions/application-commands#registering-a-command

There is a global rate limit of 200 application command creates per day, per guild