Source code for discohook.adapter

from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union

from .embed import Embed
from .enums import InteractionCallbackType, InteractionType
from .errors import InteractionTypeMismatch
from .file import File
from .message import Message
from .modal import Modal
from .models import AllowedMentions
from .option import Choice
from .params import MISSING, _EditingPayload, _SendingPayload
from .poll import Poll
from .view import View

if TYPE_CHECKING:
    from .interaction import Interaction


[docs]class InteractionResponse: """ Represents a response message sent by an interaction """ def __init__(self, interaction: "Interaction") -> None: self.inter = interaction
[docs] async def delete(self): """ Deletes the response message. """ await self.inter.client.http.delete_webhook_message( self.inter.application_id, self.inter.token, "@original" )
[docs] async def edit( self, content: Optional[str] = MISSING, *, embed: Optional[Embed] = MISSING, embeds: Optional[List[Embed]] = MISSING, view: Optional[View] = MISSING, tts: Optional[bool] = MISSING, file: Optional[File] = MISSING, files: Optional[List[File]] = MISSING, suppress_embeds: Optional[bool] = MISSING, ) -> Message: """ Edits the response message. Parameters ---------- same as :meth:`Message.edit` """ payload = _EditingPayload( content=content, embed=embed, embeds=embeds, view=view, tts=tts, file=file, files=files, suppress_embeds=suppress_embeds, ) if view and view is not MISSING: self.inter.client.load_view(view) resp = await self.inter.client.http.edit_webhook_message( self.inter.application_id, self.inter.token, "@original", payload.to_form(), ) data = await resp.json() return Message(self.inter.client, data)
[docs]class FollowupResponse: """ Represents a followup message sent by an interaction, subclassed from :class:`Message`. """ def __init__(self, payload: Dict[str, Any], interaction: "Interaction") -> None: self.message = Message(interaction.client, payload) self.interaction = interaction
[docs] async def delete(self): """ Deletes the followup message. """ return await self.interaction.client.http.delete_webhook_message( self.interaction.application_id, self.interaction.token, self.message.id, )
[docs] async def edit( self, content: Optional[str] = MISSING, *, embed: Optional[Embed] = MISSING, embeds: Optional[List[Embed]] = MISSING, view: Optional[View] = MISSING, tts: Optional[bool] = MISSING, file: Optional[File] = MISSING, files: Optional[List[File]] = MISSING, suppress_embeds: Optional[bool] = MISSING, ) -> Message: """ Edits the followup message. Parameters ---------- same as :meth:`Message.edit` """ payload = _EditingPayload( content=content, embed=embed, embeds=embeds, view=view, tts=tts, file=file, files=files, suppress_embeds=suppress_embeds, ) if view and view is not MISSING: self.interaction.client.load_view(view) resp = await self.interaction.client.http.edit_webhook_message( self.interaction.application_id, self.interaction.token, self.message.id, payload.to_form(), ) data = await resp.json() return Message(self.interaction.client, data)
class ResponseAdapter: """ Interface for sending responses to interactions """ def __init__(self, interaction: "Interaction") -> None: self.inter = interaction async def send( self, content: Optional[str] = None, *, embed: Optional[Embed] = None, embeds: Optional[List[Embed]] = None, view: Optional[View] = None, tts: Optional[bool] = False, file: Optional[File] = None, files: Optional[List[File]] = None, allowed_mentions: Optional[AllowedMentions] = None, ephemeral: Optional[bool] = False, suppress_embeds: Optional[bool] = False, poll: Optional[Poll] = None, ) -> InteractionResponse: """ Sends a response to the interaction Parameters ---------- content: Optional[str] The content of the message to send embed: Optional[Embed] The embed to send with the message embeds: Optional[List[Embed]] The list of embeds to send with the message (max 10) view: Optional[View] The view to send with the message tts: Optional[bool] Whether the message should be sent as tts or not file: Optional[File] The file to send with the message files: Optional[List[File]] The list of files to send with the message allowed_mentions: Optional[AllowedMentions] The allowed_mentions object to send with the message ephemeral: Optional[bool] Whether the message should be ephemeral or not suppress_embeds: Optional[bool] Whether the embeds should be suppressed or not poll: Optional[Poll] The poll to send with the message Returns ------- InteractionResponse """ payload = _SendingPayload( content=content, embed=embed, embeds=embeds, view=view, tts=tts, file=file, files=files, ephemeral=ephemeral, suppress_embeds=suppress_embeds, allowed_mentions=allowed_mentions, poll=poll, ) if view: self.inter.client.load_view(view) payload = payload.to_form(InteractionCallbackType.channel_message_with_source) self.inter._responded = True await self.inter.client.http.send_interaction_mp_callback( self.inter.id, self.inter.token, payload ) return InteractionResponse(self.inter) async def send_modal(self, modal: Union[Modal, Any]) -> InteractionResponse: """ Sends a modal to the interaction Parameters ---------- modal: Modal The modal to send Returns ------- InteractionResponse """ if self.inter.type not in ( InteractionType.component, InteractionType.app_command, ): raise InteractionTypeMismatch( f"Method not supported for {self.inter.type}", self.inter ) self.inter.client.active_components[modal.custom_id] = modal payload = { "data": modal.to_dict(), "type": InteractionCallbackType.modal, } self.inter._responded = True await self.inter.client.http.send_interaction_callback( self.inter.id, self.inter.token, payload ) return InteractionResponse(self.inter) async def autocomplete(self, choices: List[Choice]): """ Sends autocomplete choices to the interaction (max 25) Parameters ---------- choices: List[Choice] The choices to send """ if self.inter.type != InteractionType.autocomplete: raise InteractionTypeMismatch( f"Method not supported for {self.inter.type}", self.inter ) choices = choices[:25] payload = { "type": InteractionCallbackType.autocomplete, "data": {"choices": [i.to_dict() for i in choices]}, } await self.inter.client.http.send_interaction_callback( self.inter.id, self.inter.token, payload ) async def defer( self, ephemeral: bool = False, thinking: bool = False ) -> InteractionResponse: """ Defers the interaction Parameters ---------- ephemeral: bool Whether the successive responses should be ephemeral or not (only for Application Commands or `thinking` is `True`) thinking: bool Whether to send a new "is thinking..." message to be edited later (DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE) or do nothing to edit the original message later (DEFERRED_UPDATE_MESSAGE). Not available for application commands. """ payload = {} if ( self.inter.type is InteractionType.component or self.inter.type is InteractionType.modal_submit ): if thinking: payload["type"] = ( InteractionCallbackType.deferred_channel_message_with_source ) if ephemeral: payload["data"] = {"flags": 64} else: payload["type"] = ( InteractionCallbackType.deferred_update_component_message ) elif self.inter.type == InteractionType.app_command: payload["type"] = ( InteractionCallbackType.deferred_channel_message_with_source ) if ephemeral: payload["data"] = {"flags": 64} else: raise InteractionTypeMismatch( f"Method not supported for {self.inter.type}", self.inter ) self.inter._responded = True await self.inter.client.http.send_interaction_callback( self.inter.id, self.inter.token, payload ) return InteractionResponse(self.inter) async def require_premium(self): """ Prompts the user that a premium purchase is required for this interaction This method is only available for applications with a premium SKU set up """ if self.inter.type == InteractionType.autocomplete: raise InteractionTypeMismatch( f"Method not supported for {self.inter.type}", self.inter ) payload = { "data": {}, "type": InteractionCallbackType.premium_required, } self.inter._responded = True await self.inter.client.http.send_interaction_callback( self.inter.id, self.inter.token, payload ) return InteractionResponse(self.inter) async def update_message( self, content: Optional[str] = MISSING, *, embed: Optional[Embed] = MISSING, embeds: Optional[List[Embed]] = MISSING, view: Optional[View] = MISSING, tts: Optional[bool] = MISSING, file: Optional[File] = MISSING, files: Optional[List[File]] = MISSING, suppress_embeds: Optional[bool] = MISSING, ) -> InteractionResponse: """ Edits the message, the component was attached to. This method is only available for component interactions. Parameters ---------- content: Optional[str] The new content of the message. embed: Optional[Embed] The new embed of the message. embeds: Optional[List[Embed]] The new embeds of the message. view: Optional[View] The new view of the message. tts: Optional[bool] Whether the message should be sent with text-to-speech. file: Optional[File] A file to send with the message. files: Optional[List[File]] A list of files to send with the message. suppress_embeds: Optional[bool] Whether the embeds should be suppressed. Returns ------- InteractionResponse """ if not ( self.inter.type == InteractionType.component or self.inter.type == InteractionType.modal_submit ): raise InteractionTypeMismatch( f"Method not supported for {self.inter.type}", self.inter ) payload = _EditingPayload( content=content, embed=embed, embeds=embeds, view=view, tts=tts, file=file, files=files, suppress_embeds=suppress_embeds, ) if view and view is not MISSING: self.inter.client.load_view(view) payload = payload.to_form(InteractionCallbackType.update_component_message) self.inter._responded = True await self.inter.client.http.send_interaction_mp_callback( self.inter.id, self.inter.token, payload ) return InteractionResponse(self.inter) async def followup( self, content: Optional[str] = None, *, embed: Optional[Embed] = None, embeds: Optional[List[Embed]] = None, view: Optional[View] = None, tts: Optional[bool] = False, file: Optional[File] = None, files: Optional[List[File]] = None, allowed_mentions: Optional[AllowedMentions] = None, ephemeral: Optional[bool] = False, suppress_embeds: Optional[bool] = False, poll: Optional[Poll] = None, ) -> FollowupResponse: """ Sends a follow-up message to a deferred interaction Parameters ---------- content: Optional[str] The content of the message to send embed: Optional[Embed] The embed to send with the message embeds: Optional[List[Embed]] The list of embeds to send with the message (max 10) view: Optional[View] The view to send with the message tts: Optional[bool] Whether the message should be sent as tts or not file: Optional[File] The file to send with the message files: Optional[List[File]] The list of files to send with the message allowed_mentions: Optional[AllowedMentions] The allowed_mentions object to send with the message ephemeral: Optional[bool] Whether the message should be ephemeral or not suppress_embeds: Optional[bool] Whether the message should suppress embeds or not poll: Optional[Poll] The poll to send with the message """ payload = _SendingPayload( content=content, embed=embed, embeds=embeds, view=view, tts=tts, file=file, files=files, ephemeral=ephemeral, suppress_embeds=suppress_embeds, allowed_mentions=allowed_mentions, poll=poll, ) if view: self.inter.client.load_view(view) resp = await self.inter.client.http.send_webhook_message( self.inter.application_id, self.inter.token, payload.to_form() ) data = await resp.json() return FollowupResponse(data, self.inter)