discorb 0.13.4 → 0.15.1

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/build_version.yml +1 -1
  4. data/.github/workflows/codeql-analysis.yml +70 -0
  5. data/.github/workflows/lint-push.yml +20 -0
  6. data/.github/workflows/lint.yml +16 -0
  7. data/.rubocop.yml +74 -0
  8. data/Changelog.md +30 -0
  9. data/Gemfile +7 -3
  10. data/Rakefile +28 -22
  11. data/discorb.gemspec +1 -0
  12. data/docs/events.md +50 -0
  13. data/docs/faq.md +8 -8
  14. data/examples/commands/bookmarker.rb +2 -1
  15. data/examples/commands/hello.rb +1 -0
  16. data/examples/commands/inspect.rb +3 -2
  17. data/examples/components/authorization_button.rb +2 -1
  18. data/examples/components/select_menu.rb +2 -1
  19. data/examples/extension/main.rb +1 -0
  20. data/examples/extension/message_expander.rb +1 -0
  21. data/examples/simple/eval.rb +3 -2
  22. data/examples/simple/ping_pong.rb +1 -0
  23. data/examples/simple/rolepanel.rb +1 -0
  24. data/examples/simple/wait_for_message.rb +4 -3
  25. data/exe/discorb +8 -7
  26. data/lib/discorb/allowed_mentions.rb +71 -0
  27. data/lib/discorb/app_command/command.rb +336 -0
  28. data/lib/discorb/app_command/handler.rb +168 -0
  29. data/lib/discorb/app_command.rb +2 -426
  30. data/lib/discorb/application.rb +16 -7
  31. data/lib/discorb/asset.rb +11 -0
  32. data/lib/discorb/{file.rb → attachment.rb} +55 -33
  33. data/lib/discorb/audit_logs.rb +45 -7
  34. data/lib/discorb/channel.rb +65 -15
  35. data/lib/discorb/client.rb +34 -27
  36. data/lib/discorb/common.rb +19 -27
  37. data/lib/discorb/components/button.rb +105 -0
  38. data/lib/discorb/components/select_menu.rb +143 -0
  39. data/lib/discorb/components/text_input.rb +96 -0
  40. data/lib/discorb/components.rb +11 -276
  41. data/lib/discorb/dictionary.rb +5 -0
  42. data/lib/discorb/embed.rb +73 -40
  43. data/lib/discorb/emoji.rb +48 -5
  44. data/lib/discorb/error.rb +9 -5
  45. data/lib/discorb/event.rb +36 -24
  46. data/lib/discorb/exe/about.rb +1 -0
  47. data/lib/discorb/exe/irb.rb +4 -3
  48. data/lib/discorb/exe/new.rb +6 -7
  49. data/lib/discorb/exe/run.rb +2 -1
  50. data/lib/discorb/exe/setup.rb +8 -5
  51. data/lib/discorb/exe/show.rb +1 -0
  52. data/lib/discorb/extend.rb +19 -14
  53. data/lib/discorb/extension.rb +5 -1
  54. data/lib/discorb/gateway.rb +112 -51
  55. data/lib/discorb/gateway_requests.rb +4 -7
  56. data/lib/discorb/guild.rb +73 -41
  57. data/lib/discorb/guild_template.rb +26 -5
  58. data/lib/discorb/http.rb +38 -18
  59. data/lib/discorb/integration.rb +24 -9
  60. data/lib/discorb/intents.rb +16 -11
  61. data/lib/discorb/interaction/autocomplete.rb +6 -5
  62. data/lib/discorb/interaction/command.rb +66 -12
  63. data/lib/discorb/interaction/components.rb +19 -3
  64. data/lib/discorb/interaction/modal.rb +33 -0
  65. data/lib/discorb/interaction/response.rb +45 -4
  66. data/lib/discorb/interaction/root.rb +16 -0
  67. data/lib/discorb/interaction.rb +2 -1
  68. data/lib/discorb/invite.rb +11 -7
  69. data/lib/discorb/log.rb +5 -5
  70. data/lib/discorb/member.rb +22 -3
  71. data/lib/discorb/message.rb +39 -234
  72. data/lib/discorb/message_meta.rb +186 -0
  73. data/lib/discorb/modules.rb +39 -15
  74. data/lib/discorb/permission.rb +16 -7
  75. data/lib/discorb/presence.rb +45 -9
  76. data/lib/discorb/rate_limit.rb +7 -4
  77. data/lib/discorb/reaction.rb +6 -0
  78. data/lib/discorb/role.rb +12 -0
  79. data/lib/discorb/sticker.rb +22 -14
  80. data/lib/discorb/user.rb +12 -1
  81. data/lib/discorb/utils/colored_puts.rb +1 -0
  82. data/lib/discorb/voice_state.rb +23 -2
  83. data/lib/discorb/webhook.rb +54 -3
  84. data/lib/discorb.rb +5 -2
  85. data/sig/discorb.rbs +838 -702
  86. data/template-replace/scripts/arrow.rb +1 -0
  87. data/template-replace/scripts/favicon.rb +1 -0
  88. data/template-replace/scripts/index.rb +2 -1
  89. data/template-replace/scripts/locale_ja.rb +5 -4
  90. data/template-replace/scripts/sidebar.rb +1 -0
  91. data/template-replace/scripts/version.rb +7 -10
  92. data/template-replace/scripts/yard_replace.rb +5 -4
  93. metadata +17 -3
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+ module Discorb
3
+ #
4
+ # Represents a allowed mentions in a message.
5
+ #
6
+ class AllowedMentions
7
+ # @return [Boolean] Whether to allow @everyone or @here.
8
+ attr_accessor :everyone
9
+ # @return [Boolean, Array<Discorb::Role>] The roles to allow, or false to disable.
10
+ attr_accessor :roles
11
+ # @return [Boolean, Array<Discorb::User>] The users to allow, or false to disable.
12
+ attr_accessor :users
13
+ # @return [Boolean] Whether to ping the user that sent the message to reply.
14
+ attr_accessor :replied_user
15
+
16
+ #
17
+ # Initializes a new instance of the AllowedMentions class.
18
+ #
19
+ # @param [Boolean] everyone Whether to allow @everyone or @here.
20
+ # @param [Boolean, Array<Discorb::Role>] roles The roles to allow, or false to disable.
21
+ # @param [Boolean, Array<Discorb::User>] users The users to allow, or false to disable.
22
+ # @param [Boolean] replied_user Whether to ping the user that sent the message to reply.
23
+ #
24
+ def initialize(everyone: nil, roles: nil, users: nil, replied_user: nil)
25
+ @everyone = everyone
26
+ @roles = roles
27
+ @users = users
28
+ @replied_user = replied_user
29
+ end
30
+
31
+ def inspect
32
+ "#<#{self.class} @everyone=#{@everyone} @roles=#{@roles} @users=#{@users} @replied_user=#{@replied_user}>"
33
+ end
34
+
35
+ #
36
+ # Converts the object to a hash.
37
+ # @private
38
+ #
39
+ # @param [Discorb::AllowedMentions, nil] other The object to merge.
40
+ #
41
+ # @return [Hash] The hash.
42
+ #
43
+ def to_hash(other = nil)
44
+ payload = {
45
+ parse: %w[everyone roles users],
46
+ }
47
+ replied_user = nil_merge(@replied_user, other&.replied_user)
48
+ everyone = nil_merge(@everyone, other&.everyone)
49
+ roles = nil_merge(@roles, other&.roles)
50
+ users = nil_merge(@users, other&.users)
51
+ payload[:replied_user] = replied_user
52
+ payload[:parse].delete("everyone") if everyone == false
53
+ if (roles == false) || roles.is_a?(Array)
54
+ payload[:roles] = roles.map { |u| u.id.to_s } if roles.is_a? Array
55
+ payload[:parse].delete("roles")
56
+ end
57
+ if (users == false) || users.is_a?(Array)
58
+ payload[:users] = users.map { |u| u.id.to_s } if users.is_a? Array
59
+ payload[:parse].delete("users")
60
+ end
61
+ payload
62
+ end
63
+
64
+ def nil_merge(*args)
65
+ args.each do |a|
66
+ return a unless a.nil?
67
+ end
68
+ nil
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,336 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Handles application commands.
6
+ #
7
+ module ApplicationCommand
8
+ #
9
+ # Represents a application command.
10
+ # @abstract
11
+ #
12
+ class Command < DiscordModel
13
+ # @return [String] The name of the command.
14
+ attr_reader :name
15
+ # @return [Array<#to_s>] The guild ids that the command is enabled in.
16
+ attr_reader :guild_ids
17
+ # @return [Proc] The block of the command.
18
+ attr_reader :block
19
+ # @return [:chat_input, :user, :message] The type of the command.
20
+ attr_reader :type
21
+ # @return [Integer] The raw type of the command.
22
+ attr_reader :type_raw
23
+ # @return [Discorb::Dictionary{Discorb::Snowflake, :global => Discorb::Snowflake}] The ID mapping.
24
+ attr_reader :id_map
25
+
26
+ # @private
27
+ # @return [{Integer => Symbol}] The mapping of raw types to types.
28
+ TYPES = {
29
+ 1 => :chat_input,
30
+ 2 => :user,
31
+ 3 => :message,
32
+ }.freeze
33
+
34
+ #
35
+ # Initialize a new command.
36
+ # @private
37
+ #
38
+ # @param [String] name The name of the command.
39
+ # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
40
+ # @param [Proc] block The block of the command.
41
+ # @param [:chat_input, :user, :message] type The type of the command.
42
+ #
43
+ def initialize(name, guild_ids, block, type)
44
+ @name = name
45
+ @guild_ids = guild_ids&.map(&:to_s)
46
+ @block = block
47
+ @raw_type = type
48
+ @type = Discorb::ApplicationCommand::Command::TYPES[type]
49
+ @type_raw = type
50
+ @id_map = Discorb::Dictionary.new
51
+ end
52
+
53
+ #
54
+ # Changes the self pointer to the given object.
55
+ # @private
56
+ #
57
+ # @param [Object] instance The object to change the self pointer to.
58
+ #
59
+ def replace_block(instance)
60
+ current_block = @block.dup
61
+ @block = proc do |*args|
62
+ instance.instance_exec(*args, &current_block)
63
+ end
64
+ end
65
+
66
+ #
67
+ # Converts the object to a hash.
68
+ # @private
69
+ #
70
+ # @return [Hash] The hash represents the object.
71
+ #
72
+ def to_hash
73
+ {
74
+ name: @name,
75
+ default_permission: @default_permission,
76
+ type: @type_raw,
77
+ }
78
+ end
79
+
80
+ #
81
+ # Represents the slash command.
82
+ #
83
+ class SlashCommand < Command
84
+ # @return [String] The description of the command.
85
+ attr_reader :description
86
+ # @return [Hash{String => Hash}] The options of the command.
87
+ attr_reader :options
88
+
89
+ #
90
+ # Initialize a new slash command.
91
+ # @private
92
+ #
93
+ # @param [String] name The name of the command.
94
+ # @param [String] description The description of the command.
95
+ # @param [Hash{String => Hash}] options The options of the command.
96
+ # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
97
+ # @param [Proc] block The block of the command.
98
+ # @param [:chat_input, :user, :message] type The type of the command.
99
+ # @param [Discorb::ApplicationCommand::Command, nil] parent The parent command.
100
+ #
101
+ def initialize(name, description, options, guild_ids, block, type, parent)
102
+ super(name, guild_ids, block, type)
103
+ @description = description
104
+ @options = options
105
+ @id = nil
106
+ @parent = parent
107
+ @id_map = Discorb::Dictionary.new
108
+ end
109
+
110
+ #
111
+ # Returns the commands name.
112
+ #
113
+ # @return [String] The name of the command.
114
+ #
115
+ def to_s
116
+ (@parent + " " + @name).strip
117
+ end
118
+
119
+ #
120
+ # Converts the object to a hash.
121
+ # @private
122
+ #
123
+ # @return [Hash] The hash represents the object.
124
+ #
125
+ def to_hash
126
+ options_payload = options.map do |name, value|
127
+ ret = {
128
+ type: case value[:type]
129
+ when String, :string, :str
130
+ 3
131
+ when Integer, :integer, :int
132
+ 4
133
+ when TrueClass, FalseClass, :boolean, :bool
134
+ 5
135
+ when Discorb::User, Discorb::Member, :user, :member
136
+ 6
137
+ when Discorb::Channel, :channel
138
+ 7
139
+ when Discorb::Role, :role
140
+ 8
141
+ when :mentionable
142
+ 9
143
+ when Float, :float
144
+ 10
145
+ when :attachment
146
+ 11
147
+ else
148
+ raise ArgumentError, "Invalid option type: #{value[:type]}"
149
+ end,
150
+ name: name,
151
+ description: value[:description],
152
+ required: value[:required].nil? ? !value[:optional] : value[:required],
153
+ }
154
+
155
+ ret[:choices] = value[:choices].map { |t| { name: t[0], value: t[1] } } if value[:choices]
156
+
157
+ ret[:channel_types] = value[:channel_types].map(&:channel_type) if value[:channel_types]
158
+
159
+ ret[:autocomplete] = !value[:autocomplete].nil? if value[:autocomplete]
160
+ if value[:range]
161
+ ret[:min_value] = value[:range].begin
162
+ ret[:max_value] = value[:range].end
163
+ end
164
+ ret
165
+ end
166
+ {
167
+ name: @name,
168
+ default_permission: true,
169
+ description: @description,
170
+ options: options_payload,
171
+ }
172
+ end
173
+ end
174
+
175
+ #
176
+ # Represents the command with subcommands.
177
+ #
178
+ class GroupCommand < Command
179
+ # @return [Array<Discorb::ApplicationCommand::Command::SlashCommand, Discorb::ApplicationCommand::Command::SubcommandGroup>] The subcommands of the command.
180
+ attr_reader :commands
181
+ # @return [String] The description of the command.
182
+ attr_reader :description
183
+
184
+ #
185
+ # Initialize a new group command.
186
+ # @private
187
+ #
188
+ # @param [String] name The name of the command.
189
+ # @param [String] description The description of the command.
190
+ # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
191
+ # @param [:chat_input, :user, :message] type The type of the command.
192
+ # @param [Discorb::Client] client The client of the command.
193
+ #
194
+ def initialize(name, description, guild_ids, type, client)
195
+ super(name, guild_ids, block, type)
196
+ @description = description
197
+ @commands = []
198
+ @client = client
199
+ @id_map = Discorb::Dictionary.new
200
+ end
201
+
202
+ #
203
+ # Add new subcommand.
204
+ #
205
+ # @param (see Discorb::ApplicationCommand::Handler#slash)
206
+ # @return [Discorb::ApplicationCommand::Command::SlashCommand] The added subcommand.
207
+ #
208
+ def slash(command_name, description, options = {}, &block)
209
+ command = Discorb::ApplicationCommand::Command::SlashCommand.new(command_name, description, options, [], block, 1, @name)
210
+ @client.bottom_commands << command
211
+ @commands << command
212
+ command
213
+ end
214
+
215
+ #
216
+ # Add new subcommand group.
217
+ #
218
+ # @param [String] command_name Group name.
219
+ # @param [String] description Group description.
220
+ #
221
+ # @yield Block to yield with the command.
222
+ # @yieldparam [Discorb::ApplicationCommand::Command::SubcommandGroup] group Group command.
223
+ #
224
+ # @return [Discorb::ApplicationCommand::Command::SubcommandGroup] Command object.
225
+ #
226
+ # @see file:docs/application_command.md Application Commands
227
+ #
228
+ def group(command_name, description, &block)
229
+ command = Discorb::ApplicationCommand::Command::SubcommandGroup.new(command_name, description, @name, @client)
230
+ command.yield_self(&block) if block_given?
231
+ @commands << command
232
+ command
233
+ end
234
+
235
+ #
236
+ # Returns the command name.
237
+ #
238
+ # @return [String] The command name.
239
+ #
240
+ def to_s
241
+ @name
242
+ end
243
+
244
+ #
245
+ # Changes the self pointer to the given object.
246
+ # @private
247
+ #
248
+ # @param [Object] instance The object to change to.
249
+ #
250
+ def block_replace(instance)
251
+ super
252
+ @commands.each { |c| c.replace_block(instance) }
253
+ end
254
+
255
+ #
256
+ # Converts the object to a hash.
257
+ # @private
258
+ #
259
+ # @return [Hash] The hash represents the object.
260
+ #
261
+ def to_hash
262
+ options_payload = @commands.map do |command|
263
+ if command.is_a?(SlashCommand)
264
+ {
265
+ name: command.name,
266
+ description: command.description,
267
+ default_permission: true,
268
+ type: 1,
269
+ options: command.to_hash[:options],
270
+ }
271
+ else
272
+ {
273
+ name: command.name,
274
+ description: command.description,
275
+ default_permission: true,
276
+ type: 2,
277
+ options: command.commands.map { |c| c.to_hash.merge(type: 1) },
278
+ }
279
+ end
280
+ end
281
+
282
+ {
283
+ name: @name,
284
+ default_permission: @enabled,
285
+ description: @description,
286
+ options: options_payload,
287
+ }
288
+ end
289
+ end
290
+
291
+ #
292
+ # Represents the subcommand group.
293
+ #
294
+ class SubcommandGroup < GroupCommand
295
+ # @return [Array<Discorb::ApplicationCommand::Command::SlashCommand>] The subcommands of the command.
296
+ attr_reader :commands
297
+
298
+ #
299
+ # Initialize a new subcommand group.
300
+ # @private
301
+ #
302
+ # @param [String] name The name of the command.
303
+ # @param [String] description The description of the command.
304
+ # @param [Discorb::ApplicationCommand::Command::GroupCommand] parent The parent command.
305
+ # @param [Discorb::Client] client The client.
306
+ def initialize(name, description, parent, client)
307
+ super(name, description, [], 1, client)
308
+
309
+ @commands = []
310
+ @parent = parent
311
+ end
312
+
313
+ def to_s
314
+ @parent + " " + @name
315
+ end
316
+
317
+ #
318
+ # Add new subcommand.
319
+ # @param (see Discorb::ApplicationCommand::Handler#slash)
320
+ # @return [Discorb::ApplicationCommand::Command::SlashCommand] The added subcommand.
321
+ #
322
+ def slash(command_name, description, options = {}, &block)
323
+ command = Discorb::ApplicationCommand::Command::SlashCommand.new(command_name, description, options, [], block, 1, @parent + " " + @name)
324
+ @commands << command
325
+ @client.bottom_commands << command
326
+ command
327
+ end
328
+ end
329
+
330
+ class << self
331
+ # @private
332
+ attr_reader :types
333
+ end
334
+ end
335
+ end
336
+ end
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Handles application commands.
6
+ #
7
+ module ApplicationCommand
8
+ #
9
+ # Module to handle application commands.
10
+ #
11
+ module Handler
12
+ #
13
+ # Add new top-level command.
14
+ #
15
+ # @param [String] command_name Command name.
16
+ # @param [String] description Command description.
17
+ # @param [Hash{String => Hash{:description => String, :optional => Boolean, :type => Object}}] options Command options.
18
+ # The key is the option name, the value is a hash with the following keys:
19
+ #
20
+ # | Key | Type | Description |
21
+ # | --- | --- | --- |
22
+ # | `:description` | `String` | Description of the option. |
23
+ # | `:required` | Whether the argument is required. `optional` will be used if not specified. |
24
+ # | `:optional` | Whether the argument is optional. `required` will be used if not specified. |
25
+ # | `:type` | `Object` | Type of the option. |
26
+ # | `:choice` | `Hash{String => String, Integer, Float}` | Type of the option. |
27
+ # | `:default` | `Object` | Default value of the option. |
28
+ # | `:channel_types` | `Array<Class<Discorb::Channel>>` | Type of the channel option. |
29
+ # | `:autocomplete` | `Proc` | Autocomplete function. |
30
+ # | `:range` | `Range` | Range of the option. Only valid for numeric options. (`:int`, `:float`) |
31
+ #
32
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
33
+ # @param [Proc] block Command block.
34
+ #
35
+ # @return [Discorb::ApplicationCommand::Command::SlashCommand] Command object.
36
+ #
37
+ # @see file:docs/application_command.md#register-slash-command Application Comamnds: Register Slash Command
38
+ # @see file:docs/cli/setup.md CLI: setup
39
+ #
40
+ def slash(command_name, description, options = {}, guild_ids: nil, &block)
41
+ command = Discorb::ApplicationCommand::Command::SlashCommand.new(command_name, description, options, guild_ids, block, 1, "")
42
+ @commands << command
43
+ @bottom_commands << command
44
+ command
45
+ end
46
+
47
+ #
48
+ # Add new command with group.
49
+ #
50
+ # @param [String] command_name Command name.
51
+ # @param [String] description Command description.
52
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
53
+ #
54
+ # @yield Block to yield with the command.
55
+ # @yieldparam [Discorb::ApplicationCommand::Command::GroupCommand] group Group command.
56
+ #
57
+ # @return [Discorb::ApplicationCommand::Command::GroupCommand] Command object.
58
+ #
59
+ # @see file:docs/application_command.md Application Commands
60
+ # @see file:docs/cli/setup.md CLI: setup
61
+ #
62
+ def slash_group(command_name, description, guild_ids: nil, &block)
63
+ command = Discorb::ApplicationCommand::Command::GroupCommand.new(command_name, description, guild_ids, nil, self)
64
+ command.yield_self(&block) if block_given?
65
+ @commands << command
66
+ command
67
+ end
68
+
69
+ #
70
+ # Add message context menu command.
71
+ #
72
+ # @param [String] command_name Command name.
73
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
74
+ # @param [Proc] block Command block.
75
+ # @yield [interaction, message] Block to execute.
76
+ # @yieldparam [Discorb::CommandInteraction::UserMenuCommand] interaction Interaction object.
77
+ # @yieldparam [Discorb::Message] message Message object.
78
+ #
79
+ # @return [Discorb::ApplicationCommand::Command] Command object.
80
+ #
81
+ def message_command(command_name, guild_ids: nil, &block)
82
+ command = Discorb::ApplicationCommand::Command.new(command_name, guild_ids, block, 3)
83
+ @commands << command
84
+ command
85
+ end
86
+
87
+ #
88
+ # Add user context menu command.
89
+ #
90
+ # @param [String] command_name Command name.
91
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
92
+ # @param [Proc] block Command block.
93
+ # @yield [interaction, user] Block to execute.
94
+ # @yieldparam [Discorb::CommandInteraction::UserMenuCommand] interaction Interaction object.
95
+ # @yieldparam [Discorb::User] user User object.
96
+ #
97
+ # @return [Discorb::ApplicationCommand::Command] Command object.
98
+ #
99
+ def user_command(command_name, guild_ids: nil, &block)
100
+ command = Discorb::ApplicationCommand::Command.new(command_name, guild_ids, block, 2)
101
+ @commands << command
102
+ command
103
+ end
104
+
105
+ #
106
+ # Setup commands.
107
+ # @async
108
+ # @see Client#initialize
109
+ #
110
+ # @param [String] token Bot token.
111
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to use as default. If `false` is given, it will be global command.
112
+ #
113
+ # @note `token` parameter only required if you don't run client.
114
+ #
115
+ def setup_commands(token = nil, guild_ids: nil)
116
+ Async do
117
+ @token ||= token
118
+ @http = HTTP.new(self)
119
+ global_commands = @commands.select { |c| c.guild_ids == false or c.guild_ids == [] }
120
+ local_commands = @commands.select { |c| c.guild_ids.is_a?(Array) and c.guild_ids.any? }
121
+ default_commands = @commands.select { |c| c.guild_ids.nil? }
122
+ if guild_ids.is_a?(Array)
123
+ default_commands.each do |command|
124
+ command.instance_variable_set(:@guild_ids, guild_ids)
125
+ end
126
+ local_commands += default_commands
127
+ else
128
+ global_commands += default_commands
129
+ end
130
+ final_guild_ids = local_commands.map(&:guild_ids).flatten.map(&:to_s).uniq
131
+ app_info = fetch_application.wait
132
+ unless global_commands.empty?
133
+ @http.request(
134
+ Route.new(
135
+ "/applications/#{app_info.id}/commands",
136
+ "//applications/:application_id/commands",
137
+ :put
138
+ ),
139
+ global_commands.map(&:to_hash)
140
+ ).wait
141
+ end
142
+ if ENV["DISCORB_CLI_FLAG"] == "setup"
143
+ sputs "Registered commands for global:"
144
+ global_commands.each do |command|
145
+ iputs "- #{command.name}"
146
+ end
147
+ end
148
+ unless final_guild_ids.empty?
149
+ final_guild_ids.each do |guild_id|
150
+ commands = local_commands.select { |c| c.guild_ids.include?(guild_id) }
151
+ @http.request(
152
+ Route.new("/applications/#{app_info.id}/guilds/#{guild_id}/commands",
153
+ "//applications/:application_id/guilds/:guild_id/commands",
154
+ :put),
155
+ commands.map(&:to_hash)
156
+ ).wait
157
+ sputs "Registered commands for #{guild_id}:"
158
+ commands.each do |command|
159
+ iputs "- #{command.name}"
160
+ end
161
+ end
162
+ end
163
+ @log.info "Successfully setup commands"
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end