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,394 +1,466 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- module ApplicationCommand
5
- #
6
- # Represents a application command.
7
- # @abstract
8
- #
9
- class Command < DiscordModel
10
- # @return [Hash{String => String}] The name of the command.
11
- attr_reader :name
12
- # @return [Array<#to_s>] The guild ids that the command is enabled in.
13
- attr_reader :guild_ids
14
- # @return [Proc] The block of the command.
15
- attr_reader :block
16
- # @return [:chat_input, :user, :message] The type of the command.
17
- attr_reader :type
18
- # @return [Integer] The raw type of the command.
19
- attr_reader :type_raw
20
- # @return [Discorb::Permission] The default permissions for this command.
21
- attr_reader :default_permission
22
- # @return [Boolean] Whether the command is enabled in DMs.
23
- attr_reader :dm_permission
24
-
25
- # @private
26
- # @return [{Integer => Symbol}] The mapping of raw types to types.
27
- TYPES = {
28
- 1 => :chat_input,
29
- 2 => :user,
30
- 3 => :message,
31
- }.freeze
32
-
33
- #
34
- # Initialize a new command.
35
- # @private
36
- #
37
- # @param [String, Hash{Symbol => String}] name The name of the command.
38
- # @param [Array<#to_s>, false, nil] guild_ids The guild ids that the command is enabled in.
39
- # @param [Proc] block The block of the command.
40
- # @param [Integer] type The type of the command.
41
- # @param [Boolean] dm_permission Whether the command is enabled in DMs.
42
- # @param [Discorb::Permission] default_permission The default permission of the command.
43
- #
44
- def initialize(name, guild_ids, block, type, dm_permission = true, default_permission = nil) # rubocop:disable Style/OptionalBooleanParameter
45
- @name = name.is_a?(String) ? { "default" => name } : ApplicationCommand.modify_localization_hash(name)
46
- @guild_ids = guild_ids&.map(&:to_s)
47
- @block = block
48
- @type = Discorb::ApplicationCommand::Command::TYPES[type]
49
- @type_raw = type
50
- @dm_permission = dm_permission
51
- @default_permission = default_permission
52
- end
53
-
54
- #
55
- # Changes the self pointer of block to the given object.
56
- # @private
57
- #
58
- # @param [Object] instance The object to change the self pointer to.
59
- #
60
- def replace_block(instance)
61
- current_block = @block.dup
62
- @block = proc do |*args|
63
- instance.instance_exec(*args, &current_block)
64
- end
65
- end
66
-
67
- #
68
- # Converts the object to a hash.
69
- # @private
70
- #
71
- # @return [Hash] The hash represents the object.
72
- #
73
- def to_hash
74
- {
75
- name: @name["default"],
76
- name_localizations: @name.except("default"),
77
- type: @type_raw,
78
- dm_permission: @dm_permission,
79
- default_member_permissions: @default_permission&.value&.to_s,
80
- }
81
- end
82
-
83
- #
84
- # Represents the slash command.
85
- #
86
- class ChatInputCommand < Command
87
- # @return [Hash{String => String}] The description of the command.
88
- attr_reader :description
89
- # @return [Hash{String => Hash}] The options of the command.
90
- attr_reader :options
91
-
92
- #
93
- # Initialize a new slash command.
94
- # @private
95
- #
96
- # @param [String, Hash{Symbol => String}] name The name of the command.
97
- # The hash should have `default`, and language keys.
98
- # @param [String, Hash{Symbol => String}] description The description of the command.
99
- # The hash should have `default`, and language keys.
100
- # @param [Hash{String => Hash}] options The options of the command.
101
- # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
102
- # @param [Proc] block The block of the command.
103
- # @param [Integer] type The type of the command.
104
- # @param [Discorb::ApplicationCommand::Command, nil] parent The parent command.
105
- # @param [Boolean] dm_permission Whether the command is enabled in DMs.
106
- # @param [Discorb::Permission] default_permission The default permission of the command.
107
- #
108
- def initialize(name, description, options, guild_ids, block, type, parent, dm_permission, default_permission)
109
- super(name, guild_ids, block, type, dm_permission, default_permission)
110
- @description = if description.is_a?(String)
111
- {
112
- "default" => description,
113
- }
114
- else
115
- ApplicationCommand.modify_localization_hash(description)
116
- end
117
- @options = options
118
- @parent = parent
119
- end
120
-
121
- #
122
- # Returns the commands name.
123
- #
124
- # @return [String] The name of the command.
125
- #
126
- def to_s
127
- "#{@parent} #{@name["default"]}".strip
128
- end
129
-
130
- #
131
- # Converts the object to a hash.
132
- # @private
133
- #
134
- # @return [Hash] The hash represents the object.
135
- #
136
- def to_hash
137
- options_payload = options.map do |name, value|
138
- ret = {
139
- type: case value[:type]
140
- when String, :string, :str
141
- 3
142
- when Integer, :integer, :int
143
- 4
144
- when TrueClass, FalseClass, :boolean, :bool
145
- 5
146
- when Discorb::User, Discorb::Member, :user, :member
147
- 6
148
- when Discorb::Channel, :channel
149
- 7
150
- when Discorb::Role, :role
151
- 8
152
- when :mentionable
153
- 9
154
- when Float, :float
155
- 10
156
- when :attachment
157
- 11
158
- else
159
- raise ArgumentError, "Invalid option type: #{value[:type]}"
160
- end,
161
- name: name,
162
- name_localizations: ApplicationCommand.modify_localization_hash(value[:name_localizations]),
163
- required: value[:required].nil? ? !value[:optional] : value[:required],
164
- }
165
-
166
- if value[:description].is_a?(String)
167
- ret[:description] = value[:description]
168
- else
169
- description = ApplicationCommand.modify_localization_hash(value[:description])
170
- ret[:description] = description["default"]
171
- ret[:description_localizations] = description.except("default")
172
- end
173
- if value[:choices]
174
- ret[:choices] = value[:choices].map do |k, v|
175
- r = {
176
- name: k, value: v,
177
- }
178
- if choices_localizations = value[:choices_localizations].clone
179
- name_localizations = ApplicationCommand.modify_localization_hash(choices_localizations.delete(k) do
180
- warn "Missing localization for #{k}"
181
- {}
182
- end)
183
- r[:name_localizations] = name_localizations.except("default")
184
- r[:name] = name_localizations["default"]
185
- r.delete(:name_localizations) if r[:name_localizations].nil?
186
- end
187
- r
188
- end
189
- end
190
-
191
- ret[:channel_types] = value[:channel_types].map(&:channel_type) if value[:channel_types]
192
-
193
- ret[:autocomplete] = !value[:autocomplete].nil? if value[:autocomplete]
194
- if value[:range]
195
- ret[:min_value] = value[:range].begin
196
- ret[:max_value] = value[:range].end
197
- end
198
- ret
199
- end
200
- {
201
- name: @name["default"],
202
- name_localizations: @name.except("default"),
203
- description: @description["default"],
204
- description_localizations: @description.except("default"),
205
- options: options_payload,
206
- dm_permission: @dm_permission,
207
- default_member_permissions: @default_permission&.value&.to_s,
208
- }
209
- end
210
- end
211
-
212
- #
213
- # Represents the command with subcommands.
214
- #
215
- class GroupCommand < Command
216
- # @return [Array<Discorb::ApplicationCommand::Command>] The subcommands of the command.
217
- attr_reader :commands
218
- # @return [Hash{String => String}] The description of the command.
219
- attr_reader :description
220
-
221
- #
222
- # Initialize a new group command.
223
- # @private
224
- #
225
- # @param [String, Hash{Symbol => String}] name The name of the command.
226
- # @param [String, Hash{Symbol => String}] description The description of the command.
227
- # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
228
- # @param [Discorb::Client] client The client of the command.
229
- # @param [Boolean] dm_permission Whether the command is enabled in DMs.
230
- # @param [Discorb::Permission] default_permission The default permission of the command.
231
- #
232
- def initialize(name, description, guild_ids, client, dm_permission, default_permission)
233
- super(name, guild_ids, block, 1, dm_permission, default_permission)
234
- @description = if description.is_a?(String)
235
- {
236
- "default" => description,
237
- }
238
- else
239
- ApplicationCommand.modify_localization_hash(description)
240
- end
241
- @commands = []
242
- @client = client
243
- end
244
-
245
- #
246
- # Add new subcommand.
247
- #
248
- # @param (see Discorb::ApplicationCommand::Handler#slash)
249
- # @return [Discorb::ApplicationCommand::Command::ChatInputCommand] The added subcommand.
250
- #
251
- def slash(command_name, description, options = {}, dm_permission: true, default_permission: nil, &block)
252
- command = Discorb::ApplicationCommand::Command::ChatInputCommand.new(
253
- command_name,
254
- description,
255
- options,
256
- [],
257
- block,
258
- 1,
259
- self,
260
- dm_permission,
261
- default_permission
262
- )
263
- @client.callable_commands << command
264
- @commands << command
265
- command
266
- end
267
-
268
- #
269
- # Add new subcommand group.
270
- #
271
- # @param [String] command_name Group name.
272
- # @param [String] description Group description.
273
- #
274
- # @yield Block to yield with the command.
275
- # @yieldparam [Discorb::ApplicationCommand::Command::SubcommandGroup] group Group command.
276
- #
277
- # @return [Discorb::ApplicationCommand::Command::SubcommandGroup] Command object.
278
- #
279
- # @see file:docs/application_command.md Application Commands
280
- #
281
- def group(command_name, description)
282
- command = Discorb::ApplicationCommand::Command::SubcommandGroup.new(command_name, description, self, @client)
283
- yield command if block_given?
284
- @commands << command
285
- command
286
- end
287
-
288
- #
289
- # Returns the command name.
290
- #
291
- # @return [String] The command name.
292
- #
293
- def to_s
294
- @name["default"]
295
- end
296
-
297
- #
298
- # Changes the self pointer to the given object.
299
- # @private
300
- #
301
- # @param [Object] instance The object to change to.
302
- #
303
- def block_replace(instance)
304
- super
305
- @commands.each { |c| c.replace_block(instance) }
306
- end
307
-
308
- #
309
- # Converts the object to a hash.
310
- # @private
311
- #
312
- # @return [Hash] The hash represents the object.
313
- #
314
- def to_hash
315
- options_payload = @commands.map do |command|
316
- if command.is_a?(ChatInputCommand)
317
- {
318
- name: command.name["default"],
319
- name_localizations: command.name.except("default"),
320
- description: command.description["default"],
321
- description_localizations: command.description.except("default"),
322
- type: 1,
323
- options: command.to_hash[:options],
324
- }
325
- else
326
- {
327
- name: command.name["default"],
328
- name_localizations: command.name.except("default"),
329
- description: command.description["default"],
330
- description_localizations: command.description.except("default"),
331
- type: 2,
332
- options: command.commands.map do |c|
333
- c.to_hash.merge(type: 1).except(:dm_permission, :default_member_permissions)
334
- end,
335
- }
336
- end
337
- end
338
-
339
- {
340
- name: @name["default"],
341
- name_localizations: @name.except("default"),
342
- description: @description["default"],
343
- description_localizations: @description.except("default"),
344
- dm_permission: @dm_permission,
345
- default_member_permissions: @default_permission&.value&.to_s,
346
- options: options_payload,
347
- }
348
- end
349
- end
350
-
351
- #
352
- # Represents the subcommand group.
353
- #
354
- class SubcommandGroup < GroupCommand
355
- # @return [Array<Discorb::ApplicationCommand::Command::ChatInputCommand>] The subcommands of the command.
356
- attr_reader :commands
357
-
358
- #
359
- # Initialize a new subcommand group.
360
- # @private
361
- #
362
- # @param [String] name The name of the command.
363
- # @param [String] description The description of the command.
364
- # @param [Discorb::ApplicationCommand::Command::GroupCommand] parent The parent command.
365
- # @param [Discorb::Client] client The client.
366
- def initialize(name, description, parent, client)
367
- super(name, description, [], client, nil, nil)
368
-
369
- @commands = []
370
- @parent = parent
371
- end
372
-
373
- def to_s
374
- "#{@parent} #{@name}"
375
- end
376
-
377
- #
378
- # Add new subcommand.
379
- # @param (see Discorb::ApplicationCommand::Handler#slash)
380
- # @return [Discorb::ApplicationCommand::Command::ChatInputCommand] The added subcommand.
381
- #
382
- def slash(command_name, description, options = {}, &block)
383
- command = Discorb::ApplicationCommand::Command::ChatInputCommand.new(
384
- command_name, description, options, [],
385
- block, 1, self, nil, nil
386
- )
387
- @commands << command
388
- @client.callable_commands << command
389
- command
390
- end
391
- end
392
- end
393
- end
394
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ module ApplicationCommand
5
+ #
6
+ # Represents a application command.
7
+ # @abstract
8
+ #
9
+ class Command < DiscordModel
10
+ # @return [Hash{String => String}] The name of the command.
11
+ attr_reader :name
12
+ # @return [Array<#to_s>] The guild ids that the command is enabled in.
13
+ attr_reader :guild_ids
14
+ # @return [Proc] The block of the command.
15
+ attr_reader :block
16
+ # @return [:chat_input, :user, :message] The type of the command.
17
+ attr_reader :type
18
+ # @return [Integer] The raw type of the command.
19
+ attr_reader :type_raw
20
+ # @return [Discorb::Permission] The default permissions for this command.
21
+ attr_reader :default_permission
22
+ # @return [Boolean] Whether the command is enabled in DMs.
23
+ attr_reader :dm_permission
24
+
25
+ # @private
26
+ # @return [{Integer => Symbol}] The mapping of raw types to types.
27
+ TYPES = { 1 => :chat_input, 2 => :user, 3 => :message }.freeze
28
+
29
+ #
30
+ # Initialize a new command.
31
+ # @private
32
+ #
33
+ # @param [String, Hash{Symbol => String}] name The name of the command.
34
+ # @param [Array<#to_s>, false, nil] guild_ids The guild ids that the command is enabled in.
35
+ # @param [Proc] block The block of the command.
36
+ # @param [Integer] type The type of the command.
37
+ # @param [Boolean] dm_permission Whether the command is enabled in DMs.
38
+ # @param [Discorb::Permission] default_permission The default permission of the command.
39
+ #
40
+ def initialize(
41
+ name,
42
+ guild_ids,
43
+ block,
44
+ type,
45
+ dm_permission = true,
46
+ default_permission = nil
47
+ )
48
+ @name =
49
+ (
50
+ if name.is_a?(String)
51
+ { "default" => name }
52
+ else
53
+ ApplicationCommand.modify_localization_hash(name)
54
+ end
55
+ )
56
+ @guild_ids = guild_ids&.map(&:to_s)
57
+ @block = block
58
+ @type = Discorb::ApplicationCommand::Command::TYPES[type]
59
+ @type_raw = type
60
+ @dm_permission = dm_permission
61
+ @default_permission = default_permission
62
+ end
63
+
64
+ #
65
+ # Changes the self pointer of block to the given object.
66
+ # @private
67
+ #
68
+ # @param [Object] instance The object to change the self pointer to.
69
+ #
70
+ def replace_block(instance)
71
+ current_block = @block.dup
72
+ @block = proc { |*args| instance.instance_exec(*args, &current_block) }
73
+ end
74
+
75
+ #
76
+ # Converts the object to a hash.
77
+ # @private
78
+ #
79
+ # @return [Hash] The hash represents the object.
80
+ #
81
+ def to_hash
82
+ {
83
+ name: @name["default"],
84
+ name_localizations: @name.except("default"),
85
+ type: @type_raw,
86
+ dm_permission: @dm_permission,
87
+ default_member_permissions: @default_permission&.value&.to_s
88
+ }
89
+ end
90
+
91
+ #
92
+ # Represents the slash command.
93
+ #
94
+ class ChatInputCommand < Command
95
+ # @return [Hash{String => String}] The description of the command.
96
+ attr_reader :description
97
+ # @return [Hash{String => Hash}] The options of the command.
98
+ attr_reader :options
99
+
100
+ #
101
+ # Initialize a new slash command.
102
+ # @private
103
+ #
104
+ # @param [String, Hash{Symbol => String}] name The name of the command.
105
+ # The hash should have `default`, and language keys.
106
+ # @param [String, Hash{Symbol => String}] description The description of the command.
107
+ # The hash should have `default`, and language keys.
108
+ # @param [Hash{String => Hash}] options The options of the command.
109
+ # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
110
+ # @param [Proc] block The block of the command.
111
+ # @param [Integer] type The type of the command.
112
+ # @param [Discorb::ApplicationCommand::Command, nil] parent The parent command.
113
+ # @param [Boolean] dm_permission Whether the command is enabled in DMs.
114
+ # @param [Discorb::Permission] default_permission The default permission of the command.
115
+ #
116
+ def initialize(
117
+ name,
118
+ description,
119
+ options,
120
+ guild_ids,
121
+ block,
122
+ type,
123
+ parent,
124
+ dm_permission,
125
+ default_permission
126
+ )
127
+ super(name, guild_ids, block, type, dm_permission, default_permission)
128
+ @description =
129
+ if description.is_a?(String)
130
+ { "default" => description }
131
+ else
132
+ ApplicationCommand.modify_localization_hash(description)
133
+ end
134
+ @options = options
135
+ @parent = parent
136
+ end
137
+
138
+ #
139
+ # Returns the commands name.
140
+ #
141
+ # @return [String] The name of the command.
142
+ #
143
+ def to_s
144
+ "#{@parent} #{@name["default"]}".strip
145
+ end
146
+
147
+ #
148
+ # Converts the object to a hash.
149
+ # @private
150
+ #
151
+ # @return [Hash] The hash represents the object.
152
+ #
153
+ def to_hash
154
+ options_payload =
155
+ options.map do |name, value|
156
+ ret = {
157
+ type:
158
+ case value[:type]
159
+ when String, :string, :str
160
+ 3
161
+ when Integer, :integer, :int
162
+ 4
163
+ when TrueClass, FalseClass, :boolean, :bool
164
+ 5
165
+ when Discorb::User, Discorb::Member, :user, :member
166
+ 6
167
+ when Discorb::Channel, :channel
168
+ 7
169
+ when Discorb::Role, :role
170
+ 8
171
+ when :mentionable
172
+ 9
173
+ when Float, :float
174
+ 10
175
+ when :attachment
176
+ 11
177
+ else
178
+ raise ArgumentError, "Invalid option type: #{value[:type]}"
179
+ end,
180
+ name: name,
181
+ name_localizations:
182
+ ApplicationCommand.modify_localization_hash(
183
+ value[:name_localizations]
184
+ ),
185
+ required:
186
+ value[:required].nil? ? !value[:optional] : value[:required]
187
+ }
188
+
189
+ if value[:description].is_a?(String)
190
+ ret[:description] = value[:description]
191
+ else
192
+ description =
193
+ ApplicationCommand.modify_localization_hash(
194
+ value[:description]
195
+ )
196
+ ret[:description] = description["default"]
197
+ ret[:description_localizations] = description.except("default")
198
+ end
199
+ if value[:choices]
200
+ ret[:choices] = value[:choices].map do |k, v|
201
+ r = { name: k, value: v }
202
+ if choices_localizations = value[:choices_localizations].clone
203
+ name_localizations =
204
+ ApplicationCommand.modify_localization_hash(
205
+ choices_localizations.delete(k) do
206
+ warn "Missing localization for #{k}"
207
+ {}
208
+ end
209
+ )
210
+ r[:name_localizations] = name_localizations.except(
211
+ "default"
212
+ )
213
+ r[:name] = name_localizations["default"]
214
+ r.delete(:name_localizations) if r[:name_localizations].nil?
215
+ end
216
+ r
217
+ end
218
+ end
219
+
220
+ ret[:channel_types] = value[:channel_types].map(
221
+ &:channel_type
222
+ ) if value[:channel_types]
223
+
224
+ ret[:autocomplete] = !value[:autocomplete].nil? if value[
225
+ :autocomplete
226
+ ]
227
+ if value[:range]
228
+ ret[:min_value] = value[:range].begin
229
+ ret[:max_value] = value[:range].end
230
+ end
231
+ if value[:length]
232
+ ret[:min_length] = value[:length].begin
233
+ ret[:max_length] = value[:length].end
234
+ end
235
+ ret
236
+ end
237
+ {
238
+ name: @name["default"],
239
+ name_localizations: @name.except("default"),
240
+ description: @description["default"],
241
+ description_localizations: @description.except("default"),
242
+ options: options_payload,
243
+ dm_permission: @dm_permission,
244
+ default_member_permissions: @default_permission&.value&.to_s
245
+ }
246
+ end
247
+ end
248
+
249
+ #
250
+ # Represents the command with subcommands.
251
+ #
252
+ class GroupCommand < Command
253
+ # @return [Array<Discorb::ApplicationCommand::Command>] The subcommands of the command.
254
+ attr_reader :commands
255
+ # @return [Hash{String => String}] The description of the command.
256
+ attr_reader :description
257
+
258
+ #
259
+ # Initialize a new group command.
260
+ # @private
261
+ #
262
+ # @param [String, Hash{Symbol => String}] name The name of the command.
263
+ # @param [String, Hash{Symbol => String}] description The description of the command.
264
+ # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
265
+ # @param [Discorb::Client] client The client of the command.
266
+ # @param [Boolean] dm_permission Whether the command is enabled in DMs.
267
+ # @param [Discorb::Permission] default_permission The default permission of the command.
268
+ #
269
+ def initialize(
270
+ name,
271
+ description,
272
+ guild_ids,
273
+ client,
274
+ dm_permission,
275
+ default_permission
276
+ )
277
+ super(name, guild_ids, block, 1, dm_permission, default_permission)
278
+ @description =
279
+ if description.is_a?(String)
280
+ { "default" => description }
281
+ else
282
+ ApplicationCommand.modify_localization_hash(description)
283
+ end
284
+ @commands = []
285
+ @client = client
286
+ end
287
+
288
+ #
289
+ # Add new subcommand.
290
+ #
291
+ # @param (see Discorb::ApplicationCommand::Handler#slash)
292
+ # @return [Discorb::ApplicationCommand::Command::ChatInputCommand] The added subcommand.
293
+ #
294
+ def slash(
295
+ command_name,
296
+ description,
297
+ options = {},
298
+ dm_permission: true,
299
+ default_permission: nil,
300
+ &block
301
+ )
302
+ command =
303
+ Discorb::ApplicationCommand::Command::ChatInputCommand.new(
304
+ command_name,
305
+ description,
306
+ options,
307
+ [],
308
+ block,
309
+ 1,
310
+ self,
311
+ dm_permission,
312
+ default_permission
313
+ )
314
+ @client.callable_commands << command
315
+ @commands << command
316
+ command
317
+ end
318
+
319
+ #
320
+ # Add new subcommand group.
321
+ #
322
+ # @param [String] command_name Group name.
323
+ # @param [String] description Group description.
324
+ #
325
+ # @yield Block to yield with the command.
326
+ # @yieldparam [Discorb::ApplicationCommand::Command::SubcommandGroup] group Group command.
327
+ #
328
+ # @return [Discorb::ApplicationCommand::Command::SubcommandGroup] Command object.
329
+ #
330
+ # @see file:docs/application_command.md Application Commands
331
+ #
332
+ def group(command_name, description)
333
+ command =
334
+ Discorb::ApplicationCommand::Command::SubcommandGroup.new(
335
+ command_name,
336
+ description,
337
+ self,
338
+ @client
339
+ )
340
+ yield command if block_given?
341
+ @commands << command
342
+ command
343
+ end
344
+
345
+ #
346
+ # Returns the command name.
347
+ #
348
+ # @return [String] The command name.
349
+ #
350
+ def to_s
351
+ @name["default"]
352
+ end
353
+
354
+ #
355
+ # Changes the self pointer to the given object.
356
+ # @private
357
+ #
358
+ # @param [Object] instance The object to change to.
359
+ #
360
+ def block_replace(instance)
361
+ super
362
+ @commands.each { |c| c.replace_block(instance) }
363
+ end
364
+
365
+ #
366
+ # Converts the object to a hash.
367
+ # @private
368
+ #
369
+ # @return [Hash] The hash represents the object.
370
+ #
371
+ def to_hash
372
+ options_payload =
373
+ @commands.map do |command|
374
+ if command.is_a?(ChatInputCommand)
375
+ {
376
+ name: command.name["default"],
377
+ name_localizations: command.name.except("default"),
378
+ description: command.description["default"],
379
+ description_localizations:
380
+ command.description.except("default"),
381
+ type: 1,
382
+ options: command.to_hash[:options]
383
+ }
384
+ else
385
+ {
386
+ name: command.name["default"],
387
+ name_localizations: command.name.except("default"),
388
+ description: command.description["default"],
389
+ description_localizations:
390
+ command.description.except("default"),
391
+ type: 2,
392
+ options:
393
+ command.commands.map do |c|
394
+ c
395
+ .to_hash
396
+ .merge(type: 1)
397
+ .except(:dm_permission, :default_member_permissions)
398
+ end
399
+ }
400
+ end
401
+ end
402
+
403
+ {
404
+ name: @name["default"],
405
+ name_localizations: @name.except("default"),
406
+ description: @description["default"],
407
+ description_localizations: @description.except("default"),
408
+ dm_permission: @dm_permission,
409
+ default_member_permissions: @default_permission&.value&.to_s,
410
+ options: options_payload
411
+ }
412
+ end
413
+ end
414
+
415
+ #
416
+ # Represents the subcommand group.
417
+ #
418
+ class SubcommandGroup < GroupCommand
419
+ # @return [Array<Discorb::ApplicationCommand::Command::ChatInputCommand>] The subcommands of the command.
420
+ attr_reader :commands
421
+
422
+ #
423
+ # Initialize a new subcommand group.
424
+ # @private
425
+ #
426
+ # @param [String] name The name of the command.
427
+ # @param [String] description The description of the command.
428
+ # @param [Discorb::ApplicationCommand::Command::GroupCommand] parent The parent command.
429
+ # @param [Discorb::Client] client The client.
430
+ def initialize(name, description, parent, client)
431
+ super(name, description, [], client, nil, nil)
432
+
433
+ @commands = []
434
+ @parent = parent
435
+ end
436
+
437
+ def to_s
438
+ "#{@parent} #{@name}"
439
+ end
440
+
441
+ #
442
+ # Add new subcommand.
443
+ # @param (see Discorb::ApplicationCommand::Handler#slash)
444
+ # @return [Discorb::ApplicationCommand::Command::ChatInputCommand] The added subcommand.
445
+ #
446
+ def slash(command_name, description, options = {}, &block)
447
+ command =
448
+ Discorb::ApplicationCommand::Command::ChatInputCommand.new(
449
+ command_name,
450
+ description,
451
+ options,
452
+ [],
453
+ block,
454
+ 1,
455
+ self,
456
+ nil,
457
+ nil
458
+ )
459
+ @commands << command
460
+ @client.callable_commands << command
461
+ command
462
+ end
463
+ end
464
+ end
465
+ end
466
+ end