discordrb 3.5.0 → 3.6.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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +13 -0
  3. data/.devcontainer/devcontainer.json +29 -0
  4. data/.devcontainer/postcreate.sh +4 -0
  5. data/.github/workflows/ci.yml +78 -0
  6. data/.github/workflows/codeql.yml +3 -3
  7. data/.github/workflows/deploy.yml +54 -0
  8. data/.github/workflows/release.yml +45 -0
  9. data/.rubocop.yml +52 -2
  10. data/CHANGELOG.md +95 -0
  11. data/README.md +5 -5
  12. data/discordrb-webhooks.gemspec +1 -1
  13. data/discordrb.gemspec +16 -11
  14. data/lib/discordrb/api/application.rb +84 -8
  15. data/lib/discordrb/api/channel.rb +51 -13
  16. data/lib/discordrb/api/interaction.rb +15 -6
  17. data/lib/discordrb/api/invite.rb +1 -1
  18. data/lib/discordrb/api/server.rb +96 -60
  19. data/lib/discordrb/api/user.rb +12 -2
  20. data/lib/discordrb/api/webhook.rb +20 -5
  21. data/lib/discordrb/api.rb +16 -20
  22. data/lib/discordrb/bot.rb +139 -53
  23. data/lib/discordrb/cache.rb +15 -1
  24. data/lib/discordrb/commands/command_bot.rb +7 -17
  25. data/lib/discordrb/commands/parser.rb +7 -7
  26. data/lib/discordrb/container.rb +46 -0
  27. data/lib/discordrb/data/activity.rb +1 -1
  28. data/lib/discordrb/data/application.rb +1 -0
  29. data/lib/discordrb/data/attachment.rb +23 -3
  30. data/lib/discordrb/data/avatar_decoration.rb +26 -0
  31. data/lib/discordrb/data/call.rb +22 -0
  32. data/lib/discordrb/data/channel.rb +140 -15
  33. data/lib/discordrb/data/collectibles.rb +45 -0
  34. data/lib/discordrb/data/embed.rb +10 -3
  35. data/lib/discordrb/data/emoji.rb +20 -1
  36. data/lib/discordrb/data/integration.rb +3 -0
  37. data/lib/discordrb/data/interaction.rb +164 -27
  38. data/lib/discordrb/data/member.rb +145 -28
  39. data/lib/discordrb/data/message.rb +198 -51
  40. data/lib/discordrb/data/overwrite.rb +2 -0
  41. data/lib/discordrb/data/primary_server.rb +60 -0
  42. data/lib/discordrb/data/profile.rb +2 -7
  43. data/lib/discordrb/data/reaction.rb +2 -1
  44. data/lib/discordrb/data/recipient.rb +1 -1
  45. data/lib/discordrb/data/role.rb +151 -22
  46. data/lib/discordrb/data/server.rb +115 -41
  47. data/lib/discordrb/data/server_preview.rb +68 -0
  48. data/lib/discordrb/data/snapshot.rb +110 -0
  49. data/lib/discordrb/data/user.rb +68 -8
  50. data/lib/discordrb/data/voice_region.rb +1 -0
  51. data/lib/discordrb/data/webhook.rb +2 -5
  52. data/lib/discordrb/data.rb +6 -0
  53. data/lib/discordrb/errors.rb +5 -2
  54. data/lib/discordrb/events/await.rb +1 -1
  55. data/lib/discordrb/events/channels.rb +37 -0
  56. data/lib/discordrb/events/generic.rb +2 -0
  57. data/lib/discordrb/events/guilds.rb +6 -1
  58. data/lib/discordrb/events/interactions.rb +135 -42
  59. data/lib/discordrb/events/invites.rb +2 -0
  60. data/lib/discordrb/events/members.rb +19 -2
  61. data/lib/discordrb/events/message.rb +39 -8
  62. data/lib/discordrb/events/presence.rb +2 -0
  63. data/lib/discordrb/events/raw.rb +1 -0
  64. data/lib/discordrb/events/reactions.rb +2 -0
  65. data/lib/discordrb/events/roles.rb +2 -0
  66. data/lib/discordrb/events/threads.rb +10 -6
  67. data/lib/discordrb/events/typing.rb +1 -0
  68. data/lib/discordrb/events/voice_server_update.rb +1 -0
  69. data/lib/discordrb/events/voice_state_update.rb +1 -0
  70. data/lib/discordrb/events/webhooks.rb +1 -0
  71. data/lib/discordrb/gateway.rb +29 -13
  72. data/lib/discordrb/paginator.rb +3 -3
  73. data/lib/discordrb/permissions.rb +54 -43
  74. data/lib/discordrb/version.rb +1 -1
  75. data/lib/discordrb/websocket.rb +0 -10
  76. data/lib/discordrb.rb +17 -1
  77. metadata +53 -25
  78. data/.circleci/config.yml +0 -152
