Skip to content

Commit

Permalink
attachments in interaction responses
Browse files Browse the repository at this point in the history
* Attatchments in interaction responses

* Minor fix

* Debug

* Another attempt?

* Again

* An attempt

* Minor fix

* M

* Bugfix

* M

* Cleanup

* Cleanup

* Cleanup

* Cleanup

* fix typos

* Remove unpacking operand.
  • Loading branch information
Droid00000 authored Jan 24, 2025
1 parent cfce8ce commit 8937456
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 38 deletions.
21 changes: 15 additions & 6 deletions lib/discordrb/api/interaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@ module Discordrb::API::Interaction

# Respond to an interaction.
# https://discord.com/developers/docs/interactions/slash-commands#create-interaction-response
def create_interaction_response(interaction_token, interaction_id, type, content = nil, tts = nil, embeds = nil, allowed_mentions = nil, flags = nil, components = nil)
data = { tts: tts, content: content, embeds: embeds, allowed_mentions: allowed_mentions, flags: flags, components: components }.compact
def create_interaction_response(interaction_token, interaction_id, type, content = nil, tts = nil, embeds = nil, allowed_mentions = nil, flags = nil, components = nil, attachments = nil)
body = { tts: tts, content: content, embeds: embeds, allowed_mentions: allowed_mentions, flags: flags, components: components }.compact

body = if attachments
files = [*0...attachments.size].zip(attachments).to_h
{ **files, payload_json: { type: type, data: body }.to_json }
else
{ type: type, data: body }.to_json
end

headers = { content_type: :json } unless attachments

Discordrb::API.request(
:interactions_iid_token_callback,
interaction_id,
:post,
"#{Discordrb::API.api_base}/interactions/#{interaction_id}/#{interaction_token}/callback",
{ type: type, data: data }.to_json,
content_type: :json
body,
headers
)
end

Expand All @@ -42,8 +51,8 @@ def get_original_interaction_response(interaction_token, application_id)

# Edit the original response to an interaction.
# https://discord.com/developers/docs/interactions/slash-commands#edit-original-interaction-response
def edit_original_interaction_response(interaction_token, application_id, content = nil, embeds = nil, allowed_mentions = nil, components = nil)
Discordrb::API::Webhook.token_edit_message(interaction_token, application_id, '@original', content, embeds, allowed_mentions, components)
def edit_original_interaction_response(interaction_token, application_id, content = nil, embeds = nil, allowed_mentions = nil, components = nil, attachments = nil)
Discordrb::API::Webhook.token_edit_message(interaction_token, application_id, '@original', content, embeds, allowed_mentions, components, attachments)
end

# Delete the original response to an interaction.
Expand Down
25 changes: 20 additions & 5 deletions lib/discordrb/api/webhook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,19 @@ def token_webhook(webhook_token, webhook_id)

# Execute a webhook via token.
# https://discord.com/developers/docs/resources/webhook#execute-webhook
def token_execute_webhook(webhook_token, webhook_id, wait = false, content = nil, username = nil, avatar_url = nil, tts = nil, file = nil, embeds = nil, allowed_mentions = nil, flags = nil, components = nil)
def token_execute_webhook(webhook_token, webhook_id, wait = false, content = nil, username = nil, avatar_url = nil, tts = nil, file = nil, embeds = nil, allowed_mentions = nil, flags = nil, components = nil, attachments = nil)
body = { content: content, username: username, avatar_url: avatar_url, tts: tts, embeds: embeds&.map(&:to_hash), allowed_mentions: allowed_mentions, flags: flags, components: components }

body = if file
{ file: file, payload_json: body.to_json }
elsif attachments
files = [*0...attachments.size].zip(attachments).to_h
{ **files, payload_json: body.to_json }
else
body.to_json
end

headers = { content_type: :json } unless file
headers = { content_type: :json } unless file || attachments

