Browse Source

Add support for sending and editing views in Webhook

pull/6997/head
Rapptz 4 years ago
parent
commit
2ebd5315f9
  1. 60
      discord/webhook/async_.py

60
discord/webhook/async_.py

@ -64,6 +64,7 @@ if TYPE_CHECKING:
from ..guild import Guild from ..guild import Guild
from ..channel import TextChannel from ..channel import TextChannel
from ..abc import Snowflake from ..abc import Snowflake
from ..ui.view import View
import datetime import datetime
MISSING = utils.MISSING MISSING = utils.MISSING
@ -423,6 +424,7 @@ def handle_message_parameters(
files: List[File] = MISSING, files: List[File] = MISSING,
embed: Optional[Embed] = MISSING, embed: Optional[Embed] = MISSING,
embeds: List[Embed] = MISSING, embeds: List[Embed] = MISSING,
view: Optional[View] = MISSING,
allowed_mentions: Optional[AllowedMentions] = MISSING, allowed_mentions: Optional[AllowedMentions] = MISSING,
previous_allowed_mentions: Optional[AllowedMentions] = None, previous_allowed_mentions: Optional[AllowedMentions] = None,
) -> ExecuteWebhookParameters: ) -> ExecuteWebhookParameters:
@ -449,6 +451,12 @@ def handle_message_parameters(
else: else:
payload['content'] = None payload['content'] = None
if view is not MISSING:
if view is not None:
payload['components'] = view.to_components()
else:
payload['components'] = []
payload['tts'] = tts payload['tts'] = tts
if avatar_url: if avatar_url:
payload['avatar_url'] = str(avatar_url) payload['avatar_url'] = str(avatar_url)
@ -621,6 +629,7 @@ class WebhookMessage(Message):
embed: Optional[Embed] = MISSING, embed: Optional[Embed] = MISSING,
file: File = MISSING, file: File = MISSING,
files: List[File] = MISSING, files: List[File] = MISSING,
view: Optional[View] = MISSING,
allowed_mentions: Optional[AllowedMentions] = None, allowed_mentions: Optional[AllowedMentions] = None,
): ):
"""|coro| """|coro|
@ -646,6 +655,9 @@ class WebhookMessage(Message):
allowed_mentions: :class:`AllowedMentions` allowed_mentions: :class:`AllowedMentions`
Controls the mentions being processed in this message. Controls the mentions being processed in this message.
See :meth:`.abc.Messageable.send` for more information. See :meth:`.abc.Messageable.send` for more information.
view: Optional[:class:`~discord.ui.View`]
The updated view to update this message with. If ``None`` is passed then
the view is removed.
Raises Raises
------- -------
@ -667,6 +679,7 @@ class WebhookMessage(Message):
embed=embed, embed=embed,
file=file, file=file,
files=files, files=files,
view=view,
allowed_mentions=allowed_mentions, allowed_mentions=allowed_mentions,
) )
@ -1148,6 +1161,7 @@ class Webhook(BaseWebhook):
embed: Embed = MISSING, embed: Embed = MISSING,
embeds: List[Embed] = MISSING, embeds: List[Embed] = MISSING,
allowed_mentions: AllowedMentions = MISSING, allowed_mentions: AllowedMentions = MISSING,
view: View = MISSING,
wait: Literal[True], wait: Literal[True],
) -> WebhookMessage: ) -> WebhookMessage:
... ...
@ -1166,6 +1180,7 @@ class Webhook(BaseWebhook):
embed: Embed = MISSING, embed: Embed = MISSING,
embeds: List[Embed] = MISSING, embeds: List[Embed] = MISSING,
allowed_mentions: AllowedMentions = MISSING, allowed_mentions: AllowedMentions = MISSING,
view: View = MISSING,
wait: Literal[False] = ..., wait: Literal[False] = ...,
) -> None: ) -> None:
... ...
@ -1183,6 +1198,7 @@ class Webhook(BaseWebhook):
embed: Embed = MISSING, embed: Embed = MISSING,
embeds: List[Embed] = MISSING, embeds: List[Embed] = MISSING,
allowed_mentions: AllowedMentions = MISSING, allowed_mentions: AllowedMentions = MISSING,
view: View = MISSING,
wait: bool = False, wait: bool = False,
) -> Optional[WebhookMessage]: ) -> Optional[WebhookMessage]:
"""|coro| """|coro|
@ -1218,6 +1234,8 @@ class Webhook(BaseWebhook):
ephemeral: :class:`bool` ephemeral: :class:`bool`
Indicates if the message should only be visible to the user. Indicates if the message should only be visible to the user.
This is only available to :attr:`WebhookType.application` webhooks. This is only available to :attr:`WebhookType.application` webhooks.
If a view is sent with an ephemeral message and it has no timeout set
then the timeout is set to 15 minutes.
file: :class:`File` file: :class:`File`
The file to upload. This cannot be mixed with ``files`` parameter. The file to upload. This cannot be mixed with ``files`` parameter.
files: List[:class:`File`] files: List[:class:`File`]
@ -1231,8 +1249,11 @@ class Webhook(BaseWebhook):
be mixed with the ``embed`` parameter. be mixed with the ``embed`` parameter.
allowed_mentions: :class:`AllowedMentions` allowed_mentions: :class:`AllowedMentions`
Controls the mentions being processed in this message. Controls the mentions being processed in this message.
view: :class:`discord.ui.View`
.. versionadded:: 1.4 The view to send with the message. You can only send a view
if this webhook is not partial and has state attached. A
webhook has state attached if the webhook is managed by the
library.
Raises Raises
-------- --------
@ -1248,7 +1269,8 @@ class Webhook(BaseWebhook):
The length of ``embeds`` was invalid. The length of ``embeds`` was invalid.
InvalidArgument InvalidArgument
There was no token associated with this webhook or ``ephemeral`` There was no token associated with this webhook or ``ephemeral``
was passed with the improper webhook type. was passed with the improper webhook type or there was no state
attached with this webhook when giving it a view.
Returns Returns
--------- ---------
@ -1270,6 +1292,12 @@ class Webhook(BaseWebhook):
if application_webhook: if application_webhook:
wait = True wait = True
if view is not MISSING:
if isinstance(self._state, _WebhookState):
raise InvalidArgument('Webhook views require an associated state with the webhook')
if ephemeral is True and view.timeout is None:
view.timeout = 15 * 60.0
params = handle_message_parameters( params = handle_message_parameters(
content=content, content=content,
username=username, username=username,
@ -1280,6 +1308,7 @@ class Webhook(BaseWebhook):
embed=embed, embed=embed,
embeds=embeds, embeds=embeds,
ephemeral=ephemeral, ephemeral=ephemeral,
view=view,
allowed_mentions=allowed_mentions, allowed_mentions=allowed_mentions,
previous_allowed_mentions=previous_mentions, previous_allowed_mentions=previous_mentions,
) )
@ -1293,8 +1322,16 @@ class Webhook(BaseWebhook):
files=params.files, files=params.files,
wait=wait, wait=wait,
) )
msg = None
if wait: if wait:
return self._create_message(data) msg = self._create_message(data)
if view is not MISSING:
message_id = None if msg is None else msg.id
self._state.store_view(view, message_id)
return msg
async def fetch_message(self, id: int) -> WebhookMessage: async def fetch_message(self, id: int) -> WebhookMessage:
"""|coro| """|coro|
@ -1346,6 +1383,7 @@ class Webhook(BaseWebhook):
embed: Optional[Embed] = MISSING, embed: Optional[Embed] = MISSING,
file: File = MISSING, file: File = MISSING,
files: List[File] = MISSING, files: List[File] = MISSING,
view: Optional[View] = MISSING,
allowed_mentions: Optional[AllowedMentions] = None, allowed_mentions: Optional[AllowedMentions] = None,
): ):
"""|coro| """|coro|
@ -1376,6 +1414,10 @@ class Webhook(BaseWebhook):
allowed_mentions: :class:`AllowedMentions` allowed_mentions: :class:`AllowedMentions`
Controls the mentions being processed in this message. Controls the mentions being processed in this message.
See :meth:`.abc.Messageable.send` for more information. See :meth:`.abc.Messageable.send` for more information.
view: Optional[:class:`~discord.ui.View`]
The updated view to update this message with. If ``None`` is passed then
the view is removed. The webhook must have state attached, similar to
:meth:`send`.
Raises Raises
------- -------
@ -1388,12 +1430,16 @@ class Webhook(BaseWebhook):
ValueError ValueError
The length of ``embeds`` was invalid The length of ``embeds`` was invalid
InvalidArgument InvalidArgument
There was no token associated with this webhook. There was no token associated with this webhook or the webhook had
no state.
""" """
if self.token is None: if self.token is None:
raise InvalidArgument('This webhook does not have a token associated with it') raise InvalidArgument('This webhook does not have a token associated with it')
if view is not MISSING and isinstance(self._state, _WebhookState):
raise InvalidArgument('This webhook does not have state associated with it')
previous_mentions: Optional[AllowedMentions] = getattr(self._state, 'allowed_mentions', None) previous_mentions: Optional[AllowedMentions] = getattr(self._state, 'allowed_mentions', None)
params = handle_message_parameters( params = handle_message_parameters(
content=content, content=content,
@ -1401,6 +1447,7 @@ class Webhook(BaseWebhook):
files=files, files=files,
embed=embed, embed=embed,
embeds=embeds, embeds=embeds,
view=view,
allowed_mentions=allowed_mentions, allowed_mentions=allowed_mentions,
previous_allowed_mentions=previous_mentions, previous_allowed_mentions=previous_mentions,
) )
@ -1415,6 +1462,9 @@ class Webhook(BaseWebhook):
files=params.files, files=params.files,
) )
if view:
self._state.store_view(view, message_id)
async def delete_message(self, message_id: int): async def delete_message(self, message_id: int):
"""|coro| """|coro|

Loading…
Cancel
Save