Skip to content

Releases: breqdev/flask-discord-interactions

Quart support! Use asyncio with commands

27 May 04:48
1c73244
Compare
Choose a tag to compare

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

05 May 23:41
7fe26f1
Compare
Choose a tag to compare

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, and Channel 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

23 Apr 05:37
Compare
Choose a tag to compare

This release adds two new options to app.config:

  • DONT_VALIDATE_SIGNATURE disables validating the signature on incoming POST requests
  • DONT_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

16 Apr 23:30
Compare
Choose a tag to compare

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

14 Apr 20:48
Compare
Choose a tag to compare

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.

Thank you to @bradday4 for submitting this PR (#7)!

Add decorator-based subcommand syntax and type-annotation-based parameter syntax

02 Apr 04:41
Compare
Choose a tag to compare

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

01 Apr 22:29
Compare
Choose a tag to compare

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 to InteractionResponse as source-less messages (ACKNOWLEDGE, CHANNEL_MESSAGE) are deprecated
  • Added the deferred argument to InteractionResponse to support the new DEFERRED_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 with DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE to reflect the new name and behavior

Replace register_slash_commands and clear_slash_commands with update_slash_commands

07 Jan 04:40
Compare
Choose a tag to compare

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

06 Jan 06:29
Compare
Choose a tag to compare
v0.1.2

Add support for sending files in followup messages

Minor API tweaks

04 Jan 04:03
Compare
Choose a tag to compare
Minor API tweaks Pre-release
Pre-release

Add a README, remove the need to explicitly get a token, restructure examples