aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorretke <[email protected]>2019-04-14 01:08:01 +0200
committerRapptz <[email protected]>2019-04-17 20:47:21 -0400
commit440db2a568a0983a3a836e9a7e4fe736f60a1a67 (patch)
tree1bc0936d49457297b1e1513f385bf2ea8eecefd9
parentRemove legacy nsfw check. (diff)
downloaddiscord.py-440db2a568a0983a3a836e9a7e4fe736f60a1a67.tar.xz
discord.py-440db2a568a0983a3a836e9a7e4fe736f60a1a67.zip
[commands] Add MessageConverter to fetch messages by URL or ID.
-rw-r--r--discord/ext/commands/converter.py37
-rw-r--r--docs/ext/commands/api.rst3
2 files changed, 39 insertions, 1 deletions
diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py
index 2d4375a8..60ad297c 100644
--- a/discord/ext/commands/converter.py
+++ b/discord/ext/commands/converter.py
@@ -31,7 +31,7 @@ import discord
from .errors import BadArgument, NoPrivateMessage
-__all__ = ['Converter', 'MemberConverter', 'UserConverter',
+__all__ = ['Converter', 'MemberConverter', 'UserConverter', 'MessageConverter',
'TextChannelConverter', 'InviteConverter', 'RoleConverter',
'GameConverter', 'ColourConverter', 'VoiceChannelConverter',
'EmojiConverter', 'PartialEmojiConverter', 'CategoryChannelConverter',
@@ -159,6 +159,41 @@ class UserConverter(IDConverter):
return result
+class MessageConverter(IDConverter):
+ """Converts to a :class:`discord.Message`.
+
+ The lookup strategy is as follows (in order):
+
+ 1. Lookup by "{channel ID}-{message ID}" (retrieved by shift-clicking on "Copy ID")
+ 2. Lookup by message ID (the message **must** be in the context channel)
+ 3. Lookup by message URL
+ """
+
+ async def convert(self, ctx, argument):
+ id_regex = re.compile(r'^(?:(?P<channel_id>[0-9]{15,21})-)?(?P<message_id>[0-9]{15,21})$')
+ link_regex = re.compile(
+ r'^https?://(?:(ptb|canary)\.)?discordapp\.com/channels/'
+ r'(?:([0-9]{15,21})|(@me))'
+ r'/(?P<channel_id>[0-9]{15,21})/(?P<message_id>[0-9]{15,21})$'
+ )
+ match = id_regex.match(argument) or link_regex.match(argument)
+ if not match:
+ raise BadArgument('Message "{msg}" not found.'.format(msg=argument))
+ message_id = int(match.group("message_id"))
+ channel_id = match.group("channel_id")
+ message = ctx.bot._connection._get_message(message_id)
+ if message:
+ return message
+ channel = ctx.bot.get_channel(int(channel_id)) if channel_id else ctx.channel
+ if not channel:
+ raise BadArgument('Channel "{channel}" not found.'.format(channel=channel_id))
+ try:
+ return await channel.fetch_message(message_id)
+ except discord.errors.NotFound:
+ raise BadArgument('Message "{msg}" not found.'.format(msg=argument))
+ except discord.errors.Forbidden:
+ raise BadArgument("Can't read messages in {channel}".format(channel=channel.mention))
+
class TextChannelConverter(IDConverter):
"""Converts to a :class:`TextChannel`.
diff --git a/docs/ext/commands/api.rst b/docs/ext/commands/api.rst
index 4722a56a..166fdb1d 100644
--- a/docs/ext/commands/api.rst
+++ b/docs/ext/commands/api.rst
@@ -168,6 +168,9 @@ Converters
.. autoclass:: discord.ext.commands.UserConverter
:members:
+.. autoclass:: discord.ext.commands.MessageConverter
+ :members:
+
.. autoclass:: discord.ext.commands.TextChannelConverter
:members: