discorb 0.16.0 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitattributes +1 -0
- data/.github/workflows/build_main.yml +2 -2
- data/.github/workflows/build_version.yml +1 -1
- data/.github/workflows/codeql-analysis.yml +1 -1
- data/.github/workflows/lint-push.yml +3 -5
- data/.github/workflows/lint.yml +1 -1
- data/.github/workflows/spec.yml +30 -0
- data/.lefthook/commit-msg/validator.rb +5 -0
- data/.rspec +2 -0
- data/.rspec_parallel +2 -0
- data/.rubocop.yml +43 -6
- data/Changelog.md +14 -1
- data/Gemfile +14 -8
- data/Rakefile +41 -26
- data/bin/console +3 -3
- data/docs/Examples.md +1 -1
- data/docs/application_command.md +138 -46
- data/docs/cli/irb.md +2 -2
- data/docs/cli/new.md +14 -9
- data/docs/cli/run.md +7 -11
- data/docs/cli.md +17 -10
- data/docs/events.md +209 -211
- data/docs/extension.md +1 -2
- data/docs/faq.md +0 -1
- data/docs/tutorial.md +12 -12
- data/docs/voice_events.md +106 -106
- data/examples/commands/message.rb +63 -0
- data/examples/commands/permission.rb +18 -0
- data/examples/commands/slash.rb +44 -0
- data/examples/commands/user.rb +51 -0
- data/examples/components/authorization_button.rb +2 -2
- data/examples/components/select_menu.rb +2 -2
- data/examples/extension/main.rb +1 -1
- data/examples/extension/message_expander.rb +5 -2
- data/examples/simple/eval.rb +2 -2
- data/examples/simple/ping_pong.rb +1 -1
- data/examples/simple/rolepanel.rb +1 -1
- data/examples/simple/shard.rb +1 -1
- data/examples/simple/wait_for_message.rb +1 -1
- data/exe/discorb +31 -16
- data/lefthook.yml +45 -0
- data/lib/discorb/allowed_mentions.rb +1 -0
- data/lib/discorb/app_command/command.rb +127 -65
- data/lib/discorb/app_command/common.rb +25 -0
- data/lib/discorb/app_command/handler.rb +115 -33
- data/lib/discorb/app_command.rb +2 -1
- data/lib/discorb/application.rb +1 -0
- data/lib/discorb/asset.rb +1 -2
- data/lib/discorb/attachment.rb +1 -1
- data/lib/discorb/audit_logs.rb +11 -8
- data/lib/discorb/channel/base.rb +108 -0
- data/lib/discorb/channel/category.rb +32 -0
- data/lib/discorb/channel/container.rb +44 -0
- data/lib/discorb/channel/dm.rb +28 -0
- data/lib/discorb/channel/guild.rb +245 -0
- data/lib/discorb/channel/stage.rb +140 -0
- data/lib/discorb/channel/text.rb +345 -0
- data/lib/discorb/channel/thread.rb +321 -0
- data/lib/discorb/channel/voice.rb +79 -0
- data/lib/discorb/channel.rb +2 -1165
- data/lib/discorb/client.rb +38 -26
- data/lib/discorb/common.rb +2 -1
- data/lib/discorb/components/button.rb +2 -1
- data/lib/discorb/components/select_menu.rb +4 -2
- data/lib/discorb/components/text_input.rb +12 -2
- data/lib/discorb/components.rb +1 -1
- data/lib/discorb/embed.rb +22 -7
- data/lib/discorb/emoji.rb +30 -3
- data/lib/discorb/emoji_table.rb +4969 -3
- data/lib/discorb/event.rb +29 -4
- data/lib/discorb/exe/about.rb +1 -0
- data/lib/discorb/exe/irb.rb +2 -4
- data/lib/discorb/exe/new.rb +90 -23
- data/lib/discorb/exe/run.rb +8 -22
- data/lib/discorb/exe/setup.rb +25 -12
- data/lib/discorb/exe/show.rb +4 -3
- data/lib/discorb/extend.rb +1 -0
- data/lib/discorb/extension.rb +6 -3
- data/lib/discorb/flag.rb +11 -0
- data/lib/discorb/gateway.rb +67 -19
- data/lib/discorb/guild.rb +188 -56
- data/lib/discorb/guild_template.rb +10 -4
- data/lib/discorb/http.rb +16 -9
- data/lib/discorb/integration.rb +4 -1
- data/lib/discorb/intents.rb +1 -1
- data/lib/discorb/interaction/autocomplete.rb +28 -16
- data/lib/discorb/interaction/command.rb +36 -12
- data/lib/discorb/interaction/components.rb +5 -2
- data/lib/discorb/interaction/modal.rb +0 -1
- data/lib/discorb/interaction/response.rb +61 -22
- data/lib/discorb/interaction/root.rb +13 -13
- data/lib/discorb/interaction.rb +1 -0
- data/lib/discorb/invite.rb +5 -2
- data/lib/discorb/member.rb +25 -5
- data/lib/discorb/message.rb +47 -14
- data/lib/discorb/message_meta.rb +1 -0
- data/lib/discorb/modules.rb +56 -14
- data/lib/discorb/presence.rb +2 -2
- data/lib/discorb/rate_limit.rb +7 -2
- data/lib/discorb/reaction.rb +4 -4
- data/lib/discorb/role.rb +19 -4
- data/lib/discorb/shard.rb +1 -1
- data/lib/discorb/sticker.rb +8 -7
- data/lib/discorb/user.rb +2 -1
- data/lib/discorb/utils/colored_puts.rb +1 -0
- data/lib/discorb/voice_state.rb +10 -6
- data/lib/discorb/webhook.rb +36 -24
- data/lib/discorb.rb +5 -3
- data/po/yard.pot +9 -9
- data/sig/discorb.rbs +7232 -7235
- metadata +21 -5
- data/examples/commands/bookmarker.rb +0 -42
- data/examples/commands/hello.rb +0 -10
- data/examples/commands/inspect.rb +0 -25
data/lib/discorb/client.rb
CHANGED
@@ -54,7 +54,7 @@ module Discorb
|
|
54
54
|
attr_reader :shards
|
55
55
|
# @private
|
56
56
|
# @return [Hash{Discorb::Snowflake => Discorb::ApplicationCommand::Command}] The commands on the top level.
|
57
|
-
attr_reader :
|
57
|
+
attr_reader :callable_commands
|
58
58
|
# @private
|
59
59
|
# @return [{String => Thread::Mutex}] A hash of mutexes.
|
60
60
|
attr_reader :mutex
|
@@ -81,7 +81,8 @@ module Discorb
|
|
81
81
|
# @param [:debug, :info, :warn, :error, :critical] log_level The log level.
|
82
82
|
# @param [Boolean] wait_until_ready Whether to delay event dispatch until ready.
|
83
83
|
# @param [Boolean] fetch_member Whether to fetch member on ready. This may slow down the client. Default to `false`.
|
84
|
-
# @param [String] title
|
84
|
+
# @param [String] title
|
85
|
+
# The title of the process. `false` to default of ruby, `nil` to `discorb: User#0000`. Default to `nil`.
|
85
86
|
#
|
86
87
|
def initialize(
|
87
88
|
allowed_mentions: nil, intents: nil, message_caches: 1000,
|
@@ -93,7 +94,11 @@ module Discorb
|
|
93
94
|
@intents = (intents or Intents.default)
|
94
95
|
@events = {}
|
95
96
|
@api_version = nil
|
96
|
-
@logger = logger || Logger.new(
|
97
|
+
@logger = logger || Logger.new(
|
98
|
+
$stdout,
|
99
|
+
progname: "discorb",
|
100
|
+
level: Logger::ERROR,
|
101
|
+
)
|
97
102
|
@user = nil
|
98
103
|
@users = Discorb::Dictionary.new
|
99
104
|
@channels = Discorb::Dictionary.new
|
@@ -108,7 +113,7 @@ module Discorb
|
|
108
113
|
@tasks = []
|
109
114
|
@conditions = {}
|
110
115
|
@commands = []
|
111
|
-
@
|
116
|
+
@callable_commands = []
|
112
117
|
@status = :initialized
|
113
118
|
@fetch_member = fetch_member
|
114
119
|
@title = title
|
@@ -206,7 +211,11 @@ module Discorb
|
|
206
211
|
block.call(*args)
|
207
212
|
logger.debug "Dispatched proc with ID #{block.id.inspect}"
|
208
213
|
rescue StandardError, ScriptError => e
|
209
|
-
|
214
|
+
if event_name == :error
|
215
|
+
raise e
|
216
|
+
else
|
217
|
+
dispatch(:error, event_name, args, e)
|
218
|
+
end
|
210
219
|
end
|
211
220
|
end
|
212
221
|
end
|
@@ -276,7 +285,13 @@ module Discorb
|
|
276
285
|
#
|
277
286
|
def fetch_invite(code, with_count: true, with_expiration: true)
|
278
287
|
Async do
|
279
|
-
_resp, data = @http.request(
|
288
|
+
_resp, data = @http.request(
|
289
|
+
Route.new(
|
290
|
+
"/invites/#{code}?with_count=#{with_count}&with_expiration=#{with_expiration}",
|
291
|
+
"//invites/:code",
|
292
|
+
:get
|
293
|
+
)
|
294
|
+
).wait
|
280
295
|
Invite.new(self, data, false)
|
281
296
|
end
|
282
297
|
end
|
@@ -387,6 +402,7 @@ module Discorb
|
|
387
402
|
case ext
|
388
403
|
when Class
|
389
404
|
raise ArgumentError, "#{ext} is not a extension" unless ext < Discorb::Extension
|
405
|
+
|
390
406
|
ins = ext.new(self, ...)
|
391
407
|
when Discorb::Extension
|
392
408
|
ins = ext
|
@@ -415,13 +431,13 @@ module Discorb
|
|
415
431
|
|
416
432
|
cls = ins.class
|
417
433
|
cls.loaded(self, ...) if cls.respond_to? :loaded
|
418
|
-
ins.class.
|
434
|
+
ins.class.callable_commands.each do |cmd|
|
419
435
|
unless cmd.respond_to? :self_replaced
|
420
436
|
cmd.define_singleton_method(:extension) { ins.class.name }
|
421
437
|
cmd.replace_block(ins)
|
422
438
|
cmd.block.define_singleton_method(:self_replaced) { true }
|
423
439
|
end
|
424
|
-
@
|
440
|
+
@callable_commands << cmd
|
425
441
|
end
|
426
442
|
@extensions[ins.class.name] = ins
|
427
443
|
ins
|
@@ -440,9 +456,10 @@ module Discorb
|
|
440
456
|
# @note If the token is nil, you should use `discorb run` with the `-e` or `--env` option.
|
441
457
|
#
|
442
458
|
def run(token = nil, shards: nil, shard_count: nil)
|
443
|
-
token ||= ENV
|
459
|
+
token ||= ENV.fetch("DISCORB_CLI_TOKEN", nil)
|
444
460
|
raise ArgumentError, "Token is not specified, and -e/--env is not specified" if token.nil?
|
445
|
-
|
461
|
+
|
462
|
+
case ENV.fetch("DISCORB_CLI_FLAG", nil)
|
446
463
|
when nil
|
447
464
|
start_client(token, shards: shards, shard_count: shard_count)
|
448
465
|
when "run"
|
@@ -490,18 +507,19 @@ module Discorb
|
|
490
507
|
|
491
508
|
def before_run(token)
|
492
509
|
require "json"
|
493
|
-
options = JSON.parse(ENV
|
510
|
+
options = JSON.parse(ENV.fetch("DISCORB_CLI_OPTIONS", nil), symbolize_names: true)
|
494
511
|
setup_commands(token) if options[:setup]
|
495
512
|
end
|
496
513
|
|
497
514
|
def run_setup(token)
|
498
515
|
guild_ids = "global"
|
499
|
-
if guilds = ENV
|
516
|
+
if guilds = ENV.fetch("DISCORB_SETUP_GUILDS", nil)
|
500
517
|
guild_ids = guilds.split(",")
|
501
518
|
end
|
502
519
|
guild_ids = false if guild_ids == ["global"]
|
503
520
|
setup_commands(token, guild_ids: guild_ids).wait
|
504
|
-
|
521
|
+
clear_commands(token, ENV.fetch("DISCORB_SETUP_CLEAR_GUILDS", "").split(","))
|
522
|
+
if ENV.fetch("DISCORB_SETUP_SCRIPT", nil) == "true"
|
505
523
|
@events[:setup]&.each do |event|
|
506
524
|
event.call
|
507
525
|
end
|
@@ -563,17 +581,11 @@ module Discorb
|
|
563
581
|
end
|
564
582
|
|
565
583
|
def main_loop(shard)
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
set_status(:running, shard)
|
572
|
-
close_condition.signal
|
573
|
-
raise
|
574
|
-
end
|
575
|
-
close_condition.wait
|
576
|
-
main_task.stop
|
584
|
+
set_status(:running, shard)
|
585
|
+
connect_gateway(false).wait
|
586
|
+
rescue StandardError
|
587
|
+
set_status(:closed, shard)
|
588
|
+
raise
|
577
589
|
end
|
578
590
|
|
579
591
|
def main_task
|
@@ -595,13 +607,13 @@ module Discorb
|
|
595
607
|
def set_default_events
|
596
608
|
on :error, override: true do |event_name, _args, e|
|
597
609
|
message = "An error occurred while dispatching #{event_name}:\n#{e.full_message}"
|
598
|
-
logger.error message
|
610
|
+
logger.error message
|
599
611
|
end
|
600
612
|
|
601
613
|
once :standby do
|
602
614
|
next if @title == false
|
603
615
|
|
604
|
-
title = @title || ENV
|
616
|
+
title = @title || ENV.fetch("DISCORB_CLI_TITLE", nil) || "discorb: #{@user}"
|
605
617
|
Process.setproctitle title
|
606
618
|
end
|
607
619
|
end
|
data/lib/discorb/common.rb
CHANGED
@@ -4,7 +4,7 @@ module Discorb
|
|
4
4
|
# @return [String] The API base URL.
|
5
5
|
API_BASE_URL = "https://discord.com/api/v10"
|
6
6
|
# @return [String] The version of discorb.
|
7
|
-
VERSION = "0.
|
7
|
+
VERSION = "0.17.0"
|
8
8
|
# @return [Array<Integer>] The version array of discorb.
|
9
9
|
VERSION_ARRAY = VERSION.split(".").map(&:to_i).freeze
|
10
10
|
# @return [String] The user agent for the bot.
|
@@ -152,6 +152,7 @@ module Discorb
|
|
152
152
|
def major_param
|
153
153
|
param_type = @key.split("/").find { |k| k.start_with?(":") }
|
154
154
|
return "" unless param_type
|
155
|
+
|
155
156
|
param = url.gsub(API_BASE_URL, "").split("/")[@key.split("/").index(param_type) - 1]
|
156
157
|
%w[:channel_id :guild_id :webhook_id].include?(param_type) ? param : ""
|
157
158
|
end
|
@@ -53,7 +53,8 @@ module Discorb
|
|
53
53
|
#
|
54
54
|
# Converts the button to a hash.
|
55
55
|
#
|
56
|
-
# @see https://discord.com/developers/docs/interactions/message-components#button-object-button-structure
|
56
|
+
# @see https://discord.com/developers/docs/interactions/message-components#button-object-button-structure
|
57
|
+
# Official Discord API docs
|
57
58
|
# @return [Hash] A hash representation of the button.
|
58
59
|
#
|
59
60
|
def to_hash
|
@@ -37,7 +37,8 @@ module Discorb
|
|
37
37
|
#
|
38
38
|
# Converts the select menu to a hash.
|
39
39
|
#
|
40
|
-
# @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure
|
40
|
+
# @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure
|
41
|
+
# Official Discord API docs
|
41
42
|
# @return [Hash] A hash representation of the select menu.
|
42
43
|
#
|
43
44
|
def to_hash
|
@@ -109,7 +110,8 @@ module Discorb
|
|
109
110
|
#
|
110
111
|
# Converts the option to a hash.
|
111
112
|
#
|
112
|
-
# @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-option-structure
|
113
|
+
# @see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-option-structure
|
114
|
+
# Official Discord API docs
|
113
115
|
# @return [Hash] Hash representation of the option.
|
114
116
|
#
|
115
117
|
def to_hash
|
@@ -40,7 +40,16 @@ module Discorb
|
|
40
40
|
# @param [String, nil] value The prefilled value of the text input.
|
41
41
|
# @param [String, nil] placeholder The placeholder of the text input.
|
42
42
|
#
|
43
|
-
def initialize(
|
43
|
+
def initialize(
|
44
|
+
label,
|
45
|
+
custom_id,
|
46
|
+
style,
|
47
|
+
min_length: nil,
|
48
|
+
max_length: nil,
|
49
|
+
required: false,
|
50
|
+
value: nil,
|
51
|
+
placeholder: nil
|
52
|
+
)
|
44
53
|
@label = label
|
45
54
|
@custom_id = custom_id
|
46
55
|
@style = style
|
@@ -54,7 +63,8 @@ module Discorb
|
|
54
63
|
#
|
55
64
|
# Converts the select menu to a hash.
|
56
65
|
#
|
57
|
-
# @see https://discord.com/developers/docs/interactions/message-components#text-inputs-text-input-structure
|
66
|
+
# @see https://discord.com/developers/docs/interactions/message-components#text-inputs-text-input-structure
|
67
|
+
# Official Discord API docs
|
58
68
|
# @return [Hash] A hash representation of the text input.
|
59
69
|
#
|
60
70
|
def to_hash
|
data/lib/discorb/components.rb
CHANGED
data/lib/discorb/embed.rb
CHANGED
@@ -44,8 +44,18 @@ module Discorb
|
|
44
44
|
# @param [Discorb::Embed::Image, String] image The image of embed.
|
45
45
|
# @param [Discorb::Embed::Thumbnail, String] thumbnail The thumbnail of embed.
|
46
46
|
#
|
47
|
-
def initialize(
|
48
|
-
|
47
|
+
def initialize(
|
48
|
+
title = nil,
|
49
|
+
description = nil,
|
50
|
+
color: nil,
|
51
|
+
url: nil,
|
52
|
+
timestamp: nil,
|
53
|
+
author: nil,
|
54
|
+
fields: nil,
|
55
|
+
footer: nil,
|
56
|
+
image: nil,
|
57
|
+
thumbnail: nil
|
58
|
+
)
|
49
59
|
@title = title
|
50
60
|
@description = description
|
51
61
|
@url = url
|
@@ -161,7 +171,8 @@ module Discorb
|
|
161
171
|
#
|
162
172
|
# Convert author to hash.
|
163
173
|
#
|
164
|
-
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure
|
174
|
+
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure
|
175
|
+
# Offical Discord API Docs
|
165
176
|
# @return [Hash] Converted author.
|
166
177
|
#
|
167
178
|
def to_hash
|
@@ -193,7 +204,8 @@ module Discorb
|
|
193
204
|
#
|
194
205
|
# Convert footer to hash.
|
195
206
|
#
|
196
|
-
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure
|
207
|
+
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure
|
208
|
+
# Offical Discord API Docs
|
197
209
|
# @return [Hash] Converted footer.
|
198
210
|
#
|
199
211
|
def to_hash
|
@@ -231,7 +243,8 @@ module Discorb
|
|
231
243
|
#
|
232
244
|
# Convert field to hash.
|
233
245
|
#
|
234
|
-
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure
|
246
|
+
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure
|
247
|
+
# Offical Discord API Docs
|
235
248
|
# @return [Hash] Converted field.
|
236
249
|
#
|
237
250
|
def to_hash
|
@@ -279,7 +292,8 @@ module Discorb
|
|
279
292
|
#
|
280
293
|
# Convert image to hash for sending.
|
281
294
|
#
|
282
|
-
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure
|
295
|
+
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure
|
296
|
+
# Offical Discord API Docs
|
283
297
|
# @return [Hash] Converted image.
|
284
298
|
#
|
285
299
|
def to_hash
|
@@ -323,7 +337,8 @@ module Discorb
|
|
323
337
|
#
|
324
338
|
# Convert thumbnail to hash for sending.
|
325
339
|
#
|
326
|
-
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure
|
340
|
+
# @see https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure
|
341
|
+
# Offical Discord API Docs
|
327
342
|
# @return [Hash] Converted thumbnail.
|
328
343
|
#
|
329
344
|
def to_hash
|
data/lib/discorb/emoji.rb
CHANGED
@@ -103,7 +103,10 @@ module Discorb
|
|
103
103
|
payload = {}
|
104
104
|
payload[:name] = name if name != Discorb::Unset
|
105
105
|
payload[:roles] = roles.map { |r| Discorb::Utils.try(r, :id) } if roles != Discorb::Unset
|
106
|
-
@client.http.request(
|
106
|
+
@client.http.request(
|
107
|
+
Route.new("/guilds/#{@guild.id}/emojis/#{@id}", "//guilds/:guild_id/emojis/:emoji_id",
|
108
|
+
:patch), payload, audit_log_reason: reason,
|
109
|
+
)
|
107
110
|
self
|
108
111
|
end
|
109
112
|
end
|
@@ -120,7 +123,10 @@ module Discorb
|
|
120
123
|
#
|
121
124
|
def delete!(reason: nil)
|
122
125
|
Async do
|
123
|
-
@client.http.request(
|
126
|
+
@client.http.request(
|
127
|
+
Route.new("/guilds/#{@guild.id}/emojis/#{@id}", "//guilds/:guild_id/emojis/:emoji_id",
|
128
|
+
:delete), {}, audit_log_reason: reason,
|
129
|
+
).wait
|
124
130
|
@available = false
|
125
131
|
self
|
126
132
|
end
|
@@ -230,10 +236,31 @@ module Discorb
|
|
230
236
|
elsif EmojiTable::UNICODE_TO_DISCORD.key?(name)
|
231
237
|
@name = EmojiTable::UNICODE_TO_DISCORD[name][0]
|
232
238
|
@value = name
|
239
|
+
elsif EmojiTable::SKIN_TONES.any? { |t| name.include?(t) }
|
240
|
+
name2 = name.dup
|
241
|
+
EmojiTable::SKIN_TONES.each.with_index do |t, i|
|
242
|
+
next unless name2.include?(t)
|
243
|
+
|
244
|
+
@skin_tone = i
|
245
|
+
name2.sub!(t, "")
|
246
|
+
break
|
247
|
+
end
|
248
|
+
raise ArgumentError, "Invalid skin tone: #{tone}" unless @skin_tone
|
249
|
+
|
250
|
+
@name = EmojiTable::UNICODE_TO_DISCORD[name2]
|
251
|
+
@value = name
|
233
252
|
else
|
234
253
|
raise ArgumentError, "No such emoji: #{name}"
|
235
254
|
end
|
236
|
-
|
255
|
+
if tone.positive?
|
256
|
+
unless @value = EmojiTable::DISCORD_TO_UNICODE["#{name}_tone#{tone}"]
|
257
|
+
raise ArgumentError,
|
258
|
+
"Invalid skin tone for emoji: #{name}"
|
259
|
+
end
|
260
|
+
|
261
|
+
@name = "#{name}_tone#{tone}"
|
262
|
+
@skin_tone = tone
|
263
|
+
end
|
237
264
|
end
|
238
265
|
|
239
266
|
# @return [String] The unicode string of the emoji.
|