Package: discord-interactions.py
A wrapper for the Discord Interactions API that does not rely on websockets
and can therefore be used in a stateless webhook environment.Furthermore, it allows for strict separation between your commands’ structure
and and the data that is received when triggering it.InstallationRequires Python 3.8+Latest release fromPyPIusingpip:pip installdiscord-interactions.pyLatest commit from GitHub usingpipandgit:pip installgit+https://github.com/LiBa001/discord-interactions.pyNoteInstalling directly from GitHub
requires you to haveGitinstalled on your computer.If this doesn’t work, you might try:python-mpip install ...Or if you are on windows:py-mpip install ...Use with FlaskThis library is specifically designed to work seamlessly with theFlaskmicroframework.Using API-like Data ClassesThe most API-like example with the flask extension is this:fromdiscord_interactions.flask_extimportInteractionsfromdiscord_interactionsimport(ApplicationCommand,ApplicationCommandOption,ApplicationCommandOptionType,Interaction,InteractionResponse,InteractionResponseType,InteractionApplicationCommandCallbackData,)fromflaskimportFlaskimportosapp=Flask(__name__)interactions=Interactions(app,os.getenv("CLIENT_PUBLIC_KEY"))echo_cmd=ApplicationCommand("echo","what goes around comes around")echo_cmd.add_option(ApplicationCommandOption(type=ApplicationCommandOptionType.STRING,name="message",description="This will be echoed.",required=True,))@interactions.command(echo_cmd)def_echo(interaction:Interaction):msg=interaction.data.options[0].value# "message" option contentreturnInteractionResponse(type=InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,data=InteractionApplicationCommandCallbackData(content=msg),)Here, we use the rudimentaryApplicationCommand,InteractionandInteractionResponseclasses, which are in their structure basically
exact counterparts of theoriginal API models.Let’s make it a bit simpler:@interactions.command(echo_cmd)def_echo(interaction:Interaction):# different way of getting an optionmsg=interaction.data.get_option("message").valuereturnmsgNow, we don’t need to deal withInteractionResponseanymore, but instead just
return the response content as a string. The response type then defaults toInteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE. You could also just return
None, if you don’t want to send a response. You can also simply return a boolean as a
second value, indicating whether or not the command call should be displayed in Discord
(i.e. the_WITH_SOURCEpart of the response type).
Also we get the option via theget_optionhelper method.The Object-Command MapperThis library provides another abstraction layer, though.
Inspired by the concept of databaseORMs, it has an Object-Command Mapper (OCM)
that lets you define a class for each command which will then serve as both
a generic structural description of the command (likeApplicationCommand)anda container for the actual data that is received
when the command is called (likeInteraction).So, the simplest possible example looks like this:fromdiscord_interactions.flask_extimportInteractionsfromdiscord_interactions.ocmimportCommand,OptionfromflaskimportFlaskimportosapp=Flask(__name__)interactions=Interactions(app,os.getenv("CLIENT_PUBLIC_KEY"))class_Echo(Command):""" what goes around comes around """message:str=Option("This will be echoed.",required=True)@interactions.commanddef_echo(cmd:_Echo):returncmd.messageFollowup MessagesIf you want to send messages after the initial response, you need to create followup
messages. For this purpose you can use theafter_commanddecorator, that registers
a function to be called after the actual command function has returned. The function
needs to take exactly one parameter, theAfterCommandContext, which contains the
several things, like theInteractionand initialInteractionResponse.interactions=Interactions(app,PUBLIC_KEY)@interactions.command("delay")defdelay(_:Interaction):return"starting countdown",True# this message is ephemeral@delay.after_commanddefafter_delay(ctx:AfterCommandContext):delay_time=ctx.interaction.data.options[0].valuetime.sleep(delay_time)ctx.send(f"{delay_time}seconds have passed")Message ComponentsYou can also register callbacks for message components, such as buttons.
Components are registered and identified by theircustom_id.@interactions.component("my_button")defmy_button_handler(ctx:ComponentContext):returnf"{ctx.interaction.user.username}clicked the button"More ExamplesFor more examples of the different features take a look atexamples.If you want to know how to make your Discord bot work with Slash Commands
and how to set everything up, take a look atthis example project.
It hosts the program in a serverless environment via Google Cloud Run and also
provides a demo bot, so you can try out Slash Commands in your Discord server.
Check it out to learn more!