# frozen_string_literal: true module Discorb # # Represents an interaction of Discord. # class Interaction # # A module for response with source. # module SourceResponder # @type instance: Discorb::Interaction # # Response with `DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE`(`5`). # # @async # # @param [Boolean] ephemeral Whether to make the response ephemeral. # # @return [Async::Task] The task. # def defer_source(ephemeral: false) Async do @client .http .request( Route.new( "/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post ), { type: 5, data: { flags: (ephemeral ? 1 << 6 : 0) } } ) .wait @defered = true end end # # Response with `CHANNEL_MESSAGE_WITH_SOURCE`(`4`). # # @async # # @param [String] content The content of the response. # @param [Boolean] tts Whether to send the message as text-to-speech. # @param [Discorb::Embed] embed The embed to send. # @param [Array] embeds The embeds to send. (max: 10) # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send. # @param [Discorb::Attachment] attachment The attachment to send. # @param [Array] attachments The attachments to send. (max: 10) # @param [Array, Array>] components The components to send. # @param [Boolean] ephemeral Whether to make the response ephemeral. # # @return [Discorb::Interaction::SourceResponder::CallbackMessage, Discorb::Webhook::Message] # The callback message. # def post( content = nil, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, attachment: nil, attachments: nil, components: nil, ephemeral: false ) Async do payload = {} payload[:content] = content if content payload[:tts] = tts payload[:embeds] = (embeds || [embed]) .map { |e| e&.to_hash } .filter { _1 } payload[:allowed_mentions] = allowed_mentions&.to_hash( @client.allowed_mentions ) || @client.allowed_mentions.to_hash payload[:components] = Component.to_payload(components) if components payload[:flags] = (ephemeral ? 1 << 6 : 0) attachments ||= attachment ? [attachment] : [] payload[:attachments] = attachments.map.with_index do |a, i| { id: i, filename: a.filename, description: a.description } end ret = if @responded _resp, data = @client .http .multipart_request( Route.new( "/webhooks/#{@application_id}/#{@token}", "//webhooks/:webhook_id/:token", :post ), payload, attachments ) .wait webhook = Webhook::URLWebhook.new( "/webhooks/#{@application_id}/#{@token}" ) Webhook::Message.new(webhook, data, @client) elsif @defered @client .http .multipart_request( Route.new( "/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :patch ), payload, attachments ) .wait CallbackMessage.new(@client, payload, @application_id, @token) else @client .http .multipart_request( Route.new( "/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post ), { type: 4, data: payload }, attachments ) .wait CallbackMessage.new(@client, payload, @application_id, @token) end @responded = true ret end end end # # Represents of a callback message of interaction. # class CallbackMessage # # Initializes a new instance of CallbackMessage. # @private # # @param [Client] client The client. # @param [Hash] data The payload. # @param [String] application_id The application ID. # @param [String] token The token. # def initialize(client, data, application_id, token) @client = client @data = data @application_id = application_id @token = token end # # Edits the callback message. # @async # @macro edit # # @param [String] content The new content of the message. # @param [Discorb::Embed] embed The new embed of the message. # @param [Array] embeds The new embeds of the message. # @param [Array] attachments The attachments to remain. # @param [Discorb::Attachment] file The file to send. # @param [Array] files The files to send. # # @return [Async::Task] The task. # def edit( content = Discorb::Unset, embed: Discorb::Unset, embeds: Discorb::Unset, file: Discorb::Unset, files: Discorb::Unset, attachments: Discorb::Unset ) Async do payload = {} payload[:content] = content if content != Discorb::Unset payload[:embeds] = embed ? [embed.to_hash] : [] if embed != Discorb::Unset payload[:embeds] = embeds.map(&:to_hash) if embeds != Discorb::Unset payload[:attachments] = attachments.map(&:to_hash) if attachments != Discorb::Unset files = [file] if file != Discorb::Unset files = [] if files == Discorb::Unset @client .http .multipart_request( Route.new( "/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :patch ), payload, files ) .wait end end alias modify edit # # Deletes the callback message. # @async # @note This will fail if the message is ephemeral. # # @return [Async::Task] The task. # def delete Async do @client .http .request( Route.new( "/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :delete ) ) .wait end end def inspect "#<#{self.class.name} application_id=#{@application_id}" end end # # A module for response with update. # module UpdateResponder # @type instance: Discorb::Interaction # # Response with `DEFERRED_UPDATE_MESSAGE`(`6`). # @async # # @param [Boolean] ephemeral Whether to make the response ephemeral. # # @return [Async::Task] The task. # def defer_update(ephemeral: false) Async do @client .http .request( Route.new( "/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post ), { type: 6, data: { flags: (ephemeral ? 1 << 6 : 0) } } ) .wait end end # # Response with `UPDATE_MESSAGE`(`7`). # # @async # # @param [String] content The content of the response. # @param [Boolean] tts Whether to send the message as text-to-speech. # @param [Discorb::Embed] embed The embed to send. # @param [Array] embeds The embeds to send. (max: 10) # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send. # @param [Discorb::Attachment] attachment The attachment to send. # @param [Array] attachments The attachments to send. (max: 10) # @param [Array, Array>] components The components to send. # @param [Boolean] ephemeral Whether to make the response ephemeral. # # @return [Async::Task] The task. # def edit( content, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, attachment: nil, attachments: nil, components: nil, ephemeral: false ) Async do payload = {} payload[:content] = content if content payload[:tts] = tts tmp_embed = if embed [embed] elsif embeds embeds end payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed payload[:allowed_mentions] = ( if allowed_mentions allowed_mentions.to_hash(@client.allowed_mentions) else @client.allowed_mentions.to_hash end ) payload[:components] = Component.to_payload(components) if components payload[:flags] = (ephemeral ? 1 << 6 : 0) attachments ||= [attachment] if attachment payload[:attachments] = attachments.map.with_index do |a, i| { id: i, filename: a.filename, description: a.description } end @client .http .multipart_request( Route.new( "/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post ), { type: 7, data: payload }, attachments ) .wait end end end # # A module for response with modal. # module ModalResponder # @type instance: Discorb::Interaction # # Response with `MODAL`(`9`). # # @param [String] title The title of the modal. # @param [String] custom_id The custom id of the modal. # @param [Array] components The text inputs to send. # # @return [Async::Task] The task. # def show_modal(title, custom_id, components) Async do payload = { title: title, custom_id: custom_id, components: Component.to_payload(components) } @client .http .request( Route.new( "/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post ), { type: 9, data: payload } ) .wait end end end private def _set_data(_) nil end end end