Discordrb::API.request(
:webhooks_wid,
Expand Down Expand Up @@ -116,14 +120,25 @@ def token_get_message(webhook_token, webhook_id, message_id)

# Edit a webhook message via webhook token
# https://discord.com/developers/docs/resources/webhook#edit-webhook-message
def token_edit_message(webhook_token, webhook_id, message_id, content = nil, embeds = nil, allowed_mentions = nil, components = nil)
def token_edit_message(webhook_token, webhook_id, message_id, content = nil, embeds = nil, allowed_mentions = nil, components = nil, attachments = nil)
body = { content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components }

body = if attachments
files = [*0...attachments.size].zip(attachments).to_h
{ **files, payload_json: body.to_json }
else
body.to_json
end

headers = { content_type: :json } unless attachments

Discordrb::API.request(
:webhooks_wid_messages,
webhook_id,
:patch,
"#{Discordrb::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}",
{ content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components }.to_json,
content_type: :json
body,
headers
)
end

Expand Down
39 changes: 22 additions & 17 deletions lib/discordrb/data/interaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ def initialize(data, bot)
# @param flags [Integer] Message flags.
# @param ephemeral [true, false] Whether this message should only be visible to the interaction initiator.
# @param wait [true, false] Whether this method should return a Message object of the interaction response.
# @param components [Array<#to_h>] An array of components
# @param components [Array<#to_h>] An array of components.
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`.
# @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
# @yieldparam view [Webhooks::View] A builder for creating interaction components.
def respond(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil)
def respond(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, attachments: nil)
flags |= 1 << 6 if ephemeral

builder = Discordrb::Webhooks::Builder.new
Expand All @@ -105,7 +106,7 @@ def respond(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0
components ||= view
data = builder.to_json_hash

Discordrb::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:channel_message], data[:content], tts, data[:embeds], data[:allowed_mentions], flags, components.to_a)
Discordrb::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:channel_message], data[:content], tts, data[:embeds], data[:allowed_mentions], flags, components.to_a, attachments)

return unless wait

Expand Down Expand Up @@ -157,10 +158,11 @@ def show_modal(title:, custom_id:, components: nil)
# @param flags [Integer] Message flags.
# @param ephemeral [true, false] Whether this message should only be visible to the interaction initiator.
# @param wait [true, false] Whether this method should return a Message object of the interaction response.
# @param components [Array<#to_h>] An array of components
# @param components [Array<#to_h>] An array of components.
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`.
# @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
# @yieldparam view [Webhooks::View] A builder for creating interaction components.
def update_message(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil)
def update_message(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, attachments: nil)
flags |= 1 << 6 if ephemeral

builder = Discordrb::Webhooks::Builder.new
Expand All @@ -172,7 +174,7 @@ def update_message(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, f
components ||= view
data = builder.to_json_hash

Discordrb::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:update_message], data[:content], tts, data[:embeds], data[:allowed_mentions], flags, components.to_a)
Discordrb::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:update_message], data[:content], tts, data[:embeds], data[:allowed_mentions], flags, components.to_a, attachments)

return unless wait

