update docs and add message replies

This commit is contained in:
iDutchy
2020-11-18 17:49:58 -06:00
parent 195bace135
commit 690dcdaf2e
11 changed files with 234 additions and 48 deletions

View File

@ -15,7 +15,7 @@ __title__ = 'discord'
__author__ = 'Rapptz'
__license__ = 'MIT'
__copyright__ = 'Copyright 2015-2020 Rapptz'
__version__ = '1.5.1.4'
__version__ = '1.5.1.5'
__path__ = __import__('pkgutil').extend_path(__path__, __name__)

View File

@ -802,7 +802,7 @@ class Messageable(metaclass=abc.ABCMeta):
async def send(self, content=None, *, tts=False, embed=None, file=None,
files=None, delete_after=None, nonce=None,
allowed_mentions=None):
allowed_mentions=None, message_reference=None):
"""|coro|
Sends a message to the destination with the content given.
@ -847,6 +847,12 @@ class Messageable(metaclass=abc.ABCMeta):
are used instead.
.. versionadded:: 1.4
message_reference: :class:`~discord.MessageReference`
A reference to the :class:`~discord.Message` to which you are replying, i.e. as created using
:meth:`~discord.MessageReference.from_message`. You can control whether this mentions the author
of the referenced Message using :attr:`~discord.AllowedMentions.replied_user`.
.. versionadded:: 1.5.1.5
Raises
--------
@ -878,6 +884,9 @@ class Messageable(metaclass=abc.ABCMeta):
else:
allowed_mentions = state.allowed_mentions and state.allowed_mentions.to_dict()
if message_reference is not None:
message_reference = message_reference.to_dict()
if file is not None and files is not None:
raise InvalidArgument('cannot pass both file and files parameter to send()')
@ -887,7 +896,8 @@ class Messageable(metaclass=abc.ABCMeta):
try:
data = await state.http.send_files(channel.id, files=[file], allowed_mentions=allowed_mentions,
content=content, tts=tts, embed=embed, nonce=nonce)
content=content, tts=tts, embed=embed, nonce=nonce,
message_reference=message_reference)
finally:
file.close()
@ -899,13 +909,15 @@ class Messageable(metaclass=abc.ABCMeta):
try:
data = await state.http.send_files(channel.id, files=files, content=content, tts=tts,
embed=embed, nonce=nonce, allowed_mentions=allowed_mentions)
embed=embed, nonce=nonce, allowed_mentions=allowed_mentions,
message_reference=message_reference)
finally:
for f in files:
f.close()
else:
data = await state.http.send_message(channel.id, content, tts=tts, embed=embed,
nonce=nonce, allowed_mentions=allowed_mentions)
nonce=nonce, allowed_mentions=allowed_mentions,
message_reference=message_reference)
ret = state.create_message(channel=channel, data=data)
if delete_after is not None:

View File

@ -146,7 +146,7 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
def can_send(self):
""":class:`bool`: Checks if the bot can send messages
.. versionadded:: 1.5.0.1"""
.. versionadded:: 1.5.0.2"""
return self.permissions_for(self.guild.me).send_messages
def permissions_for(self, member):

View File

@ -332,3 +332,28 @@ class Context(discord.abc.Messageable):
return None
except CommandError as e:
await cmd.on_help_command_error(self, e)
async def reply(self, content=None, **kwargs):
"""|coro|
A shortcut method to :meth:`~discord.abc.Messageable.send` to reply to the
:class:`~discord.Message` that invoked the command.
.. versionadded:: 1.5.1.5
Raises
--------
~discord.HTTPException
Sending the message failed.
~discord.Forbidden
You do not have the proper permissions to send the message.
~discord.InvalidArgument
The ``files`` list is not of the appropriate size or
you specified both ``file`` and ``files``.
Returns
---------
:class:`~discord.Message`
The message that was sent.
"""
return await self.message.reply(content, **kwargs)

View File

@ -340,7 +340,7 @@ class HTTPClient:
return self.request(Route('POST', '/users/@me/channels'), json=payload)
def send_message(self, channel_id, content, *, tts=False, embed=None, nonce=None, allowed_mentions=None):
def send_message(self, channel_id, content, *, tts=False, embed=None, nonce=None, allowed_mentions=None, message_referece=None):
r = Route('POST', '/channels/{channel_id}/messages', channel_id=channel_id)
payload = {}
@ -359,12 +359,15 @@ class HTTPClient:
if allowed_mentions:
payload['allowed_mentions'] = allowed_mentions
if message_reference:
payload['message_reference'] = message_reference
return self.request(r, json=payload)
def send_typing(self, channel_id):
return self.request(Route('POST', '/channels/{channel_id}/typing', channel_id=channel_id))
def send_files(self, channel_id, *, files, content=None, tts=False, embed=None, nonce=None, allowed_mentions=None):
def send_files(self, channel_id, *, files, content=None, tts=False, embed=None, nonce=None, allowed_mentions=None, message_reference=None):
r = Route('POST', '/channels/{channel_id}/messages', channel_id=channel_id)
form = aiohttp.FormData()
@ -377,6 +380,8 @@ class HTTPClient:
payload['nonce'] = nonce
if allowed_mentions:
payload['allowed_mentions'] = allowed_mentions
if message_reference:
payload['message_reference'] = message_reference
form.add_field('payload_json', utils.to_json(payload))
if len(files) == 1:

