simmsb/calamity

Support Discord slash commands

BorisNikulin opened this issue · 4 comments

As of December 15, 2020 Discord released slash commands which allow "first party" custom command integration. This new API entails telling discord about your slash commands, the name followed by the args the command takes and their types, and Discord will mutually exclusively notify either a webbhook type service that responds with the JSON or recieve an interaction event from the gateway and then the bot must then tell Discord its response. In the context of a Discord library, I think operating via the gateway makes more sense.

Adding support for this feature will require:

  • Data types for declaring the slash commands(ApplicationCommand)
  • Data types for receiving interactions (Interaction)
  • Data types for responding to interactions (Interaction Response)
  • Create slash commands via the API (Docs, GET,POST,PATCH,DELETE /applications/{application.id}/commands, GET,POST,PATCH,DELETE /applications/{application.id}/guilds/{guild.id}/commands)
  • Handle the INTERACTION_CREATE gateway event (Docs are sparse but I believe the payload of the event would be the interaction JSON defined above and talked about in the docs just linked)
  • Respond initially to the interaction in 3s via the API (Docs, POST /interactions/{interaction.id}/{interaction.token}/callback)
  • Optionally respond additionally within 15m via the API (Docs, PATCH,DELETE /webhooks/<application_id>/<interaction_token>/messages/@original, POST /webhooks/<application_id>/<interaction_token>, PATCH /webhooks/<application_id>/<interaction_token>/messages/<message_id>)

Limitations

In this documentation you'll find some notes about limits and caps on certain parts of Slash Commands. At a high level, they are as follows:

  • An app can have up to 50 top-level global commands (50 commands with unique names)
  • An app can have up to an additional 50 guild commands per guild
  • An app can have up to 10 subcommand groups on a top-level command
  • An app can have up to 10 subcommands within a subcommand group
  • choices can have up to 10 values per option
  • commands can have up to 10 options per command
  • Limitations on command names
  • Limitations on nesting subcommands and groups

The webhook version of the API requires verifying public/private key signatures, however since this approach would probably not be used there is no need to worry about it.

To use slash commands the bots does need different permissions though, but that is on the bot creator to setup properly.

A Note on the ability to declare commands and their arguments

By being able to declare the types of the commands and the arguments it should be possible to create n high level DSL that would allow declaring the command, something like optparse-aplicative, along with a handler. Running the DSL would produce the required slash command declarations as well as a router that can take interactions and, by using the name and the arguments, route the interaction to the correct handler. In this regard, the DSL might look like servant.

It'll probably be fairly simple to update the current command DSL to include information for constructing slash commands from them (https://hackage.haskell.org/package/calamity-0.1.23.1/docs/Calamity-Commands-Command.html), and add some machinery for parsing the responses and handling them.

Though currently slash commands are fairly flawed (see: discord-jda/JDA#1470) so I'm not too interested in implementing anything for them at the current time.

Fair enough. Seems like they're in a public beta labeled as v1.

This will become obligatory next year as message content will become a privileged intent.

Small bots will continue to work with chat commands