discorb 0.11.1 → 0.12.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/.github/workflows/package_register.yml +34 -0
- data/Changelog.md +23 -0
- data/README.md +4 -3
- data/discorb.gemspec +0 -2
- data/docs/cli/{init.md → new.md} +0 -0
- data/docs/cli/setup.md +1 -1
- data/docs/cli.md +1 -1
- data/docs/events.md +5 -0
- data/lib/discorb/app_command.rb +14 -0
- data/lib/discorb/channel.rb +0 -42
- data/lib/discorb/client.rb +45 -42
- data/lib/discorb/color.rb +1 -0
- data/lib/discorb/common.rb +7 -1
- data/lib/discorb/error.rb +8 -5
- data/lib/discorb/gateway.rb +60 -47
- data/lib/discorb/interaction/autocomplete.rb +49 -0
- data/lib/discorb/interaction/command.rb +142 -0
- data/lib/discorb/interaction/components.rb +85 -0
- data/lib/discorb/interaction/response.rb +188 -0
- data/lib/discorb/interaction/root.rb +94 -0
- data/lib/discorb/interaction.rb +2 -616
- data/lib/discorb/log.rb +3 -2
- data/lib/discorb/message.rb +3 -1
- data/lib/discorb/modules.rb +42 -0
- data/lib/discorb/rate_limit.rb +2 -2
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d57f5fd6920be7c5549687ec85d3012dede743981482fc806099789d3d9f4048
|
4
|
+
data.tar.gz: 513c3e45c0da27f8e509c4ed7238c5f6da3cd39b61a0681874a97d507068ffc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7603b6c7017898fbd705ffaa602f370111c6d122a2e68a7b6c017c6fa622d9b6990e684bf574104844e8dc6601176a47894815cfb3756ae16305fe74709da118
|
7
|
+
data.tar.gz: 0fa148e0c26c45a8aa0c3a9e2dbdfb4995bc9e939c9588d93b575b711baccc906b20ba3f8edfe4906ae5838565bd0be6befc5cf7e6b2ca25f1f465e21fa6622a
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Publish Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags:
|
6
|
+
- "v*"
|
7
|
+
workflow_dispatch:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@master
|
15
|
+
|
16
|
+
- name: Set up Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: "3.0"
|
20
|
+
|
21
|
+
- name: Setup Release Credentials
|
22
|
+
env:
|
23
|
+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
24
|
+
run: |
|
25
|
+
mkdir -p $HOME/.gem
|
26
|
+
touch $HOME/.gem/credentials
|
27
|
+
chmod 600 $HOME/.gem/credentials
|
28
|
+
echo "---" >$HOME/.gem/credentials
|
29
|
+
echo ":github: Bearer ${GITHUB_TOKEN}" >> $HOME/.gem/credentials
|
30
|
+
- name: Publish Gem to GitHub Packages
|
31
|
+
run: |
|
32
|
+
export OWNER=$( echo ${{ github.repository }} | cut -d "/" -f 1 )
|
33
|
+
gem build *.gemspec
|
34
|
+
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
|
data/Changelog.md
CHANGED
@@ -2,8 +2,31 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
## v0.12
|
6
|
+
|
7
|
+
### v0.12.0
|
8
|
+
|
9
|
+
- Refactor: Refactor the code
|
10
|
+
- Fix: Fix resuming gateway, finally
|
11
|
+
- Fix: Fix `@client` in slash command handler in extension
|
12
|
+
|
5
13
|
## v0.11
|
6
14
|
|
15
|
+
### v0.11.4
|
16
|
+
|
17
|
+
- Fix: Fix unpinning messages
|
18
|
+
|
19
|
+
### v0.11.3
|
20
|
+
|
21
|
+
- Add: Add `Snowflake#id` as alias for `Snowflake#to_s`
|
22
|
+
- Fix: Fix `Message#unpin`
|
23
|
+
|
24
|
+
### v0.11.2
|
25
|
+
|
26
|
+
- Add: Add `setup` event
|
27
|
+
- Fix: Fix gateway resuming
|
28
|
+
- Add: Add GitHub Packages
|
29
|
+
|
7
30
|
### v0.11.1
|
8
31
|
|
9
32
|
- Improve: Improve rate limit handling
|
data/README.md
CHANGED
@@ -4,11 +4,12 @@
|
|
4
4
|
<a href="https://rubygems.org/gems/discorb"><img src="https://img.shields.io/gem/dt/discorb?logo=rubygems&logoColor=fff&label=Downloads&style=flat-square&labelColor=2f3136" alt="Gem"></a>
|
5
5
|
<a href="https://rubygems.org/gems/discorb"><img src="https://img.shields.io/gem/v/discorb?logo=rubygems&logoColor=fff&label=Version&style=flat-square&labelColor=2f3136" alt="Gem"></a>
|
6
6
|
<a href="https://discord.gg/hCP6zq8Vpj"><img src="https://img.shields.io/discord/863581274916913193?logo=discord&logoColor=fff&color=5865f2&label=Discord&style=flat-square&labelColor=2f3136" alt="Discord"></a>
|
7
|
-
<a href="https://github.com/discorb-lib/discorb"><img src="https://img.shields.io/github/stars/discorb-lib/discorb?color=24292e&label=Stars&logo=GitHub&logoColor=fff&style=flat-square&labelColor=2f3136" alt="GitHub"></a
|
7
|
+
<a href="https://github.com/discorb-lib/discorb"><img src="https://img.shields.io/github/stars/discorb-lib/discorb?color=24292e&label=Stars&logo=GitHub&logoColor=fff&style=flat-square&labelColor=2f3136" alt="GitHub"></a>
|
8
|
+
<a href="https://codeclimate.com/github/discorb-lib/discorb"><img alt="Code Climate maintainability" src="https://img.shields.io/codeclimate/maintainability/discorb-lib/discorb?logo=Code%20Climate&logoColor=ffffff&style=flat-square&labelColor=2f3136&label=Maintainability"></a></div>
|
8
9
|
|
9
10
|
----
|
10
11
|
|
11
|
-
discorb is a Discord API wrapper
|
12
|
+
discorb is a Discord API wrapper written in Ruby.
|
12
13
|
|
13
14
|
## Installation
|
14
15
|
|
@@ -98,7 +99,7 @@ end
|
|
98
99
|
client.run(ENV["DISCORD_BOT_TOKEN"])
|
99
100
|
```
|
100
101
|
|
101
|
-
Note
|
102
|
+
Note you must run `discorb setup` before using slash commands.
|
102
103
|
|
103
104
|
## Contributing
|
104
105
|
|
data/discorb.gemspec
CHANGED
@@ -13,8 +13,6 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.license = "MIT"
|
14
14
|
spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
|
15
15
|
|
16
|
-
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
-
|
18
16
|
spec.metadata["homepage_uri"] = spec.homepage
|
19
17
|
spec.metadata["source_code_uri"] = "https://github.com/discorb-lib/discorb"
|
20
18
|
spec.metadata["changelog_uri"] = "https://discorb-lib.github.io/file.Changelog.html"
|
data/docs/cli/{init.md → new.md}
RENAMED
File without changes
|
data/docs/cli/setup.md
CHANGED
data/docs/cli.md
CHANGED
@@ -16,7 +16,7 @@ Currently, discorb has the following commands:
|
|
16
16
|
|
17
17
|
| Command | Description |
|
18
18
|
|---------|-------------|
|
19
|
-
| {file:docs/cli/
|
19
|
+
| {file:docs/cli/new.md `new`} | Create a new project. |
|
20
20
|
| {file:docs/cli/irb.md `irb`} | Start an interactive Ruby shell with connected client. |
|
21
21
|
| {file:docs/cli/run.md `run`} | Run a client. |
|
22
22
|
| {file:docs/cli/setup.md `setup`} | Setup application commands. |
|
data/docs/events.md
CHANGED
@@ -88,6 +88,11 @@ Fires when the client is resumed connection.
|
|
88
88
|
Fires when an error occurs during an event.
|
89
89
|
Defaults to printing the error to stderr, override to handle it yourself.
|
90
90
|
|
91
|
+
#### `setup()`
|
92
|
+
|
93
|
+
Fires when `discorb setup` is run.
|
94
|
+
This is useful for setting up some dependencies, such as the database.
|
95
|
+
|
91
96
|
### Guild events
|
92
97
|
|
93
98
|
#### `guild_join(guild)`
|
data/lib/discorb/app_command.rb
CHANGED
@@ -172,6 +172,14 @@ module Discorb
|
|
172
172
|
@id_map = Discorb::Dictionary.new
|
173
173
|
end
|
174
174
|
|
175
|
+
# @private
|
176
|
+
def replace_block(instance)
|
177
|
+
current_block = @block.dup
|
178
|
+
@block = Proc.new do |*args|
|
179
|
+
instance.instance_exec(*args, ¤t_block)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
175
183
|
# @private
|
176
184
|
def to_hash
|
177
185
|
{
|
@@ -314,6 +322,12 @@ module Discorb
|
|
314
322
|
@name
|
315
323
|
end
|
316
324
|
|
325
|
+
# @private
|
326
|
+
def block_replace(instance)
|
327
|
+
super
|
328
|
+
@commands.each { |c| c.replace_block(instance) }
|
329
|
+
end
|
330
|
+
|
317
331
|
# @private
|
318
332
|
def to_hash
|
319
333
|
options_payload = @commands.map do |command|
|
data/lib/discorb/channel.rb
CHANGED
@@ -482,48 +482,6 @@ module Discorb
|
|
482
482
|
end
|
483
483
|
end
|
484
484
|
|
485
|
-
#
|
486
|
-
# Fetch the pinned messages in the channel.
|
487
|
-
# @macro async
|
488
|
-
# @macro http
|
489
|
-
#
|
490
|
-
# @return [Async::Task<Array<Discorb::Message>>] The pinned messages in the channel.
|
491
|
-
#
|
492
|
-
def fetch_pins
|
493
|
-
Async do
|
494
|
-
_resp, data = @client.http.get("/channels/#{@id}/pins").wait
|
495
|
-
data.map { |pin| Message.new(@client, pin) }
|
496
|
-
end
|
497
|
-
end
|
498
|
-
|
499
|
-
#
|
500
|
-
# Pin a message in the channel.
|
501
|
-
# @macro async
|
502
|
-
# @macro http
|
503
|
-
#
|
504
|
-
# @param [Discorb::Message] message The message to pin.
|
505
|
-
# @param [String] reason The reason of pinning the message.
|
506
|
-
#
|
507
|
-
def pin_message(message, reason: nil)
|
508
|
-
Async do
|
509
|
-
@client.http.put("/channels/#{@id}/pins/#{message.id}", {}, audit_log_reason: reason).wait
|
510
|
-
end
|
511
|
-
end
|
512
|
-
|
513
|
-
#
|
514
|
-
# Unpin a message in the channel.
|
515
|
-
# @macro async
|
516
|
-
# @macro http
|
517
|
-
#
|
518
|
-
# @param [Discorb::Message] message The message to unpin.
|
519
|
-
# @param [String] reason The reason of unpinning the message.
|
520
|
-
#
|
521
|
-
def unpin_message(message, reason: nil)
|
522
|
-
Async do
|
523
|
-
@client.http.delete("/channels/#{@id}/pins/#{message.id}", {}, audit_log_reason: reason).wait
|
524
|
-
end
|
525
|
-
end
|
526
|
-
|
527
485
|
#
|
528
486
|
# Start thread in the channel.
|
529
487
|
# @macro async
|
data/lib/discorb/client.rb
CHANGED
@@ -395,10 +395,11 @@ module Discorb
|
|
395
395
|
end
|
396
396
|
end
|
397
397
|
@commands.delete_if do |cmd|
|
398
|
-
cmd.respond_to? :extension and cmd.extension == ins.name
|
398
|
+
cmd.respond_to? :extension and cmd.extension == ins.class.name
|
399
399
|
end
|
400
400
|
ins.class.commands.each do |cmd|
|
401
|
-
cmd.define_singleton_method(:extension) { ins.name }
|
401
|
+
cmd.define_singleton_method(:extension) { ins.class.name }
|
402
|
+
cmd.replace_block(ins)
|
402
403
|
@commands << cmd
|
403
404
|
end
|
404
405
|
|
@@ -428,46 +429,10 @@ module Discorb
|
|
428
429
|
when nil
|
429
430
|
start_client(token)
|
430
431
|
when "run"
|
431
|
-
|
432
|
-
options = JSON.parse(ENV["DISCORB_CLI_OPTIONS"], symbolize_names: true)
|
433
|
-
@daemon = options[:daemon]
|
434
|
-
|
435
|
-
setup_commands(token) if options[:setup]
|
436
|
-
if options[:log_level]
|
437
|
-
if options[:log_level] == "none"
|
438
|
-
@log.out = nil
|
439
|
-
else
|
440
|
-
@log.out = case options[:log_file]
|
441
|
-
when nil, "stderr"
|
442
|
-
$stderr
|
443
|
-
when "stdout"
|
444
|
-
$stdout
|
445
|
-
else
|
446
|
-
::File.open(options[:log_file], "a")
|
447
|
-
end
|
448
|
-
@log.level = options[:log_level].to_sym
|
449
|
-
@log.colorize_log = case options[:log_color]
|
450
|
-
when nil
|
451
|
-
if @log.out == $stdout || @log.out == $stderr
|
452
|
-
true
|
453
|
-
else
|
454
|
-
false
|
455
|
-
end
|
456
|
-
when true, false
|
457
|
-
options[:log_color]
|
458
|
-
end
|
459
|
-
end
|
460
|
-
end
|
432
|
+
before_run(token)
|
461
433
|
start_client(token)
|
462
434
|
when "setup"
|
463
|
-
|
464
|
-
if guilds = ENV["DISCORB_SETUP_GUILDS"]
|
465
|
-
guild_ids = guilds.split(",")
|
466
|
-
end
|
467
|
-
if guild_ids == ["global"]
|
468
|
-
guild_ids = false
|
469
|
-
end
|
470
|
-
setup_commands(token, guild_ids: guild_ids).wait
|
435
|
+
run_setup(token)
|
471
436
|
end
|
472
437
|
end
|
473
438
|
|
@@ -483,17 +448,55 @@ module Discorb
|
|
483
448
|
|
484
449
|
private
|
485
450
|
|
451
|
+
def before_run(token)
|
452
|
+
require "json"
|
453
|
+
options = JSON.parse(ENV["DISCORB_CLI_OPTIONS"], symbolize_names: true)
|
454
|
+
setup_commands(token) if options[:setup]
|
455
|
+
if options[:log_level]
|
456
|
+
if options[:log_level] == "none"
|
457
|
+
@log.out = nil
|
458
|
+
else
|
459
|
+
@log.out = case options[:log_file]
|
460
|
+
when nil, "stderr"
|
461
|
+
$stderr
|
462
|
+
when "stdout"
|
463
|
+
$stdout
|
464
|
+
else
|
465
|
+
::File.open(options[:log_file], "a")
|
466
|
+
end
|
467
|
+
@log.level = options[:log_level].to_sym
|
468
|
+
@log.colorize_log = options[:log_color] == nil ? @log.out.isatty : options[:log_color]
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
def run_setup(token)
|
474
|
+
guild_ids = "global"
|
475
|
+
if guilds = ENV["DISCORB_SETUP_GUILDS"]
|
476
|
+
guild_ids = guilds.split(",")
|
477
|
+
end
|
478
|
+
if guild_ids == ["global"]
|
479
|
+
guild_ids = false
|
480
|
+
end
|
481
|
+
setup_commands(token, guild_ids: guild_ids).wait
|
482
|
+
@events[:setup]&.each do |event|
|
483
|
+
event.call
|
484
|
+
end
|
485
|
+
self.on_setup if respond_to? :on_setup
|
486
|
+
end
|
487
|
+
|
486
488
|
def start_client(token)
|
487
489
|
Async do |task|
|
488
|
-
trap(:SIGINT) {
|
490
|
+
Signal.trap(:SIGINT) {
|
489
491
|
@log.info "SIGINT received, closing..."
|
492
|
+
Signal.trap(:SIGINT, "DEFAULT")
|
490
493
|
close!
|
491
494
|
}
|
492
495
|
@token = token.to_s
|
493
496
|
@close_condition = Async::Condition.new
|
494
497
|
@main_task = Async do
|
495
498
|
@status = :running
|
496
|
-
connect_gateway(
|
499
|
+
connect_gateway(false).wait
|
497
500
|
rescue
|
498
501
|
@status = :stopped
|
499
502
|
@close_condition.signal
|
data/lib/discorb/color.rb
CHANGED
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/v9"
|
6
6
|
# @return [String] The version of discorb.
|
7
|
-
VERSION = "0.
|
7
|
+
VERSION = "0.12.0"
|
8
8
|
# @return [String] The user agent for the bot.
|
9
9
|
USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}"
|
10
10
|
|
@@ -64,6 +64,10 @@ module Discorb
|
|
64
64
|
# Increment of snowflake.
|
65
65
|
#
|
66
66
|
# @return [Integer] Increment of snowflake.
|
67
|
+
# @!attribute [r] id
|
68
|
+
# Alias of to_s.
|
69
|
+
#
|
70
|
+
# @return [String] The snowflake.
|
67
71
|
|
68
72
|
#
|
69
73
|
# Compares snowflake with other object.
|
@@ -105,5 +109,7 @@ module Discorb
|
|
105
109
|
def increment
|
106
110
|
@value & 0xFFF
|
107
111
|
end
|
112
|
+
|
113
|
+
alias id to_s
|
108
114
|
end
|
109
115
|
end
|
data/lib/discorb/error.rb
CHANGED
@@ -38,7 +38,8 @@ module Discorb
|
|
38
38
|
# @abstract
|
39
39
|
#
|
40
40
|
class HTTPError < DiscorbError
|
41
|
-
# @return [String] the
|
41
|
+
# @return [String] the JSON response code.
|
42
|
+
# @see https://discord.com/developers/docs/topics/opcodes-and-status-codes#json-json-error-codes
|
42
43
|
attr_reader :code
|
43
44
|
# @return [Net::HTTPResponse] the HTTP response.
|
44
45
|
attr_reader :response
|
@@ -47,7 +48,7 @@ module Discorb
|
|
47
48
|
def initialize(resp, data)
|
48
49
|
@code = data[:code]
|
49
50
|
@response = resp
|
50
|
-
super(data[:message])
|
51
|
+
super(data[:message] + " (#{@code})")
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
@@ -60,9 +61,11 @@ module Discorb
|
|
60
61
|
@code = data[:code]
|
61
62
|
@response = resp
|
62
63
|
DiscorbError.instance_method(:initialize).bind(self).call(
|
63
|
-
[
|
64
|
-
"#{
|
65
|
-
|
64
|
+
[
|
65
|
+
data[:message] + " (#{@code})", enumerate_errors(data[:errors])
|
66
|
+
.map { |ek, ev| "#{ek}=>#{ev}" }
|
67
|
+
.join("\n"),
|
68
|
+
].join("\n")
|
66
69
|
)
|
67
70
|
end
|
68
71
|
end
|
data/lib/discorb/gateway.rb
CHANGED
@@ -481,54 +481,74 @@ module Discorb
|
|
481
481
|
module Handler
|
482
482
|
private
|
483
483
|
|
484
|
-
def connect_gateway(
|
485
|
-
|
484
|
+
def connect_gateway(reconnect)
|
485
|
+
if reconnect
|
486
|
+
@log.info "Reconnecting to gateway..."
|
487
|
+
else
|
488
|
+
@log.info "Connecting to gateway..."
|
489
|
+
end
|
486
490
|
Async do
|
487
|
-
@
|
488
|
-
@
|
491
|
+
@connection&.close
|
492
|
+
@http = HTTP.new(self)
|
489
493
|
_, gateway_response = @http.get("/gateway").wait
|
490
494
|
gateway_url = gateway_response[:url]
|
491
495
|
endpoint = Async::HTTP::Endpoint.parse("#{gateway_url}?v=9&encoding=json&compress=zlib-stream",
|
492
496
|
alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
|
493
497
|
begin
|
494
|
-
Async::WebSocket::Client.connect(endpoint, headers: [["User-Agent", Discorb::USER_AGENT]], handler: RawConnection)
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
498
|
+
@connection = Async::WebSocket::Client.connect(endpoint, headers: [["User-Agent", Discorb::USER_AGENT]], handler: RawConnection)
|
499
|
+
@zlib_stream = Zlib::Inflate.new(Zlib::MAX_WBITS)
|
500
|
+
buffer = +""
|
501
|
+
begin
|
499
502
|
while (message = @connection.read)
|
500
|
-
|
503
|
+
buffer << message
|
501
504
|
if message.end_with?((+"\x00\x00\xff\xff").force_encoding("ASCII-8BIT"))
|
502
505
|
begin
|
503
|
-
data = @zlib_stream.inflate(
|
504
|
-
|
506
|
+
data = @zlib_stream.inflate(buffer)
|
507
|
+
buffer = +""
|
505
508
|
message = JSON.parse(data, symbolize_names: true)
|
506
509
|
rescue JSON::ParserError
|
507
|
-
|
510
|
+
buffer = +""
|
508
511
|
@log.error "Received invalid JSON from gateway."
|
509
512
|
@log.debug "#{data}"
|
510
513
|
else
|
511
|
-
handle_gateway(message)
|
514
|
+
handle_gateway(message, reconnect)
|
512
515
|
end
|
513
516
|
end
|
514
517
|
end
|
518
|
+
rescue Async::Wrapper::Cancelled, OpenSSL::SSL::SSLError, Async::Wrapper::WaitError, EOFError => e
|
519
|
+
@log.error "Gateway connection closed: #{e.class}: #{e.message}"
|
520
|
+
connect_gateway(true)
|
521
|
+
else # should never happen
|
522
|
+
connect_gateway(true)
|
515
523
|
end
|
516
524
|
rescue Protocol::WebSocket::ClosedError => e
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
raise ClientError.new("Authentication failed
|
521
|
-
when
|
522
|
-
@log.info "
|
523
|
-
connect_gateway(
|
525
|
+
@tasks.map(&:stop)
|
526
|
+
case e.code
|
527
|
+
when 4004
|
528
|
+
raise ClientError.new("Authentication failed"), cause: nil
|
529
|
+
when 4009
|
530
|
+
@log.info "Session timed out, reconnecting."
|
531
|
+
connect_gateway(true)
|
532
|
+
when 4014
|
533
|
+
raise ClientError.new("Disallowed intents were specified"), cause: nil
|
534
|
+
when 4002, 4003, 4005, 4007
|
535
|
+
raise ClientError.new(<<~EOS), cause: e
|
536
|
+
Disconnected from gateway, probably due to library issues.
|
537
|
+
#{e.message}
|
538
|
+
|
539
|
+
Please report this to the library issue tracker.
|
540
|
+
https://github.com/discorb-lib/discorb/issues
|
541
|
+
EOS
|
542
|
+
when 1001
|
543
|
+
@log.info "Gateway closed with code 1001, reconnecting."
|
544
|
+
connect_gateway(true)
|
524
545
|
else
|
525
|
-
@log.error "Discord WebSocket closed
|
546
|
+
@log.error "Discord WebSocket closed with code #{e.code}."
|
547
|
+
@log.debug "#{e.message}"
|
526
548
|
connect_gateway(false)
|
527
549
|
end
|
528
|
-
rescue EOFError, Async::Wrapper::Cancelled, Async::Wrapper::WaitError
|
529
|
-
connect_gateway(false)
|
530
550
|
rescue => e
|
531
|
-
@log.error "Discord WebSocket error: #{e.
|
551
|
+
@log.error "Discord WebSocket error: #{e.full_message}"
|
532
552
|
connect_gateway(false)
|
533
553
|
end
|
534
554
|
end
|
@@ -540,15 +560,23 @@ module Discorb
|
|
540
560
|
@log.debug "Sent message #{{ op: opcode, d: value }.to_json.gsub(@token, "[Token]")}"
|
541
561
|
end
|
542
562
|
|
543
|
-
def handle_gateway(payload)
|
563
|
+
def handle_gateway(payload, reconnect)
|
544
564
|
Async do |task|
|
545
565
|
data = payload[:d]
|
546
566
|
@last_s = payload[:s] if payload[:s]
|
547
|
-
@log.debug "Received message with opcode #{payload[:op]} from gateway:
|
567
|
+
@log.debug "Received message with opcode #{payload[:op]} from gateway:"
|
568
|
+
@log.debug "#{payload.to_json.gsub(@token, "[Token]")}"
|
548
569
|
case payload[:op]
|
549
570
|
when 10
|
550
571
|
@heartbeat_interval = data[:heartbeat_interval]
|
551
|
-
if
|
572
|
+
if reconnect
|
573
|
+
payload = {
|
574
|
+
token: @token,
|
575
|
+
session_id: @session_id,
|
576
|
+
seq: @last_s,
|
577
|
+
}
|
578
|
+
send_gateway(6, **payload)
|
579
|
+
else
|
552
580
|
payload = {
|
553
581
|
token: @token,
|
554
582
|
intents: @intents.value,
|
@@ -557,38 +585,22 @@ module Discorb
|
|
557
585
|
}
|
558
586
|
payload[:presence] = @identify_presence if @identify_presence
|
559
587
|
send_gateway(2, **payload)
|
560
|
-
Async do
|
561
|
-
sleep 2
|
562
|
-
next unless @uncached_guilds.nil?
|
563
|
-
|
564
|
-
raise ClientError, "Failed to connect to gateway.\nHint: This usually means that your intents are invalid."
|
565
|
-
exit 1
|
566
|
-
end
|
567
|
-
else
|
568
|
-
payload = {
|
569
|
-
token: @token,
|
570
|
-
session_id: @session_id,
|
571
|
-
seq: @last_s,
|
572
|
-
}
|
573
|
-
send_gateway(6, **payload)
|
574
588
|
end
|
575
589
|
when 7
|
576
590
|
@log.info "Received opcode 7, reconnecting"
|
577
591
|
@tasks.map(&:stop)
|
578
|
-
@connection.close
|
579
|
-
connect_gateway(false)
|
580
592
|
when 9
|
581
593
|
@log.warn "Received opcode 9, closed connection"
|
582
594
|
@tasks.map(&:stop)
|
583
595
|
if data
|
584
596
|
@log.info "Connection is resumable, reconnecting"
|
585
597
|
@connection.close
|
586
|
-
connect_gateway(
|
598
|
+
connect_gateway(true)
|
587
599
|
else
|
588
600
|
@log.info "Connection is not resumable, reconnecting with opcode 2"
|
589
|
-
sleep(2)
|
590
601
|
@connection.close
|
591
|
-
|
602
|
+
sleep(2)
|
603
|
+
connect_gateway(false)
|
592
604
|
end
|
593
605
|
when 11
|
594
606
|
@log.debug "Received opcode 11"
|
@@ -1028,6 +1040,7 @@ module Discorb
|
|
1028
1040
|
dispatch(interaction.class.event_name, interaction)
|
1029
1041
|
when "RESUMED"
|
1030
1042
|
@log.info("Successfully resumed connection")
|
1043
|
+
@tasks << handle_heartbeat
|
1031
1044
|
dispatch(:resumed)
|
1032
1045
|
else
|
1033
1046
|
if respond_to?("event_" + event_name.downcase)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Discorb
|
2
|
+
#
|
3
|
+
# Represents auto complete interaction.
|
4
|
+
#
|
5
|
+
class AutoComplete < Interaction
|
6
|
+
@interaction_type = 4
|
7
|
+
@interaction_name = :auto_complete
|
8
|
+
|
9
|
+
# @private
|
10
|
+
def _set_data(data)
|
11
|
+
super
|
12
|
+
Sync do
|
13
|
+
name, options = Discorb::CommandInteraction::SlashCommand.get_command_data(data)
|
14
|
+
|
15
|
+
unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
|
16
|
+
@client.log.warn "Unknown command name #{name}, ignoring"
|
17
|
+
next
|
18
|
+
end
|
19
|
+
|
20
|
+
option_map = command.options.map { |k, v| [k.to_s, v[:default]] }.to_h
|
21
|
+
Discorb::CommandInteraction::SlashCommand.modify_option_map(option_map, options)
|
22
|
+
focused_index = options.find_index { |o| o[:focused] }
|
23
|
+
val = command.options.values[focused_index][:autocomplete]&.call(self, *command.options.map { |k, v| option_map[k.to_s] })
|
24
|
+
send_complete_result(val)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @private
|
29
|
+
def send_complete_result(val)
|
30
|
+
@client.http.post("/interactions/#{@id}/#{@token}/callback", {
|
31
|
+
type: 8,
|
32
|
+
data: {
|
33
|
+
choices: val.map do |vk, vv|
|
34
|
+
{
|
35
|
+
name: vk,
|
36
|
+
value: vv,
|
37
|
+
}
|
38
|
+
end,
|
39
|
+
},
|
40
|
+
}).wait
|
41
|
+
rescue Discorb::NotFoundError
|
42
|
+
@client.log.warn "Failed to send auto complete result, This may be caused by the suggestion is taking too long (over 3 seconds) to respond", fallback: $stderr
|
43
|
+
end
|
44
|
+
|
45
|
+
class << self
|
46
|
+
alias make_interaction new
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|