@@ -29,70 +29,65 @@ module Discordrb::Events
29
29
  # @see Interaction#user
30
30
  delegate :type, :server, :server_id, :channel, :channel_id, :user, to: :interaction
31
31
 
32
+ # @!visibility private
32
33
  def initialize(data, bot)
33
34
  @interaction = Discordrb::Interaction.new(data, bot)
34
35
  @bot = bot
35
36
  end
36
37
 
37
- # (see Interaction#respond)
38
- def respond(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, &block)
39
- @interaction.respond(
40
- content: content, tts: tts, embeds: embeds, allowed_mentions: allowed_mentions,
41
- flags: flags, ephemeral: ephemeral, wait: wait, components: components, &block
42
- )
38
+ # @see Interaction#respond
39
+ def respond(...)
40
+ @interaction.respond(...)
43
41
  end
44
42
 
45
- # (see Interaction#defer)
46
- def defer(flags: 0, ephemeral: true)
47
- @interaction.defer(flags: flags, ephemeral: ephemeral)
43
+ # @see Interaction#defer
44
+ def defer(...)
45
+ @interaction.defer(...)
48
46
  end
49
47
 
50
- # (see Interaction#update_message)
51
- def update_message(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, &block)
52
- @interaction.update_message(
53
- content: content, tts: tts, embeds: embeds, allowed_mentions: allowed_mentions,
54
- flags: flags, ephemeral: ephemeral, wait: wait, components: components, &block
55
- )
48
+ # @see Interaction#update_message
49
+ def update_message(...)
50
+ @interaction.update_message(...)
56
51
  end
57
52
 
58
- # (see Interaction#show_modal)
59
- def show_modal(title:, custom_id:, components: nil, &block)
60
- @interaction.show_modal(title: title, custom_id: custom_id, components: components, &block)
53
+ # @see Interaction#show_modal
54
+ def show_modal(...)
55
+ @interaction.show_modal(...)
61
56
  end
62
57
 
63
- # (see Interaction#edit_response)
64
- def edit_response(content: nil, embeds: nil, allowed_mentions: nil, components: nil, &block)
65
- @interaction.edit_response(content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components, &block)
58
+ # @see Interaction#edit_response
59
+ def edit_response(...)
60
+ @interaction.edit_response(...)
66
61
  end
67
62
 
68
- # (see Interaction#delete_response)
63
+ # @see Interaction#delete_response
69
64
  def delete_response
70
65
  @interaction.delete_response
71
66
  end
72
67
 
73
- # (see Interaction#send_message)
74
- def send_message(content: nil, embeds: nil, tts: false, allowed_mentions: nil, flags: 0, ephemeral: nil, components: nil, &block)
75
- @interaction.send_message(content: content, embeds: embeds, tts: tts, allowed_mentions: allowed_mentions, flags: flags, ephemeral: ephemeral, components: components, &block)
68
+ # @see Interaction#send_message
69
+ def send_message(...)
70
+ @interaction.send_message(...)
76
71
  end
77
72
 
78
- # (see Interaction#edit_message)
79
- def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, &block)
80
- @interaction.edit_message(message, content: content, embeds: embeds, allowed_mentions: allowed_mentions, &block)
73
+ # @see Interaction#edit_message
74
+ def edit_message(...)
75
+ @interaction.edit_message(...)
81
76
  end
82
77
 
83
- # (see Interaction#delete_message)
84
- def delete_message(message)
85
- @interaction.delete_message(message)
78
+ # @see Interaction#delete_message
79
+ def delete_message(...)
80
+ @interaction.delete_message(...)
86
81
  end
87
82
 
88
- # (see Interaction#defer_update)
83
+ # @see Interaction#defer_update
89
84
  def defer_update
90
85
  @interaction.defer_update
