Implement a ctx.send helper for slash commands
This commit is contained in:
		@@ -25,8 +25,8 @@ from __future__ import annotations
 | 
			
		||||
 | 
			
		||||
import inspect
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
from typing import Any, Dict, Generic, List, Optional, TYPE_CHECKING, TypeVar, Union
 | 
			
		||||
from datetime import timedelta
 | 
			
		||||
from typing import Any, Dict, Generic, List, Literal, Optional, TYPE_CHECKING, TypeVar, Union, overload
 | 
			
		||||
 | 
			
		||||
import discord.abc
 | 
			
		||||
import discord.utils
 | 
			
		||||
@@ -41,6 +41,7 @@ if TYPE_CHECKING:
 | 
			
		||||
    from discord.member import Member
 | 
			
		||||
    from discord.state import ConnectionState
 | 
			
		||||
    from discord.user import ClientUser, User
 | 
			
		||||
    from discord.webhook import WebhookMessage
 | 
			
		||||
    from discord.interactions import Interaction
 | 
			
		||||
    from discord.voice_client import VoiceProtocol
 | 
			
		||||
 | 
			
		||||
@@ -397,6 +398,81 @@ class Context(discord.abc.Messageable, Generic[BotT]):
 | 
			
		||||
        except CommandError as e:
 | 
			
		||||
            await cmd.on_help_command_error(self, e)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @overload
 | 
			
		||||
    async def send(self,
 | 
			
		||||
        content: Optional[str] = None,
 | 
			
		||||
        return_message: Literal[False] = False,
 | 
			
		||||
        ephemeral: bool = False, **kwargs: Any
 | 
			
		||||
    ) -> Optional[Union[Message, WebhookMessage]]: ...
 | 
			
		||||
    @overload
 | 
			
		||||
    async def send(self,
 | 
			
		||||
        content: Optional[str] = None,
 | 
			
		||||
        return_message: Literal[True] = True,
 | 
			
		||||
        ephemeral: bool = False, **kwargs: Any
 | 
			
		||||
    ) -> Union[Message, WebhookMessage]: ...
 | 
			
		||||
 | 
			
		||||
    async def send(self,
 | 
			
		||||
        content: Optional[str] = None,
 | 
			
		||||
        return_message: bool = True,
 | 
			
		||||
        ephemeral: bool = False, **kwargs: Any
 | 
			
		||||
    ) -> Optional[Union[Message, WebhookMessage]]:
 | 
			
		||||
        """
 | 
			
		||||
        |coro|
 | 
			
		||||
 | 
			
		||||
        A shortcut method to :meth:`.abc.Messageable.send` with interaction helpers.
 | 
			
		||||
 | 
			
		||||
        This function takes all the parameters of :meth:`.abc.Messageable.send` plus the following:
 | 
			
		||||
 | 
			
		||||
        Parameters
 | 
			
		||||
        ------------
 | 
			
		||||
        return_message: :class:`bool`
 | 
			
		||||
            Ignored if not in a slash command context.
 | 
			
		||||
            If this is set to False more native interaction methods will be used.
 | 
			
		||||
        ephemeral: :class:`bool`
 | 
			
		||||
            Ignored if not in a slash command context.
 | 
			
		||||
            Indicates if the message should only be visible to the user who started the interaction.
 | 
			
		||||
            If a view is sent with an ephemeral message and it has no timeout set then the timeout
 | 
			
		||||
            is set to 15 minutes.
 | 
			
		||||
 | 
			
		||||
        Returns
 | 
			
		||||
        --------
 | 
			
		||||
        Optional[Union[:class:`.Message`, :class:`.WebhookMessage`]]
 | 
			
		||||
            In a slash command context, the message that was sent if return_message is True.
 | 
			
		||||
 | 
			
		||||
            In a normal context, it always returns a :class:`.Message`
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        if (
 | 
			
		||||
            self.interaction is None
 | 
			
		||||
            or (
 | 
			
		||||
                self.interaction.response.responded_at is not None
 | 
			
		||||
                and discord.utils.utcnow() - self.interaction.response.responded_at >= timedelta(minutes=15)
 | 
			
		||||
        )):
 | 
			
		||||
            return await super().send(content, **kwargs)
 | 
			
		||||
 | 
			
		||||
        # Remove unsupported arguments from kwargs
 | 
			
		||||
        kwargs.pop("nonce", None)
 | 
			
		||||
        kwargs.pop("stickers", None)
 | 
			
		||||
        kwargs.pop("reference", None)
 | 
			
		||||
        kwargs.pop("delete_after", None)
 | 
			
		||||
        kwargs.pop("mention_author", None)
 | 
			
		||||
 | 
			
		||||
        if not (
 | 
			
		||||
            return_message
 | 
			
		||||
            or self.interaction.response.is_done()
 | 
			
		||||
            or any(arg in kwargs for arg in ("file", "files", "allowed_mentions"))
 | 
			
		||||
        ):
 | 
			
		||||
            send = self.interaction.response.send_message
 | 
			
		||||
        else:
 | 
			
		||||
            # We have to defer in order to use the followup webhook
 | 
			
		||||
            if not self.interaction.response.is_done():
 | 
			
		||||
                await self.interaction.response.defer(ephemeral=ephemeral)
 | 
			
		||||
 | 
			
		||||
            send = self.interaction.followup.send
 | 
			
		||||
 | 
			
		||||
        return await send(content, ephemeral=ephemeral, **kwargs) # type: ignore
 | 
			
		||||
 | 
			
		||||
    @discord.utils.copy_doc(Message.reply)
 | 
			
		||||
    async def reply(self, content: Optional[str] = None, **kwargs: Any) -> Message:
 | 
			
		||||
        return await self.message.reply(content, **kwargs)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user