discorb 0.11.4 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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