diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index d1ed1ade0..659f1d1bb 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -69,7 +69,6 @@ if TYPE_CHECKING: from ..guild import Guild from ..channel import TextChannel from ..abc import Snowflake - from ..ui.view import View import datetime MISSING = utils.MISSING @@ -123,11 +122,11 @@ class AsyncWebhookAdapter: headers['Content-Type'] = 'application/json' to_send = utils._to_json(payload) - if auth_token is not None: - headers['Authorization'] = f'Bot {auth_token}' + if auth_token is not None: # TODO: same as sync.py + headers['Authorization'] = f'{auth_token}' if reason is not None: - headers['X-Audit-Log-Reason'] = urlquote(reason, safe='/ ') + headers['X-Audit-Log-Reason'] = urlquote(reason) response: Optional[aiohttp.ClientResponse] = None data: Optional[Union[Dict[str, Any], str]] = None @@ -149,7 +148,7 @@ class AsyncWebhookAdapter: try: async with session.request(method, url, data=to_send, headers=headers, params=params) as response: _log.debug( - 'Webhook ID %s with %s %s has returned status code %s', + 'Webhook ID %s with %s %s has returned status code %s.', webhook_id, method, url, @@ -163,7 +162,7 @@ class AsyncWebhookAdapter: if remaining == '0' and response.status != 429: delta = utils._parse_ratelimit_header(response) _log.debug( - 'Webhook ID %s has been pre-emptively rate limited, waiting %.2f seconds', webhook_id, delta + 'Webhook ID %s has been pre-emptively rate limited, waiting %.2f seconds.', webhook_id, delta ) lock.delay_by(delta) @@ -175,7 +174,7 @@ class AsyncWebhookAdapter: raise HTTPException(response, data) retry_after: float = data['retry_after'] # type: ignore - _log.warning('Webhook ID %s is rate limited. Retrying in %.2f seconds', webhook_id, retry_after) + _log.warning('Webhook ID %s is rate limited. Retrying in %.2f seconds.', webhook_id, retry_after) await asyncio.sleep(retry_after) continue @@ -341,79 +340,6 @@ class AsyncWebhookAdapter: route = Route('GET', '/webhooks/{webhook_id}/{webhook_token}', webhook_id=webhook_id, webhook_token=token) return self.request(route, session=session) - def create_interaction_response( - self, - interaction_id: int, - token: str, - *, - session: aiohttp.ClientSession, - type: int, - data: Optional[Dict[str, Any]] = None, - ) -> Response[None]: - payload: Dict[str, Any] = { - 'type': type, - } - - if data is not None: - payload['data'] = data - - route = Route( - 'POST', - '/interactions/{webhook_id}/{webhook_token}/callback', - webhook_id=interaction_id, - webhook_token=token, - ) - - return self.request(route, session=session, payload=payload) - - def get_original_interaction_response( - self, - application_id: int, - token: str, - *, - session: aiohttp.ClientSession, - ) -> Response[MessagePayload]: - r = Route( - 'GET', - '/webhooks/{webhook_id}/{webhook_token}/messages/@original', - webhook_id=application_id, - webhook_token=token, - ) - return self.request(r, session=session) - - def edit_original_interaction_response( - self, - application_id: int, - token: str, - *, - session: aiohttp.ClientSession, - payload: Optional[Dict[str, Any]] = None, - multipart: Optional[List[Dict[str, Any]]] = None, - files: Optional[List[File]] = None, - ) -> Response[MessagePayload]: - r = Route( - 'PATCH', - '/webhooks/{webhook_id}/{webhook_token}/messages/@original', - webhook_id=application_id, - webhook_token=token, - ) - return self.request(r, session, payload=payload, multipart=multipart, files=files) - - def delete_original_interaction_response( - self, - application_id: int, - token: str, - *, - session: aiohttp.ClientSession, - ) -> Response[None]: - r = Route( - 'DELETE', - '/webhooks/{webhook_id}/{wehook_token}/messages/@original', - webhook_id=application_id, - wehook_token=token, - ) - return self.request(r, session=session) - class ExecuteWebhookParameters(NamedTuple): payload: Optional[Dict[str, Any]] @@ -427,12 +353,10 @@ def handle_message_parameters( username: str = MISSING, avatar_url: Any = MISSING, tts: bool = False, - ephemeral: bool = False, file: File = MISSING, files: List[File] = MISSING, embed: Optional[Embed] = MISSING, embeds: List[Embed] = MISSING, - view: Optional[View] = MISSING, allowed_mentions: Optional[AllowedMentions] = MISSING, previous_allowed_mentions: Optional[AllowedMentions] = None, ) -> ExecuteWebhookParameters: @@ -441,7 +365,7 @@ def handle_message_parameters( if embeds is not MISSING and embed is not MISSING: raise TypeError('Cannot mix embed and embeds keyword arguments.') - payload = {} + payload = {'tts': tts} if embeds is not MISSING: if len(embeds) > 10: raise InvalidArgument('embeds has a maximum of 10 elements.') @@ -459,19 +383,10 @@ def handle_message_parameters( else: payload['content'] = None - if view is not MISSING: - if view is not None: - payload['components'] = view.to_components() - else: - payload['components'] = [] - - payload['tts'] = tts if avatar_url: payload['avatar_url'] = str(avatar_url) if username: payload['username'] = username - if ephemeral: - payload['flags'] = 64 if allowed_mentions: if previous_allowed_mentions is not None: @@ -614,14 +529,14 @@ class _WebhookState: return self._parent.http # Some data classes assign state.http and that should be kosher - # however, using it should result in a late-binding error. + # However, using it should result in a late-binding error return _FriendlyHttpAttributeErrorHelper() def __getattr__(self, attr): if self._parent is not None: return getattr(self._parent, attr) - raise AttributeError(f'PartialWebhookState does not support {attr!r}.') + raise AttributeError(f'PartialWebhookState does not support {attr!r}') class WebhookMessage(Message): @@ -645,7 +560,6 @@ class WebhookMessage(Message): embed: Optional[Embed] = MISSING, file: File = MISSING, files: List[File] = MISSING, - view: Optional[View] = MISSING, allowed_mentions: Optional[AllowedMentions] = None, ) -> WebhookMessage: """|coro| @@ -678,11 +592,6 @@ class WebhookMessage(Message): allowed_mentions: :class:`AllowedMentions` Controls the mentions being processed in this message. 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. - - .. versionadded:: 2.0 Raises ------- @@ -709,7 +618,6 @@ class WebhookMessage(Message): embed=embed, file=file, files=files, - view=view, allowed_mentions=allowed_mentions, ) @@ -1208,13 +1116,11 @@ class Webhook(BaseWebhook): username: str = MISSING, avatar_url: Any = MISSING, tts: bool = MISSING, - ephemeral: bool = MISSING, file: File = MISSING, files: List[File] = MISSING, embed: Embed = MISSING, embeds: List[Embed] = MISSING, allowed_mentions: AllowedMentions = MISSING, - view: View = MISSING, thread: Snowflake = MISSING, wait: Literal[True], ) -> WebhookMessage: @@ -1228,13 +1134,11 @@ class Webhook(BaseWebhook): username: str = MISSING, avatar_url: Any = MISSING, tts: bool = MISSING, - ephemeral: bool = MISSING, file: File = MISSING, files: List[File] = MISSING, embed: Embed = MISSING, embeds: List[Embed] = MISSING, allowed_mentions: AllowedMentions = MISSING, - view: View = MISSING, thread: Snowflake = MISSING, wait: Literal[False] = ..., ) -> None: @@ -1247,13 +1151,11 @@ class Webhook(BaseWebhook): username: str = MISSING, avatar_url: Any = MISSING, tts: bool = False, - ephemeral: bool = False, file: File = MISSING, files: List[File] = MISSING, embed: Embed = MISSING, embeds: List[Embed] = MISSING, allowed_mentions: AllowedMentions = MISSING, - view: View = MISSING, thread: Snowflake = MISSING, wait: bool = False, ) -> Optional[WebhookMessage]: @@ -1288,13 +1190,6 @@ class Webhook(BaseWebhook): string then it is explicitly cast using ``str``. tts: :class:`bool` Indicates if the message should be sent using text-to-speech. - ephemeral: :class:`bool` - Indicates if the message should only be visible to the user. - 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. - - .. versionadded:: 2.0 file: :class:`File` The file to upload. This cannot be mixed with ``files`` parameter. files: List[:class:`File`] @@ -1310,13 +1205,6 @@ class Webhook(BaseWebhook): Controls the mentions being processed in this message. .. versionadded:: 1.4 - view: :class:`discord.ui.View` - 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. - - .. versionadded:: 2.0 thread: :class:`~discord.abc.Snowflake` The thread to send this webhook to. @@ -1335,9 +1223,7 @@ class Webhook(BaseWebhook): ValueError The length of ``embeds`` was invalid. InvalidArgument - There was no token associated with this webhook or ``ephemeral`` - was passed with the improper webhook type or there was no state - attached with this webhook when giving it a view. + There was no token associated with this webhook. Returns --------- @@ -1352,19 +1238,9 @@ class Webhook(BaseWebhook): if content is None: content = MISSING - application_webhook = self.type is WebhookType.application - if ephemeral and not application_webhook: - raise InvalidArgument('ephemeral messages can only be sent from application webhooks') - - if application_webhook: + if self.type is WebhookType.application 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( content=content, username=username, @@ -1374,8 +1250,6 @@ class Webhook(BaseWebhook): files=files, embed=embed, embeds=embeds, - ephemeral=ephemeral, - view=view, allowed_mentions=allowed_mentions, previous_allowed_mentions=previous_mentions, ) @@ -1399,10 +1273,6 @@ class Webhook(BaseWebhook): if wait: msg = self._create_message(data) - if view is not MISSING and not view.is_finished(): - 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: @@ -1455,7 +1325,6 @@ class Webhook(BaseWebhook): embed: Optional[Embed] = MISSING, file: File = MISSING, files: List[File] = MISSING, - view: Optional[View] = MISSING, allowed_mentions: Optional[AllowedMentions] = None, ) -> WebhookMessage: """|coro| @@ -1493,12 +1362,6 @@ class Webhook(BaseWebhook): allowed_mentions: :class:`AllowedMentions` Controls the mentions being processed in this message. 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`. - - .. versionadded:: 2.0 Raises ------- @@ -1523,12 +1386,6 @@ class Webhook(BaseWebhook): if self.token is None: raise InvalidArgument('This webhook does not have a token associated with it') - if view is not MISSING: - if isinstance(self._state, _WebhookState): - raise InvalidArgument('This webhook does not have state associated with it') - - self._state.prevent_view_updates_for(message_id) - previous_mentions: Optional[AllowedMentions] = getattr(self._state, 'allowed_mentions', None) params = handle_message_parameters( content=content, @@ -1536,7 +1393,6 @@ class Webhook(BaseWebhook): files=files, embed=embed, embeds=embeds, - view=view, allowed_mentions=allowed_mentions, previous_allowed_mentions=previous_mentions, ) @@ -1552,8 +1408,6 @@ class Webhook(BaseWebhook): ) message = self._create_message(data) - if view and not view.is_finished(): - self._state.store_view(view, message_id) return message async def delete_message(self, message_id: int, /) -> None: diff --git a/discord/webhook/sync.py b/discord/webhook/sync.py index 5c85a0365..2ea15da76 100644 --- a/discord/webhook/sync.py +++ b/discord/webhook/sync.py @@ -22,11 +22,13 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -# If you're wondering why this is essentially copy pasted from the async_.py -# file, then it's due to needing two separate types to make the typing shenanigans -# a bit easier to write. It's an unfortunate design. Originally, these types were -# merged and an adapter was used to differentiate between the async and sync versions. -# However, this proved to be difficult to provide typings for, so here we are. +""" +If you're wondering why this is essentially copy pasted from the async_.py +file, then it's due to needing two separate types to make the typing shenanigans +a bit easier to write. It's an unfortunate design. Originally, these types were +merged and an adapter was used to differentiate between the async and sync versions. +However, this proved to be difficult to provide typings for, so here we are. +""" from __future__ import annotations @@ -119,11 +121,11 @@ class WebhookAdapter: headers['Content-Type'] = 'application/json' to_send = utils._to_json(payload) - if auth_token is not None: - headers['Authorization'] = f'Bot {auth_token}' + if auth_token is not None: # TODO: is this possible with users? + headers['Authorization'] = f'{auth_token}' if reason is not None: - headers['X-Audit-Log-Reason'] = urlquote(reason, safe='/ ') + headers['X-Audit-Log-Reason'] = urlquote(reason) response: Optional[Response] = None data: Optional[Union[Dict[str, Any], str]] = None @@ -151,7 +153,7 @@ class WebhookAdapter: method, url, data=to_send, files=file_data, headers=headers, params=params ) as response: _log.debug( - 'Webhook ID %s with %s %s has returned status code %s', + 'Webhook ID %s with %s %s has returned status code %s.', webhook_id, method, url, @@ -169,7 +171,7 @@ class WebhookAdapter: if remaining == '0' and response.status_code != 429: delta = utils._parse_ratelimit_header(response) _log.debug( - 'Webhook ID %s has been pre-emptively rate limited, waiting %.2f seconds', webhook_id, delta + 'Webhook ID %s has been pre-emptively rate limited, waiting %.2f seconds.', webhook_id, delta ) lock.delay_by(delta) @@ -181,7 +183,7 @@ class WebhookAdapter: raise HTTPException(response, data) retry_after: float = data['retry_after'] # type: ignore - _log.warning('Webhook ID %s is rate limited. Retrying in %.2f seconds', webhook_id, retry_after) + _log.warning('Webhook ID %s is rate limited. Retrying in %.2f seconds.', webhook_id, retry_after) time.sleep(retry_after) continue