Releases: breqdev/flask-discord-interactions
Quart support! Use asyncio with commands
This release introduces the ability to use Quart instead of Flask (#18, #23). This allows developers to write commands that use asyncio, which is a more familiar experience for longtime discord.py users.
from quart import Quart
import quart.flask_patch
from flask_discord_interactions import DiscordInteractions
app = Quart(__name__)
discord = DiscordInteractions(app)
discord.update_slash_commands()
@discord.command()
async def ping(ctx):
"Respond with a friendly 'pong'!"
return "Pong!"
# Non-async functions still work
@discord.command()
def pong(ctx):
return "Ping!"
Additionally, this adds an AsyncContext
object for handling followup messages:
@discord.command()
async def wait(ctx, seconds: int):
async def do_followup():
await asyncio.sleep(seconds)
await ctx.edit("Done!")
await ctx.close()
asyncio.create_task(do_followup())
return Response(deferred=True)
# Normal followups use the normal Context
@discord.command()
def wait_sync(ctx, seconds: int):
def do_followup():
time.sleep(seconds)
ctx.edit("Done!")
threading.Thread(target=do_followup).start()
return Response(deferred=True)
This update also allows embeds to be included in ephemeral responses, as per #19.
Testing Client, Context Dataclasses, Response and Embed Dataclasses
New features:
- A
Client
object that can be used to run automated tests against Slash Commands (#16) - An
Embed
dataclass that can be used to create embeds more pythonically (#17)
Changes:
Context
,Member
,Role
,User
, andChannel
are now dataclasses, making initialization easier (#16)Response
is now a dataclass (#17)
Project structure:
pytest
is now used to run unit tests and generate coverage reports
Add offline mode which disables sig check for local debugging
This release adds two new options to app.config
:
DONT_VALIDATE_SIGNATURE
disables validating the signature on incoming POST requestsDONT_REGISTER_WITH_DISCORD
disables registering slash commands with the Discord API
These can be used to debug a bot locally using Postman, cURL, or a similar tool. Read the documentation here for more information.
Thank you @akiller for submitting and documenting this patch! (#13)
Allow using Enums to define choices for options
This release adds the ability to use Python Enums to define option choices using type hinting.
Old syntax (still works, but no longer the recommended way):
@discord.command(options=[{
"name": "choice",
"description": "Your favorite animal",
"type": CommandOptionType.STRING,
"required": True,
"choices": [
{
"name": "Dog",
"value": "dog"
},
{
"name": "Cat",
"value": "cat"
}
]
}])
def favorite(ctx, choice):
"What is your favorite animal?"
return f"{ctx.author.display_name} chooses {choice}!"
New syntax:
class Animal(enum.Enum):
Dog = "dog"
Cat = "cat"
@discord.command(annotations={"choice": "Your favorite animal"})
def favorite(ctx, choice: Animal):
"What is your favorite animal?"
return f"{ctx.author.display_name} chooses {choice}!"
Additionally, this version now includes Sphinx docs.
Add a throttle to handle rate-limiting automatically
Add a throttle to handle Discord rate-limiting automatically.
Discord lowered the rate-limit for slash command registration. Previously, this library did not respect the rate limit, and it would crash if it received a 429 Too Many Requests
from Discord. This update uses the X-RateLimit
headers, as per the Discord docs, to add a time delay between requests if necessary to avoid this issue.
Add decorator-based subcommand syntax and type-annotation-based parameter syntax
This release makes some changes to the syntax for declaring subcommands and command parameters in order to bring it more in line with Discord.py.
Note that the old syntax still works, but moving forward, the new syntax will be the preferred method.
Subcommands
Old syntax:
@discord.command(options=[
{
"name": "google",
"description": "Search with Google",
"type": CommandOptionType.SUB_COMMAND,
"options": [{
"name": "query",
"description": "Search query",
"type": CommandOptionType.STRING,
"required": True
}]
},
{
"name": "bing",
"description": "Search with Bing",
"type": CommandOptionType.SUB_COMMAND,
"options": [{
"name": "query",
"description": "Search query",
"type": CommandOptionType.STRING,
"required": True
}]
}
])
def search(ctx, subcommand, *, query):
"Search the Internet!"
quoted = urllib.parse.quote_plus(query)
if subcommand == "google":
return f"https://google.com/search?q={quoted}"
if subcommand == "bing":
return f"https://bing.com/search?q={quoted}"
New syntax:
comic = discord.command_group("comic")
@comic.command()
def xkcd(ctx, number: int):
return f"https://xkcd.com/{number}/"
@comic.command()
def homestuck(ctx, number: int):
return f"https://homestuck.com/story/{number}"
Command Parameters
Old syntax:
@discord.command(options=[{
"name": "channel",
"description": "The channel to show information about",
"type": CommandOptionType.CHANNEL,
"required": True
}])
def channel_info(ctx, channel):
return InteractionResponse("...")
New syntax:
@discord.command(annotations={"channel": "The channel to show information about"})
def channel_info(ctx, channel: Channel):
return Response(...)
Renaming
Old names are (for now) being kept as aliases.
InteractionResponse
->Response
InteractionContext
->Context
Add subcommands, ephemeral responses, context objects
Adds the following features:
- Support for subcommands and subcommand groups in the command options field
- A flag to make an
InteractionResponse
ephemeral - User, Role, and Channel parameters now receive an object (e.g.
InteractionChannel
) with relevant attributes
Breaking changes relating to InteractionResponse
response types:
- Removed the
with_source
argument toInteractionResponse
as source-less messages (ACKNOWLEDGE
,CHANNEL_MESSAGE
) are deprecated - Added the
deferred
argument toInteractionResponse
to support the newDEFERRED_CHANNEL_MESSAGE_WITH_SOURCE
type (and the new "Application is thinking..." UI) - Updated the response types in
InteractionResponseType
:- Removed deprecated types (
ACKNOWLEDGE
,CHANNEL_MESSAGE
) -- these no longer work well with the Discord client - Replaced
ACKNOWLEDGE_WITH_SOURCE
withDEFERRED_CHANNEL_MESSAGE_WITH_SOURCE
to reflect the new name and behavior
- Removed deprecated types (
Replace register_slash_commands and clear_slash_commands with update_slash_commands
Replaces
discord.register_slash_commands()
discord.clear_slash_commands()
with
discord.update_slash_commands()
which makes a lot more sense.
Add support for blueprints, followup messages, and sending files
v0.1.2 Add support for sending files in followup messages
Minor API tweaks
Add a README, remove the need to explicitly get a token, restructure examples