discorb 0.11.4 → 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/Changelog.md +8 -0
- data/README.md +2 -1
- data/lib/discorb/app_command.rb +14 -0
- data/lib/discorb/client.rb +44 -36
- data/lib/discorb/common.rb +1 -1
- data/lib/discorb/error.rb +8 -5
- data/lib/discorb/gateway.rb +30 -23
- 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 -618
- metadata +7 -2
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
|
data/Changelog.md
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,8 @@
|
|
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
|
|
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/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,41 +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 = options[:log_color] == nil ? @log.out.isatty : options[:log_color]
|
450
|
-
end
|
451
|
-
end
|
432
|
+
before_run(token)
|
452
433
|
start_client(token)
|
453
434
|
when "setup"
|
454
|
-
|
455
|
-
if guilds = ENV["DISCORB_SETUP_GUILDS"]
|
456
|
-
guild_ids = guilds.split(",")
|
457
|
-
end
|
458
|
-
if guild_ids == ["global"]
|
459
|
-
guild_ids = false
|
460
|
-
end
|
461
|
-
setup_commands(token, guild_ids: guild_ids).wait
|
462
|
-
@events[:setup]&.each do |event|
|
463
|
-
event.call
|
464
|
-
end
|
465
|
-
self.on_setup if respond_to? :on_setup
|
435
|
+
run_setup(token)
|
466
436
|
end
|
467
437
|
end
|
468
438
|
|
@@ -478,10 +448,48 @@ module Discorb
|
|
478
448
|
|
479
449
|
private
|
480
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
|
+
|
481
488
|
def start_client(token)
|
482
489
|
Async do |task|
|
483
|
-
trap(:SIGINT) {
|
490
|
+
Signal.trap(:SIGINT) {
|
484
491
|
@log.info "SIGINT received, closing..."
|
492
|
+
Signal.trap(:SIGINT, "DEFAULT")
|
485
493
|
close!
|
486
494
|
}
|
487
495
|
@token = token.to_s
|
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
|
|
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
@@ -482,38 +482,44 @@ module Discorb
|
|
482
482
|
private
|
483
483
|
|
484
484
|
def connect_gateway(reconnect)
|
485
|
-
|
485
|
+
if reconnect
|
486
|
+
@log.info "Reconnecting to gateway..."
|
487
|
+
else
|
488
|
+
@log.info "Connecting to gateway..."
|
489
|
+
end
|
486
490
|
Async do
|
491
|
+
@connection&.close
|
487
492
|
@http = HTTP.new(self)
|
488
493
|
_, gateway_response = @http.get("/gateway").wait
|
489
494
|
gateway_url = gateway_response[:url]
|
490
495
|
endpoint = Async::HTTP::Endpoint.parse("#{gateway_url}?v=9&encoding=json&compress=zlib-stream",
|
491
496
|
alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
|
492
497
|
begin
|
493
|
-
Async::WebSocket::Client.connect(endpoint, headers: [["User-Agent", Discorb::USER_AGENT]], handler: RawConnection)
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
handle_gateway(message, reconnect)
|
511
|
-
end
|
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
|
502
|
+
while (message = @connection.read)
|
503
|
+
buffer << message
|
504
|
+
if message.end_with?((+"\x00\x00\xff\xff").force_encoding("ASCII-8BIT"))
|
505
|
+
begin
|
506
|
+
data = @zlib_stream.inflate(buffer)
|
507
|
+
buffer = +""
|
508
|
+
message = JSON.parse(data, symbolize_names: true)
|
509
|
+
rescue JSON::ParserError
|
510
|
+
buffer = +""
|
511
|
+
@log.error "Received invalid JSON from gateway."
|
512
|
+
@log.debug "#{data}"
|
513
|
+
else
|
514
|
+
handle_gateway(message, reconnect)
|
512
515
|
end
|
513
516
|
end
|
514
|
-
rescue EOFError, Async::Wrapper::Cancelled, Async::Wrapper::WaitError
|
515
|
-
# Ignore
|
516
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)
|
517
523
|
end
|
518
524
|
rescue Protocol::WebSocket::ClosedError => e
|
519
525
|
@tasks.map(&:stop)
|
@@ -542,7 +548,7 @@ module Discorb
|
|
542
548
|
connect_gateway(false)
|
543
549
|
end
|
544
550
|
rescue => e
|
545
|
-
@log.error "Discord WebSocket error: #{e.
|
551
|
+
@log.error "Discord WebSocket error: #{e.full_message}"
|
546
552
|
connect_gateway(false)
|
547
553
|
end
|
548
554
|
end
|
@@ -1034,6 +1040,7 @@ module Discorb
|
|
1034
1040
|
dispatch(interaction.class.event_name, interaction)
|
1035
1041
|
when "RESUMED"
|
1036
1042
|
@log.info("Successfully resumed connection")
|
1043
|
+
@tasks << handle_heartbeat
|
1037
1044
|
dispatch(:resumed)
|
1038
1045
|
else
|
1039
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
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Discorb
|
2
|
+
#
|
3
|
+
# Represents a command interaction.
|
4
|
+
#
|
5
|
+
class CommandInteraction < Interaction
|
6
|
+
@interaction_type = 2
|
7
|
+
@interaction_name = :application_command
|
8
|
+
include Interaction::SourceResponse
|
9
|
+
|
10
|
+
#
|
11
|
+
# Represents a slash command interaction.
|
12
|
+
#
|
13
|
+
class SlashCommand < CommandInteraction
|
14
|
+
@command_type = 1
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def _set_data(data)
|
19
|
+
super
|
20
|
+
|
21
|
+
name, options = SlashCommand.get_command_data(data)
|
22
|
+
|
23
|
+
unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
|
24
|
+
@client.log.warn "Unknown command name #{name}, ignoring"
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
option_map = command.options.map { |k, v| [k.to_s, v[:default]] }.to_h
|
29
|
+
SlashCommand.modify_option_map(option_map, options)
|
30
|
+
|
31
|
+
command.block.call(self, *command.options.map { |k, v| option_map[k.to_s] })
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
# @private
|
36
|
+
def get_command_data(data)
|
37
|
+
name = data[:name]
|
38
|
+
options = nil
|
39
|
+
return name, options unless (option = data[:options]&.first)
|
40
|
+
|
41
|
+
case option[:type]
|
42
|
+
when 1
|
43
|
+
name += " #{option[:name]}"
|
44
|
+
options = option[:options]
|
45
|
+
when 2
|
46
|
+
name += " #{option[:name]}"
|
47
|
+
unless option[:options]&.first&.[](:type) == 1
|
48
|
+
options = option[:options]
|
49
|
+
return name, options
|
50
|
+
end
|
51
|
+
option_sub = option[:options]&.first
|
52
|
+
name += " #{option_sub[:name]}"
|
53
|
+
options = option_sub[:options]
|
54
|
+
else
|
55
|
+
options = data[:options]
|
56
|
+
end
|
57
|
+
|
58
|
+
return name, options
|
59
|
+
end
|
60
|
+
|
61
|
+
# @private
|
62
|
+
def modify_option_map(option_map, options)
|
63
|
+
options ||= []
|
64
|
+
options.each_with_index do |option|
|
65
|
+
val = case option[:type]
|
66
|
+
when 3, 4, 5, 10
|
67
|
+
option[:value]
|
68
|
+
when 6
|
69
|
+
guild.members[option[:value]] || guild.fetch_member(option[:value]).wait
|
70
|
+
when 7
|
71
|
+
guild.channels[option[:value]] || guild.fetch_channels.wait.find { |channel| channel.id == option[:value] }
|
72
|
+
when 8
|
73
|
+
guild.roles[option[:value]] || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
|
74
|
+
when 9
|
75
|
+
guild.members[option[:value]] || guild.roles[option[:value]] || guild.fetch_member(option[:value]).wait || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
|
76
|
+
end
|
77
|
+
option_map[option[:name]] = val
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Represents a user context menu interaction.
|
85
|
+
#
|
86
|
+
class UserMenuCommand < CommandInteraction
|
87
|
+
@command_type = 2
|
88
|
+
|
89
|
+
# @return [Discorb::Member, Discorb::User] The target user.
|
90
|
+
attr_reader :target
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def _set_data(data)
|
95
|
+
@target = guild.members[data[:target_id]] || Discorb::Member.new(@client, @guild_id, data[:resolved][:users][data[:target_id].to_sym], data[:resolved][:members][data[:target_id].to_sym])
|
96
|
+
@client.commands.find { |c| c.name == data[:name] && c.type_raw == 2 }.block.call(self, @target)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Represents a message context menu interaction.
|
102
|
+
#
|
103
|
+
class MessageMenuCommand < CommandInteraction
|
104
|
+
@command_type = 3
|
105
|
+
|
106
|
+
# @return [Discorb::Message] The target message.
|
107
|
+
attr_reader :target
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def _set_data(data)
|
112
|
+
@target = Message.new(@client, data[:resolved][:messages][data[:target_id].to_sym].merge(guild_id: @guild_id.to_s))
|
113
|
+
@client.commands.find { |c| c.name == data[:name] && c.type_raw == 3 }.block.call(self, @target)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def _set_data(data)
|
120
|
+
@name = data[:name]
|
121
|
+
end
|
122
|
+
|
123
|
+
class << self
|
124
|
+
# @private
|
125
|
+
attr_reader :command_type
|
126
|
+
|
127
|
+
# @private
|
128
|
+
def make_interaction(client, data)
|
129
|
+
nested_classes.each do |klass|
|
130
|
+
return klass.new(client, data) if !klass.command_type.nil? && klass.command_type == data[:data][:type]
|
131
|
+
end
|
132
|
+
client.log.warn("Unknown command type #{data[:type]}, initialized CommandInteraction")
|
133
|
+
CommandInteraction.new(client, data)
|
134
|
+
end
|
135
|
+
|
136
|
+
# @private
|
137
|
+
def nested_classes
|
138
|
+
constants.select { |c| const_get(c).is_a? Class }.map { |c| const_get(c) }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Discorb
|
2
|
+
|
3
|
+
#
|
4
|
+
# Represents a message component interaction.
|
5
|
+
# @abstract
|
6
|
+
#
|
7
|
+
class MessageComponentInteraction < Interaction
|
8
|
+
include Interaction::SourceResponse
|
9
|
+
include Interaction::UpdateResponse
|
10
|
+
# @return [String] The content of the response.
|
11
|
+
attr_reader :custom_id
|
12
|
+
# @return [Discorb::Message] The target message.
|
13
|
+
attr_reader :message
|
14
|
+
|
15
|
+
@interaction_type = 3
|
16
|
+
@interaction_name = :message_component
|
17
|
+
|
18
|
+
# @private
|
19
|
+
def initialize(client, data)
|
20
|
+
super
|
21
|
+
@message = Message.new(@client, data[:message].merge({ member: data[:member] }))
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
# @private
|
26
|
+
attr_reader :component_type
|
27
|
+
|
28
|
+
# @private
|
29
|
+
def make_interaction(client, data)
|
30
|
+
nested_classes.each do |klass|
|
31
|
+
return klass.new(client, data) if !klass.component_type.nil? && klass.component_type == data[:data][:component_type]
|
32
|
+
end
|
33
|
+
client.log.warn("Unknown component type #{data[:component_type]}, initialized Interaction")
|
34
|
+
MessageComponentInteraction.new(client, data)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @private
|
38
|
+
def nested_classes
|
39
|
+
constants.select { |c| const_get(c).is_a? Class }.map { |c| const_get(c) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Represents a button interaction.
|
45
|
+
#
|
46
|
+
class Button < MessageComponentInteraction
|
47
|
+
@component_type = 2
|
48
|
+
@event_name = :button_click
|
49
|
+
# @return [String] The custom id of the button.
|
50
|
+
attr_reader :custom_id
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def _set_data(data)
|
55
|
+
@custom_id = data[:custom_id]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Represents a select menu interaction.
|
61
|
+
#
|
62
|
+
class SelectMenu < MessageComponentInteraction
|
63
|
+
@component_type = 3
|
64
|
+
@event_name = :select_menu_select
|
65
|
+
# @return [String] The custom id of the select menu.
|
66
|
+
attr_reader :custom_id
|
67
|
+
# @return [Array<String>] The selected options.
|
68
|
+
attr_reader :values
|
69
|
+
|
70
|
+
# @!attribute [r] value
|
71
|
+
# @return [String] The first selected value.
|
72
|
+
|
73
|
+
def value
|
74
|
+
@values[0]
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def _set_data(data)
|
80
|
+
@custom_id = data[:custom_id]
|
81
|
+
@values = data[:values]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|