discordrb 3.7.1 → 3.8.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +43 -4
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/discordrb.gemspec +1 -1
- data/lib/discordrb/allowed_mentions.rb +9 -2
- data/lib/discordrb/api/channel.rb +15 -0
- data/lib/discordrb/api/interaction.rb +2 -2
- data/lib/discordrb/api/server.rb +3 -2
- data/lib/discordrb/api/webhook.rb +2 -2
- data/lib/discordrb/bot.rb +45 -7
- data/lib/discordrb/container.rb +38 -1
- data/lib/discordrb/data/activity.rb +1 -1
- data/lib/discordrb/data/audit_logs.rb +1 -1
- data/lib/discordrb/data/channel.rb +13 -3
- data/lib/discordrb/data/component.rb +422 -73
- data/lib/discordrb/data/emoji.rb +24 -2
- data/lib/discordrb/data/integration.rb +49 -30
- data/lib/discordrb/data/interaction.rb +62 -29
- data/lib/discordrb/data/message.rb +30 -48
- data/lib/discordrb/data/reaction.rb +6 -0
- data/lib/discordrb/data/role.rb +72 -19
- data/lib/discordrb/data/server.rb +18 -4
- data/lib/discordrb/data/snapshot.rb +6 -4
- data/lib/discordrb/data/webhook.rb +8 -4
- data/lib/discordrb/events/integrations.rb +100 -0
- data/lib/discordrb/events/interactions.rb +71 -37
- data/lib/discordrb/events/message.rb +3 -3
- data/lib/discordrb/version.rb +1 -1
- metadata +7 -6
data/lib/discordrb/data/role.rb
CHANGED
|
@@ -165,6 +165,8 @@ module Discordrb
|
|
|
165
165
|
@unicode_emoji = other.unicode_emoji
|
|
166
166
|
@secondary_colour = other.secondary_colour
|
|
167
167
|
@tertiary_colour = other.tertiary_colour
|
|
168
|
+
@mentionable = other.mentionable?
|
|
169
|
+
@tags = other.tags
|
|
168
170
|
end
|
|
169
171
|
|
|
170
172
|
# Updates the data cache from a hash containing data
|
|
@@ -179,14 +181,16 @@ module Discordrb
|
|
|
179
181
|
@mentionable = new_data['mentionable']
|
|
180
182
|
@flags = new_data['flags']
|
|
181
183
|
colours = new_data['colors']
|
|
184
|
+
@managed = new_data['managed']
|
|
182
185
|
@permissions.bits = new_data['permissions'].to_i
|
|
183
186
|
@colour = ColourRGB.new(colours['primary_color'])
|
|
187
|
+
@tags = Tags.new(new_data['tags']) if new_data['tags']
|
|
184
188
|
@secondary_color = ColourRGB.new(colours['secondary_color']) if colours['secondary_color']
|
|
185
189
|
@tertiary_colour = ColourRGB.new(colours['tertiary_color']) if colours['tertiary_color']
|
|
186
190
|
end
|
|
187
191
|
|
|
188
192
|
# Sets the role name to something new
|
|
189
|
-
# @param name [String] The name that should be set
|
|
193
|
+
# @param name [String, nil] The name that should be set.
|
|
190
194
|
def name=(name)
|
|
191
195
|
update_role_data(name: name)
|
|
192
196
|
end
|
|
@@ -206,7 +210,7 @@ module Discordrb
|
|
|
206
210
|
# Sets the primary role colour to something new.
|
|
207
211
|
# @param colour [ColourRGB, Integer, nil] The new colour.
|
|
208
212
|
def colour=(colour)
|
|
209
|
-
|
|
213
|
+
update_colours(primary: colour)
|
|
210
214
|
end
|
|
211
215
|
|
|
212
216
|
# Sets the secondary role colour to something new.
|
|
@@ -293,7 +297,7 @@ module Discordrb
|
|
|
293
297
|
# https://discord.com/developers/docs/topics/permissions.
|
|
294
298
|
# @example Remove all permissions from a role
|
|
295
299
|
# role.packed = 0
|
|
296
|
-
# @param packed [Integer] A bitfield with the desired permissions value.
|
|
300
|
+
# @param packed [Integer, nil] A bitfield with the desired permissions value.
|
|
297
301
|
# @param update_perms [true, false] Whether the internal data should also be updated. This should always be true
|
|
298
302
|
# when calling externally.
|
|
299
303
|
def packed=(packed, update_perms = true)
|
|
@@ -305,17 +309,9 @@ module Discordrb
|
|
|
305
309
|
# @param other [Role, String, Integer, nil] The role, or its ID, above which this role should be moved. If it is `nil`,
|
|
306
310
|
# the role will be moved above the @everyone role.
|
|
307
311
|
# @return [Integer] the new position of this role
|
|
312
|
+
# @deprecated Please migrate to using {#move} with the `above` or `below` KWARGS.
|
|
308
313
|
def sort_above(other = nil)
|
|
309
|
-
other
|
|
310
|
-
roles = @server.roles.sort_by(&:position)
|
|
311
|
-
roles.delete_at(@position)
|
|
312
|
-
|
|
313
|
-
index = other ? roles.index { |role| role.id == other.id } + 1 : 1
|
|
314
|
-
roles.insert(index, self)
|
|
315
|
-
|
|
316
|
-
updated_roles = roles.map.with_index { |role, position| { id: role.id, position: position } }
|
|
317
|
-
@server.update_role_positions(updated_roles)
|
|
318
|
-
index
|
|
314
|
+
other ? move(above: other) : move(bottom: true)
|
|
319
315
|
end
|
|
320
316
|
|
|
321
317
|
alias_method :move_above, :sort_above
|
|
@@ -327,13 +323,69 @@ module Discordrb
|
|
|
327
323
|
@server.delete_role(@id)
|
|
328
324
|
end
|
|
329
325
|
|
|
326
|
+
# Move the position of this role in the roles list.
|
|
327
|
+
# @example This will move the role 2 places above the `@everyone` role.
|
|
328
|
+
# role.move(bottom: true, offset: 2)
|
|
329
|
+
# @example This will move the role above the `@muted` role.
|
|
330
|
+
# role.move(above: 257017090932867072)
|
|
331
|
+
# @example This will move the role 3 spots below the `No Images` role.
|
|
332
|
+
# roles.move(below: 254077236989132800, offset: -3)
|
|
333
|
+
# @param bottom [true, false, nil] Whether to move the roles to the bottom of the role list.
|
|
334
|
+
# @param above [Integer, String, Role, nil] The role that this role should be moved above.
|
|
335
|
+
# @param below [Integer, String, Role, nil] The role that this role should be moved below.
|
|
336
|
+
# @param offset [Integer, nil] The number of roles to offset the new position by. A positive number will
|
|
337
|
+
# move the role above, and a negative number will move the role below. This parameter is relative and
|
|
338
|
+
# calculated after the `bottom`, `above`, and `below` parameters.
|
|
339
|
+
# @param reason [String, nil] The audit log reason to show for moving the role.
|
|
340
|
+
# @return [Integer] the new position of the role.
|
|
341
|
+
def move(bottom: nil, above: nil, below: nil, offset: 0, reason: nil)
|
|
342
|
+
# rubocop:disable Style/IfUnlessModifier
|
|
343
|
+
if [bottom, above, below].count(&:itself) > 1
|
|
344
|
+
raise ArgumentError, "'bottom', 'above', and 'below' are mutually exclusive"
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
if (above || below) && !(target = @server.role(above || below))
|
|
348
|
+
raise ArgumentError, "The given 'above' or 'below' options are not valid"
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
if (below && target&.id == @server.id) || (@id == target&.id)
|
|
352
|
+
raise ArgumentError, 'The target role that was provded is not valid'
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
# rubocop:enable Style/IfUnlessModifier
|
|
356
|
+
roles = @server.roles.uniq.sort_by { |role| [role.position, role.id] }
|
|
357
|
+
|
|
358
|
+
# Make sure we remove the current role.
|
|
359
|
+
myself = roles.rindex(self).tap { |index| roles.delete_at(index) }
|
|
360
|
+
|
|
361
|
+
index = if bottom
|
|
362
|
+
1
|
|
363
|
+
elsif below
|
|
364
|
+
roles.rindex(target)
|
|
365
|
+
elsif above
|
|
366
|
+
roles.rindex(target) + 1
|
|
367
|
+
else
|
|
368
|
+
myself
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
roles.insert([index + (offset || 0), 1].max, self)
|
|
372
|
+
|
|
373
|
+
roles = roles.map.with_index do |role, new_position|
|
|
374
|
+
{ id: role.resolve_id, position: new_position }
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
@server.update_role_positions(roles, reason: reason)
|
|
378
|
+
@position
|
|
379
|
+
end
|
|
380
|
+
|
|
330
381
|
# A rich interface designed to make working with role colours simple.
|
|
331
382
|
# @param primary [ColourRGB, Integer, nil] The new primary/base colour of this role, or nil to clear the primary colour.
|
|
332
383
|
# @param secondary [ColourRGB, Integer, nil] The new secondary colour of this role, or nil to clear the secondary colour.
|
|
333
384
|
# @param tertiary [ColourRGB, Integer,nil] The new tertiary colour of this role, or nil to clear the tertiary colour.
|
|
334
385
|
# @param holographic [true, false] Whether to apply or remove the holographic style to the role colour, overriding any other
|
|
335
386
|
# arguments that were passed. Using this argument is recommended over passing individual colours.
|
|
336
|
-
|
|
387
|
+
# @param reason [String, nil] The audit log reason to show for updating the role's colours.
|
|
388
|
+
def update_colours(primary: :undef, secondary: :undef, tertiary: :undef, holographic: :undef, reason: nil)
|
|
337
389
|
colours = {
|
|
338
390
|
primary_color: (primary == :undef ? @colour : primary)&.to_i,
|
|
339
391
|
tertiary_color: (tertiary == :undef ? @tertiary_colour : tertiary)&.to_i,
|
|
@@ -347,9 +399,9 @@ module Discordrb
|
|
|
347
399
|
}
|
|
348
400
|
|
|
349
401
|
# Only set the tertiary_color to `nil` if holographic is explicitly set to false.
|
|
350
|
-
colours[:tertiary_color] = nil if holographic.is_a?(FalseClass)
|
|
402
|
+
(colours[:tertiary_color] = nil) if holographic.is_a?(FalseClass)
|
|
351
403
|
|
|
352
|
-
update_role_data(colours: holographic == true ? holographic_colours : colours)
|
|
404
|
+
update_role_data(colours: holographic == true ? holographic_colours : colours, reason: reason)
|
|
353
405
|
end
|
|
354
406
|
|
|
355
407
|
alias_method :update_colors, :update_colours
|
|
@@ -361,14 +413,15 @@ module Discordrb
|
|
|
361
413
|
|
|
362
414
|
private
|
|
363
415
|
|
|
416
|
+
# @!visibility private
|
|
364
417
|
def update_role_data(new_data)
|
|
365
418
|
update_data(JSON.parse(API::Server.update_role(@bot.token, @server.id, @id,
|
|
366
|
-
new_data[:name]
|
|
419
|
+
new_data.key?(:name) ? new_data[:name] : :undef,
|
|
367
420
|
:undef,
|
|
368
421
|
new_data.key?(:hoist) ? new_data[:hoist] : :undef,
|
|
369
422
|
new_data.key?(:mentionable) ? new_data[:mentionable] : :undef,
|
|
370
|
-
new_data[:permissions]
|
|
371
|
-
|
|
423
|
+
new_data.key?(:permissions) ? new_data[:permissions] : :undef,
|
|
424
|
+
new_data[:reason],
|
|
372
425
|
new_data.key?(:icon) ? new_data[:icon] : :undef,
|
|
373
426
|
new_data.key?(:unicode_emoji) ? new_data[:unicode_emoji] : :undef,
|
|
374
427
|
new_data.key?(:colours) ? new_data[:colours] : :undef)))
|
|
@@ -158,7 +158,8 @@ module Discordrb
|
|
|
158
158
|
member(@bot.profile)
|
|
159
159
|
end
|
|
160
160
|
|
|
161
|
-
# @return [Array<Integration>] an array of
|
|
161
|
+
# @return [Array<Integration>] an array of the integrations in this server.
|
|
162
|
+
# @note If the server has more than 50 integrations, they cannot be accessed.
|
|
162
163
|
def integrations
|
|
163
164
|
integration = JSON.parse(API::Server.integrations(@bot.token, @id))
|
|
164
165
|
integration.map { |element| Integration.new(element, @bot, self) }
|
|
@@ -412,11 +413,11 @@ module Discordrb
|
|
|
412
413
|
# Updates the positions of all roles on the server
|
|
413
414
|
# @note For internal use only
|
|
414
415
|
# @!visibility private
|
|
415
|
-
def update_role_positions(role_positions)
|
|
416
|
-
response = JSON.parse(API::Server.update_role_positions(@bot.token, @id, role_positions))
|
|
416
|
+
def update_role_positions(role_positions, reason: nil)
|
|
417
|
+
response = JSON.parse(API::Server.update_role_positions(@bot.token, @id, role_positions, reason))
|
|
417
418
|
response.each do |data|
|
|
418
419
|
updated_role = Role.new(data, @bot, self)
|
|
419
|
-
role(updated_role.id)
|
|
420
|
+
role(updated_role.id)&.update_from(updated_role)
|
|
420
421
|
end
|
|
421
422
|
end
|
|
422
423
|
|
|
@@ -921,6 +922,19 @@ module Discordrb
|
|
|
921
922
|
process_emoji(new_data['emojis'])
|
|
922
923
|
end
|
|
923
924
|
|
|
925
|
+
# Updates the threads for this server's cache
|
|
926
|
+
# @note For internal use only
|
|
927
|
+
# @!visibility private
|
|
928
|
+
def clear_threads(ids = nil)
|
|
929
|
+
if ids.nil?
|
|
930
|
+
@channels.reject!(&:thread?)
|
|
931
|
+
@channels_by_id.delete_if { |_, channel| channel.thread? }
|
|
932
|
+
else
|
|
933
|
+
@channels.reject! { |channel| channel.thread? && ids.any?(channel.parent&.id) }
|
|
934
|
+
@channels_by_id.delete_if { |_, channel| channel.thread? && ids.any?(channel.parent&.id) }
|
|
935
|
+
end
|
|
936
|
+
end
|
|
937
|
+
|
|
924
938
|
# The inspect method is overwritten to give more useful output
|
|
925
939
|
def inspect
|
|
926
940
|
"<Server name=#{@name} id=#{@id} large=#{@large} region=#{@region} owner=#{@owner} afk_channel_id=#{@afk_channel_id} system_channel_id=#{@system_channel_id} afk_timeout=#{@afk_timeout}>"
|
|
@@ -38,11 +38,11 @@ module Discordrb
|
|
|
38
38
|
@content = data['content']
|
|
39
39
|
@mention_roles = data['mention_roles']&.map(&:resolve_id) || []
|
|
40
40
|
@embeds = data['embeds']&.map { |embed| Embed.new(embed, self) } || []
|
|
41
|
-
@attachments = data['attachments']&.map { |file| Attachment.new(file, self, bot) } || []
|
|
41
|
+
@attachments = data['attachments']&.map { |file| Attachment.new(file, self, @bot) } || []
|
|
42
42
|
@created_at = data['timestamp'] ? Time.parse(data['timestamp']) : nil
|
|
43
43
|
@edited_at = data['edited_timestamp'] ? Time.parse(data['edited_timestamp']) : nil
|
|
44
|
-
@mentions = data['mentions']&.map { |mention| bot.ensure_user(mention) } || []
|
|
45
|
-
@components = data['components']&.map { |component| Components.from_data(component, bot) } || []
|
|
44
|
+
@mentions = data['mentions']&.map { |mention| @bot.ensure_user(mention) } || []
|
|
45
|
+
@components = data['components']&.map { |component| Components.from_data(component, @bot) } || []
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
# Check whether the message snapshot has been edited.
|
|
@@ -85,7 +85,9 @@ module Discordrb
|
|
|
85
85
|
case component
|
|
86
86
|
when Components::Button
|
|
87
87
|
component
|
|
88
|
-
when Components::
|
|
88
|
+
when Components::Section
|
|
89
|
+
component.accessory if component.accessory.is_a?(Components::Button)
|
|
90
|
+
when Components::ActionRow, Components::Container
|
|
89
91
|
component.buttons
|
|
90
92
|
end
|
|
91
93
|
end
|
|
@@ -136,7 +136,7 @@ module Discordrb
|
|
|
136
136
|
# @return [Message, nil] If `wait` is `true`, a {Message} will be returned. Otherwise this method will return `nil`.
|
|
137
137
|
# @note This is only available to webhooks with publically exposed tokens. This excludes channel follow webhooks and webhooks retrieved
|
|
138
138
|
# via the audit log.
|
|
139
|
-
def execute(content: nil, username: nil, avatar_url: nil, tts: nil, file: nil, embeds: nil, allowed_mentions: nil, wait: true, builder: nil, components: nil)
|
|
139
|
+
def execute(content: nil, username: nil, avatar_url: nil, tts: nil, file: nil, embeds: nil, allowed_mentions: nil, wait: true, builder: nil, components: nil, flags: 0, has_components: false)
|
|
140
140
|
raise Discordrb::Errors::UnauthorizedWebhook unless @token
|
|
141
141
|
|
|
142
142
|
params = { content: content, username: username, avatar_url: avatar_url, tts: tts, file: file, embeds: embeds, allowed_mentions: allowed_mentions }
|
|
@@ -144,12 +144,14 @@ module Discordrb
|
|
|
144
144
|
builder ||= Webhooks::Builder.new
|
|
145
145
|
view = Webhooks::View.new
|
|
146
146
|
|
|
147
|
+
flags |= (1 << 15) if has_components
|
|
148
|
+
|
|
147
149
|
yield(builder, view) if block_given?
|
|
148
150
|
|
|
149
151
|
data = builder.to_json_hash.merge(params.compact)
|
|
150
152
|
components ||= view
|
|
151
153
|
|
|
152
|
-
resp = API::Webhook.token_execute_webhook(@token, @id, wait, data[:content], data[:username], data[:avatar_url], data[:tts], data[:file], data[:embeds], data[:allowed_mentions],
|
|
154
|
+
resp = API::Webhook.token_execute_webhook(@token, @id, wait, data[:content], data[:username], data[:avatar_url], data[:tts], data[:file], data[:embeds], data[:allowed_mentions], flags, components.to_a)
|
|
153
155
|
|
|
154
156
|
Message.new(JSON.parse(resp), @bot) if wait
|
|
155
157
|
end
|
|
@@ -173,7 +175,7 @@ module Discordrb
|
|
|
173
175
|
# @return [Message] The updated message.
|
|
174
176
|
# @param components [View, Array<Hash>] Interaction components to associate with this message.
|
|
175
177
|
# @note When editing `allowed_mentions`, it will update visually in the client but not alert the user with a notification.
|
|
176
|
-
def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, builder: nil, components: nil)
|
|
178
|
+
def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, builder: nil, components: nil, flags: 0, has_components: false)
|
|
177
179
|
raise Discordrb::Errors::UnauthorizedWebhook unless @token
|
|
178
180
|
|
|
179
181
|
params = { content: content, embeds: embeds, allowed_mentions: allowed_mentions }.compact
|
|
@@ -181,12 +183,14 @@ module Discordrb
|
|
|
181
183
|
builder ||= Webhooks::Builder.new
|
|
182
184
|
view ||= Webhooks::View.new
|
|
183
185
|
|
|
186
|
+
flags |= (1 << 15) if has_components
|
|
187
|
+
|
|
184
188
|
yield(builder, view) if block_given?
|
|
185
189
|
|
|
186
190
|
data = builder.to_json_hash.merge(params.compact)
|
|
187
191
|
components ||= view
|
|
188
192
|
|
|
189
|
-
resp = API::Webhook.token_edit_message(@token, @id, message.resolve_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a)
|
|
193
|
+
resp = API::Webhook.token_edit_message(@token, @id, message.resolve_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a, nil, flags)
|
|
190
194
|
Message.new(JSON.parse(resp), @bot)
|
|
191
195
|
end
|
|
192
196
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'discordrb/data'
|
|
4
|
+
require 'discordrb/events/generic'
|
|
5
|
+
|
|
6
|
+
module Discordrb::Events
|
|
7
|
+
# Generic superclass for integration events.
|
|
8
|
+
class IntegrationEvent < Event
|
|
9
|
+
# @return [Server] the server associated with the event.
|
|
10
|
+
attr_reader :server
|
|
11
|
+
|
|
12
|
+
# @return [Integration] the integration associated with the event.
|
|
13
|
+
attr_reader :integration
|
|
14
|
+
|
|
15
|
+
# @!visibility private
|
|
16
|
+
def initialize(data, bot)
|
|
17
|
+
@bot = bot
|
|
18
|
+
@server = bot.server(data['guild_id'].to_i)
|
|
19
|
+
@integration = Discordrb::Integration.new(data, @bot, @server)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Raised whenever an integration is created.
|
|
24
|
+
class IntegrationCreateEvent < IntegrationEvent; end
|
|
25
|
+
|
|
26
|
+
# Raised whenever an integration is updated.
|
|
27
|
+
class IntegrationUpdateEvent < IntegrationEvent; end
|
|
28
|
+
|
|
29
|
+
# Raised whenever an integration is deleted.
|
|
30
|
+
class IntegrationDeleteEvent < Event
|
|
31
|
+
# @return [Server] the server associated with the event.
|
|
32
|
+
attr_reader :server
|
|
33
|
+
|
|
34
|
+
# @return [Integer] the ID of the integration that was removed.
|
|
35
|
+
attr_reader :integration_id
|
|
36
|
+
|
|
37
|
+
# @return [Integer, nil] the ID of the application that was removed.
|
|
38
|
+
attr_reader :application_id
|
|
39
|
+
|
|
40
|
+
# @!visibility private
|
|
41
|
+
def initialize(data, bot)
|
|
42
|
+
@bot = bot
|
|
43
|
+
@server = bot.server(data['guild_id'].to_i)
|
|
44
|
+
@integration_id = data['id'].to_i
|
|
45
|
+
@application_id = data['application_id']&.to_i
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Generic event handler for integration events.
|
|
50
|
+
class IntegrationEventHandler < EventHandler
|
|
51
|
+
# @!visibility private
|
|
52
|
+
def matches?(event)
|
|
53
|
+
# Check for the proper event type.
|
|
54
|
+
return false unless event.is_a?(IntegrationEvent)
|
|
55
|
+
|
|
56
|
+
[
|
|
57
|
+
matches_all(@attributes[:server], event.server) do |a, e|
|
|
58
|
+
a&.resolve_id == e&.resolve_id
|
|
59
|
+
end,
|
|
60
|
+
|
|
61
|
+
matches_all(@attributes[:id], event.integration) do |a, e|
|
|
62
|
+
a&.resolve_id == e&.resolve_id
|
|
63
|
+
end,
|
|
64
|
+
|
|
65
|
+
matches_all(@attributes[:application], event.integration) do |a, e|
|
|
66
|
+
a&.resolve_id == e.application&.resolve_id
|
|
67
|
+
end
|
|
68
|
+
].reduce(true, &:&)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Event handler for INTEGRATION_CREATE events.
|
|
73
|
+
class IntegrationCreateEventHandler < IntegrationEventHandler; end
|
|
74
|
+
|
|
75
|
+
# Event handler for INTEGRATION_UPDATE events.
|
|
76
|
+
class IntegrationUpdateEventHandler < IntegrationEventHandler; end
|
|
77
|
+
|
|
78
|
+
# Event handler for INTEGRATION_DELETE events.
|
|
79
|
+
class IntegrationDeleteEventHandler < EventHandler
|
|
80
|
+
# @!visibility private
|
|
81
|
+
def matches?(event)
|
|
82
|
+
# Check for the proper event type.
|
|
83
|
+
return false unless event.is_a?(IntegrationDeleteEvent)
|
|
84
|
+
|
|
85
|
+
[
|
|
86
|
+
matches_all(@attributes[:server], event.server) do |a, e|
|
|
87
|
+
a&.resolve_id == e&.resolve_id
|
|
88
|
+
end,
|
|
89
|
+
|
|
90
|
+
matches_all(@attributes[:id], event.integration_id) do |a, e|
|
|
91
|
+
a&.resolve_id == e&.resolve_id
|
|
92
|
+
end,
|
|
93
|
+
|
|
94
|
+
matches_all(@attributes[:application], event.application_id) do |a, e|
|
|
95
|
+
a&.resolve_id == e&.resolve_id
|
|
96
|
+
end
|
|
97
|
+
].reduce(true, &:&)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -6,6 +6,9 @@ require 'discordrb/data'
|
|
|
6
6
|
module Discordrb::Events
|
|
7
7
|
# Generic subclass for interaction events
|
|
8
8
|
class InteractionCreateEvent < Event
|
|
9
|
+
# Struct to allow accessing data via [] or methods.
|
|
10
|
+
Resolved = Struct.new('Resolved', :channels, :members, :messages, :roles, :users, :attachments) # rubocop:disable Lint/StructNewOverride
|
|
11
|
+
|
|
9
12
|
# @return [Interaction] The interaction for this event.
|
|
10
13
|
attr_reader :interaction
|
|
11
14
|
|
|
@@ -33,7 +36,13 @@ module Discordrb::Events
|
|
|
33
36
|
# @!attribute [r] context
|
|
34
37
|
# @return [Integer]
|
|
35
38
|
# @see Interaction#context
|
|
36
|
-
|
|
39
|
+
# @!attribute [r] user_integration?
|
|
40
|
+
# @return [true, false]
|
|
41
|
+
# @see Interaction#user_integration?
|
|
42
|
+
# @!attribute [r] server_integration?
|
|
43
|
+
# @return [true, false]
|
|
44
|
+
# @see Interaction#server_integration?
|
|
45
|
+
delegate :type, :server, :server_id, :channel, :channel_id, :user, :user_locale, :context, :user_integration?, :server_integration?, to: :interaction
|
|
37
46
|
|
|
38
47
|
# @!visibility private
|
|
39
48
|
def initialize(data, bot)
|
|
@@ -95,6 +104,38 @@ module Discordrb::Events
|
|
|
95
104
|
def get_component(...)
|
|
96
105
|
@interaction.get_component(...)
|
|
97
106
|
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
# @!visibility private
|
|
111
|
+
def process_resolved(resolved_data)
|
|
112
|
+
resolved_data['users']&.each do |id, data|
|
|
113
|
+
@resolved[:users][id.to_i] = @bot.ensure_user(data)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
resolved_data['roles']&.each do |id, data|
|
|
117
|
+
@resolved[:roles][id.to_i] = Discordrb::Role.new(data, @bot)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
resolved_data['channels']&.each do |id, data|
|
|
121
|
+
data['guild_id'] = @interaction.server_id
|
|
122
|
+
@resolved[:channels][id.to_i] = Discordrb::Channel.new(data, @bot)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
resolved_data['members']&.each do |id, data|
|
|
126
|
+
data['user'] = resolved_data['users'][id]
|
|
127
|
+
data['guild_id'] = @interaction.server_id
|
|
128
|
+
@resolved[:members][id.to_i] = Discordrb::Member.new(data, nil, @bot)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
resolved_data['messages']&.each do |id, data|
|
|
132
|
+
@resolved[:messages][id.to_i] = Discordrb::Message.new(data, @bot)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
resolved_data['attachments']&.each do |id, data|
|
|
136
|
+
@resolved[:attachments][id.to_i] = Discordrb::Attachment.new(data, nil, @bot)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
98
139
|
end
|
|
99
140
|
|
|
100
141
|
# Event handler for INTERACTION_CREATE events.
|
|
@@ -130,9 +171,6 @@ module Discordrb::Events
|
|
|
130
171
|
|
|
131
172
|
# Event for ApplicationCommand interactions.
|
|
132
173
|
class ApplicationCommandEvent < InteractionCreateEvent
|
|
133
|
-
# Struct to allow accessing data via [] or methods.
|
|
134
|
-
Resolved = Struct.new('Resolved', :channels, :members, :messages, :roles, :users, :attachments) # rubocop:disable Lint/StructNewOverride
|
|
135
|
-
|
|
136
174
|
# @return [Symbol] The name of the command.
|
|
137
175
|
attr_reader :command_name
|
|
138
176
|
|
|
@@ -145,7 +183,7 @@ module Discordrb::Events
|
|
|
145
183
|
# @return [Symbol, nil] The name of the subcommand relevant to this event.
|
|
146
184
|
attr_reader :subcommand
|
|
147
185
|
|
|
148
|
-
# @return [Resolved]
|
|
186
|
+
# @return [Resolved] The resolved channels, roles, users, members, and attachments for this event.
|
|
149
187
|
attr_reader :resolved
|
|
150
188
|
|
|
151
189
|
# @return [Hash<Symbol, Object>] Arguments provided to the command, mapped as `Name => Value`.
|
|
@@ -198,35 +236,6 @@ module Discordrb::Events
|
|
|
198
236
|
|
|
199
237
|
private
|
|
200
238
|
|
|
201
|
-
def process_resolved(resolved_data)
|
|
202
|
-
resolved_data['users']&.each do |id, data|
|
|
203
|
-
@resolved[:users][id.to_i] = @bot.ensure_user(data)
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
resolved_data['roles']&.each do |id, data|
|
|
207
|
-
@resolved[:roles][id.to_i] = Discordrb::Role.new(data, @bot)
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
resolved_data['channels']&.each do |id, data|
|
|
211
|
-
data['guild_id'] = @interaction.server_id
|
|
212
|
-
@resolved[:channels][id.to_i] = Discordrb::Channel.new(data, @bot)
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
resolved_data['members']&.each do |id, data|
|
|
216
|
-
data['user'] = resolved_data['users'][id]
|
|
217
|
-
data['guild_id'] = @interaction.server_id
|
|
218
|
-
@resolved[:members][id.to_i] = Discordrb::Member.new(data, nil, @bot)
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
resolved_data['messages']&.each do |id, data|
|
|
222
|
-
@resolved[:messages][id.to_i] = Discordrb::Message.new(data, @bot)
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
resolved_data['attachments']&.each do |id, data|
|
|
226
|
-
@resolved[:attachments][id.to_i] = Discordrb::Attachment.new(data, nil, @bot)
|
|
227
|
-
end
|
|
228
|
-
end
|
|
229
|
-
|
|
230
239
|
def transform_options_hash(hash)
|
|
231
240
|
hash.to_h { |opt| [opt['name'], opt['options'] || opt['value']] }
|
|
232
241
|
end
|
|
@@ -397,15 +406,40 @@ module Discordrb::Events
|
|
|
397
406
|
|
|
398
407
|
# An event for when a user submits a modal.
|
|
399
408
|
class ModalSubmitEvent < ComponentEvent
|
|
400
|
-
# @return [Array<
|
|
409
|
+
# @return [Array<Component>] an array of partial component objects that were in the modal.
|
|
401
410
|
attr_reader :components
|
|
402
411
|
|
|
412
|
+
# @return [Resolved] The resolved channels, roles, users, members, and attachments for the modal.
|
|
413
|
+
attr_reader :resolved
|
|
414
|
+
|
|
415
|
+
# @!visibility private
|
|
416
|
+
def initialize(data, bot)
|
|
417
|
+
super
|
|
418
|
+
|
|
419
|
+
@resolved = Resolved.new({}, {}, {}, {}, {}, {})
|
|
420
|
+
process_resolved(data['data']['resolved']) if data['data']['resolved']
|
|
421
|
+
end
|
|
422
|
+
|
|
403
423
|
# Get the value of an input passed to the modal.
|
|
404
424
|
# @param custom_id [String] The custom ID of the component to look for.
|
|
405
|
-
# @return [String, nil]
|
|
425
|
+
# @return [String, nil] The selected value for the component.
|
|
406
426
|
def value(custom_id)
|
|
407
427
|
get_component(custom_id)&.value
|
|
408
428
|
end
|
|
429
|
+
|
|
430
|
+
# Get the selected values from a select menu or file upload component.
|
|
431
|
+
# @param custom_id [String] The custom ID of the component to look for.
|
|
432
|
+
# @return [Array<String>, nil] The values that were chosen for the component.
|
|
433
|
+
def values(custom_id)
|
|
434
|
+
get_component(custom_id)&.values
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
# Get the attachments that a user uploaded in this modal.
|
|
438
|
+
# @param custom_id [String] The custom ID of the file upload component to get attachments for.
|
|
439
|
+
# @return [Array<Attachment>] the attachments that were uploaded to the file upload component.
|
|
440
|
+
def attachments(custom_id)
|
|
441
|
+
values(custom_id)&.map { |id| @resolved[:attachments][id.to_i] } || []
|
|
442
|
+
end
|
|
409
443
|
end
|
|
410
444
|
|
|
411
445
|
# Event handler for a modal submission.
|
|
@@ -455,7 +489,7 @@ module Discordrb::Events
|
|
|
455
489
|
def initialize(data, bot)
|
|
456
490
|
super
|
|
457
491
|
|
|
458
|
-
users = data['data']['resolved']['users'].
|
|
492
|
+
users = data['data']['resolved']['users'].map { |_, user| @bot.ensure_user(user) }
|
|
459
493
|
roles = data['data']['resolved']['roles'] ? data['data']['resolved']['roles'].keys.map { |e| bot.server(data['guild_id']).role(e) } : []
|
|
460
494
|
@values = { users: users, roles: roles }
|
|
461
495
|
end
|
|
@@ -18,7 +18,7 @@ module Discordrb::Events
|
|
|
18
18
|
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
|
19
19
|
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
|
20
20
|
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
|
21
|
-
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2)
|
|
21
|
+
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2), SUPPRESS_NOTIFICATIONS (1 << 12), and IS_COMPONENTS_V2 (1 << 15) can be set.
|
|
22
22
|
# @return [Discordrb::Message] the message that was sent
|
|
23
23
|
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
|
|
24
24
|
channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components, flags)
|
|
@@ -33,7 +33,7 @@ module Discordrb::Events
|
|
|
33
33
|
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
|
34
34
|
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
|
35
35
|
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
|
36
|
-
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2)
|
|
36
|
+
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2), SUPPRESS_NOTIFICATIONS (1 << 12), and IS_COMPONENTS_V2 (1 << 15) can be set.
|
|
37
37
|
# @yield [embed] Yields the embed to allow for easy building inside a block.
|
|
38
38
|
# @yieldparam embed [Discordrb::Webhooks::Embed] The embed from the parameters, or a new one.
|
|
39
39
|
# @return [Message] The resulting message.
|
|
@@ -49,7 +49,7 @@ module Discordrb::Events
|
|
|
49
49
|
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
|
50
50
|
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
|
51
51
|
# @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
|
|
52
|
-
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2)
|
|
52
|
+
# @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2), SUPPRESS_NOTIFICATIONS (1 << 12), and IS_COMPONENTS_V2 (1 << 15) can be set.
|
|
53
53
|
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, components = nil, flags = 0)
|
|
54
54
|
channel.send_temporary_message(content, timeout, tts, embed, attachments, allowed_mentions, components, flags)
|
|
55
55
|
end
|
data/lib/discordrb/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: discordrb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- meew0
|
|
@@ -86,14 +86,14 @@ dependencies:
|
|
|
86
86
|
requirements:
|
|
87
87
|
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 3.
|
|
89
|
+
version: 3.8.0
|
|
90
90
|
type: :runtime
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 3.
|
|
96
|
+
version: 3.8.0
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: bundler
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -103,7 +103,7 @@ dependencies:
|
|
|
103
103
|
version: '1.10'
|
|
104
104
|
- - "<"
|
|
105
105
|
- !ruby/object:Gem::Version
|
|
106
|
-
version: '
|
|
106
|
+
version: '5'
|
|
107
107
|
type: :development
|
|
108
108
|
prerelease: false
|
|
109
109
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -113,7 +113,7 @@ dependencies:
|
|
|
113
113
|
version: '1.10'
|
|
114
114
|
- - "<"
|
|
115
115
|
- !ruby/object:Gem::Version
|
|
116
|
-
version: '
|
|
116
|
+
version: '5'
|
|
117
117
|
- !ruby/object:Gem::Dependency
|
|
118
118
|
name: rake
|
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -344,6 +344,7 @@ files:
|
|
|
344
344
|
- lib/discordrb/events/channels.rb
|
|
345
345
|
- lib/discordrb/events/generic.rb
|
|
346
346
|
- lib/discordrb/events/guilds.rb
|
|
347
|
+
- lib/discordrb/events/integrations.rb
|
|
347
348
|
- lib/discordrb/events/interactions.rb
|
|
348
349
|
- lib/discordrb/events/invites.rb
|
|
349
350
|
- lib/discordrb/events/lifetime.rb
|
|
@@ -399,7 +400,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
399
400
|
- !ruby/object:Gem::Version
|
|
400
401
|
version: '0'
|
|
401
402
|
requirements: []
|
|
402
|
-
rubygems_version:
|
|
403
|
+
rubygems_version: 4.0.10
|
|
403
404
|
specification_version: 4
|
|
404
405
|
summary: Discord API for Ruby
|
|
405
406
|
test_files: []
|