Last active
August 11, 2021 16:34
-
-
Save noaione/738ce5ba570b4d27e00f8e69679b0bff to your computer and use it in GitHub Desktop.
A monkey-patch of a monkey-patch for discord-py-interactions [discord.py commit: 58ca9e9]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
A monkeypatch to patch some of the discord-interactions *patched* methods. | |
Refer: https://github.com/discord-py-interactions/discord-py-interactions/issues/287 | |
This was created using this commit as the original reference: | |
https://github.com/Rapptz/discord.py/commit/58ca9e99325ac2678a51cd63afd7ae917f14bc8d | |
--- | |
MIT License | |
Copyright (c) 2021 noaione | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
SOFTWARE. | |
""" | |
from typing import List, Optional, Sequence | |
from discord import File, InvalidArgument, components, embeds, message, sticker | |
from discord.ext import commands | |
from discord.http import HTTPClient, Route | |
from discord.mentions import AllowedMentions | |
__all__ = ["dpy_dslash_send_override", "dpy_send_files", "dpy_send_message"] | |
def dpy_send_files( | |
self: HTTPClient, | |
channel_id, | |
*, | |
files: Sequence[File], | |
content: Optional[str] = None, | |
tts: bool = False, | |
embed: Optional[embeds.Embed] = None, | |
embeds: Optional[List[embeds.Embed]] = None, | |
nonce: Optional[str] = None, | |
allowed_mentions: Optional[AllowedMentions] = None, | |
message_reference: Optional[message.MessageReference] = None, | |
stickers: Optional[List[sticker.StickerItem]], | |
components: Optional[List[components.Component]] = None, | |
): | |
r = Route("POST", "/channels/{channel_id}/messages", channel_id=channel_id) | |
return self.send_multipart_helper( | |
r, | |
files=files, | |
content=content, | |
tts=tts, | |
embed=embed, | |
embeds=embeds, | |
nonce=nonce, | |
allowed_mentions=allowed_mentions, | |
message_reference=message_reference, | |
stickers=stickers, | |
components=components, | |
) | |
def dpy_send_message( | |
self: HTTPClient, | |
channel_id, | |
content: str, | |
*, | |
tts: bool = False, | |
embed: Optional[embeds.Embed] = None, | |
embeds: Optional[List[embeds.Embed]] = None, | |
nonce: Optional[str] = None, | |
allowed_mentions: Optional[AllowedMentions] = None, | |
message_reference: Optional[message.MessageReference] = None, | |
stickers: Optional[List[sticker.StickerItem]] = None, | |
components: Optional[List[components.Component]] = None, | |
): | |
r = Route("POST", "/channels/{channel_id}/messages", channel_id=channel_id) | |
payload = {} | |
if content: | |
payload["content"] = content | |
if tts: | |
payload["tts"] = True | |
if embed: | |
payload["embeds"] = [embed] | |
if embeds: | |
payload["embeds"] = embeds | |
if nonce: | |
payload["nonce"] = nonce | |
if allowed_mentions: | |
payload["allowed_mentions"] = allowed_mentions | |
if message_reference: | |
payload["message_reference"] = message_reference | |
if components: | |
payload["components"] = components | |
if stickers: | |
payload["sticker_ids"] = stickers | |
return self.request(r, json=payload) | |
async def dpy_dslash_send( | |
self, | |
content: str = None, | |
*, | |
tts=False, | |
embed=None, | |
embeds=None, | |
file=None, | |
files=None, | |
components=None, | |
stickers=None, | |
delete_after=None, | |
nonce=None, | |
allowed_mentions=None, | |
reference=None, | |
mention_author=None, | |
view=None, | |
): | |
"""|coro| | |
Sends a message to the destination with the content given. | |
The content must be a type that can convert to a string through ``str(content)``. | |
If the content is set to ``None`` (the default), then the ``embed`` parameter must | |
be provided. | |
To upload a single file, the ``file`` parameter should be used with a | |
single :class:`~discord.File` object. To upload multiple files, the ``files`` | |
parameter should be used with a :class:`list` of :class:`~discord.File` objects. | |
**Specifying both parameters will lead to an exception**. | |
To upload a single embed, the ``embed`` parameter should be used with a | |
single :class:`~discord.Embed` object. To upload multiple embeds, the ``embeds`` | |
parameter should be used with a :class:`list` of :class:`~discord.Embed` objects. | |
**Specifying both parameters will lead to an exception**. | |
Parameters | |
------------ | |
content: Optional[:class:`str`] | |
The content of the message to send. | |
tts: :class:`bool` | |
Indicates if the message should be sent using text-to-speech. | |
embed: :class:`~discord.Embed` | |
The rich embed for the content. | |
file: :class:`~discord.File` | |
The file to upload. | |
files: List[:class:`~discord.File`] | |
A list of files to upload. Must be a maximum of 10. | |
nonce: :class:`int` | |
The nonce to use for sending this message. If the message was successfully sent, | |
then the message will have a nonce with this value. | |
delete_after: :class:`float` | |
If provided, the number of seconds to wait in the background | |
before deleting the message we just sent. If the deletion fails, | |
then it is silently ignored. | |
allowed_mentions: :class:`~discord.AllowedMentions` | |
Controls the mentions being processed in this message. If this is | |
passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`. | |
The merging behaviour only overrides attributes that have been explicitly passed | |
to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`. | |
If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions` | |
are used instead. | |
.. versionadded:: 1.4 | |
reference: Union[:class:`~discord.Message`, :class:`~discord.MessageReference`, :class:`~discord.PartialMessage`] | |
A reference to the :class:`~discord.Message` to which you are replying, this can be created using | |
:meth:`~discord.Message.to_reference` or passed directly as a :class:`~discord.Message`. You can control | |
whether this mentions the author of the referenced message using the :attr:`~discord.AllowedMentions.replied_user` | |
attribute of ``allowed_mentions`` or by setting ``mention_author``. | |
.. versionadded:: 1.6 | |
mention_author: Optional[:class:`bool`] | |
If set, overrides the :attr:`~discord.AllowedMentions.replied_user` attribute of ``allowed_mentions``. | |
.. versionadded:: 1.6 | |
view: :class:`discord.ui.View` | |
A Discord UI View to add to the message. | |
embeds: List[:class:`~discord.Embed`] | |
A list of embeds to upload. Must be a maximum of 10. | |
.. versionadded:: 2.0 | |
stickers: Sequence[Union[:class:`~discord.GuildSticker`, :class:`~discord.StickerItem`]] | |
A list of stickers to upload. Must be a maximum of 3. | |
.. versionadded:: 2.0 | |
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, | |
you specified both ``file`` and ``files``, | |
or you specified both ``embed`` and ``embeds``, | |
or the ``reference`` object is not a :class:`~discord.Message`, | |
:class:`~discord.MessageReference` or :class:`~discord.PartialMessage`. | |
Returns | |
--------- | |
:class:`~discord.Message` | |
The message that was sent. | |
""" # noqa: E501 | |
channel = await self._get_channel() | |
state = self._state | |
content = str(content) if content is not None else None | |
if embed is not None and embeds is not None: | |
raise InvalidArgument("cannot pass both embed and embeds parameter to send()") | |
if embed is not None: | |
embed = embed.to_dict() | |
elif embeds is not None: | |
if len(embeds) > 10: | |
raise InvalidArgument("embeds parameter must be a list of up to 10 elements") | |
embeds = [embed.to_dict() for embed in embeds] | |
if stickers is not None: | |
stickers = [sticker.id for sticker in stickers] | |
if allowed_mentions is not None: | |
if state.allowed_mentions is not None: | |
allowed_mentions = state.allowed_mentions.merge(allowed_mentions).to_dict() | |
else: | |
allowed_mentions = allowed_mentions.to_dict() | |
else: | |
allowed_mentions = state.allowed_mentions and state.allowed_mentions.to_dict() | |
if mention_author is not None: | |
allowed_mentions = allowed_mentions or AllowedMentions().to_dict() | |
allowed_mentions["replied_user"] = bool(mention_author) | |
if reference is not None: | |
try: | |
reference = reference.to_message_reference_dict() | |
except AttributeError: | |
raise InvalidArgument( | |
"reference parameter must be Message, MessageReference, or PartialMessage" | |
) from None | |
extended_components = [] | |
if components is not None: | |
extended_components.extend(components) | |
if view: | |
if not hasattr(view, "__discord_ui_view__"): | |
raise InvalidArgument(f"view parameter must be View not {view.__class__!r}") | |
view_component = view.to_components() | |
extended_components.extend(view_component) | |
# else: | |
# components = None | |
if len(extended_components) < 1: | |
extended_components = None | |
if file is not None and files is not None: | |
raise InvalidArgument("cannot pass both file and files parameter to send()") | |
if file is not None: | |
if not isinstance(file, File): | |
raise InvalidArgument("file parameter must be File") | |
try: | |
data = await state.http.send_files( | |
channel.id, | |
files=[file], | |
allowed_mentions=allowed_mentions, | |
content=content, | |
tts=tts, | |
embed=embed, | |
embeds=embeds, | |
nonce=nonce, | |
message_reference=reference, | |
stickers=stickers, | |
components=extended_components, | |
) | |
finally: | |
file.close() | |
elif files is not None: | |
if len(files) > 10: | |
raise InvalidArgument("files parameter must be a list of up to 10 elements") | |
elif not all(isinstance(file, File) for file in files): | |
raise InvalidArgument("files parameter must be a list of File") | |
try: | |
data = await state.http.send_files( | |
channel.id, | |
files=files, | |
content=content, | |
tts=tts, | |
embed=embed, | |
embeds=embeds, | |
nonce=nonce, | |
allowed_mentions=allowed_mentions, | |
message_reference=reference, | |
stickers=stickers, | |
components=extended_components, | |
) | |
finally: | |
for f in files: | |
f.close() | |
else: | |
data = await state.http.send_message( | |
channel.id, | |
content, | |
tts=tts, | |
embed=embed, | |
embeds=embeds, | |
nonce=nonce, | |
allowed_mentions=allowed_mentions, | |
message_reference=reference, | |
stickers=stickers, | |
components=extended_components, | |
) | |
ret = state.create_message(channel=channel, data=data) | |
if view: | |
state.store_view(view, ret.id) | |
if delete_after is not None: | |
await ret.delete(delay=delete_after) | |
return ret | |
async def dpy_dslash_send_override(context_or_channel, *args, **kwargs): | |
if isinstance(context_or_channel, commands.Context): | |
channel = context_or_channel.channel | |
else: | |
channel = context_or_channel | |
return await dpy_dslash_send(channel, *args, **kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment