Source code for discohook.adapter

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

from .embed import Embed
from .errors import InteractionTypeMismatch
from .enums import InteractionCallbackType, InteractionType
from .file import File
from .multipart import create_form
from .message import Message
from .modal import Modal
from .models import AllowedMentions
from .option import Choice
from .params import (
    MISSING,
    merge_fields,
    handle_edit_params,
    handle_send_params
)
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` """ data = handle_edit_params( 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_components(view) resp = await self.inter.client.http.edit_webhook_message( self.inter.application_id, self.inter.token, "@original", create_form(data, merge_fields(file, files)), ) 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` """ data = handle_edit_params( 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_components(view) resp = await self.interaction.client.http.edit_webhook_message( self.interaction.application_id, self.interaction.token, self.message.id, create_form(data, merge_fields(file, files)), ) 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, ) -> 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 Returns ------- InteractionResponse """ data = handle_send_params( content=content, embed=embed, embeds=embeds, view=view, tts=tts, file=file, files=files, ephemeral=ephemeral, suppress_embeds=suppress_embeds, allowed_mentions=allowed_mentions, ) if view: self.inter.client.load_components(view) payload = { "data": data, "type": InteractionCallbackType.channel_message_with_source, } await self.inter.client.http.send_interaction_mp_callback( self.inter.id, self.inter.token, create_form(payload, merge_fields(file, files)) ) self.inter._responded = True return InteractionResponse(self.inter) async def send_modal(self, modal: Union[Modal, Any]): """ Sends a modal to the interaction Parameters ---------- modal: Modal The modal to send """ if self.inter.kind not in (InteractionType.component, InteractionType.app_command): raise InteractionTypeMismatch(f"Method not supported for {self.inter.kind}") self.inter.client.active_components[modal.custom_id] = modal payload = { "data": modal.to_dict(), "type": InteractionCallbackType.modal, } await self.inter.client.http.send_interaction_callback(self.inter.id, self.inter.token, payload) 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.kind != InteractionType.autocomplete: raise InteractionTypeMismatch(f"Method not supported for {self.inter.kind}") choices = choices[:25] payload = {"type": InteractionCallbackType.autocomplete, "data": {"choices": choices}} await self.inter.client.http.send_interaction_callback(self.inter.id, self.inter.token, payload) async def defer(self, ephemeral: bool = False) -> InteractionResponse: """ Defers the interaction Parameters ---------- ephemeral: bool Whether the successive responses should be ephemeral or not (only for Application Commands) """ payload = {} if self.inter.kind == InteractionType.component: payload["type"] = InteractionCallbackType.deferred_update_component_message elif self.inter.kind == InteractionType.app_command or self.inter.kind == InteractionType.modal_submit: payload["type"] = InteractionCallbackType.deferred_channel_message_with_source if ephemeral: payload["data"] = {"flags": 64} else: raise InteractionTypeMismatch(f"Method not supported for {self.inter.kind}") await self.inter.client.http.send_interaction_callback(self.inter.id, self.inter.token, payload) self.inter._responded = True 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, ) -> None: """ 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. """ if not (self.inter.kind == InteractionType.component or self.inter.kind == InteractionType.modal_submit): raise InteractionTypeMismatch(f"Method not supported for {self.inter.kind}") data = handle_edit_params( 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_components(view) payload = {"type": InteractionCallbackType.update_component_message, "data": data} return await self.inter.client.http.send_interaction_mp_callback( self.inter.id, self.inter.token, create_form(payload, merge_fields(file, files)) ) 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, ) -> 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 """ payload = handle_send_params( content=content, embed=embed, embeds=embeds, view=view, tts=tts, file=file, files=files, ephemeral=ephemeral, suppress_embeds=suppress_embeds, allowed_mentions=allowed_mentions, ) if view: self.inter.client.load_components(view) resp = await self.inter.client.http.send_webhook_message( self.inter.application_id, self.inter.token, create_form(payload, merge_fields(file, files)) ) data = await resp.json() return FollowupResponse(data, self.inter)