91
86
  end
92
87
 
93
- # (see Interaction#get_component)
94
- def get_component(custom_id)
95
- @interaction.get_component(custom_id)
88
+ # @see Interaction#get_component
89
+ def get_component(...)
90
+ @interaction.get_component(...)
96
91
  end
97
92
  end
98
93
 
@@ -132,16 +127,16 @@ module Discordrb::Events
132
127
  # Struct to allow accessing data via [] or methods.
133
128
  Resolved = Struct.new('Resolved', :channels, :members, :messages, :roles, :users, :attachments) # rubocop:disable Lint/StructNewOverride
134
129
 
135
- # @return [String] The name of the command.
130
+ # @return [Symbol] The name of the command.
136
131
  attr_reader :command_name
137
132
 
138
133
  # @return [Integer] The ID of the command.
139
134
  attr_reader :command_id
140
135
 
141
- # @return [String, nil] The name of the subcommand group relevant to this event.
136
+ # @return [Symbol, nil] The name of the subcommand group relevant to this event.
142
137
  attr_reader :subcommand_group
143
138
 
144
- # @return [String, nil] The name of the subcommand relevant to this event.
139
+ # @return [Symbol, nil] The name of the subcommand relevant to this event.
145
140
  attr_reader :subcommand
146
141
 
147
142
  # @return [Resolved]
@@ -153,6 +148,7 @@ module Discordrb::Events
153
148
  # @return [Integer, nil] The target of this command when it is a context command.
154
149
  attr_reader :target_id
155
150
 
151
+ # @!visibility private
156
152
  def initialize(data, bot)
157
153
  super
158
154
 
@@ -246,7 +242,7 @@ module Discordrb::Events
246
242
  # @yieldparam [SubcommandBuilder]
247
243
  # @return [ApplicationCommandEventHandler]
248
244
  def group(name)
249
- raise ArgumentError, 'Unable to mix subcommands and groups' if @subcommands.any? { |_, v| v.is_a? Proc }
245
+ raise ArgumentError, 'Unable to mix subcommands and groups' if @subcommands.any? { |n, v| n == name && v.is_a?(Proc) }
250
246
 
251
247
  builder = SubcommandBuilder.new(name)
252
248
  yield builder
@@ -259,7 +255,7 @@ module Discordrb::Events
259
255
  # @yieldparam [SubcommandBuilder]
260
256
  # @return [ApplicationCommandEventHandler]
261
257
  def subcommand(name, &block)
262
- raise ArgumentError, 'Unable to mix subcommands and groups' if @subcommands.any? { |_, v| v.is_a? Hash }
258
+ raise ArgumentError, 'Unable to mix subcommands and groups' if @subcommands.any? { |n, v| n == name && v.is_a?(Hash) }
263
259
 
264
260
  @subcommands[name.to_sym] = block
265
261
 
@@ -453,8 +449,8 @@ module Discordrb::Events
453
449
  def initialize(data, bot)
454
450
  super
455
451
 
456
- users = data['data']['resolved']['users'].keys.map { |e| bot.user(e) }
457
- roles = data['data']['resolved']['roles'] ? data['data']['resolved']['roles'].keys.map { |e| bot.server(data['guild_id']).role(e) } : []
452
+ users = data['data']['resolved']['users'].keys.map { |e| bot.user(e) }
453
+ roles = data['data']['resolved']['roles'] ? data['data']['resolved']['roles'].keys.map { |e| bot.server(data['guild_id']).role(e) } : []
458
454
  @values = { users: users, roles: roles }
459
455
  end
460
456
  end
@@ -479,4 +475,101 @@ module Discordrb::Events
479
475
  # Event handler for a select channel component.
480
476
  class ChannelSelectEventHandler < ComponentEventHandler
481
477
  end