View File

@ -59,14 +59,20 @@ class AllowedMentions:
roles are not mentioned at all. If a list of :class:`abc.Snowflake`
is given then only the roles provided will be mentioned, provided those
roles are in the message content.
replied_user: :class:`bool`
Whether to mention the author of the message being replied to. Defaults
to ``True``.
.. versionadded:: 1.5.1.5
"""
__slots__ = ('everyone', 'users', 'roles')
__slots__ = ('everyone', 'users', 'roles', 'replied_user')
def __init__(self, *, everyone=default, users=default, roles=default):
def __init__(self, *, everyone=default, users=default, roles=default, replied_user=default):
self.everyone = everyone
self.users = users
self.roles = roles
self.replied_user = replied_user
@classmethod
def all(cls):
@ -74,7 +80,7 @@ class AllowedMentions:
.. versionadded:: 1.5
"""
return cls(everyone=True, users=True, roles=True)
return cls(everyone=True, users=True, roles=True, replied_user=True)
@classmethod
def none(cls):
@ -82,7 +88,7 @@ class AllowedMentions:
.. versionadded:: 1.5
"""
return cls(everyone=False, users=False, roles=False)
return cls(everyone=False, users=False, roles=False, replied_user=False)
def to_dict(self):
parse = []
@ -101,6 +107,9 @@ class AllowedMentions:
elif self.roles != False:
data['roles'] = [x.id for x in self.roles]
if self.replied_user == True:
data['replied_user'] = True
data['parse'] = parse
return data

View File

@ -235,6 +235,24 @@ class MessageReference:
self.guild_id = utils._get_as_snowflake(kwargs, 'guild_id')
self._state = state
@classmethod
def from_message(cls, message):
"""Creates a :class:`MessageReference` from an existing :class:`Message`
.. versionadded:: 1.5.1.5
Parameters
----------
message: :class:`Message`
The message to be converted into a reference.
Returns
-------
:class:`MessageReference`
A reference to the message
"""
return cls(message._state, message_id=message.id, channel_id=message.channel.id, guild_id=message.guild and message.guild.id)
@property
def cached_message(self):
"""Optional[:class:`Message`]: The cached message, if found in the internal message cache."""
@ -243,6 +261,29 @@ class MessageReference:
def __repr__(self):
return '<MessageReference message_id={0.message_id!r} channel_id={0.channel_id!r} guild_id={0.guild_id!r}>'.format(self)
def to_dict(self, specify_channel=False):
"""Converts the message reference to a dict, for transmission via the gateway.
.. versionadded:: 1.5.1.5
Parameters
-------
specify_channel: Optional[:class:`bool`]
Whether to include the channel ID in the returned object.
Defaults to False.
Returns
-------
:class:`dict`
The reference as a dict.
"""
result = {'message_id': self.message_id} if self.message_id is not None else {}
if specify_channel:
result['channel_id'] = self.channel_id
if self.guild_id is not None:
result['guild_id'] = self.guild_id
return result
def flatten_handlers(cls):
prefix = len('_handle_')
cls._HANDLERS = {
@ -288,8 +329,8 @@ class Message(Hashable):
:attr:`MessageType.call`.
reference: Optional[:class:`MessageReference`]
The message that this message references. This is only applicable to messages of
type :attr:`MessageType.pins_add` or crossposted messages created by a
followed channel integration.
type :attr:`MessageType.pins_add`, crossposted messages created by a
followed channel integration or message replies.
.. versionadded:: 1.5
@ -1123,3 +1164,29 @@ class Message(Hashable):
if state.is_bot:
raise ClientException('Must not be a bot account to ack messages.')
return await state.http.ack_message(self.channel.id, self.id)
async def reply(self, content=None, **kwargs):
"""|coro|
A shortcut method to :meth:`abc.Messageable.send` to reply to the
:class:`Message`.
.. versionadded:: 1.5.1.5
Raises
--------
~discord.HTTPException
Sending the message failed.
~discord.Forbidden
You do not have the proper permissions to send the message.
~discord.InvalidArgument
The ``files`` list is not of the appropriate size or
you specified both ``file`` and ``files``.
Returns
---------
:class:`Message`
The message that was sent.
"""
reference = MessageReference.from_message(self)
return await self.channel.send(content, message_reference=reference, **kwargs)