discorb 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/build_main.yml +2 -2
  4. data/.github/workflows/build_version.yml +1 -1
  5. data/.github/workflows/codeql-analysis.yml +1 -1
  6. data/.github/workflows/lint-push.yml +3 -5
  7. data/.github/workflows/lint.yml +1 -1
  8. data/.github/workflows/spec.yml +30 -0
  9. data/.lefthook/commit-msg/validator.rb +5 -0
  10. data/.rspec +2 -0
  11. data/.rspec_parallel +2 -0
  12. data/.rubocop.yml +43 -6
  13. data/Changelog.md +14 -1
  14. data/Gemfile +14 -8
  15. data/Rakefile +41 -26
  16. data/bin/console +3 -3
  17. data/docs/Examples.md +1 -1
  18. data/docs/application_command.md +138 -46
  19. data/docs/cli/irb.md +2 -2
  20. data/docs/cli/new.md +14 -9
  21. data/docs/cli/run.md +7 -11
  22. data/docs/cli.md +17 -10
  23. data/docs/events.md +209 -211
  24. data/docs/extension.md +1 -2
  25. data/docs/faq.md +0 -1
  26. data/docs/tutorial.md +12 -12
  27. data/docs/voice_events.md +106 -106
  28. data/examples/commands/message.rb +63 -0
  29. data/examples/commands/permission.rb +18 -0
  30. data/examples/commands/slash.rb +44 -0
  31. data/examples/commands/user.rb +51 -0
  32. data/examples/components/authorization_button.rb +2 -2
  33. data/examples/components/select_menu.rb +2 -2
  34. data/examples/extension/main.rb +1 -1
  35. data/examples/extension/message_expander.rb +5 -2
  36. data/examples/simple/eval.rb +2 -2
  37. data/examples/simple/ping_pong.rb +1 -1
  38. data/examples/simple/rolepanel.rb +1 -1
  39. data/examples/simple/shard.rb +1 -1
  40. data/examples/simple/wait_for_message.rb +1 -1
  41. data/exe/discorb +31 -16
  42. data/lefthook.yml +45 -0
  43. data/lib/discorb/allowed_mentions.rb +1 -0
  44. data/lib/discorb/app_command/command.rb +127 -65
  45. data/lib/discorb/app_command/common.rb +25 -0
  46. data/lib/discorb/app_command/handler.rb +115 -33
  47. data/lib/discorb/app_command.rb +2 -1
  48. data/lib/discorb/application.rb +1 -0
  49. data/lib/discorb/asset.rb +1 -2
  50. data/lib/discorb/attachment.rb +1 -1
  51. data/lib/discorb/audit_logs.rb +11 -8
  52. data/lib/discorb/channel/base.rb +108 -0
  53. data/lib/discorb/channel/category.rb +32 -0
  54. data/lib/discorb/channel/container.rb +44 -0
  55. data/lib/discorb/channel/dm.rb +28 -0
  56. data/lib/discorb/channel/guild.rb +245 -0
  57. data/lib/discorb/channel/stage.rb +140 -0
  58. data/lib/discorb/channel/text.rb +345 -0
  59. data/lib/discorb/channel/thread.rb +321 -0
  60. data/lib/discorb/channel/voice.rb +79 -0
  61. data/lib/discorb/channel.rb +2 -1165
  62. data/lib/discorb/client.rb +38 -26
  63. data/lib/discorb/common.rb +2 -1
  64. data/lib/discorb/components/button.rb +2 -1
  65. data/lib/discorb/components/select_menu.rb +4 -2
  66. data/lib/discorb/components/text_input.rb +12 -2
  67. data/lib/discorb/components.rb +1 -1
  68. data/lib/discorb/embed.rb +22 -7
  69. data/lib/discorb/emoji.rb +30 -3
  70. data/lib/discorb/emoji_table.rb +4969 -3
  71. data/lib/discorb/event.rb +29 -4
  72. data/lib/discorb/exe/about.rb +1 -0
  73. data/lib/discorb/exe/irb.rb +2 -4
  74. data/lib/discorb/exe/new.rb +90 -23
  75. data/lib/discorb/exe/run.rb +8 -22
  76. data/lib/discorb/exe/setup.rb +25 -12
  77. data/lib/discorb/exe/show.rb +4 -3
  78. data/lib/discorb/extend.rb +1 -0
  79. data/lib/discorb/extension.rb +6 -3
  80. data/lib/discorb/flag.rb +11 -0
  81. data/lib/discorb/gateway.rb +67 -19
  82. data/lib/discorb/guild.rb +188 -56
  83. data/lib/discorb/guild_template.rb +10 -4
  84. data/lib/discorb/http.rb +16 -9
  85. data/lib/discorb/integration.rb +4 -1
  86. data/lib/discorb/intents.rb +1 -1
  87. data/lib/discorb/interaction/autocomplete.rb +28 -16
  88. data/lib/discorb/interaction/command.rb +36 -12
  89. data/lib/discorb/interaction/components.rb +5 -2
  90. data/lib/discorb/interaction/modal.rb +0 -1
  91. data/lib/discorb/interaction/response.rb +61 -22
  92. data/lib/discorb/interaction/root.rb +13 -13
  93. data/lib/discorb/interaction.rb +1 -0
  94. data/lib/discorb/invite.rb +5 -2
  95. data/lib/discorb/member.rb +25 -5
  96. data/lib/discorb/message.rb +47 -14
  97. data/lib/discorb/message_meta.rb +1 -0
  98. data/lib/discorb/modules.rb +56 -14
  99. data/lib/discorb/presence.rb +2 -2
  100. data/lib/discorb/rate_limit.rb +7 -2
  101. data/lib/discorb/reaction.rb +4 -4
  102. data/lib/discorb/role.rb +19 -4
  103. data/lib/discorb/shard.rb +1 -1
  104. data/lib/discorb/sticker.rb +8 -7
  105. data/lib/discorb/user.rb +2 -1
  106. data/lib/discorb/utils/colored_puts.rb +1 -0
  107. data/lib/discorb/voice_state.rb +10 -6
  108. data/lib/discorb/webhook.rb +36 -24
  109. data/lib/discorb.rb +5 -3
  110. data/po/yard.pot +9 -9
  111. data/sig/discorb.rbs +7232 -7235
  112. metadata +21 -5
  113. data/examples/commands/bookmarker.rb +0 -42
  114. data/examples/commands/hello.rb +0 -10
  115. data/examples/commands/inspect.rb +0 -25
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
  require "discorb"
