discorb 0.18.0 → 0.20.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 (149) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +2 -2
  3. data/.rubocop.yml +12 -75
  4. data/Changelog.md +25 -0
  5. data/Gemfile +4 -4
  6. data/README.md +2 -1
  7. data/Rakefile +482 -459
  8. data/Steepfile +8 -6
  9. data/docs/application_command.md +1 -0
  10. data/docs/events.md +2 -2
  11. data/docs/voice_events.md +6 -6
  12. data/lib/discorb/allowed_mentions.rb +68 -72
  13. data/lib/discorb/app_command/command.rb +466 -394
  14. data/lib/discorb/app_command/common.rb +65 -25
  15. data/lib/discorb/app_command/handler.rb +304 -265
  16. data/lib/discorb/app_command.rb +5 -5
  17. data/lib/discorb/application.rb +198 -197
  18. data/lib/discorb/asset.rb +101 -101
  19. data/lib/discorb/attachment.rb +134 -119
  20. data/lib/discorb/audit_logs.rb +412 -385
  21. data/lib/discorb/automod.rb +279 -269
  22. data/lib/discorb/channel/base.rb +107 -108
  23. data/lib/discorb/channel/category.rb +32 -32
  24. data/lib/discorb/channel/container.rb +44 -44
  25. data/lib/discorb/channel/dm.rb +26 -28
  26. data/lib/discorb/channel/guild.rb +311 -246
  27. data/lib/discorb/channel/stage.rb +156 -140
  28. data/lib/discorb/channel/text.rb +430 -336
  29. data/lib/discorb/channel/thread.rb +374 -325
  30. data/lib/discorb/channel/voice.rb +85 -79
  31. data/lib/discorb/channel.rb +5 -5
  32. data/lib/discorb/client.rb +635 -623
  33. data/lib/discorb/color.rb +178 -182
  34. data/lib/discorb/common.rb +168 -164
  35. data/lib/discorb/components/button.rb +107 -106
  36. data/lib/discorb/components/select_menu.rb +157 -145
  37. data/lib/discorb/components/text_input.rb +103 -106
  38. data/lib/discorb/components.rb +68 -66
  39. data/lib/discorb/dictionary.rb +135 -135
  40. data/lib/discorb/embed.rb +404 -398
  41. data/lib/discorb/emoji.rb +309 -302
  42. data/lib/discorb/emoji_table.rb +16099 -8857
  43. data/lib/discorb/error.rb +131 -131
  44. data/lib/discorb/event.rb +360 -314
  45. data/lib/discorb/event_handler.rb +39 -39
  46. data/lib/discorb/exe/about.rb +17 -17
  47. data/lib/discorb/exe/irb.rb +72 -67
  48. data/lib/discorb/exe/new.rb +323 -315
  49. data/lib/discorb/exe/run.rb +69 -68
  50. data/lib/discorb/exe/setup.rb +57 -55
  51. data/lib/discorb/exe/show.rb +12 -12
  52. data/lib/discorb/extend.rb +25 -45
  53. data/lib/discorb/extension.rb +89 -83
  54. data/lib/discorb/flag.rb +126 -128
  55. data/lib/discorb/gateway.rb +984 -794
  56. data/lib/discorb/gateway_events.rb +670 -638
  57. data/lib/discorb/gateway_requests.rb +45 -48
  58. data/lib/discorb/guild.rb +2115 -1626
  59. data/lib/discorb/guild_template.rb +280 -241
  60. data/lib/discorb/http.rb +247 -232
  61. data/lib/discorb/image.rb +42 -42
  62. data/lib/discorb/integration.rb +169 -161
  63. data/lib/discorb/intents.rb +161 -163
  64. data/lib/discorb/interaction/autocomplete.rb +76 -62
  65. data/lib/discorb/interaction/command.rb +279 -224
  66. data/lib/discorb/interaction/components.rb +114 -104
  67. data/lib/discorb/interaction/modal.rb +36 -32
  68. data/lib/discorb/interaction/response.rb +379 -330
  69. data/lib/discorb/interaction/root.rb +271 -118
  70. data/lib/discorb/interaction.rb +5 -5
  71. data/lib/discorb/invite.rb +154 -153
  72. data/lib/discorb/member.rb +344 -311
  73. data/lib/discorb/message.rb +615 -544
  74. data/lib/discorb/message_meta.rb +197 -186
  75. data/lib/discorb/modules.rb +371 -290
  76. data/lib/discorb/permission.rb +305 -289
  77. data/lib/discorb/presence.rb +352 -346
  78. data/lib/discorb/rate_limit.rb +81 -76
  79. data/lib/discorb/reaction.rb +55 -54
  80. data/lib/discorb/role.rb +272 -240
  81. data/lib/discorb/shard.rb +76 -74
  82. data/lib/discorb/sticker.rb +193 -171
  83. data/lib/discorb/user.rb +205 -188
  84. data/lib/discorb/utils/colored_puts.rb +16 -16
  85. data/lib/discorb/utils.rb +12 -16
  86. data/lib/discorb/voice_state.rb +305 -281
  87. data/lib/discorb/webhook.rb +537 -507
  88. data/lib/discorb.rb +62 -56
  89. data/sig/discorb/activity.rbs +1 -0
  90. data/sig/discorb/allowed_mentions.rbs +1 -0
  91. data/sig/discorb/app_command/base.rbs +7 -1
  92. data/sig/discorb/application.rbs +6 -0
  93. data/sig/discorb/asset.rbs +2 -0
  94. data/sig/discorb/attachment.rbs +8 -0
  95. data/sig/discorb/audit_log.rbs +7 -0
  96. data/sig/discorb/automod.rbs +32 -6
  97. data/sig/discorb/avatar.rbs +1 -0
  98. data/sig/discorb/channel/base.rbs +8 -1
  99. data/sig/discorb/channel/category.rbs +1 -0
  100. data/sig/discorb/channel/container.rbs +4 -0
  101. data/sig/discorb/channel/stage.rbs +4 -0
  102. data/sig/discorb/channel/text.rbs +2 -2
  103. data/sig/discorb/channel/thread.rbs +11 -0
  104. data/sig/discorb/channel/voice.rbs +2 -0
  105. data/sig/discorb/client.rbs +21 -20
  106. data/sig/discorb/color.rbs +6 -0
  107. data/sig/discorb/component/base.rbs +1 -0
  108. data/sig/discorb/component/button.rbs +2 -0
  109. data/sig/discorb/component/select_menu.rbs +4 -0
  110. data/sig/discorb/component/text_input.rbs +1 -0
  111. data/sig/discorb/custom_emoji.rbs +5 -1
  112. data/sig/discorb/dictionary.rbs +2 -0
  113. data/sig/discorb/discord_model.rbs +2 -0
  114. data/sig/discorb/embed.rbs +7 -0
  115. data/sig/discorb/emoji.rbs +1 -0
  116. data/sig/discorb/event_handler.rbs +2 -1
  117. data/sig/discorb/extension.rbs +13 -12
  118. data/sig/discorb/flag.rbs +2 -0
  119. data/sig/discorb/gateway.rbs +5 -0
  120. data/sig/discorb/guild.rbs +8 -4
  121. data/sig/discorb/guild_template.rbs +1 -1
  122. data/sig/discorb/http.rbs +4 -1
  123. data/sig/discorb/image.rbs +2 -0
  124. data/sig/discorb/integration.rbs +1 -1
  125. data/sig/discorb/intents.rbs +4 -3
  126. data/sig/discorb/interaction/base.rbs +36 -0
  127. data/sig/discorb/interaction/message_component.rbs +1 -2
  128. data/sig/discorb/interaction/modal.rbs +1 -2
  129. data/sig/discorb/interaction/responder.rbs +49 -49
  130. data/sig/discorb/invite.rbs +1 -1
  131. data/sig/discorb/member.rbs +2 -0
  132. data/sig/discorb/message.rbs +8 -1
  133. data/sig/discorb/messageable.rbs +1 -4
  134. data/sig/discorb/partial_emoji.rbs +3 -0
  135. data/sig/discorb/permissions.rbs +7 -0
  136. data/sig/discorb/presence.rbs +2 -0
  137. data/sig/discorb/reaction.rbs +5 -1
  138. data/sig/discorb/role.rbs +7 -1
  139. data/sig/discorb/scheduled_event.rbs +2 -1
  140. data/sig/discorb/shard.rbs +2 -1
  141. data/sig/discorb/snowflake.rbs +2 -0
  142. data/sig/discorb/stage_instance.rbs +9 -3
  143. data/sig/discorb/sticker.rbs +1 -1
  144. data/sig/discorb/unicode_emoji.rbs +4 -0
  145. data/sig/discorb/user.rbs +24 -20
  146. data/sig/discorb/webhook.rbs +17 -6
  147. data/sig/discorb/welcome_screen.rbs +1 -0
  148. data/sig/override.rbs +2 -0
  149. metadata +3 -3
