discorb 0.0.8 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog.md +32 -1
- data/Gemfile.lock +1 -1
- data/docs/application_command.md +251 -0
- data/docs/events.md +8 -8
- data/docs/extension.md +39 -0
- data/examples/commands/bookmarker.rb +41 -0
- data/examples/commands/hello.rb +9 -0
- data/examples/commands/inspect.rb +24 -0
- data/examples/components/authorization_button.rb +1 -1
- data/examples/components/select_menu.rb +1 -1
- data/lib/discorb/asset.rb +34 -0
- data/lib/discorb/client.rb +20 -3
- data/lib/discorb/command.rb +393 -0
- data/lib/discorb/common.rb +5 -5
- data/lib/discorb/dictionary.rb +1 -1
- data/lib/discorb/embed.rb +7 -7
- data/lib/discorb/emoji.rb +6 -1
- data/lib/discorb/emoji_table.rb +9 -2
- data/lib/discorb/error.rb +4 -1
- data/lib/discorb/extension.rb +5 -2
- data/lib/discorb/gateway.rb +487 -478
- data/lib/discorb/http.rb +1 -1
- data/lib/discorb/interaction.rb +131 -19
- data/lib/discorb/log.rb +1 -1
- data/lib/discorb/member.rb +10 -1
- data/lib/discorb/user.rb +6 -1
- data/lib/discorb/webhook.rb +12 -1
- data/lib/discorb.rb +7 -7
- metadata +8 -2
@@ -0,0 +1,24 @@
|
|
1
|
+
require "discorb"
|
2
|
+
|
3
|
+
client = Discorb::Client.new
|
4
|
+
|
5
|
+
client.once :ready do
|
6
|
+
puts "Logged in as #{client.user}"
|
7
|
+
end
|
8
|
+
|
9
|
+
client.user_command("Info", guild_ids: [857373681096327180]) do |interaction|
|
10
|
+
interaction.post(embed: Discorb::Embed.new(
|
11
|
+
"Information of #{interaction.target.to_s_user}",
|
12
|
+
fields: [
|
13
|
+
Discorb::Embed::Field.new("User", interaction.target.to_s_user),
|
14
|
+
Discorb::Embed::Field.new("ID", interaction.target.id),
|
15
|
+
Discorb::Embed::Field.new("Bot", interaction.target.bot? ? "Yes" : "No"),
|
16
|
+
Discorb::Embed::Field.new("Joined at", interaction.target.joined_at.to_df("F")),
|
17
|
+
Discorb::Embed::Field.new("Created at", interaction.target.created_at.to_df("F")),
|
18
|
+
],
|
19
|
+
thumbnail: interaction.target.avatar&.url,
|
20
|
+
|
21
|
+
), hide: true)
|
22
|
+
end
|
23
|
+
|
24
|
+
client.run(ENV["DISCORD_BOT_TOKEN"])
|
@@ -36,7 +36,7 @@ client.on :button_click do |response|
|
|
36
36
|
if response.custom_id.start_with?("auth:")
|
37
37
|
id = response.custom_id.delete_prefix("auth:")
|
38
38
|
response.fired_by.add_role(id).wait
|
39
|
-
response.post("You got your role!\nHere's your role: <@&#{id}>",
|
39
|
+
response.post("You got your role!\nHere's your role: <@&#{id}>", ephemeral: true)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
data/lib/discorb/asset.rb
CHANGED
@@ -54,4 +54,38 @@ module Discorb
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Represents a default avatar.
|
60
|
+
#
|
61
|
+
class DefaultAvatar < DiscordModel
|
62
|
+
|
63
|
+
# @!attribute [r] animated?
|
64
|
+
# @return [false] For compatibility with {Asset}, always `false`.
|
65
|
+
|
66
|
+
# @!visibility private
|
67
|
+
def initialize(discriminator)
|
68
|
+
@discriminator = discriminator.to_s.rjust(4, "0")
|
69
|
+
end
|
70
|
+
|
71
|
+
def animated?
|
72
|
+
false
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Returns the URL of the avatar.
|
77
|
+
#
|
78
|
+
# @param [String] image_format The image format. This is compatible with {Asset#url}, will be ignored.
|
79
|
+
# @param [Integer] size The size of the image. This is compatible with {Asset#url}, will be ignored.
|
80
|
+
#
|
81
|
+
# @return [String] URL of the avatar.
|
82
|
+
#
|
83
|
+
def url(image_format: nil, size: 1024)
|
84
|
+
"https://cdn.discordapp.com/embed/avatars/#{@discriminator.to_i % 5}.png"
|
85
|
+
end
|
86
|
+
|
87
|
+
def inspect
|
88
|
+
"#<#{self.class} #{@discriminator}>"
|
89
|
+
end
|
90
|
+
end
|
57
91
|
end
|
data/lib/discorb/client.rb
CHANGED
@@ -41,6 +41,12 @@ module Discorb
|
|
41
41
|
attr_reader :messages
|
42
42
|
# @return [Discorb::Logger] The logger.
|
43
43
|
attr_reader :log
|
44
|
+
# @return [Array<Discorb::Command::Command>] The commands that the client is using.
|
45
|
+
attr_reader :commands
|
46
|
+
# @return [Float] The ping of the client.
|
47
|
+
# @note This will be calculated from heartbeat and heartbeat_ack.
|
48
|
+
# @return [nil] If not connected to the gateway.
|
49
|
+
attr_reader :ping
|
44
50
|
|
45
51
|
#
|
46
52
|
# Initializes a new client.
|
@@ -52,8 +58,13 @@ module Discorb
|
|
52
58
|
# @param [Boolean] colorize_log Whether to colorize the log.
|
53
59
|
# @param [:debug, :info, :warn, :error, :critical] log_level The log level.
|
54
60
|
# @param [Boolean] wait_until_ready Whether to delay event dispatch until ready.
|
61
|
+
# @param [Boolean] overwrite_application_commands Whether to overwrite application commands on ready.
|
55
62
|
#
|
56
|
-
def initialize(
|
63
|
+
def initialize(
|
64
|
+
allowed_mentions: nil, intents: nil, message_caches: 1000,
|
65
|
+
log: nil, colorize_log: false, log_level: :info,
|
66
|
+
wait_until_ready: true, overwrite_application_commands: true
|
67
|
+
)
|
57
68
|
@allowed_mentions = allowed_mentions || AllowedMentions.new(everyone: true, roles: true, users: true)
|
58
69
|
@intents = (intents or Intents.default)
|
59
70
|
@events = {}
|
@@ -72,6 +83,8 @@ module Discorb
|
|
72
83
|
@ready = false
|
73
84
|
@tasks = []
|
74
85
|
@conditions = {}
|
86
|
+
@commands = []
|
87
|
+
@overwrite_application_commands = overwrite_application_commands
|
75
88
|
end
|
76
89
|
|
77
90
|
#
|
@@ -306,7 +319,7 @@ module Discorb
|
|
306
319
|
#
|
307
320
|
# Method to wait for a event.
|
308
321
|
#
|
309
|
-
# @param [Symbol]
|
322
|
+
# @param [Symbol] event The name of the event.
|
310
323
|
# @param [Integer] timeout The timeout in seconds.
|
311
324
|
# @param [Proc] check The check to use.
|
312
325
|
#
|
@@ -347,6 +360,9 @@ module Discorb
|
|
347
360
|
#
|
348
361
|
def extend(mod)
|
349
362
|
if mod.respond_to?(:events)
|
363
|
+
@events.each_value do |event|
|
364
|
+
event.delete_if { |c| c.discriminator[:extension] == mod.name }
|
365
|
+
end
|
350
366
|
mod.events.each do |name, events|
|
351
367
|
@events[name] = [] if @events[name].nil?
|
352
368
|
events.each do |event|
|
@@ -358,6 +374,7 @@ module Discorb
|
|
358
374
|
super(mod)
|
359
375
|
end
|
360
376
|
|
361
|
-
include Discorb::
|
377
|
+
include Discorb::Gateway::Handler
|
378
|
+
include Discorb::Command::Handler
|
362
379
|
end
|
363
380
|
end
|
@@ -0,0 +1,393 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Handles application commands.
|
6
|
+
#
|
7
|
+
module Command
|
8
|
+
#
|
9
|
+
# Module to handle 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
|
+
# | `:optional` | `Boolean` | Whether the option is optional or not. |
|
24
|
+
# | `:type` | `Object` | Type of the option. |
|
25
|
+
# | `:choice` | `Hash{String => String, Integer, Float}` | Type of the option. |
|
26
|
+
#
|
27
|
+
# @param [Array<#to_s>] guild_ids Guild IDs to restrict the command to.
|
28
|
+
# @param [Proc] block Command block.
|
29
|
+
#
|
30
|
+
# @return [Discorb::Command::Command::SlashCommand]
|
31
|
+
#
|
32
|
+
# @see file:docs/application_command.md#register-slash-command
|
33
|
+
#
|
34
|
+
def slash(command_name, description, options = {}, guild_ids: [], &block)
|
35
|
+
command = Discorb::Command::Command::SlashCommand.new(command_name, description, options, guild_ids, block, 1, "")
|
36
|
+
@commands << command
|
37
|
+
command
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Add new command with group.
|
42
|
+
#
|
43
|
+
# @param [String] command_name Command name.
|
44
|
+
# @param [String] description Command description.
|
45
|
+
# @param [Array<#to_s>] guild_ids Guild IDs to restrict the command to.
|
46
|
+
#
|
47
|
+
# @return [Discorb::Command::Command::GroupCommand] Command object.
|
48
|
+
#
|
49
|
+
# @see file:docs/slash_command.md
|
50
|
+
#
|
51
|
+
def slash_group(command_name, description, guild_ids: [])
|
52
|
+
command = Discorb::Command::Command::GroupCommand.new(command_name, description, guild_ids, nil)
|
53
|
+
@commands << command
|
54
|
+
command
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# Add message context menu command.
|
59
|
+
#
|
60
|
+
# @param [String] command_name Command name.
|
61
|
+
# @param [Array<#to_s>] guild_ids Guild IDs to restrict the command to.
|
62
|
+
# @param [Proc] block Command block.
|
63
|
+
# @yield [interaction, message] Block to execute.
|
64
|
+
# @yieldparam [Discorb::CommandInteraction::UserMenuCommand] Interaction object.
|
65
|
+
# @yieldparam [Discorb::Message] user Message object.
|
66
|
+
#
|
67
|
+
# @return [Discorb::Command::Command] Command object.
|
68
|
+
#
|
69
|
+
def message_command(command_name, guild_ids: [], &block)
|
70
|
+
command = Discorb::Command::Command.new(command_name, guild_ids, block, 3)
|
71
|
+
@commands << command
|
72
|
+
command
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Add user context menu command.
|
77
|
+
#
|
78
|
+
# @param [String] command_name Command name.
|
79
|
+
# @param [Array<#to_s>] guild_ids Guild IDs to restrict the command to.
|
80
|
+
# @param [Proc] block Command block.
|
81
|
+
# @yield [interaction, user] Block to execute.
|
82
|
+
# @yieldparam [Discorb::CommandInteraction::UserMenuCommand] Interaction object.
|
83
|
+
# @yieldparam [Discorb::User] user User object.
|
84
|
+
#
|
85
|
+
# @return [Discorb::Command::Command] Command object.
|
86
|
+
#
|
87
|
+
def user_command(command_name, guild_ids: [], &block)
|
88
|
+
command = Discorb::Command::Command.new(command_name, guild_ids, block, 2)
|
89
|
+
@commands << command
|
90
|
+
command
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Setup commands.
|
95
|
+
# @note This method is called automatically if overwrite_application_commands is set to true.
|
96
|
+
# @see Client#initialize
|
97
|
+
#
|
98
|
+
# @param [String] token Bot token.
|
99
|
+
# @note `token` parameter only required if you don't run client.
|
100
|
+
#
|
101
|
+
def setup_commands(token = nil)
|
102
|
+
Async do
|
103
|
+
@token ||= token
|
104
|
+
@http = HTTP.new(self)
|
105
|
+
global_commands = @commands.select { |c| c.guild_ids.empty? }
|
106
|
+
guild_ids = Set[*@commands.map(&:guild_ids).flatten]
|
107
|
+
app_info = fetch_application.wait
|
108
|
+
http.put("/applications/#{app_info.id}/commands", global_commands.map(&:to_hash)).wait unless global_commands.empty?
|
109
|
+
guild_ids.each do |guild_id|
|
110
|
+
commands = @commands.select { |c| c.guild_ids.include?(guild_id) }
|
111
|
+
http.put("/applications/#{app_info.id}/guilds/#{guild_id}/commands", commands.map(&:to_hash)).wait
|
112
|
+
end unless guild_ids.empty?
|
113
|
+
@log.info "Successfully setup commands"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
#
|
119
|
+
# Represents a application command.
|
120
|
+
# @abstract
|
121
|
+
#
|
122
|
+
class Command < DiscordModel
|
123
|
+
# @return [String] The name of the command.
|
124
|
+
attr_reader :name
|
125
|
+
# @return [Array<#to_s>] The guild ids that the command is enabled in.
|
126
|
+
attr_reader :guild_ids
|
127
|
+
# @return [Proc] The block of the command.
|
128
|
+
attr_reader :block
|
129
|
+
# @return [:chat_input, :user, :message] The type of the command.
|
130
|
+
attr_reader :type
|
131
|
+
# @return [Integer] The raw type of the command.
|
132
|
+
attr_reader :type_raw
|
133
|
+
# @return [Discorb::Dictionary{Discorb::Snowflake, :global => Discorb::Snowflake}] The ID mapping.
|
134
|
+
attr_reader :id_map
|
135
|
+
|
136
|
+
@types = {
|
137
|
+
1 => :chat_input,
|
138
|
+
2 => :user,
|
139
|
+
3 => :message,
|
140
|
+
}.freeze
|
141
|
+
|
142
|
+
# @!visibility private
|
143
|
+
def initialize(name, guild_ids, block, type)
|
144
|
+
@name = name
|
145
|
+
@guild_ids = guild_ids.map(&:to_s)
|
146
|
+
@block = block
|
147
|
+
@raw_type = type
|
148
|
+
@type = Discorb::Command::Command.types[type]
|
149
|
+
@type_raw = type
|
150
|
+
@id_map = Discorb::Dictionary.new
|
151
|
+
end
|
152
|
+
|
153
|
+
# @!visibility private
|
154
|
+
def to_hash
|
155
|
+
{
|
156
|
+
name: @name,
|
157
|
+
default_permission: @default_permission,
|
158
|
+
type: @type_raw,
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# Represents the slash command.
|
164
|
+
#
|
165
|
+
class SlashCommand < Command
|
166
|
+
# @return [String] The description of the command.
|
167
|
+
attr_reader :description
|
168
|
+
# @return [Hash{String => Hash}] The options of the command.
|
169
|
+
attr_reader :options
|
170
|
+
|
171
|
+
# @!visibility private
|
172
|
+
def initialize(name, description, options, guild_ids, block, type, parent)
|
173
|
+
@description = description
|
174
|
+
@name = name
|
175
|
+
@guild_ids = guild_ids.map(&:to_s)
|
176
|
+
@block = block
|
177
|
+
@type = Discorb::Command::Command.types[type]
|
178
|
+
@options = options
|
179
|
+
@id = nil
|
180
|
+
@parent = parent
|
181
|
+
@id_map = Discorb::Dictionary.new
|
182
|
+
end
|
183
|
+
|
184
|
+
#
|
185
|
+
# Returns the commands name.
|
186
|
+
#
|
187
|
+
# @return [String] The name of the command.
|
188
|
+
#
|
189
|
+
def to_s
|
190
|
+
(@parent + " " + @name).strip
|
191
|
+
end
|
192
|
+
|
193
|
+
# @!visibility private
|
194
|
+
def to_hash
|
195
|
+
options_payload = options.map do |name, value|
|
196
|
+
ret = {
|
197
|
+
type: case value[:type]
|
198
|
+
when String, :string, :str
|
199
|
+
3
|
200
|
+
when Integer, :integer, :int
|
201
|
+
4
|
202
|
+
when TrueClass, FalseClass, :boolean, :bool
|
203
|
+
5
|
204
|
+
when Discorb::User, Discorb::Member, :user, :member
|
205
|
+
6
|
206
|
+
when Discorb::Channel, :channel
|
207
|
+
7
|
208
|
+
when Discorb::Role, :role
|
209
|
+
8
|
210
|
+
when :mentionable
|
211
|
+
9
|
212
|
+
when Float, :float
|
213
|
+
10
|
214
|
+
else
|
215
|
+
raise ArgumentError, "Invalid option type: #{value[:type]}"
|
216
|
+
end,
|
217
|
+
name: name,
|
218
|
+
description: value[:description],
|
219
|
+
required: !value[:optional],
|
220
|
+
}
|
221
|
+
if value[:choices]
|
222
|
+
ret[:choices] = value[:choices].map { |t| { name: t[0], value: t[1] } }
|
223
|
+
end
|
224
|
+
ret
|
225
|
+
end
|
226
|
+
{
|
227
|
+
name: @name,
|
228
|
+
default_permission: true,
|
229
|
+
description: @description,
|
230
|
+
options: options_payload,
|
231
|
+
}
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
#
|
236
|
+
# Represents the command with subcommands.
|
237
|
+
#
|
238
|
+
class GroupCommand < Command
|
239
|
+
# @return [Array<Discorb::Command::Command::SlashCommand, Discorb::Command::Command::SubcommandGroup>] The subcommands of the command.
|
240
|
+
attr_reader :commands
|
241
|
+
# @return [String] The description of the command.
|
242
|
+
attr_reader :description
|
243
|
+
|
244
|
+
# @!visibility private
|
245
|
+
def initialize(name, description, guild_ids, type)
|
246
|
+
super(name, guild_ids, block, type)
|
247
|
+
@description = description
|
248
|
+
@commands = []
|
249
|
+
@id_map = Discorb::Dictionary.new
|
250
|
+
end
|
251
|
+
|
252
|
+
#
|
253
|
+
# Add new subcommand.
|
254
|
+
#
|
255
|
+
# @param (see Discorb::Command::Handler#slash)
|
256
|
+
# @return [Discorb::Command::Command::SlashCommand] The added subcommand.
|
257
|
+
#
|
258
|
+
def slash(command_name, description, options = {}, &block)
|
259
|
+
command = Discorb::Command::Command::SlashCommand.new(command_name, description, options, [], block, 1, @name)
|
260
|
+
options_payload = options.map do |name, value|
|
261
|
+
ret = {
|
262
|
+
type: case (value[:type].is_a?(Array) ? value[:type].first : value[:type])
|
263
|
+
when String, :string
|
264
|
+
3
|
265
|
+
when Integer
|
266
|
+
4
|
267
|
+
when TrueClass, FalseClass, :boolean
|
268
|
+
5
|
269
|
+
when Discorb::User, Discorb::Member, :user, :member
|
270
|
+
6
|
271
|
+
when Discorb::Channel, :channel
|
272
|
+
7
|
273
|
+
when Discorb::Role, :role
|
274
|
+
8
|
275
|
+
when :mentionable
|
276
|
+
9
|
277
|
+
when Float
|
278
|
+
10
|
279
|
+
end,
|
280
|
+
name: name,
|
281
|
+
description: value[:description],
|
282
|
+
required: !value[:optional],
|
283
|
+
}
|
284
|
+
if value[:type].is_a?(Array)
|
285
|
+
ret[:choices] = value[:type]
|
286
|
+
end
|
287
|
+
|
288
|
+
ret
|
289
|
+
end
|
290
|
+
{
|
291
|
+
name: @name,
|
292
|
+
default_permission: true,
|
293
|
+
description: @description,
|
294
|
+
options: options_payload,
|
295
|
+
}
|
296
|
+
@commands << command
|
297
|
+
command
|
298
|
+
end
|
299
|
+
|
300
|
+
#
|
301
|
+
# Add new subcommand group.
|
302
|
+
#
|
303
|
+
# @param [String] command_name Group name.
|
304
|
+
# @param [String] description Group description.
|
305
|
+
#
|
306
|
+
# @return [Discorb::Command::Command::SubcommandGroup] Command object.
|
307
|
+
#
|
308
|
+
# @see file:docs/slash_command.md
|
309
|
+
#
|
310
|
+
def group(command_name, description)
|
311
|
+
command = Discorb::Command::Command::SubcommandGroup.new(command_name, description, @name)
|
312
|
+
@commands << command
|
313
|
+
command
|
314
|
+
end
|
315
|
+
|
316
|
+
#
|
317
|
+
# Returns the command name.
|
318
|
+
#
|
319
|
+
# @return [String] The command name.
|
320
|
+
#
|
321
|
+
def to_s
|
322
|
+
@name
|
323
|
+
end
|
324
|
+
|
325
|
+
# @!visibility private
|
326
|
+
def to_hash
|
327
|
+
options_payload = @commands.map do |command|
|
328
|
+
if command.is_a?(SlashCommand)
|
329
|
+
{
|
330
|
+
name: command.name,
|
331
|
+
description: command.description,
|
332
|
+
default_permission: command.enabled,
|
333
|
+
type: 1,
|
334
|
+
options: command.to_hash[:options],
|
335
|
+
}
|
336
|
+
else
|
337
|
+
{
|
338
|
+
name: command.name,
|
339
|
+
description: command.description,
|
340
|
+
default_permission: command.enabled,
|
341
|
+
type: 2,
|
342
|
+
options: command.commands.map { |c| c.to_hash.merge(type: 1) },
|
343
|
+
}
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
{
|
348
|
+
name: @name,
|
349
|
+
default_permission: @enabled,
|
350
|
+
description: @description,
|
351
|
+
options: options_payload,
|
352
|
+
}
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
#
|
357
|
+
# Represents the subcommand group.
|
358
|
+
#
|
359
|
+
class SubcommandGroup < GroupCommand
|
360
|
+
# @return [Array<Discorb::Command::Command::SlashCommand>] The subcommands of the command.
|
361
|
+
attr_reader :commands
|
362
|
+
|
363
|
+
# @!visibility private
|
364
|
+
def initialize(name, description, enabled, parent)
|
365
|
+
super(name, description, [], enabled, 1)
|
366
|
+
|
367
|
+
@commands = []
|
368
|
+
@parent = parent
|
369
|
+
end
|
370
|
+
|
371
|
+
def to_s
|
372
|
+
@parent + " " + @name
|
373
|
+
end
|
374
|
+
|
375
|
+
#
|
376
|
+
# Add new subcommand.
|
377
|
+
# @param (see Discorb::Command::Handler#slash)
|
378
|
+
# @return [Discorb::Command::Command::SlashCommand] The added subcommand.
|
379
|
+
#
|
380
|
+
def slash(command_name, description, options = {}, enabled: true, &block)
|
381
|
+
command = Discorb::Command::Command::SlashCommand.new(command_name, description, options, [], enabled, block, 1, @parent + " " + @name)
|
382
|
+
@commands << command
|
383
|
+
command
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
class << self
|
388
|
+
# @!visibility private
|
389
|
+
attr_reader :types
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|