Skip to content

Commit

Permalink
Support upcoming API interaction response changes
Browse files Browse the repository at this point in the history
__init__.py:
- Acknowledge and ChannelMessage without source are now pending
  deprecation, so update the docstring
* AcknowledgeWithSource is being renamed to the mouthful
  DeferredChannelMessageWithSource
* Formally warn with PendingDeprecationWarning if Acknowledge or
  ChannelMessage are used as rtypes
* Remove references to them in other places
* Allow sending a message with only flags

README.rst:
* Update README to no longer use ChannelMessage

demo_bot.py:
* Don't use deprecated enums
  • Loading branch information
Kenny2github committed Feb 21, 2021
1 parent 7daafea commit 6d8756f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 23 deletions.
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ Example Usage
ctx: slash.Context, # there MUST be one argument annotated with Context
message: msg_opt
):
"""Send a message in the bot's name""" # description of command
"""Make the bot repeat what you say""" # description of command
# respond to the interaction, must be done within 3 seconds
await ctx.respond(message, # string (or str()able) message
# sends a message without showing the command invocation
rtype=slash.InteractionResponseType.ChannelMessage)
# sends a response message immediately
rtype=slash.InteractionResponseType.ChannelMessageWithSource)
client.run(token)
Expand Down
7 changes: 4 additions & 3 deletions demo_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
async def hello(ctx: slash.Context):
"""Hello World!"""
await ctx.respond('Hello World!', flags=slash.MessageFlags.EPHEMERAL,
rtype=slash.InteractionResponseType.ChannelMessage)
rtype=slash.InteractionResponseType.ChannelMessageWithSource)

@client.slash_group()
async def say(ctx: slash.Context):
Expand Down Expand Up @@ -65,12 +65,13 @@ async def names(
"""Return a combination of IDs, somehow."""
await ctx.respond(f'```{channel.name!r} {user.name!r} {role.name!r}```',
flags=slash.MessageFlags.EPHEMERAL,
rtype=slash.InteractionResponseType.ChannelMessage)
rtype=slash.InteractionResponseType.ChannelMessageWithSource)

@client.slash_cmd()
async def stop(ctx: slash.Context):
"""Stop the bot."""
await ctx.respond(rtype=slash.InteractionResponseType.Acknowledge)
await ctx.respond('Goodbye', flags=slash.MessageFlags.EPHEMERAL,
rtype=slash.InteractionResponseType.ChannelMessageWithSource)
await client.close()

@stop.check
Expand Down
44 changes: 27 additions & 17 deletions discord/ext/slash/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ async def repeat( # command name
ctx: slash.Context, # there MUST be one argument annotated with Context
message: msg_opt
):
"""Send a message in the bot's name""" # description of command
"""Make the bot repeat what you say""" # description of command
# respond to the interaction, must be done within 3 seconds
await ctx.respond(message, # string (or str()able) message
# sends a message without showing the command invocation
rtype=slash.InteractionResponseType.ChannelMessage)
# sends a response message immediately
rtype=slash.InteractionResponseType.ChannelMessageWithSource)
client.run(token)
Expand Down Expand Up @@ -106,31 +106,35 @@ class InteractionResponseType(IntEnum):
Included only for completeness
.. attribute:: Acknowledge
ACK a command without sending a message and without showing user input.
Probably best used for debugging commands.
Pending deprecation on the API
.. attribute:: ChannelMessage
Respond with a message, but don't show user input.
Probably best suited for admin commands,
or commands with ephemeral responses.
Pending deprecation on the API
.. attribute:: ChannelMessageWithSource
Show user input and send a message. Default.
.. attribute:: AcknowledgeWithSource
.. attribute:: DeferredChannelMessageWithSource
Show user input and do nothing else.
Probably best suited for regular commands that require no response.
Show user input and display a "waiting for bot" system message.
Send a response with this type and edit the response later if you
need to do some asynchronous fetch or something.
"""
# ACK a Ping
Pong = 1
# ACK a command without sending a message, eating the user's input
# DEPRECATED - future UI will show the command message like a reply,
# so there will be no way to "[eat] the user's input"
Acknowledge = 2
# respond with a message, eating the user's input
# DEPRECATED - same as Acknowledge
ChannelMessage = 3
# respond with a message, showing the user's input
# Respond immediately to an interaction
ChannelMessageWithSource = 4
# ACK an interaction and send a response later
DeferredChannelMessageWithSource = 5
# ACK a command without sending a message, showing the user's input
AcknowledgeWithSource = 5
# (Former name and description, now renamed)
AcknowledgeWithSource = DeferredChannelMessageWithSource

class MessageFlags(IntEnum):
"""Flags to pass to the ``flags`` argument of the interaction response.
Expand Down Expand Up @@ -426,6 +430,13 @@ async def respond(
rtype: :class:`InteractionResponseType`
The type of response to send. See that class's documentation.
"""
if rtype in {
InteractionResponseType.Acknowledge,
InteractionResponseType.ChannelMessage,
}:
warn(f'{rtype!r} will be deprecated soon, see: '
'https://github.com/discord/discord-api-docs/pull/2615',
PendingDeprecationWarning)
content = str(content)
if embed and embeds:
raise TypeError('Cannot specify both embed and embeds')
Expand Down Expand Up @@ -456,15 +467,14 @@ async def respond(
}
if content or embeds:
data['data'] = {'content': content}
elif rtype in {InteractionResponseType.ChannelMessage,
InteractionResponseType.ChannelMessageWithSource}:
elif rtype == InteractionResponseType.ChannelMessageWithSource:
raise ValueError('sending channel message with no content')
if embeds:
data['data']['embeds'] = embeds
if mentions is not None:
data['data']['allowed_mentions'] = mentions.to_dict()
if flags and 'data' in data:
data['data']['flags'] = int(flags)
if flags:
data.setdefault('data', {})['flags'] = int(flags)
path = f"/interactions/{self.id}/{self.token}/callback"
route = _Route('POST', path, channel_id=self.channel.id,
guild_id=self.guild.id)
Expand Down

0 comments on commit 6d8756f

Please sign in to comment.