def _attach_image(msg: discord.Message, image: bytes): file_obj = MagicMock(spec=discord.File) file_obj.fp.read = MagicMock(return_value=image) attachment = MagicMock(spec=discord.Attachment) attachment.to_file = MagicMock(return_value=future(file_obj)) msg.attachments = [attachment]
async def from_interaction(cls, interaction: Interaction, /) -> Self: """|coro| Creates a context from a :class:`discord.Interaction`. This only works on application command based interactions, such as slash commands or context menus. On slash command based interactions this creates a synthetic :class:`~discord.Message` that points to an ephemeral message that the command invoker has executed. This means that :attr:`Context.author` returns the member that invoked the command. In a message context menu based interaction, the :attr:`Context.message` attribute is the message that the command is being executed on. This means that :attr:`Context.author` returns the author of the message being targetted. To get the member that invoked the command then :attr:`discord.Interaction.user` should be used instead. .. versionadded:: 2.0 Parameters ----------- interaction: :class:`discord.Interaction` The interaction to create a context with. Raises ------- ValueError The interaction does not have a valid command. TypeError The interaction client is not derived from :class:`Bot` or :class:`AutoShardedBot`. """ # Circular import from .bot import BotBase if not isinstance(interaction.client, BotBase): raise TypeError( 'Interaction client is not derived from commands.Bot or commands.AutoShardedBot' ) command = interaction.command if command is None: raise ValueError('interaction does not have command data') bot: BotT = interaction.client # type: ignore data: ApplicationCommandInteractionData = interaction.data # type: ignore if interaction.message is None: synthetic_payload = { 'id': interaction.id, 'reactions': [], 'embeds': [], 'mention_everyone': False, 'tts': False, 'pinned': False, 'edited_timestamp': None, 'type': MessageType.chat_input_command if data.get('type', 1) == 1 else MessageType.context_menu_command, 'flags': 64, 'content': '', 'mentions': [], 'mention_roles': [], 'attachments': [], } if interaction.channel_id is None: raise RuntimeError( 'interaction channel ID is null, this is probably a Discord bug' ) channel = interaction.channel or PartialMessageable( state=interaction._state, id=interaction.channel_id) message = Message(state=interaction._state, channel=channel, data=synthetic_payload) # type: ignore message.author = interaction.user message.attachments = [ a for _, a in interaction.namespace if isinstance(a, Attachment) ] else: message = interaction.message prefix = '/' if data.get('type', 1) == 1 else '\u200b' # Mock the prefix return cls( message=message, bot=bot, view=StringView(''), args=[], kwargs={}, prefix=prefix, interaction=interaction, invoked_with=command.name, command= command, # type: ignore # this will be a hybrid command, technically )