3
3
 
4
+ #
5
+ # Class for expanding message URL.
6
+ #
4
7
  class MessageExpander
5
8
  include Discorb::Extension
6
9
 
7
- @@message_regex = Regexp.new(
10
+ MESSAGE_PATTERN = Regexp.new(
8
11
  '(?!<)https://(?:ptb\.|canary\.)?discord(?:app)?\.com/channels/' \
9
12
  "(?<guild>[0-9]{18})/(?<channel>[0-9]{18})/(?<message>[0-9]{18})(?!>)"
10
13
  )
@@ -12,7 +15,7 @@ class MessageExpander
12
15
  event :message do |message|
13
16
  next if message.author.bot?
14
17
 
15
- message.content.to_enum(:scan, @@message_regex).map { Regexp.last_match }.each do |match|
18
+ message.content.to_enum(:scan, MESSAGE_PATTERN).map { Regexp.last_match }.each do |match|
16
19
  ch = @client.channels[match[:channel]]
17
20
  next if ch.nil?
18
21
 
@@ -25,9 +25,9 @@ client.on :message do |message|
25
25
  res = res.wait if res.is_a? Async::Task
26
26
  message.channel.post("```rb\n#{res.inspect[...1990]}\n```")
27
27
  end
28
- rescue Exception => e
28
+ rescue Exception => e # rubocop:disable Lint/RescueException
29
29
  message.reply embed: Discorb::Embed.new("Error!", "```rb\n#{e.full_message(highlight: false)[...1990]}\n```",
30
30
  color: Discorb::Color[:red])
31
31
  end
32
32
 
33
- client.run(ENV["discord_bot_token"])
33
+ client.run(ENV.fetch("discord_bot_token", nil))
@@ -14,4 +14,4 @@ client.on :message do |message|
14
14
  message.channel.post("Pong!")
15
15
  end
16
16
 
17
- client.run(ENV["DISCORD_BOT_TOKEN"])
17
+ client.run(ENV.fetch("DISCORD_BOT_TOKEN", nil))
@@ -63,4 +63,4 @@ client.on :message do |message|
63
63
  end
64
64
  end
65
65
 
66
- client.run(ENV["DISCORD_BOT_TOKEN"])
66
+ client.run(ENV.fetch("DISCORD_BOT_TOKEN", nil))
@@ -14,4 +14,4 @@ client.on :message do |message|
14
14
  message.channel.post("I'm #{client.user}, running on shard #{client.shard_id}!")
15
15
  end
16
16
 
17
- client.run(ENV["DISCORD_BOT_TOKEN"], shards: [0, 1], shard_count: 2)
17
+ client.run(ENV.fetch("DISCORD_BOT_TOKEN", nil), shards: [0, 1], shard_count: 2)
@@ -28,4 +28,4 @@ client.on :message do |message|
28
28
  end
29
29
  end
30
30
 
31
- client.run(ENV["DISCORD_BOT_TOKEN"])
31
+ client.run(ENV.fetch("DISCORD_BOT_TOKEN", nil))
data/exe/discorb CHANGED
@@ -1,32 +1,47 @@
1
1
  #! /usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- script = ARGV[0]
4
+ require "optparse"
5
5
 
6
- if script.nil?
7
- puts "\e[94mThis is a tool for discorb. Currently these tools are available:\e[m"
8
-
9
- discorb_path = $LOAD_PATH.find { |path| File.directory?(path + "/discorb") }
10
- scripts = {}
6
+ options = {
7
+ bundler: true,
8
+ }
9
+ discorb_paths = $LOAD_PATH.filter { |path| File.directory?(path + "/discorb") }
10
+ scripts = {}
11
+ discorb_paths.each do |discorb_path|
11
12
  Dir.glob(discorb_path + "/discorb/exe/*.rb") do |exe_script|
12
13
  name = File.basename(exe_script, ".rb")
13
14
  description = File.read(exe_script).match(/# description: (.+)/)&.[](1) || "No description"
14
15
  scripts[name] = description
15
16
  end
16
- max_length = scripts.keys.map(&:length).max
17
- scripts.sort.each do |name, description|
18
- puts "\e[90m#{name.rjust(max_length)}\e[m - #{description}"
17
+ end
18
+ max_length = scripts.keys.map(&:length).max
19
+ global = OptionParser.new do |opts|
20
+ opts.banner = "Usage: discorb [options] [subcommand [options]]"
21
+ opts.on("-b", "--[no-]bundler", "Whether to use bundler.") do |v|
22
+ options[:bundler] = v
19
23
  end
24
+ opts.separator ""
25
+ commands = +"Subcommands:\n"
26
+ commands << scripts.sort.map do |name, description|
27
+ " #{name.rjust(max_length)} - #{description}"
28
+ end.join("\n")
29
+ commands << "\n\nYou can run `discorb [subcommand] --help` for more information."
30
+ opts.separator commands
31
+ end
32
+ global.order!(ARGV)
20
33
 
21
- puts "\e[94m\nTo run a tool, type:\e[m\n" \
22
- "\e[34m discorb [script]\e[m"
23
-
24
- exit 1
34
+ if ARGV.empty?
35
+ puts global
36
+ abort
25
37
  end
26
38
 
39
+ require "bundler/setup" if options[:bundler]
40
+
41
+ command = ARGV.shift
42
+
27
43
  begin
28
- require "discorb/exe/#{script}"
44
+ require "discorb/exe/#{command}"
29
45
  rescue LoadError
30
- puts "\e[91mThis tool is not available: \e[90m#{script}\e[m"
31
- exit 1
46
+ warn "Unknown subcommand: #{command}"
32
47
  end
data/lefthook.yml ADDED
@@ -0,0 +1,45 @@
1
+ # EXAMPLE USAGE
2
+ # Refer for explanation to following link:
3
+ # https://github.com/evilmartians/lefthook/blob/master/docs/full_guide.md
4
+ #
5
+ # pre-push:
6
+ # commands:
7
+ # packages-audit:
8
+ # tags: frontend security
9
+ # run: yarn audit
10
+ # gems-audit:
11
+ # tags: backend security
12
+ # run: bundle audit
13
+ #
14
+ # pre-commit:
15
+ # parallel: true
16
+ # commands:
17
+ # eslint:
18
+ # glob: "*.{js,ts}"
19
+ # run: yarn eslint {staged_files}
20
+ # rubocop:
21
+ # tags: backend style
22
+ # glob: "*.rb"
23
+ # exclude: "application.rb|routes.rb"
24
+ # run: bundle exec rubocop --force-exclusion {all_files}
25
+ # govet:
26
+ # tags: backend style
27
+ # files: git ls-files -m
28
+ # glob: "*.go"
29
+ # run: go vet {files}
30
+ # scripts:
31
+ # "hello.js":
32
+ # runner: node
33
+ # "any.go":
34
+ # runner: go run
35
+ pre-commit:
36
+ parallel: true
37
+ commands:
38
+ linting:
39
+ glob: "*.rb"
40
+ run: rubocop {staged_files}
41
+
42
+ commit-msg:
43
+ scripts:
44
+ "validator.rb":
45
+ runner: ruby
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Discorb
3
4
  #
4
5
  # Represents a allowed mentions in a message.
@@ -1,16 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Discorb
4
- #
5
- # Handles application commands.
6
- #
7
4
  module ApplicationCommand
8
5
  #
9
6
  # Represents a application command.
10
7
  # @abstract
11
8
  #
12
9
  class Command < DiscordModel
13
- # @return [String] The name of the command.
10
+ # @return [Hash{Symbol => String}] The name of the command.
14
11
  attr_reader :name
15
12
  # @return [Array<#to_s>] The guild ids that the command is enabled in.
16
13
  attr_reader :guild_ids
@@ -20,8 +17,10 @@ module Discorb
20
17
  attr_reader :type
21
18
  # @return [Integer] The raw type of the command.
22
19
  attr_reader :type_raw
23
- # @return [Discorb::Dictionary{Discorb::Snowflake, :global => Discorb::Snowflake}] The ID mapping.
24
- attr_reader :id_map
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
25
24
 
26
25
  # @private
27
26
  # @return [{Integer => Symbol}] The mapping of raw types to types.
@@ -35,23 +34,25 @@ module Discorb
35
34
  # Initialize a new command.
36
35
  # @private
37
36
  #
38
- # @param [String] name The name of the command.
37
+ # @param [String, Hash{Symbol => String}] name The name of the command.
39
38
  # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
40
39
  # @param [Proc] block The block of the command.
41
40
  # @param [:chat_input, :user, :message] 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.
42
43
  #
43
- def initialize(name, guild_ids, block, type)
44
- @name = name
44
+ def initialize(name, guild_ids, block, type, dm_permission = nil, default_permission = nil)
45
+ @name = name.is_a?(String) ? { "default" => name } : ApplicationCommand.modify_localization_hash(name)
45
46
  @guild_ids = guild_ids&.map(&:to_s)
46
47
  @block = block
47
- @raw_type = type
48
48
  @type = Discorb::ApplicationCommand::Command::TYPES[type]
49
49
  @type_raw = type
50
- @id_map = Discorb::Dictionary.new
50
+ @dm_permission = dm_permission
51
+ @default_permission = default_permission
51
52
  end
52
53
 
53
54
  #
54
- # Changes the self pointer to the given object.
55
+ # Changes the self pointer of block to the given object.
55
56
  # @private
56
57
  #
57
58
  # @param [Object] instance The object to change the self pointer to.
@@ -71,17 +72,19 @@ module Discorb
71
72
  #
72
73
  def to_hash
73
74
  {
74
- name: @name,
75
- default_permission: @default_permission,
75
+ name: @name["default"],
76
+ name_localizations: @name.except("default"),
76
77
  type: @type_raw,
78
+ dm_permission: @dm_permission,
79
+ default_member_permissions: @default_permission&.value&.to_s,
77
80
  }
78
81
  end
79
82
 
80
83
  #
81
84
  # Represents the slash command.
82
85
  #
83
- class SlashCommand < Command
84
- # @return [String] The description of the command.
86
+ class ChatInputCommand < Command
87
+ # @return [Hash{String => String}] The description of the command.
85
88
  attr_reader :description
86
89
  # @return [Hash{String => Hash}] The options of the command.
87
90
  attr_reader :options
@@ -90,21 +93,29 @@ module Discorb
90
93
  # Initialize a new slash command.
91
94
  # @private
92
95
  #
93
- # @param [String] name The name of the command.
94
- # @param [String] description The description of the command.
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.
95
100
  # @param [Hash{String => Hash}] options The options of the command.
96
101
  # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
97
102
  # @param [Proc] block The block of the command.
98
103
  # @param [:chat_input, :user, :message] type The type of the command.
99
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.
100
107
  #
101
- def initialize(name, description, options, guild_ids, block, type, parent)
102
- super(name, guild_ids, block, type)
103
- @description = description
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
104
117
  @options = options
105
- @id = nil
106
118
  @parent = parent
107
- @id_map = Discorb::Dictionary.new
108
119
  end
109
120
 
110
121
  #
@@ -113,7 +124,7 @@ module Discorb
113
124
  # @return [String] The name of the command.
114
125
  #
115
126
  def to_s
116
- (@parent + " " + @name).strip
127
+ "#{@parent} #{@name["default"]}".strip
117
128
  end
118
129
 
119
130
  #
@@ -148,11 +159,34 @@ module Discorb
148
159
  raise ArgumentError, "Invalid option type: #{value[:type]}"
149
160
  end,
150
161
  name: name,
151
- description: value[:description],
162
+ name_localizations: ApplicationCommand.modify_localization_hash(value[:name_localizations]),
152
163
  required: value[:required].nil? ? !value[:optional] : value[:required],
153
164
  }
154
165
 
155
- ret[:choices] = value[:choices].map { |t| { name: t[0], value: t[1] } } if value[:choices]
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
156
190
 
157
191
  ret[:channel_types] = value[:channel_types].map(&:channel_type) if value[:channel_types]
158
192
 
@@ -164,10 +198,13 @@ module Discorb
164
198
  ret
165
199
  end
166
200
  {
167
- name: @name,
168
- default_permission: true,
169
- description: @description,
201
+ name: @name["default"],
202
+ name_localizations: @name.except("default"),
203
+ description: @description["default"],
204
+ description_localizations: @description.except("default"),
170
205
  options: options_payload,
206
+ dm_permission: @dm_permission,
207
+ default_member_permissions: @default_permission&.value&.to_s,
171
208
  }
172
209
  end
173
210
  end
@@ -176,7 +213,10 @@ module Discorb
176
213
  # Represents the command with subcommands.
177
214
  #
178
215
  class GroupCommand < Command
179
- # @return [Array<Discorb::ApplicationCommand::Command::SlashCommand, Discorb::ApplicationCommand::Command::SubcommandGroup>] The subcommands of the command.
216
+ # @return [Array<
217
+ # Discorb::ApplicationCommand::Command::ChatInputCommand,
218
+ # Discorb::ApplicationCommand::Command::SubcommandGroup
219
+ # >] The subcommands of the command.
180
220
  attr_reader :commands
181
221
  # @return [String] The description of the command.
182
222
  attr_reader :description
@@ -185,29 +225,46 @@ module Discorb
185
225
  # Initialize a new group command.
186
226
  # @private
187
227
  #
188
- # @param [String] name The name of the command.
189
- # @param [String] description The description of the command.
228
+ # @param [String, Hash{Symbol => String}] name The name of the command.
229
+ # @param [String, Hash{Symbol => String}] description The description of the command.
190
230
  # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
191
231
  # @param [:chat_input, :user, :message] type The type of the command.
192
232
  # @param [Discorb::Client] client The client of the command.
233
+ # @param [Boolean] dm_permission Whether the command is enabled in DMs.
234
+ # @param [Discorb::Permission] default_permission The default permission of the command.
193
235
  #
194
- def initialize(name, description, guild_ids, type, client)
195
- super(name, guild_ids, block, type)
196
- @description = description
236
+ def initialize(name, description, guild_ids, type, client, dm_permission, default_permission)
237
+ super(name, guild_ids, block, type, dm_permission, default_permission)
238
+ @description = if description.is_a?(String)
239
+ {
240
+ "default" => description,
241
+ }
242
+ else
243
+ ApplicationCommand.modify_localization_hash(description)
244
+ end
197
245
  @commands = []
198
246
  @client = client
199
- @id_map = Discorb::Dictionary.new
200
247
  end
201
248
 
202
249
  #
203
250
  # Add new subcommand.
204
251
  #
205
252
  # @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
253
+ # @return [Discorb::ApplicationCommand::Command::ChatInputCommand] The added subcommand.
254
+ #
255
+ def slash(command_name, description, options = {}, dm_permission: true, default_permission: nil, &block)
256
+ command = Discorb::ApplicationCommand::Command::ChatInputCommand.new(
257
+ command_name,
258
+ description,
259
+ options,
260
+ [],
261
+ block,
262
+ 1,
263
+ self,
264
+ dm_permission,
265
+ default_permission
266
+ )
267
+ @client.callable_commands << command
211
268
  @commands << command
212
269
  command
213
270
  end
@@ -227,7 +284,7 @@ module Discorb
227
284
  #
228
285
  def group(command_name, description, &block)
229
286
  command = Discorb::ApplicationCommand::Command::SubcommandGroup.new(command_name, description, @name, @client)
230
- command.yield_self(&block) if block_given?
287
+ command.then(&block) if block_given?
231
288
  @commands << command
232
289
  command
233
290
  end
@@ -238,7 +295,7 @@ module Discorb
238
295
  # @return [String] The command name.
239
296
  #
240
297
  def to_s
241
- @name
298
+ @name["default"]
242
299
  end
243
300
 
244
301
  #
@@ -260,29 +317,36 @@ module Discorb
260
317
  #
261
318
  def to_hash
262
319
  options_payload = @commands.map do |command|
263
- if command.is_a?(SlashCommand)
320
+ if command.is_a?(ChatInputCommand)
264
321
  {
265
- name: command.name,
266
- description: command.description,
267
- default_permission: true,
322
+ name: command.name["default"],
323
+ name_localizations: command.name.except("default"),
324
+ description: command.description["default"],
325
+ description_localizations: command.description.except("default"),
268
326
  type: 1,
269
327
  options: command.to_hash[:options],
270
328
  }
271
329
  else
272
330
  {
273
- name: command.name,
274
- description: command.description,
275
- default_permission: true,
331
+ name: command.name["default"],
332
+ name_localizations: command.name.except("default"),
333
+ description: command.description["default"],
334
+ description_localizations: command.description.except("default"),
276
335
  type: 2,
277
- options: command.commands.map { |c| c.to_hash.merge(type: 1) },
336
+ options: command.commands.map do |c|
337
+ c.to_hash.merge(type: 1).except(:dm_permission, :default_member_permissions)
338
+ end,
278
339
  }
279
340
  end
280
341
  end
281
342
 
282
343
  {
283
- name: @name,
284
- default_permission: @enabled,
285
- description: @description,
344
+ name: @name["default"],
345
+ name_localizations: @name.except("default"),
346
+ description: @description["default"],
347
+ description_localizations: @description.except("default"),
348
+ dm_permission: @dm_permission,
349
+ default_member_permissions: @default_permission&.value&.to_s,
286
350
  options: options_payload,
287
351
  }
288
352
  end
@@ -292,7 +356,7 @@ module Discorb
292
356
  # Represents the subcommand group.
293
357
  #
294
358
  class SubcommandGroup < GroupCommand
295
- # @return [Array<Discorb::ApplicationCommand::Command::SlashCommand>] The subcommands of the command.
359
+ # @return [Array<Discorb::ApplicationCommand::Command::ChatInputCommand>] The subcommands of the command.
296
360
  attr_reader :commands
297
361
 
298
362
  #
@@ -304,33 +368,31 @@ module Discorb
304
368
  # @param [Discorb::ApplicationCommand::Command::GroupCommand] parent The parent command.
305
369
  # @param [Discorb::Client] client The client.
306
370
  def initialize(name, description, parent, client)
307
- super(name, description, [], 1, client)
371
+ super(name, description, [], 1, client, nil, nil)
308
372
 
309
373
  @commands = []
310
374
  @parent = parent
311
375
  end
312
376
 
313
377
  def to_s
314
- @parent + " " + @name
378
+ "#{@parent} #{@name}"
315
379
  end
316
380
 
317
381
  #
318
382
  # Add new subcommand.
319
383
  # @param (see Discorb::ApplicationCommand::Handler#slash)
320
- # @return [Discorb::ApplicationCommand::Command::SlashCommand] The added subcommand.
384
+ # @return [Discorb::ApplicationCommand::Command::ChatInputCommand] The added subcommand.
321
385
  #
322
386
  def slash(command_name, description, options = {}, &block)
323
- command = Discorb::ApplicationCommand::Command::SlashCommand.new(command_name, description, options, [], block, 1, @parent + " " + @name)
387
+ command = Discorb::ApplicationCommand::Command::ChatInputCommand.new(
388
+ command_name, description, options, [],
389
+ block, 1, self, nil, nil
390
+ )
324
391
  @commands << command
325
- @client.bottom_commands << command
392
+ @client.callable_commands << command
326
393
  command
327
394
  end
328
395
  end
329
-
330
- class << self
331
- # @private
332
- attr_reader :types
333
- end
334
396
  end
335
397
  end
336
398
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Handles application commands.
6
+ #
7
+ module ApplicationCommand
8
+ # @return [Array<String>] List of valid locales.
9
+ VALID_LOCALES = %w[da de en-GB en-US es-ES fr hr it lt hu nl no pl pt-BR ro fi sv-SE vi tr cs el bg ru uk hi th
10
+ zh-CN ja zh-TW ko].freeze
11
+
12
+ module_function
13
+
14
+ def modify_localization_hash(hash)
15
+ hash.to_h do |rkey, value|
16
+ key = rkey.to_s.gsub("_", "-")
17
+ raise ArgumentError, "Invalid locale: #{key}" if VALID_LOCALES.none? do |valid|
18
+ valid.downcase == key.downcase
19
+ end && key != "default"
20
+
21
+ [key == "default" ? "default" : VALID_LOCALES.find { |valid| valid.downcase == key.downcase }, value]
22
+ end
23
+ end
24
+ end
25
+ end