478
+
479
+ # Event handler for an autocomplete option choices.
480
+ class AutocompleteEventHandler < InteractionCreateEventHandler
481
+ def matches?(event)
482
+ return false unless super
483
+ return false unless event.is_a?(AutocompleteEvent)
484
+
485
+ [
486
+ matches_all(@attributes[:name], event.focused) { |a, e| a&.to_s == e },
487
+ matches_all(@attributes[:command_id], event.command_id) { |a, e| a&.to_i == e },
488
+ matches_all(@attributes[:subcommand], event.subcommand) { |a, e| a&.to_sym == e },
489
+ matches_all(@attributes[:command_name], event.command_name) { |a, e| a&.to_sym == e },
490
+ matches_all(@attributes[:subcommand_group], event.subcommand_group) { |a, e| a&.to_sym == e },
491
+ matches_all(@attributes[:server], event.server_id) { |a, e| a&.resolve_id == e }
492
+ ].reduce(&:&)
493
+ end
494
+ end
495
+
496
+ # An event for an autocomplete option choice.
497
+ class AutocompleteEvent < ApplicationCommandEvent
498
+ # @return [String] Name of the currently focused option.
499
+ attr_reader :focused
500
+
501
+ # @return [Hash] An empty hash that can be used to return choices by adding K/V pairs.
502
+ attr_reader :choices
503
+
504
+ # @!visibility private
505
+ def initialize(data, bot)
506
+ super
507
+
508
+ @choices = {}
509
+
510
+ options = data['data']['options']
511
+
512
+ options = case options[0]['type']
513
+ when 1
514
+ options[0]['options']
515
+ when 2
516
+ options[0]['options'][0]['options']
517
+ else
518
+ options
519
+ end
520
+
521
+ @focused = options.find { |opt| opt.key?('focused') }['name']
522
+ end
523
+
524
+ # Respond to this interaction with autocomplete choices.
525
+ # @param choices [Array<Hash>, Hash, nil] Autocomplete choices to return.
526
+ def respond(choices:)
527
+ @interaction.show_autocomplete_choices(choices || [])
528
+ end
529
+ end
530
+
531
+ # An event for whenever an application command's permissions are updated.
532
+ class ApplicationCommandPermissionsUpdateEvent < Event
533
+ # @return [Integer] the ID of the server where the command permissions were updated.
534
+ attr_reader :server_id
535
+
536
+ # @return [Integer, nil] the ID of the application command that was updated.
537
+ attr_reader :command_id
538
+
539
+ # @return [Array<ApplicationCommand::Permission>] the permissions that were updated.
540
+ attr_reader :permissions
541
+
542
+ # @return [Integer] the ID of the application whose commands were updated.
543
+ attr_reader :application_id
544
+
545
+ # @!visibility private
546
+ def initialize(data, bot)
547
+ @bot = bot
548
+ @server_id = data['guild_id'].to_i
549
+ @application_id = data['application_id'].to_i
550
+ @command_id = data['id'].to_i if data['id'].to_i != @application_id
551
+ @permissions = data['permissions'].map do |permission|
552
+ Discordrb::ApplicationCommand::Permission.new(permission, data, bot)
553
+ end
554
+ end
555
+
556
+ # @return [Server] the server where the command's permissions were updated.
557
+ def server
558
+ @bot.server(@server_id)
559
+ end
560
+ end
561
+
562
+ # Event handler for the APPLICATION_COMMAND_PERMISSIONS_UPDATE event.
563
+ class ApplicationCommandPermissionsUpdateEventHandler < EventHandler
564
+ # @!visibility private
565
+ def matches?(event)
566
+ return false unless event.is_a?(ApplicationCommandPermissionsUpdateEvent)
567
+
568
+ [
569
+ matches_all(@attributes[:server], event.server_id) { |a, e| a.resolve_id == e },
570
+ matches_all(@attributes[:command_id], event.command_id) { |a, e| a.resolve_id == e },
571
+ matches_all(@attributes[:application_id], event.application_id) { |a, e| a.resolve_id == e }
572
+ ].reduce(&:&)
573
+ end
574
+ end
482
575
  end
@@ -34,6 +34,7 @@ module Discordrb::Events
34
34
 
35
35
  alias temporary? temporary
36
36
 
37
+ # @!visibility private
37
38
  def initialize(data, invite, bot)
38
39
  @bot = bot
39
40
  @invite = invite
@@ -53,6 +54,7 @@ module Discordrb::Events
53
54
  # @return [String] The code of the deleted invite.
54
55
  attr_reader :code
55
56
 
57
+ # @!visibility private
56
58
  def initialize(data, bot)
57
59
  @bot = bot
58
60
  @channel = bot.channel(data['channel_id'])
@@ -16,6 +16,7 @@ module Discordrb::Events
16
16
  # @return [Server] the server on which the event happened.