@@ -1,62 +1,76 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents auto complete interaction.
6
- #
7
- class AutoComplete < Interaction
8
- @interaction_type = 4
9
- @interaction_name = :auto_complete
10
-
11
- private
12
-
13
- def _set_data(data)
14
- super
15
- Sync do
16
- name, options = Discorb::CommandInteraction::ChatInputCommand.get_command_data(data)
17
-
18
- unless (command = @client.callable_commands.find { |c| c.to_s == name && c.type_raw == 1 })
19
- @client.logger.warn "Unknown command name #{name}, ignoring"
20
- next
21
- end
22
-
23
- option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
24
- Discorb::CommandInteraction::ChatInputCommand.modify_option_map(option_map, options, guild, {}, {})
25
- focused_index = options.find_index { |o| o[:focused] }
26
- val = command.options.values.filter do |option|
27
- option[:type] != :attachment
28
- end[focused_index][:autocomplete]&.call(self, *command.options.map do |k, _v|
29
- option_map[k.to_s]
30
- end)
31
- send_complete_result(val)
32
- end
33
- end
34
-
35
- def send_complete_result(val)
36
- @client.http.request(
37
- Route.new(
38
- "/interactions/#{@id}/#{@token}/callback",
39
- "//interactions/:interaction_id/:token/callback",
40
- :post
41
- ), {
42
- type: 8,
43
- data: {
44
- choices: val.map do |vk, vv|
45
- {
46
- name: vk,
47
- value: vv,
48
- }
49
- end,
50
- },
51
- }
52
- ).wait
53
- rescue Discorb::NotFoundError
54
- @client.logger.warn "Failed to send auto complete result, " \
55
- "This may be caused by the suggestion is taking too long (over 3 seconds) to respond"
56
- end
57
-
58
- class << self
59
- alias make_interaction new
60
- end
61
- end
62
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents auto complete interaction.
6
+ #
7
+ class AutoComplete < Interaction
8
+ @interaction_type = 4
9
+ @interaction_name = :auto_complete
10
+
11
+ private
12
+
13
+ def _set_data(data)
14
+ super
15
+ Sync do
16
+ name, options =
17
+ Discorb::CommandInteraction::ChatInputCommand.get_command_data(data)
18
+
19
+ unless (
20
+ command =
21
+ @client.callable_commands.find do |c|
22
+ c.to_s == name && c.type_raw == 1
23
+ end
24
+ )
25
+ @client.logger.warn "Unknown command name #{name}, ignoring"
26
+ next
27
+ end
28
+
29
+ option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
30
+ Discorb::CommandInteraction::ChatInputCommand.modify_option_map(
31
+ option_map,
32
+ options,
33
+ guild,
34
+ {},
35
+ {}
36
+ )
37
+ focused_index = options.find_index { |o| o[:focused] }
38
+ val =
39
+ command.options.values.filter do |option|
40
+ option[:type] != :attachment
41
+ end[
42
+ focused_index
43
+ ][
44
+ :autocomplete
45
+ ]&.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
46
+ send_complete_result(val)
47
+ end
48
+ end
49
+
50
+ def send_complete_result(val)
51
+ @client
52
+ .http
53
+ .request(
54
+ Route.new(
55
+ "/interactions/#{@id}/#{@token}/callback",
56
+ "//interactions/:interaction_id/:token/callback",
57
+ :post
58
+ ),
59
+ {
60
+ type: 8,
61
+ data: {
62
+ choices: val.map { |vk, vv| { name: vk, value: vv } }
63
+ }
64
+ }
65
+ )
66
+ .wait
67
+ rescue Discorb::NotFoundError
68
+ @client.logger.warn "Failed to send auto complete result, " \
69
+ "This may be caused by the suggestion is taking too long (over 3 seconds) to respond"
70
+ end
71
+
72
+ class << self
73
+ alias make_interaction new
74
+ end
75
+ end
76
+ end
@@ -1,224 +1,279 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents a command interaction.
6
- #
7
- class CommandInteraction < Interaction
8
- @interaction_type = 2
9
- @interaction_name = :application_command
10
- include Interaction::SourceResponder
11
- include Interaction::ModalResponder
12
-
13
- #
14
- # Represents a slash command interaction.
15
- #
16
- class ChatInputCommand < CommandInteraction
17
- @command_type = 1
18
- @event_name = :slash_command
19
-
20
- private
21
-
22
- def _set_data(data)
23
- super
24
-
25
- name, options = ChatInputCommand.get_command_data(data)
26
-
27
- unless (command = @client.callable_commands.find { |c| c.to_s == name && c.type_raw == 1 })
28
- @client.logger.warn "Unknown command name #{name}, ignoring"
29
- return
30
- end
31
-
32
- option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
33
- ChatInputCommand.modify_option_map(option_map, options, guild, @members, @attachments)
34
-
35
- command.block.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
36
- end
37
-
38
- class << self
39
- #
40
- # Get command data from the given data.
41
- # @private
42
- #
43
- # @param [Hash] data The data of the command.
44
- #
45
- def get_command_data(data)
46
- name = data[:name]
47
- options = nil
48
- return name, options unless (option = data[:options]&.first)
49
-
50
- case option[:type]
51
- when 1
52
- name += " #{option[:name]}"
53
- options = option[:options]
54
- when 2
55
- name += " #{option[:name]}"
56
- unless option[:options]&.first&.[](:type) == 1
57
- options = option[:options]
58
- return name, options
59
- end
60
- option_sub = option[:options]&.first
61
- name += " #{option_sub[:name]}"
62
- options = option_sub[:options]
63
- else
64
- options = data[:options]
65
- end
66
-
67
- [name, options]
68
- end
69
-
70
- #
71
- # Modify the option map with the given options.
72
- # @private
73
- #
74
- # @param [Hash] option_map The option map to modify.
75
- # @param [Array<Hash>] options The options for modifying.
76
- # @param [Discorb::Guild] guild The guild where the command is executed.
77
- # @param [{Discorb::Snowflake => Discorb::Member}] members The cached members of the guild.
78
- # @param [{Integer => Discorb::Attachment}] attachments The cached attachments of the message.
79
- def modify_option_map(option_map, options, guild, members, attachments)
80
- options ||= []
81
- options.each do |option|
82
- val = case option[:type]
83
- when 3, 4, 5, 10
84
- option[:value]
85
- when 6
86
- members[option[:value]] || guild && (guild.members[option[:value]] ||
87
- guild.fetch_member(option[:value]).wait)
88
- when 7
89
- if guild
90
- guild.channels[option[:value]] || guild.fetch_channels.wait.find do |channel|
91
- channel.id == option[:value]
92
- end
93
- end
94
- when 8
95
- guild && (guild.roles[option[:value]] ||
96
- guild.fetch_roles.wait.find { |role| role.id == option[:value] })
97
- when 9
98
- members[option[:value]] ||
99
- guild && (guild.members[option[:value]] ||
100
- guild.roles[option[:value]] ||
101
- guild.fetch_member(option[:value]).wait ||
102
- guild.fetch_roles.wait.find do |role|
103
- role.id == option[:value]
104
- end)
105
- when 11
106
- attachments[option[:value]]
107
- end
108
- option_map[option[:name]] = val
109
- end
110
- end
111
- end
112
- end
113
-
114
- #
115
- # Represents a user context menu interaction.
116
- #
117
- class UserMenuCommand < CommandInteraction
118
- @command_type = 2
119
- @event_name = :user_command
120
-
121
- # @return [Discorb::Member, Discorb::User] The target user.
122
- attr_reader :target
123
-
124
- private
125
-
126
- def _set_data(data)
127
- super
128
- @target = guild.members[data[:target_id]] || Discorb::Member.new(
129
- @client, @guild_id,
130
- data[:resolved][:users][data[:target_id].to_sym],
131
- data[:resolved][:members][data[:target_id].to_sym]
132
- )
133
- command = @client.commands.find { |c| c.name["default"] == data[:name] && c.type_raw == 2 }
134
- if command
135
- command.block.call(self, @target)
136
- else
137
- @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
138
- end
139
- end
140
- end
141
-
142
- #
143
- # Represents a message context menu interaction.
144
- #
145
- class MessageMenuCommand < CommandInteraction
146
- @command_type = 3
147
- @event_name = :message_command
148
-
149
- # @return [Discorb::Message] The target message.
150
- attr_reader :target
151
-
152
- private
153
-
154
- def _set_data(data)
155
- super
156
- @target = @messages[data[:target_id]]
157
- command = @client.commands.find { |c| c.name["default"] == data[:name] && c.type_raw == 3 }
158
- if command
159
- command.block.call(self, @target)
160
- else
161
- @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
162
- end
163
- end
164
- end
165
-
166
- private
167
-
168
- def _set_data(data)
169
- super
170
- @name = data[:name]
171
- @messages, @attachments, @members = {}, {}, {}
172
-
173
- if data[:resolved]
174
- data[:resolved][:users]&.each do |id, user|
175
- @client.users[id] = Discorb::User.new(@client, user)
176
- end
177
- data[:resolved][:members]&.each do |id, member|
178
- @members[id] = Discorb::Member.new(
179
- @client, @guild_id, data[:resolved][:users][id], member
180
- )
181
- end
182
-
183
- data[:resolved][:messages]&.each do |id, message|
184
- @messages[id.to_s] = Message.new(@client, message.merge(guild_id: @guild_id.to_s))
185
- end
186
- data[:resolved][:attachments]&.each do |id, attachment|
187
- @attachments[id.to_s] = Attachment.new(attachment)
188
- end
189
- end
190
- end
191
-
192
- class << self
193
- # @private
194
- attr_reader :command_type, :event_name
195
-
196
- #
197
- # Creates a new CommandInteraction instance for the given data.
198
- # @private
199
- #
200
- # @param [Discorb::Client] client The client.
201
- # @param [Hash] data The data for the command.
202
- #
203
- def make_interaction(client, data)
204
- nested_classes.each do |klass|
205
- if !klass.command_type.nil? && klass.command_type == data[:data][:type]
206
- interaction = klass.new(client, data)
207
- client.dispatch(klass.event_name, interaction)
208
- return interaction
209
- end
210
- end
211
- client.logger.warn("Unknown command type #{data[:type]}, initialized CommandInteraction")
212
- CommandInteraction.new(client, data)
213
- end
214
-
215
- #
216
- # Returns the classes under this class.
217
- # @private
218
- #
219
- def nested_classes
220
- constants.select { |c| const_get(c).is_a? Class }.map { |c| const_get(c) }
221
- end
222
- end
223
- end
224
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a command interaction.
6
+ #
7
+ class CommandInteraction < Interaction
8
+ @interaction_type = 2
9
+ @interaction_name = :application_command
10
+ include Interaction::SourceResponder
11
+ include Interaction::ModalResponder
12
+
13
+ #
14
+ # Represents a slash command interaction.
15
+ #
16
+ class ChatInputCommand < CommandInteraction
17
+ @command_type = 1
18
+ @event_name = :slash_command
19
+
20
+ private
21
+
22
+ def _set_data(data)
23
+ super
24
+
25
+ name, options = ChatInputCommand.get_command_data(data)
26
+
27
+ unless (
28
+ command =
29
+ @client.callable_commands.find do |c|
30
+ c.to_s == name && c.type_raw == 1
31
+ end
32
+ )
33
+ @client.logger.warn "Unknown command name #{name}, ignoring"
34
+ return
35
+ end
36
+
37
+ option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
38
+ ChatInputCommand.modify_option_map(
39
+ option_map,
40
+ options,
41
+ guild,
42
+ @members,
43
+ @attachments
44
+ )
45
+
46
+ command.block.call(
47
+ self,
48
+ *command.options.map { |k, _v| option_map[k.to_s] }
49
+ )
50
+ end
51
+
52
+ class << self
53
+ #
54
+ # Get command data from the given data.
55
+ # @private
56
+ #
57
+ # @param [Hash] data The data of the command.
58
+ #
59
+ def get_command_data(data)
60
+ name = data[:name]
61
+ options = nil
62
+ return name, options unless (option = data[:options]&.first)
63
+
64
+ case option[:type]
65
+ when 1
66
+ name += " #{option[:name]}"
67
+ options = option[:options]
68
+ when 2
69
+ name += " #{option[:name]}"
70
+ unless option[:options]&.first&.[](:type) == 1
71
+ options = option[:options]
72
+ return name, options
73
+ end
74
+ option_sub = option[:options]&.first
75
+ name += " #{option_sub[:name]}"
76
+ options = option_sub[:options]
77
+ else
78
+ options = data[:options]
79
+ end
80
+
81
+ [name, options]
82
+ end
83
+
84
+ #
85
+ # Modify the option map with the given options.
86
+ # @private
87
+ #
88
+ # @param [Hash] option_map The option map to modify.
89
+ # @param [Array<Hash>] options The options for modifying.
90
+ # @param [Discorb::Guild] guild The guild where the command is executed.
91
+ # @param [{Discorb::Snowflake => Discorb::Member}] members The cached members of the guild.
92
+ # @param [{Integer => Discorb::Attachment}] attachments The cached attachments of the message.
93
+ def modify_option_map(option_map, options, guild, members, attachments)
94
+ options ||= []
95
+ options.each do |option|
96
+ val =
97
+ case option[:type]
98
+ when 3, 4, 5, 10
99
+ option[:value]
100
+ when 6
101
+ members[option[:value]] ||
102
+ (
103
+ guild &&
104
+ (
105
+ guild.members[option[:value]] ||
106
+ guild.fetch_member(option[:value]).wait
107
+ )
108
+ )
109
+ when 7
110
+ if guild
111
+ guild.channels[option[:value]] ||
112
+ guild.fetch_channels.wait.find do |channel|
113
+ channel.id == option[:value]
114
+ end
115
+ end
116
+ when 8
117
+ guild &&
118
+ (
119
+ guild.roles[option[:value]] ||
120
+ guild.fetch_roles.wait.find do |role|
121
+ role.id == option[:value]
122
+ end
123
+ )
124
+ when 9
125
+ members[option[:value]] ||
126
+ (
127
+ guild &&
128
+ (
129
+ guild.members[option[:value]] ||
130
+ guild.roles[option[:value]] ||
131
+ guild.fetch_member(option[:value]).wait ||
132
+ guild.fetch_roles.wait.find do |role|
133
+ role.id == option[:value]
134
+ end
135
+ )
136
+ )
137
+ when 11
138
+ attachments[option[:value]]
139
+ end
140
+ option_map[option[:name]] = val
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ #
147
+ # Represents a user context menu interaction.
148
+ #
149
+ class UserMenuCommand < CommandInteraction
150
+ @command_type = 2
151
+ @event_name = :user_command
152
+
153
+ # @return [Discorb::Member, Discorb::User] The target user.
154
+ attr_reader :target
155
+
156
+ private
157
+
158
+ def _set_data(data)
159
+ super
160
+ @target =
161
+ guild.members[data[:target_id]] ||
162
+ Discorb::Member.new(
163
+ @client,
164
+ @guild_id,
165
+ data[:resolved][:users][data[:target_id].to_sym],
166
+ data[:resolved][:members][data[:target_id].to_sym]
167
+ )
168
+ command =
169
+ @client.commands.find do |c|
170
+ c.name["default"] == data[:name] && c.type_raw == 2
171
+ end
172
+ if command
173
+ command.block.call(self, @target)
174
+ else
175
+ @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
176
+ end
177
+ end
178
+ end
179
+
180
+ #
181
+ # Represents a message context menu interaction.
182
+ #
183
+ class MessageMenuCommand < CommandInteraction
184
+ @command_type = 3
185
+ @event_name = :message_command
186
+
187
+ # @return [Discorb::Message] The target message.
188
+ attr_reader :target
189
+
190
+ private
191
+
192
+ def _set_data(data)
193
+ super
194
+ @target = @messages[data[:target_id]]
195
+ command =
196
+ @client.commands.find do |c|
197
+ c.name["default"] == data[:name] && c.type_raw == 3
198
+ end
199
+ if command
200
+ command.block.call(self, @target)
201
+ else
202
+ @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
203
+ end
204
+ end
205
+ end
206
+
207
+ private
208
+
209
+ def _set_data(data)
210
+ super
211
+ @name = data[:name]
212
+ @messages = {}
213
+ @attachments = {}
214
+ @members = {}
215
+
216
+ if data[:resolved]
217
+ data[:resolved][:users]&.each do |id, user|
218
+ @client.users[id] = Discorb::User.new(@client, user)
219
+ end
220
+ data[:resolved][:members]&.each do |id, member|
221
+ @members[id] = Discorb::Member.new(
222
+ @client,
223
+ @guild_id,
224
+ data[:resolved][:users][id],
225
+ member
226
+ )
227
+ end
228
+
229
+ data[:resolved][:messages]&.each do |id, message|
230
+ @messages[id.to_s] = Message.new(
231
+ @client,
232
+ message.merge(guild_id: @guild_id.to_s)
233
+ )
234
+ end
235
+ data[:resolved][:attachments]&.each do |id, attachment|
236
+ @attachments[id.to_s] = Attachment.new(attachment)
237
+ end
238
+ end
239
+ end
240
+
241
+ class << self
242
+ # @private
243
+ attr_reader :command_type, :event_name
244
+
245
+ #
246
+ # Creates a new CommandInteraction instance for the given data.
247
+ # @private
248
+ #
249
+ # @param [Discorb::Client] client The client.
250
+ # @param [Hash] data The data for the command.
251
+ #
252
+ def make_interaction(client, data)
253
+ nested_classes.each do |klass|
254
+ unless !klass.command_type.nil? &&
255
+ klass.command_type == data[:data][:type]
256
+ next
257
+ end
258
+ interaction = klass.new(client, data)
259
+ client.dispatch(klass.event_name, interaction)
260
+ return interaction
261
+ end
262
+ client.logger.warn(
263
+ "Unknown command type #{data[:type]}, initialized CommandInteraction"
264
+ )
265
+ CommandInteraction.new(client, data)
266
+ end
267
+
268
+ #
269
+ # Returns the classes under this class.
270
+ # @private
271
+ #
272
+ def nested_classes
273
+ constants
274
+ .select { |c| const_get(c).is_a? Class }
275
+ .map { |c| const_get(c) }
276
+ end
277
+ end
278
+ end
279
+ end