discorb 0.11.4 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,188 @@
1
+ module Discorb
2
+ class Interaction
3
+ #
4
+ # A module for response with source.
5
+ #
6
+ module SourceResponse
7
+ #
8
+ # Response with `DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE`(`5`).
9
+ #
10
+ # @macro async
11
+ # @macro http
12
+ #
13
+ # @param [Boolean] ephemeral Whether to make the response ephemeral.
14
+ #
15
+ def defer_source(ephemeral: false)
16
+ Async do
17
+ @client.http.post("/interactions/#{@id}/#{@token}/callback", {
18
+ type: 5,
19
+ data: {
20
+ flags: (ephemeral ? 1 << 6 : 0),
21
+ },
22
+ }).wait
23
+ @defered = true
24
+ end
25
+ end
26
+
27
+ #
28
+ # Response with `CHANNEL_MESSAGE_WITH_SOURCE`(`4`).
29
+ #
30
+ # @macro async
31
+ # @macro http
32
+ #
33
+ # @param [String] content The content of the response.
34
+ # @param [Boolean] tts Whether to send the message as text-to-speech.
35
+ # @param [Discorb::Embed] embed The embed to send.
36
+ # @param [Array<Discorb::Embed>] embeds The embeds to send. (max: 10)
37
+ # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
38
+ # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
39
+ # @param [Boolean] ephemeral Whether to make the response ephemeral.
40
+ #
41
+ # @return [Discorb::Interaction::SourceResponse::CallbackMessage, Discorb::Webhook::Message] The callback message.
42
+ #
43
+ def post(content = nil, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil, ephemeral: false)
44
+ Async do
45
+ payload = {}
46
+ payload[:content] = content if content
47
+ payload[:tts] = tts
48
+ payload[:embeds] = (embeds || [embed])&.map { |e| e&.to_hash }.filter { _1 }
49
+ payload[:allowed_mentions] = allowed_mentions&.to_hash(@client.allowed_mentions) || @client.allowed_mentions.to_hash
50
+ payload[:components] = Component.to_payload(components) if components
51
+ payload[:flags] = (ephemeral ? 1 << 6 : 0)
52
+
53
+ ret = if @responded
54
+ _resp, data = @client.http.post("/webhooks/#{@application_id}/#{@token}", payload).wait
55
+ webhook = Webhook::URLWebhook.new("/webhooks/#{@application_id}/#{@token}")
56
+ Webhook::Message.new(webhook, data, @client)
57
+ elsif @defered
58
+ @client.http.patch("/webhooks/#{@application_id}/#{@token}/messages/@original", payload).wait
59
+ CallbackMessage.new(@client, payload, @application_id, @token)
60
+ else
61
+ @client.http.post("/interactions/#{@id}/#{@token}/callback", { type: 4, data: payload }).wait
62
+ CallbackMessage.new(@client, payload, @application_id, @token)
63
+ end
64
+ @responded = true
65
+ ret
66
+ end
67
+ end
68
+
69
+ class CallbackMessage
70
+ # @private
71
+ def initialize(client, data, application_id, token)
72
+ @client = client
73
+ @data = data
74
+ @application_id = application_id
75
+ @token = token
76
+ end
77
+
78
+ #
79
+ # Edits the callback message.
80
+ # @macro async
81
+ # @macro http
82
+ # @macro edit
83
+ #
84
+ # @param [String] content The new content of the message.
85
+ # @param [Discorb::Embed] embed The new embed of the message.
86
+ # @param [Array<Discorb::Embed>] embeds The new embeds of the message.
87
+ # @param [Array<Discorb::Attachment>] attachments The attachments to remain.
88
+ # @param [Discorb::File] file The file to send.
89
+ # @param [Array<Discorb::File>] files The files to send.
90
+ #
91
+ def edit(
92
+ content = :unset,
93
+ embed: :unset, embeds: :unset,
94
+ file: :unset, files: :unset,
95
+ attachments: :unset
96
+ )
97
+ Async do
98
+ payload = {}
99
+ payload[:content] = content if content != :unset
100
+ payload[:embeds] = embed ? [embed.to_hash] : [] if embed != :unset
101
+ payload[:embeds] = embeds.map(&:to_hash) if embeds != :unset
102
+ payload[:attachments] = attachments.map(&:to_hash) if attachments != :unset
103
+ files = [file] if file != :unset
104
+ if files == :unset
105
+ headers = {
106
+ "Content-Type" => "application/json",
107
+ }
108
+ else
109
+ headers, payload = HTTP.multipart(payload, files)
110
+ end
111
+ @client.http.patch("/webhooks/#{@application_id}/#{@token}/messages/@original", payload, headers: headers).wait
112
+ end
113
+ end
114
+
115
+ alias modify edit
116
+
117
+ #
118
+ # Deletes the callback message.
119
+ # @note This will fail if the message is ephemeral.
120
+ #
121
+ def delete!
122
+ Async do
123
+ @client.http.delete("/webhooks/#{@application_id}/#{@token}/messages/@original").wait
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ #
130
+ # A module for response with update.
131
+ #
132
+ module UpdateResponse
133
+ #
134
+ # Response with `DEFERRED_UPDATE_MESSAGE`(`6`).
135
+ #
136
+ # @param [Boolean] ephemeral Whether to make the response ephemeral.
137
+ #
138
+ def defer_update(ephemeral: false)
139
+ Async do
140
+ @client.http.post("/interactions/#{@id}/#{@token}/callback", {
141
+ type: 6,
142
+ data: {
143
+ flags: (ephemeral ? 1 << 6 : 0),
144
+ },
145
+ }).wait
146
+ end
147
+ end
148
+
149
+ #
150
+ # Response with `UPDATE_MESSAGE`(`7`).
151
+ #
152
+ # @macro async
153
+ # @macro http
154
+ #
155
+ # @param [String] content The content of the response.
156
+ # @param [Boolean] tts Whether to send the message as text-to-speech.
157
+ # @param [Discorb::Embed] embed The embed to send.
158
+ # @param [Array<Discorb::Embed>] embeds The embeds to send. (max: 10)
159
+ # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
160
+ # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
161
+ # @param [Boolean] ephemeral Whether to make the response ephemeral.
162
+ #
163
+ def edit(content, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil, ephemeral: false)
164
+ Async do
165
+ payload = {}
166
+ payload[:content] = content if content
167
+ payload[:tts] = tts
168
+ tmp_embed = if embed
169
+ [embed]
170
+ elsif embeds
171
+ embeds
172
+ end
173
+ payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
174
+ payload[:allowed_mentions] = allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
175
+ payload[:components] = Component.to_payload(components) if components
176
+ payload[:flags] = (ephemeral ? 1 << 6 : 0)
177
+ @client.http.post("/interactions/#{@id}/#{@token}/callback", { type: 7, data: payload }).wait
178
+ end
179
+ end
180
+ end
181
+
182
+ private
183
+
184
+ def _set_data(*)
185
+ nil
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,94 @@
1
+ module Discorb
2
+ #
3
+ # Represents a user interaction with the bot.
4
+ #
5
+ class Interaction < DiscordModel
6
+ # @return [Discorb::Snowflake] The ID of the interaction.
7
+ attr_reader :id
8
+ # @return [Discorb::Snowflake] The ID of the application that created the interaction.
9
+ attr_reader :application_id
10
+ # @return [Symbol] The type of interaction.
11
+ attr_reader :type
12
+ # @return [Discorb::Member] The member that created the interaction.
13
+ attr_reader :member
14
+ # @return [Discorb::User] The user that created the interaction.
15
+ attr_reader :user
16
+ # @return [Integer] The type of interaction.
17
+ # @note This is always `1` for now.
18
+ attr_reader :version
19
+ # @return [String] The token for the interaction.
20
+ attr_reader :token
21
+
22
+ # @!attribute [r] guild
23
+ # @macro client_cache
24
+ # @return [Discorb::Guild] The guild the interaction took place in.
25
+ # @!attribute [r] channel
26
+ # @macro client_cache
27
+ # @return [Discorb::Channel] The channel the interaction took place in.
28
+ # @!attribute [r] target
29
+ # @return [Discorb::User, Discorb::Member] The user or member the interaction took place with.
30
+
31
+ @interaction_type = nil
32
+ @interaction_name = nil
33
+
34
+ # @private
35
+ def initialize(client, data)
36
+ @client = client
37
+ @id = Snowflake.new(data[:id])
38
+ @application_id = Snowflake.new(data[:application_id])
39
+ @type = self.class.interaction_name
40
+ @type_id = self.class.interaction_type
41
+ @guild_id = data[:guild_id] && Snowflake.new(data[:guild_id])
42
+ @channel_id = data[:channel_id] && Snowflake.new(data[:channel_id])
43
+ @member = guild.members[data[:member][:id]] || Member.new(@client, @guild_id, data[:member][:user], data[:member]) if data[:member]
44
+ @user = @client.users[data[:user][:id]] || User.new(@client, data[:user]) if data[:user]
45
+ @token = data[:token]
46
+ @version = data[:version]
47
+ @defered = false
48
+ @responded = false
49
+ _set_data(data[:data])
50
+ end
51
+
52
+ def guild
53
+ @client.guilds[@guild_id]
54
+ end
55
+
56
+ def channel
57
+ @client.channels[@channel_id]
58
+ end
59
+
60
+ def target
61
+ @member || @user
62
+ end
63
+
64
+ alias fired_by target
65
+ alias from target
66
+
67
+ def inspect
68
+ "#<#{self.class} id=#{@id}>"
69
+ end
70
+
71
+ class << self
72
+ # @private
73
+ attr_reader :interaction_type, :interaction_name, :event_name
74
+
75
+ # @private
76
+ def make_interaction(client, data)
77
+ interaction = nil
78
+ descendants.each do |klass|
79
+ interaction = klass.make_interaction(client, data) if !klass.interaction_type.nil? && klass.interaction_type == data[:type]
80
+ end
81
+ if interaction.nil?
82
+ client.log.warn("Unknown interaction type #{data[:type]}, initialized Interaction")
83
+ interaction = Interaction.new(client, data)
84
+ end
85
+ interaction
86
+ end
87
+
88
+ # @private
89
+ def descendants
90
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
91
+ end
92
+ end
93
+ end
94
+ end