17
17
  attr_reader :server
18
18
 
19
+ # @!visibility private
19
20
  def initialize(data, bot)
20
21
  @bot = bot
21
22
 
@@ -28,11 +29,13 @@ module Discordrb::Events
28
29
 
29
30
  private
30
31
 
32
+ # @!visibility private
31
33
  def init_user(data, _)
32
34
  user_id = data['user']['id'].to_i
33
35
  @user = @server.member(user_id)
34
36
  end
35
37
 
38
+ # @!visibility private
36
39
  def init_roles(data, _)
37
40
  @roles = [@server.role(@server.id)]
38
41
  return unless data['roles']
@@ -71,7 +74,20 @@ module Discordrb::Events
71
74
 
72
75
  # Member is updated (roles added or deleted)
73
76
  # @see Discordrb::EventContainer#member_update
74
- class ServerMemberUpdateEvent < ServerMemberEvent; end
77
+ class ServerMemberUpdateEvent < ServerMemberEvent
78
+ # @!visibility private
79
+ # @note Override init_user so we don't make requests all the time on large servers
80
+ def init_user(data, _)
81
+ @user_id = data['user']['id']
82
+ end
83
+
84
+ # @return [Member] the member in question.
85
+ def user
86
+ @server&.member(@user_id)
87
+ end
88
+
89
+ alias_method :member, :user
90
+ end
75
91
 
76
92
  # Event handler for {ServerMemberUpdateEvent}
77
93
  class ServerMemberUpdateEventHandler < ServerMemberEventHandler; end
@@ -79,7 +95,8 @@ module Discordrb::Events
79
95
  # Member leaves
80
96
  # @see Discordrb::EventContainer#member_leave
81
97
  class ServerMemberDeleteEvent < ServerMemberEvent
82
- # Override init_user to account for the deleted user on the server
98
+ # @!visibility private
99
+ # @note Override init_user to account for the deleted user on the server
83
100
  def init_user(data, bot)
84
101
  @user = Discordrb::User.new(data['user'], bot)
85
102
  end
@@ -18,9 +18,10 @@ 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) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
21
22
  # @return [Discordrb::Message] the message that was sent
22
- def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
23
- channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components)
23
+ def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0)
24
+ channel.send_message(content, tts, embed, attachments, allowed_mentions, message_reference, components, flags)
24
25
  end
25
26
 
26
27
  # The same as {#send_message}, but yields a {Webhooks::Embed} for easy building of embedded content inside a block.
@@ -32,11 +33,12 @@ module Discordrb::Events
32
33
  # @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
33
34
  # @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
34
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) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
35
37
  # @yield [embed] Yields the embed to allow for easy building inside a block.
36
38
  # @yieldparam embed [Discordrb::Webhooks::Embed] The embed from the parameters, or a new one.
37
39
  # @return [Message] The resulting message.
38
- def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil, &block)
39
- channel.send_embed(message, embed, attachments, tts, allowed_mentions, message_reference, components, &block)
40
+ def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0, &block)
41
+ channel.send_embed(message, embed, attachments, tts, allowed_mentions, message_reference, components, flags, &block)
40
42
  end
41
43
 
42
44
  # Sends a temporary message to the channel this message was sent in, right now.
@@ -47,8 +49,15 @@ module Discordrb::Events
47
49
  # @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
48
50
  # @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
49
51
  # @param components [View, Array<Hash>, nil] A collection of components to attach to the message.
50
- def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, components = nil)
51
- channel.send_temporary_message(content, timeout, tts, embed, attachments, allowed_mentions, components)
52
+ # @param flags [Integer] Flags for this message. Currently only SUPPRESS_EMBEDS (1 << 2) and SUPPRESS_NOTIFICATIONS (1 << 12) can be set.
53
+ def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, components = nil, flags = 0)
54
+ channel.send_temporary_message(content, timeout, tts, embed, attachments, allowed_mentions, components, flags)
55
+ end
56
+
57
+ # Sends a message to the channel this message was sent in, right now.
58
+ # @see Channel#send_message!
59
+ def send_message!(...)
60
+ channel.send_message!(...)
52
61
  end
53
62
 
54
63
  # Adds a string to be sent after the event has finished execution. Avoids problems with rate limiting because only
@@ -84,6 +93,9 @@ module Discordrb::Events
84
93
  alias_method :send, :send_message