Expand All @@ -184,10 +186,11 @@ def update_message(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, f
# @param content [String] The content of the message.
# @param embeds [Array<Hash, Webhooks::Embed>] The embeds for the message.
# @param allowed_mentions [Hash, AllowedMentions] Mentions that can ping on this message.
# @param components [Array<#to_h>] An array of components
# @param components [Array<#to_h>] An array of components.
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`.
# @return [InteractionMessage] The updated response message.
# @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
def edit_response(content: nil, embeds: nil, allowed_mentions: nil, components: nil)
def edit_response(content: nil, embeds: nil, allowed_mentions: nil, components: nil, attachments: nil)
builder = Discordrb::Webhooks::Builder.new
view = Discordrb::Webhooks::View.new

Expand All @@ -196,7 +199,7 @@ def edit_response(content: nil, embeds: nil, allowed_mentions: nil, components:

components ||= view
data = builder.to_json_hash
resp = Discordrb::API::Interaction.edit_original_interaction_response(@token, @application_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a)
resp = Discordrb::API::Interaction.edit_original_interaction_response(@token, @application_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a, attachments)

Interactions::Message.new(JSON.parse(resp), @bot, @interaction)
end
Expand All @@ -212,8 +215,9 @@ def delete_response
# @param allowed_mentions [Hash, AllowedMentions] Mentions that can ping on this message.
# @param flags [Integer] Message flags.
# @param ephemeral [true, false] Whether this message should only be visible to the interaction initiator.
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`.
# @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
def send_message(content: nil, embeds: nil, tts: false, allowed_mentions: nil, flags: 0, ephemeral: false, components: nil)
def send_message(content: nil, embeds: nil, tts: false, allowed_mentions: nil, flags: 0, ephemeral: false, components: nil, attachments: nil)
flags |= 64 if ephemeral

builder = Discordrb::Webhooks::Builder.new
Expand All @@ -226,7 +230,7 @@ def send_message(content: nil, embeds: nil, tts: false, allowed_mentions: nil, f
data = builder.to_json_hash

resp = Discordrb::API::Webhook.token_execute_webhook(
@token, @application_id, true, data[:content], nil, nil, tts, nil, data[:embeds], data[:allowed_mentions], flags, components.to_a
@token, @application_id, true, data[:content], nil, nil, tts, nil, data[:embeds], data[:allowed_mentions], flags, components.to_a, attachments
)
Interactions::Message.new(JSON.parse(resp), @bot, @interaction)
end
Expand All @@ -235,8 +239,9 @@ def send_message(content: nil, embeds: nil, tts: false, allowed_mentions: nil, f
# @param content [String] The message content.
# @param embeds [Array<Hash, Webhooks::Embed>] The embeds for the message.
# @param allowed_mentions [Hash, AllowedMentions] Mentions that can ping on this message.
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`.
# @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, components: nil)
def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, components: nil, attachments: nil)
builder = Discordrb::Webhooks::Builder.new
view = Discordrb::Webhooks::View.new

Expand All @@ -247,7 +252,7 @@ def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, comp
data = builder.to_json_hash

resp = Discordrb::API::Webhook.token_edit_message(
@token, @application_id, message.resolve_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a
@token, @application_id, message.resolve_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a, attachments
)
Interactions::Message.new(JSON.parse(resp), @bot, @interaction)
end
Expand Down Expand Up @@ -777,8 +782,8 @@ def channel
# Respond to this message.
# @param (see Interaction#send_message)
# @yieldparam (see Interaction#send_message)
def respond(content: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: true, components: nil, &block)
@interaction.send_message(content: content, embeds: embeds, allowed_mentions: allowed_mentions, flags: flags, ephemeral: ephemeral, components: components, &block)
def respond(content: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: true, components: nil, attachments: nil, &block)
@interaction.send_message(content: content, embeds: embeds, allowed_mentions: allowed_mentions, flags: flags, ephemeral: ephemeral, components: components, attachments: attachments, &block)
end

# Delete this message.
Expand All @@ -791,8 +796,8 @@ def delete
# @param embeds (see Interaction#send_message)
# @param allowed_mentions (see Interaction#send_message)
# @yieldparam (see Interaction#send_message)
def edit(content: nil, embeds: nil, allowed_mentions: nil, components: nil, &block)
@interaction.edit_message(@id, content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components, &block)
def edit(content: nil, embeds: nil, allowed_mentions: nil, components: nil, attachments: nil, &block)
@interaction.edit_message(@id, content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components, attachments: attachments, &block)
end

# @return [Discordrb::Message]
Expand Down
22 changes: 12 additions & 10 deletions lib/discordrb/events/interactions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ def initialize(data, bot)
end

# (see Interaction#respond)
def respond(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, &block)
def respond(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, attachments: nil, &block)
@interaction.respond(
content: content, tts: tts, embeds: embeds, allowed_mentions: allowed_mentions,
flags: flags, ephemeral: ephemeral, wait: wait, components: components, &block
flags: flags, ephemeral: ephemeral, wait: wait, components: components, attachments: attachments,
&block
)
end

Expand All @@ -48,10 +49,11 @@ def defer(flags: 0, ephemeral: true)
end

# (see Interaction#update_message)
def update_message(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, &block)
def update_message(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, attachments: nil, &block)
@interaction.update_message(
content: content, tts: tts, embeds: embeds, allowed_mentions: allowed_mentions,
flags: flags, ephemeral: ephemeral, wait: wait, components: components, &block
flags: flags, ephemeral: ephemeral, wait: wait, components: components, attachments: attachments,
&block
)
end

Expand All @@ -61,8 +63,8 @@ def show_modal(title:, custom_id:, components: nil, &block)
end

# (see Interaction#edit_response)
def edit_response(content: nil, embeds: nil, allowed_mentions: nil, components: nil, &block)
@interaction.edit_response(content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components, &block)
def edit_response(content: nil, embeds: nil, allowed_mentions: nil, components: nil, attachments: nil, &block)
@interaction.edit_response(content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components, attachments: attachments, &block)
end

# (see Interaction#delete_response)
Expand All @@ -71,13 +73,13 @@ def delete_response
end

# (see Interaction#send_message)
def send_message(content: nil, embeds: nil, tts: false, allowed_mentions: nil, flags: 0, ephemeral: nil, components: nil, &block)
@interaction.send_message(content: content, embeds: embeds, tts: tts, allowed_mentions: allowed_mentions, flags: flags, ephemeral: ephemeral, components: components, &block)
def send_message(content: nil, embeds: nil, tts: false, allowed_mentions: nil, flags: 0, ephemeral: nil, components: nil, attachments: nil, &block)
@interaction.send_message(content: content, embeds: embeds, tts: tts, allowed_mentions: allowed_mentions, flags: flags, ephemeral: ephemeral, components: components, attachments: attachments, &block)
end

# (see Interaction#edit_message)
def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, &block)
@interaction.edit_message(message, content: content, embeds: embeds, allowed_mentions: allowed_mentions, &block)
def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, attachments: nil, &block)
@interaction.edit_message(message, content: content, embeds: embeds, allowed_mentions: allowed_mentions, attachments: attachments, &block)
end

# (see Interaction#delete_message)
Expand Down

0 comments on commit 8937456

Please sign in to comment.