85
94
  alias_method :respond, :send_message
86
95
  alias_method :send_temp, :send_temporary_message
96
+
97
+ alias_method :send!, :send_message!
98
+ alias_method :respond!, :send_message!
87
99
  end
88
100
 
89
101
  # Event raised when a text message is sent to a channel
@@ -124,6 +136,7 @@ module Discordrb::Events
124
136
  # @see Channel#server
125
137
  delegate :server, to: :channel
126
138
 
139
+ # @!visibility private
127
140
  def initialize(message, bot)
128
141
  @bot = bot
129
142
  @message = message
@@ -226,7 +239,9 @@ module Discordrb::Events
226
239
  a == e
227
240
  end
228
241
  end,
229
- matches_all(@attributes[:from], event.author) do |a, e|
242
+ matches_all(@attributes[:from], event.message) do |a, e|
243
+ # Resolve the author in the block in order to prevent resolving the author even when the attribute is `nil`
244
+ e = e.author
230
245
  case a
231
246
  when String
232
247
  a == e.name
@@ -247,9 +262,18 @@ module Discordrb::Events
247
262
  match ? (e == match[0]) : false
248
263
  end
249
264
  end,
265
+ matches_all(@attributes[:type] || @attributes[:message_type], event.message.type) do |a, e|
266
+ case a
267
+ when String, Symbol
268
+ Discordrb::Message::TYPES[a.to_sym] == e
269
+ when Integer
270
+ a == e
271
+ end
272
+ end,
250
273
  matches_all(@attributes[:after], event.timestamp) { |a, e| a > e },
251
274
  matches_all(@attributes[:before], event.timestamp) { |a, e| a < e },
252
- matches_all(@attributes[:private], event.channel.private?) { |a, e| !e == !a }
275
+ matches_all(@attributes[:private], event.channel.private?) { |a, e| !e == !a },
276
+ matches_all(@attributes[:server], event.server) { |a, e| a&.resolve_id == e&.resolve_id }
253
277
  ].reduce(true, &:&)
254
278
  end
255
279
 
@@ -282,10 +306,14 @@ module Discordrb::Events
282
306
  # @return [Integer] the ID associated with this event
283
307
  attr_reader :id
284
308
 
309
+ # @return [Server, nil] the server associated with this event
310
+ attr_reader :server
311
+
285
312
  # @!visibility private
286
313
  def initialize(data, bot)
287
314
  @id = data['id'].to_i
288
315
  @channel = bot.channel(data['channel_id'].to_i)
316
+ @server = @channel.server
289
317
  @saved_message = ''
290
318
  @bot = bot
291
319
  end
@@ -311,6 +339,9 @@ module Discordrb::Events
311
339
  else
312
340
  a == e
313
341
  end
342
+ end,
343
+ matches_all(@attributes[:server], event.server) do |a, e|
344
+ a&.resolve_id == e&.resolve_id
314
345
  end
315
346
  ].reduce(true, &:&)
316
347
  end
@@ -19,6 +19,7 @@ module Discordrb::Events
19
19
  # on various device types (`:desktop`, `:mobile`, or `:web`). The value will be `nil` if the user is offline or invisible.
20
20
  attr_reader :client_status
21
21
 
22
+ # @!visibility private
22
23
  def initialize(data, bot)
23
24
  @bot = bot
24
25
 
@@ -82,6 +83,7 @@ module Discordrb::Events
82
83
  # on various device types (`:desktop`, `:mobile`, or `:web`). The value will be `nil` if the user is offline or invisible.
83
84
  attr_reader :client_status
84
85
 
86
+ # @!visibility private
85
87
  def initialize(data, activity, bot)
86
88
  @bot = bot
87
89
  @activity = activity
@@ -14,6 +14,7 @@ module Discordrb::Events
14
14
  attr_reader :data
15
15
  alias_method :d, :data
16
16
 
17
+ # @!visibility private
17
18
  def initialize(type, data, bot)
18
19
  @type = type
19
20
  @data = data
@@ -14,6 +14,7 @@ module Discordrb::Events
14
14
  # @!visibility private
15
15
  attr_reader :message_id
16
16
 
17
+ # @!visibility private
17
18
  def initialize(data, bot)
18
19
  @bot = bot
19
20
 
@@ -113,6 +114,7 @@ module Discordrb::Events
113
114
  # @!visibility private
114
115
  attr_reader :message_id
115
116
 
117
+ # @!visibility private
116
118
  def initialize(data, bot)
117
119
  @bot = bot
118
120
 
@@ -17,6 +17,7 @@ module Discordrb::Events
17
17
  # @see Role#name
18
18
  delegate :name, to: :role
19
19
 
20
+ # @!visibility private
20
21
  def initialize(data, bot)
21
22
  @bot = bot
22
23
 
@@ -54,6 +55,7 @@ module Discordrb::Events
54
55
  # @return [Server] the server on which a role got deleted.
55
56
  attr_reader :server
56
57
 
58
+ # @!visibility private
57
59
  def initialize(data, bot)
58
60
  @bot = bot
59
61
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Generic subclass for threads
3
4
  module Discordrb::Events
4
5
  # Raised when a thread is created
5
6
  class ThreadCreateEvent < Event
@@ -8,6 +9,7 @@ module Discordrb::Events
8
9
 
9
10
  delegate :name, :server, :owner, :parent_channel, :thread_metadata, to: :thread
10
11
 
12
+ # @!visibility private
11
13
  def initialize(data, bot)
12
14
  @bot = bot
13
15
  @thread = data.is_a?(Discordrb::Channel) ? data : bot.channel(data['id'].to_i)
@@ -62,9 +64,6 @@ module Discordrb::Events
62
64
  # @return [Channel]
63
65
  attr_reader :thread
64
66
 
65
- # @return [Array<Member, User>]
66
- attr_reader :added_members
67
-
68
67
  # @return [Array<Integer>]
69
68
  attr_reader :removed_member_ids
70
69
 
@@ -73,17 +72,22 @@ module Discordrb::Events
73
72
 
74
73
  delegate :name, :server, :owner, :parent_channel, :thread_metadata, to: :thread
75
74
 
75
+ # @!visibility private
76
76
  def initialize(data, bot)
77
77
  @bot = bot
78
+ @server = bot.server(data['guild_id'].to_i) if data['guild_id']
78
79
  @thread = data.is_a?(Discordrb::Channel) ? data : bot.channel(data['id'].to_i)
79
- @added_members = data['added_members']&.map do |member|
80
- data['guild_id'] ? bot.member(data['guild_id'], member['user_id']) : bot.user(member['user_id'])
81
- end || []
80
+ @added_member_ids = data['added_members']&.map { |m| m['user_id']&.to_i } || []
82
81
  @removed_member_ids = data['removed_member_ids']&.map(&:resolve_id) || []
83
82
  @member_count = data['member_count']
84
83
  end
85
84
  end
86
85
 
86
+ # @return [Array<Member, User>] the members that were added to the thread
87
+ def added_members
88
+ @added_members ||= @added_member_ids&.map { |id| @server&.member(id) || @bot.user(id) }
89
+ end
90
+
87
91
  # Event handler for ThreadMembersUpdateEvent
88
92
  class ThreadMembersUpdateEventHandler < ThreadCreateEventHandler
89
93
  def matches?(event)
@@ -17,6 +17,7 @@ module Discordrb::Events
17
17
  # @return [Time] when the typing happened.
18
18
  attr_reader :timestamp
19
19
 
20
+ # @!visibility private
20
21
  def initialize(data, bot)
21
22
  @bot = bot
22
23
 
@@ -19,6 +19,7 @@ module Discordrb::Events
19
19
  # @return [String] The voice server host.
20
20
  attr_reader :endpoint
21
21
 
22
+ # @!visibility private
22
23
  def initialize(data, bot)
23
24
  @bot = bot
24
25
 
@@ -11,6 +11,7 @@ module Discordrb::Events
11
11
  # @return [Channel, nil] the old channel this user was on, or nil if the user is newly joining voice.
12
12
  attr_reader :old_channel
13
13
 
14
+ # @!visibility private
14
15
  def initialize(data, old_channel_id, bot)
15
16
  @bot = bot
16
17
 
@@ -12,6 +12,7 @@ module Discordrb::Events
12
12
  # @return [Channel] the channel the webhook is associated to
13
13
  attr_reader :channel
14
14
 
15
+ # @!visibility private
15
16
  def initialize(data, bot)
16
17
  @bot = bot
17
18