discorb 0.13.1 → 0.14.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/.gitattributes +2 -0
- data/.github/workflows/build_version.yml +3 -3
- data/.github/workflows/codeql-analysis.yml +70 -0
- data/.github/workflows/lint-push.yml +18 -0
- data/.github/workflows/lint.yml +16 -0
- data/.rubocop.yml +70 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/Changelog.md +33 -0
- data/Gemfile +7 -3
- data/README.md +1 -1
- data/Rakefile +35 -35
- data/discorb.gemspec +13 -1
- data/examples/commands/bookmarker.rb +2 -1
- data/examples/commands/hello.rb +1 -0
- data/examples/commands/inspect.rb +3 -2
- data/examples/components/authorization_button.rb +2 -1
- data/examples/components/select_menu.rb +2 -1
- data/examples/extension/main.rb +1 -0
- data/examples/extension/message_expander.rb +1 -0
- data/examples/simple/eval.rb +3 -2
- data/examples/simple/ping_pong.rb +1 -0
- data/examples/simple/rolepanel.rb +1 -0
- data/examples/simple/wait_for_message.rb +4 -3
- data/exe/discorb +8 -7
- data/lib/discorb/allowed_mentions.rb +64 -0
- data/lib/discorb/app_command/command.rb +274 -0
- data/lib/discorb/app_command/handler.rb +168 -0
- data/lib/discorb/app_command.rb +2 -404
- data/lib/discorb/asset.rb +3 -1
- data/lib/discorb/audit_logs.rb +3 -3
- data/lib/discorb/channel.rb +89 -53
- data/lib/discorb/client.rb +36 -33
- data/lib/discorb/common.rb +28 -21
- data/lib/discorb/components/button.rb +106 -0
- data/lib/discorb/components/select_menu.rb +157 -0
- data/lib/discorb/components/text_input.rb +96 -0
- data/lib/discorb/components.rb +11 -276
- data/lib/discorb/dictionary.rb +13 -2
- data/lib/discorb/embed.rb +2 -2
- data/lib/discorb/emoji.rb +21 -5
- data/lib/discorb/emoji_table.rb +1 -1
- data/lib/discorb/error.rb +4 -6
- data/lib/discorb/event.rb +13 -11
- data/lib/discorb/exe/about.rb +1 -0
- data/lib/discorb/exe/irb.rb +4 -3
- data/lib/discorb/exe/new.rb +6 -7
- data/lib/discorb/exe/run.rb +2 -1
- data/lib/discorb/exe/setup.rb +8 -5
- data/lib/discorb/exe/show.rb +1 -0
- data/lib/discorb/extend.rb +19 -14
- data/lib/discorb/extension.rb +5 -1
- data/lib/discorb/gateway.rb +75 -27
- data/lib/discorb/guild.rb +58 -80
- data/lib/discorb/guild_template.rb +5 -5
- data/lib/discorb/http.rb +34 -169
- data/lib/discorb/integration.rb +32 -3
- data/lib/discorb/intents.rb +1 -1
- data/lib/discorb/interaction/autocomplete.rb +5 -4
- data/lib/discorb/interaction/command.rb +34 -9
- data/lib/discorb/interaction/components.rb +5 -2
- data/lib/discorb/interaction/modal.rb +33 -0
- data/lib/discorb/interaction/response.rb +41 -12
- data/lib/discorb/interaction/root.rb +1 -0
- data/lib/discorb/interaction.rb +2 -1
- data/lib/discorb/invite.rb +1 -1
- data/lib/discorb/log.rb +4 -3
- data/lib/discorb/member.rb +4 -6
- data/lib/discorb/message.rb +31 -282
- data/lib/discorb/message_meta.rb +205 -0
- data/lib/discorb/modules.rb +11 -11
- data/lib/discorb/permission.rb +2 -2
- data/lib/discorb/presence.rb +6 -3
- data/lib/discorb/rate_limit.rb +15 -21
- data/lib/discorb/role.rb +3 -3
- data/lib/discorb/sticker.rb +2 -2
- data/lib/discorb/user.rb +3 -3
- data/lib/discorb/utils/colored_puts.rb +1 -0
- data/lib/discorb/voice_state.rb +7 -2
- data/lib/discorb/webhook.rb +8 -5
- data/lib/discorb.rb +1 -0
- data/template-replace/scripts/arrow.rb +1 -0
- data/template-replace/scripts/favicon.rb +1 -0
- data/template-replace/scripts/index.rb +2 -1
- data/template-replace/scripts/locale_ja.rb +5 -4
- data/template-replace/scripts/sidebar.rb +1 -0
- data/template-replace/scripts/version.rb +7 -10
- data/template-replace/scripts/yard_replace.rb +5 -4
- metadata +29 -4
data/lib/discorb/http.rb
CHANGED
@@ -17,10 +17,11 @@ module Discorb
|
|
17
17
|
end
|
18
18
|
|
19
19
|
#
|
20
|
-
# Execute a
|
20
|
+
# Execute a request.
|
21
21
|
# @async
|
22
22
|
#
|
23
|
-
# @param [
|
23
|
+
# @param [Discorb::Route] path The path to the resource.
|
24
|
+
# @param [String, Hash] body The body of the request. Defaults to an empty string.
|
24
25
|
# @param [Hash] headers The headers to send with the request.
|
25
26
|
# @param [String] audit_log_reason The audit log reason to send with the request.
|
26
27
|
# @param [Hash] kwargs The keyword arguments.
|
@@ -30,46 +31,25 @@ module Discorb
|
|
30
31
|
#
|
31
32
|
# @raise [Discorb::HTTPError] The request was failed.
|
32
33
|
#
|
33
|
-
def
|
34
|
-
Async do |
|
35
|
-
@ratelimit_handler.wait(
|
36
|
-
resp =
|
34
|
+
def request(path, body = "", headers: nil, audit_log_reason: nil, **kwargs)
|
35
|
+
Async do |_task|
|
36
|
+
@ratelimit_handler.wait(path)
|
37
|
+
resp = if %i[post patch put].include? path.method
|
38
|
+
http.send(path.method, get_path(path), get_body(body), get_headers(headers, body, audit_log_reason), **kwargs)
|
39
|
+
else
|
40
|
+
http.send(path.method, get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
|
41
|
+
end
|
37
42
|
data = get_response_data(resp)
|
38
|
-
@ratelimit_handler.save(
|
39
|
-
handle_response(
|
43
|
+
@ratelimit_handler.save(path, resp)
|
44
|
+
handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
43
48
|
#
|
44
|
-
# Execute a
|
49
|
+
# Execute a multipart request.
|
45
50
|
# @async
|
46
51
|
#
|
47
|
-
# @param [
|
48
|
-
# @param [String, Hash] body The body of the request.
|
49
|
-
# @param [Hash] headers The headers to send with the request.
|
50
|
-
# @param [String] audit_log_reason The audit log reason to send with the request.
|
51
|
-
# @param [Hash] kwargs The keyword arguments.
|
52
|
-
#
|
53
|
-
# @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
|
54
|
-
# @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
|
55
|
-
#
|
56
|
-
# @raise [Discorb::HTTPError] The request was failed.
|
57
|
-
#
|
58
|
-
def post(path, body = "", headers: nil, audit_log_reason: nil, **kwargs)
|
59
|
-
Async do |task|
|
60
|
-
@ratelimit_handler.wait("POST", path)
|
61
|
-
resp = http.post(get_path(path), get_body(body), get_headers(headers, body, audit_log_reason), **kwargs)
|
62
|
-
data = get_response_data(resp)
|
63
|
-
@ratelimit_handler.save("POST", path, resp)
|
64
|
-
handle_response(:post, resp, data, path, body, headers, audit_log_reason, kwargs)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
#
|
69
|
-
# Execute a multipart POST request.
|
70
|
-
# @async
|
71
|
-
#
|
72
|
-
# @param [String] path The path to the resource.
|
52
|
+
# @param [Discorb::Route] path The path to the resource.
|
73
53
|
# @param [String, Hash] body The body of the request.
|
74
54
|
# @param [Array<Discorb::File>] files The files to upload.
|
75
55
|
# @param [Hash] headers The headers to send with the request.
|
@@ -81,12 +61,12 @@ module Discorb
|
|
81
61
|
#
|
82
62
|
# @raise [Discorb::HTTPError] The request was failed.
|
83
63
|
#
|
84
|
-
def
|
85
|
-
Async do |
|
86
|
-
@ratelimit_handler.wait(
|
87
|
-
req = Net::HTTP
|
64
|
+
def multipart_request(path, body, files, headers: nil, audit_log_reason: nil, **kwargs)
|
65
|
+
Async do |_task|
|
66
|
+
@ratelimit_handler.wait(path)
|
67
|
+
req = Net::HTTP.const_get(path.method.to_s.capitalize).new(get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
|
88
68
|
data = [
|
89
|
-
["payload_json", get_body(body)]
|
69
|
+
["payload_json", get_body(body)]
|
90
70
|
]
|
91
71
|
files&.each_with_index do |file, i|
|
92
72
|
next if file.nil?
|
@@ -97,117 +77,8 @@ module Discorb
|
|
97
77
|
session.use_ssl = true
|
98
78
|
resp = session.request(req)
|
99
79
|
data = get_response_data(resp)
|
100
|
-
@ratelimit_handler.save(
|
101
|
-
handle_response(
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
#
|
106
|
-
# Execute a PATCH request.
|
107
|
-
# @async
|
108
|
-
#
|
109
|
-
# @param [String] path The path to the resource.
|
110
|
-
# @param [String, Hash] body The body of the request.
|
111
|
-
# @param [Hash] headers The headers to send with the request.
|
112
|
-
# @param [String] audit_log_reason The audit log reason to send with the request.
|
113
|
-
# @param [Hash] kwargs The keyword arguments.
|
114
|
-
#
|
115
|
-
# @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
|
116
|
-
# @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
|
117
|
-
#
|
118
|
-
# @raise [Discorb::HTTPError] The request was failed.
|
119
|
-
#
|
120
|
-
def patch(path, body = "", headers: nil, audit_log_reason: nil, **kwargs)
|
121
|
-
Async do |task|
|
122
|
-
@ratelimit_handler.wait("PATCH", path)
|
123
|
-
resp = http.patch(get_path(path), get_body(body), get_headers(headers, body, audit_log_reason), **kwargs)
|
124
|
-
data = get_response_data(resp)
|
125
|
-
@ratelimit_handler.save("PATCH", path, resp)
|
126
|
-
handle_response(:patch, resp, data, path, body, headers, audit_log_reason, kwargs)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
#
|
131
|
-
# Execute a PATCH request.
|
132
|
-
# @async
|
133
|
-
#
|
134
|
-
# @param [String] path The path to the resource.
|
135
|
-
# @param [String, Hash] body The body of the request.
|
136
|
-
# @param [Hash] headers The headers to send with the request.
|
137
|
-
# @param [String] audit_log_reason The audit log reason to send with the request.
|
138
|
-
# @param [Hash] kwargs The keyword arguments.
|
139
|
-
#
|
140
|
-
# @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
|
141
|
-
# @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
|
142
|
-
#
|
143
|
-
# @raise [Discorb::HTTPError] The request was failed.
|
144
|
-
#
|
145
|
-
def multipart_patch(path, body = "", headers: nil, audit_log_reason: nil, **kwargs)
|
146
|
-
Async do |task|
|
147
|
-
@ratelimit_handler.wait("PATCH", path)
|
148
|
-
req = Net::HTTP::Patch.new(get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
|
149
|
-
data = [
|
150
|
-
["payload_json", get_body(body)],
|
151
|
-
]
|
152
|
-
files&.each_with_index do |file, i|
|
153
|
-
data << ["files[#{i}]", file.io, { filename: file.filename, content_type: file.content_type }]
|
154
|
-
end
|
155
|
-
req.set_form(data, "multipart/form-data")
|
156
|
-
session = Net::HTTP.new("discord.com", 443)
|
157
|
-
session.use_ssl = true
|
158
|
-
resp = session.request(req)
|
159
|
-
data = get_response_data(resp)
|
160
|
-
@ratelimit_handler.save("PATCH", path, resp)
|
161
|
-
handle_response(:patch, resp, data, path, body, headers, audit_log_reason, kwargs)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
#
|
166
|
-
# Execute a PUT request.
|
167
|
-
# @async
|
168
|
-
#
|
169
|
-
# @param [String] path The path to the resource.
|
170
|
-
# @param [String, Hash] body The body of the request.
|
171
|
-
# @param [Hash] headers The headers to send with the request.
|
172
|
-
# @param [String] audit_log_reason The audit log reason to send with the request.
|
173
|
-
# @param [Hash] kwargs The keyword arguments.
|
174
|
-
#
|
175
|
-
# @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
|
176
|
-
# @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
|
177
|
-
#
|
178
|
-
# @raise [Discorb::HTTPError] The request was failed.
|
179
|
-
#
|
180
|
-
def put(path, body = "", headers: nil, audit_log_reason: nil, **kwargs)
|
181
|
-
Async do |task|
|
182
|
-
@ratelimit_handler.wait("PUT", path)
|
183
|
-
resp = http.put(get_path(path), get_body(body), get_headers(headers, body, audit_log_reason), **kwargs)
|
184
|
-
data = get_response_data(resp)
|
185
|
-
@ratelimit_handler.save("PUT", path, resp)
|
186
|
-
handle_response(:put, resp, data, path, body, headers, audit_log_reason, kwargs)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
#
|
191
|
-
# Execute a DELETE request.
|
192
|
-
# @async
|
193
|
-
#
|
194
|
-
# @param [String] path The path to the resource.
|
195
|
-
# @param [Hash] headers The headers to send with the request.
|
196
|
-
# @param [String] audit_log_reason The audit log reason to send with the request.
|
197
|
-
# @param [Hash] kwargs The keyword arguments.
|
198
|
-
#
|
199
|
-
# @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
|
200
|
-
# @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
|
201
|
-
#
|
202
|
-
# @raise [Discorb::HTTPError] The request was failed.
|
203
|
-
#
|
204
|
-
def delete(path, headers: nil, audit_log_reason: nil, **kwargs)
|
205
|
-
Async do
|
206
|
-
@ratelimit_handler.wait("DELETE", path)
|
207
|
-
resp = http.delete(get_path(path), get_headers(headers, "", audit_log_reason))
|
208
|
-
data = get_response_data(resp)
|
209
|
-
@ratelimit_handler.save("DELETE", path, resp)
|
210
|
-
handle_response(:delete, resp, data, path, nil, headers, audit_log_reason, kwargs)
|
80
|
+
@ratelimit_handler.save(path, resp)
|
81
|
+
handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
|
211
82
|
end
|
212
83
|
end
|
213
84
|
|
@@ -217,16 +88,12 @@ module Discorb
|
|
217
88
|
|
218
89
|
private
|
219
90
|
|
220
|
-
def handle_response(
|
91
|
+
def handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
|
221
92
|
case resp.code
|
222
93
|
when "429"
|
223
|
-
@client.log.info("Rate limit exceeded for #{method} #{path}, waiting #{data[:retry_after]} seconds")
|
94
|
+
@client.log.info("Rate limit exceeded for #{path.method} #{path.url}, waiting #{data[:retry_after]} seconds")
|
224
95
|
sleep(data[:retry_after])
|
225
|
-
|
226
|
-
__send__(method, path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
227
|
-
else
|
228
|
-
__send__(method, path, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
229
|
-
end
|
96
|
+
request(path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
230
97
|
when "400"
|
231
98
|
raise BadRequestError.new(resp, data)
|
232
99
|
when "401"
|
@@ -263,10 +130,10 @@ module Discorb
|
|
263
130
|
end
|
264
131
|
|
265
132
|
def get_path(path)
|
266
|
-
full_path = if path.start_with?("https://")
|
267
|
-
path
|
133
|
+
full_path = if path.url.start_with?("https://")
|
134
|
+
path.url
|
268
135
|
else
|
269
|
-
API_BASE_URL + path
|
136
|
+
API_BASE_URL + path.url
|
270
137
|
end
|
271
138
|
uri = URI(full_path)
|
272
139
|
full_path.sub(uri.scheme + "://" + uri.host, "")
|
@@ -276,15 +143,13 @@ module Discorb
|
|
276
143
|
begin
|
277
144
|
data = JSON.parse(resp.body, symbolize_names: true)
|
278
145
|
rescue JSON::ParserError, TypeError
|
279
|
-
if resp.body.nil? || resp.body.empty?
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
end
|
285
|
-
if resp["Via"].nil? && resp.code == "429" && data.is_a?(String)
|
286
|
-
raise CloudFlareBanError.new(resp, @client)
|
146
|
+
data = if resp.body.nil? || resp.body.empty?
|
147
|
+
nil
|
148
|
+
else
|
149
|
+
resp.body
|
150
|
+
end
|
287
151
|
end
|
152
|
+
raise CloudFlareBanError.new(resp, @client) if resp["Via"].nil? && resp.code == "429" && data.is_a?(String)
|
288
153
|
data
|
289
154
|
end
|
290
155
|
|
data/lib/discorb/integration.rb
CHANGED
@@ -44,12 +44,11 @@ module Discorb
|
|
44
44
|
}
|
45
45
|
|
46
46
|
# @private
|
47
|
-
def initialize(client, data, guild_id
|
47
|
+
def initialize(client, data, guild_id)
|
48
48
|
@client = client
|
49
49
|
@data = data
|
50
50
|
@guild_id = guild_id
|
51
51
|
_set_data(data)
|
52
|
-
guild.integrations[@id] = self unless no_cache
|
53
52
|
end
|
54
53
|
|
55
54
|
def guild
|
@@ -66,7 +65,7 @@ module Discorb
|
|
66
65
|
#
|
67
66
|
def delete!(reason: nil)
|
68
67
|
Async do
|
69
|
-
@client.http.
|
68
|
+
@client.http.request(Route.new("/guilds/#{@guild}/integrations/#{@id}", "//guilds/:guild_id/integrations/:integration_id", :delete), audit_log_reason: reason).wait
|
70
69
|
end
|
71
70
|
end
|
72
71
|
|
@@ -110,5 +109,35 @@ module Discorb
|
|
110
109
|
@name = data[:name]
|
111
110
|
end
|
112
111
|
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Represents an application for an integration.
|
115
|
+
#
|
116
|
+
class Application < DiscordModel
|
117
|
+
# @return [Discorb::Snowflake] The ID of the application.
|
118
|
+
attr_reader :id
|
119
|
+
# @return [String] The name of the application.
|
120
|
+
attr_reader :name
|
121
|
+
# @return [Asset] The icon of the application.
|
122
|
+
# @return [nil] If the application has no icon.
|
123
|
+
attr_reader :icon
|
124
|
+
# @return [String] The description of the application.
|
125
|
+
attr_reader :description
|
126
|
+
# @return [String] The summary of the application.
|
127
|
+
attr_reader :summary
|
128
|
+
# @return [Discorb::User] The bot user associated with the application.
|
129
|
+
# @return [nil] If the application has no bot user.
|
130
|
+
attr_reader :bot
|
131
|
+
|
132
|
+
# @private
|
133
|
+
def initialize(client, data)
|
134
|
+
@id = Snowflake.new(data[:id])
|
135
|
+
@name = data[:name]
|
136
|
+
@icon = data[:icon] && Asset.new(self, data[:icon])
|
137
|
+
@description = data[:description]
|
138
|
+
@summary = data[:summary]
|
139
|
+
@bot = data[:bot] and client.users[data[:bot][:id]] || Discorb::User.new(client, data[:bot])
|
140
|
+
end
|
141
|
+
end
|
113
142
|
end
|
114
143
|
end
|
data/lib/discorb/intents.rb
CHANGED
@@ -86,7 +86,7 @@ module Discorb
|
|
86
86
|
if @raw_value.key?(name)
|
87
87
|
@raw_value[name]
|
88
88
|
elsif name.end_with?("=") && @raw_value.key?(name[0..-2].to_sym)
|
89
|
-
raise ArgumentError, "true/false expected" unless args.is_a?
|
89
|
+
raise ArgumentError, "true/false expected" unless args.is_a?(TrueClass) || args.is_a?(FalseClass)
|
90
90
|
|
91
91
|
@raw_value[name[0..-2].to_sym] = args
|
92
92
|
else
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Discorb
|
2
3
|
#
|
3
4
|
# Represents auto complete interaction.
|
@@ -17,17 +18,17 @@ module Discorb
|
|
17
18
|
next
|
18
19
|
end
|
19
20
|
|
20
|
-
option_map = command.options.
|
21
|
-
Discorb::CommandInteraction::SlashCommand.modify_option_map(option_map, options, guild)
|
21
|
+
option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
|
22
|
+
Discorb::CommandInteraction::SlashCommand.modify_option_map(option_map, options, guild, {}, {})
|
22
23
|
focused_index = options.find_index { |o| o[:focused] }
|
23
|
-
val = command.options.values[focused_index][:autocomplete]&.call(self, *command.options.map { |k,
|
24
|
+
val = command.options.values.filter { |option| option[:type] != :attachment }[focused_index][:autocomplete]&.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
|
24
25
|
send_complete_result(val)
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
29
|
# @private
|
29
30
|
def send_complete_result(val)
|
30
|
-
@client.http.
|
31
|
+
@client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), {
|
31
32
|
type: 8,
|
32
33
|
data: {
|
33
34
|
choices: val.map do |vk, vv|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Discorb
|
2
3
|
#
|
3
4
|
# Represents a command interaction.
|
@@ -5,7 +6,8 @@ module Discorb
|
|
5
6
|
class CommandInteraction < Interaction
|
6
7
|
@interaction_type = 2
|
7
8
|
@interaction_name = :application_command
|
8
|
-
include Interaction::
|
9
|
+
include Interaction::SourceResponder
|
10
|
+
include Interaction::ModalResponder
|
9
11
|
|
10
12
|
#
|
11
13
|
# Represents a slash command interaction.
|
@@ -25,10 +27,10 @@ module Discorb
|
|
25
27
|
return
|
26
28
|
end
|
27
29
|
|
28
|
-
option_map = command.options.
|
29
|
-
SlashCommand.modify_option_map(option_map, options, guild)
|
30
|
+
option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
|
31
|
+
SlashCommand.modify_option_map(option_map, options, guild, @members, @attachments)
|
30
32
|
|
31
|
-
command.block.call(self, *command.options.map { |k,
|
33
|
+
command.block.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
|
32
34
|
end
|
33
35
|
|
34
36
|
class << self
|
@@ -55,13 +57,13 @@ module Discorb
|
|
55
57
|
options = data[:options]
|
56
58
|
end
|
57
59
|
|
58
|
-
|
60
|
+
[name, options]
|
59
61
|
end
|
60
62
|
|
61
63
|
# @private
|
62
|
-
def modify_option_map(option_map, options, guild)
|
64
|
+
def modify_option_map(option_map, options, guild, members, attachments)
|
63
65
|
options ||= []
|
64
|
-
options.
|
66
|
+
options.each do |option|
|
65
67
|
val = case option[:type]
|
66
68
|
when 3, 4, 5, 10
|
67
69
|
option[:value]
|
@@ -72,7 +74,9 @@ module Discorb
|
|
72
74
|
when 8
|
73
75
|
guild.roles[option[:value]] || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
|
74
76
|
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] }
|
77
|
+
members[option[:value]] || guild.members[option[:value]] || guild.roles[option[:value]] || guild.fetch_member(option[:value]).wait || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
|
78
|
+
when 11
|
79
|
+
attachments[option[:value]]
|
76
80
|
end
|
77
81
|
option_map[option[:name]] = val
|
78
82
|
end
|
@@ -92,6 +96,7 @@ module Discorb
|
|
92
96
|
private
|
93
97
|
|
94
98
|
def _set_data(data)
|
99
|
+
super
|
95
100
|
@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
101
|
@client.commands.find { |c| c.name == data[:name] && c.type_raw == 2 }.block.call(self, @target)
|
97
102
|
end
|
@@ -109,7 +114,8 @@ module Discorb
|
|
109
114
|
private
|
110
115
|
|
111
116
|
def _set_data(data)
|
112
|
-
|
117
|
+
super
|
118
|
+
@target = @messages[data[:target_id]]
|
113
119
|
@client.commands.find { |c| c.name == data[:name] && c.type_raw == 3 }.block.call(self, @target)
|
114
120
|
end
|
115
121
|
end
|
@@ -117,7 +123,26 @@ module Discorb
|
|
117
123
|
private
|
118
124
|
|
119
125
|
def _set_data(data)
|
126
|
+
super
|
120
127
|
@name = data[:name]
|
128
|
+
@messages, @attachments, @members = {}, {}, {}
|
129
|
+
|
130
|
+
if data[:resolved]
|
131
|
+
data[:resolved][:users]&.each do |id, user|
|
132
|
+
@client.users[id] = Discorb::User.new(@client, user)
|
133
|
+
end
|
134
|
+
data[:resolved][:members]&.each do |id, member|
|
135
|
+
@members[id] = Discorb::Member.new(
|
136
|
+
@client, @guild_id, data[:resolved][:users][id], member
|
137
|
+
)
|
138
|
+
end
|
139
|
+
data[:resolved][:messages]&.to_h do |id, _message|
|
140
|
+
@messages[id.to_i] = Message.new(@client, data[:resolved][:messages][data[:target_id].to_sym].merge(guild_id: @guild_id.to_s)).merge(guild_id: @guild_id.to_s)
|
141
|
+
end
|
142
|
+
data[:resolved][:attachments]&.to_h do |id, attachment|
|
143
|
+
@attachments[id.to_s] = Attachment.new(attachment)
|
144
|
+
end
|
145
|
+
end
|
121
146
|
end
|
122
147
|
|
123
148
|
class << self
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Discorb
|
2
3
|
|
3
4
|
#
|
@@ -5,8 +6,10 @@ module Discorb
|
|
5
6
|
# @abstract
|
6
7
|
#
|
7
8
|
class MessageComponentInteraction < Interaction
|
8
|
-
include Interaction::
|
9
|
-
include Interaction::
|
9
|
+
include Interaction::SourceResponder
|
10
|
+
include Interaction::UpdateResponder
|
11
|
+
include Interaction::ModalResponder
|
12
|
+
|
10
13
|
# @return [String] The content of the response.
|
11
14
|
attr_reader :custom_id
|
12
15
|
# @return [Discorb::Message] The target message.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
|
5
|
+
#
|
6
|
+
# Represents a modal interaction.
|
7
|
+
#
|
8
|
+
class ModalInteraction < Interaction
|
9
|
+
include Interaction::SourceResponder
|
10
|
+
|
11
|
+
@interaction_type = 5
|
12
|
+
@interaction_name = :modal_submit
|
13
|
+
@event_name = :modal_submit
|
14
|
+
|
15
|
+
# @return [String] The custom id of the modal.
|
16
|
+
attr_reader :custom_id
|
17
|
+
# @return [{String => String}] The contents of the modal.
|
18
|
+
attr_reader :contents
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def _set_data(data)
|
23
|
+
@custom_id = data[:custom_id]
|
24
|
+
@contents = data[:components].to_h do |component|
|
25
|
+
[component[:components][0][:custom_id], component[:components][0][:value]]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
alias make_interaction new
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Discorb
|
3
|
+
#
|
4
|
+
# Represents an interaction of Discord.
|
5
|
+
#
|
2
6
|
class Interaction
|
3
7
|
#
|
4
8
|
# A module for response with source.
|
5
9
|
#
|
6
|
-
module
|
10
|
+
module SourceResponder
|
7
11
|
#
|
8
12
|
# Response with `DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE`(`5`).
|
9
13
|
#
|
@@ -15,7 +19,7 @@ module Discorb
|
|
15
19
|
#
|
16
20
|
def defer_source(ephemeral: false)
|
17
21
|
Async do
|
18
|
-
@client.http.
|
22
|
+
@client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), {
|
19
23
|
type: 5,
|
20
24
|
data: {
|
21
25
|
flags: (ephemeral ? 1 << 6 : 0),
|
@@ -38,27 +42,27 @@ module Discorb
|
|
38
42
|
# @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
|
39
43
|
# @param [Boolean] ephemeral Whether to make the response ephemeral.
|
40
44
|
#
|
41
|
-
# @return [Discorb::Interaction::
|
45
|
+
# @return [Discorb::Interaction::SourceResponder::CallbackMessage, Discorb::Webhook::Message] The callback message.
|
42
46
|
#
|
43
47
|
def post(content = nil, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil, ephemeral: false)
|
44
48
|
Async do
|
45
49
|
payload = {}
|
46
50
|
payload[:content] = content if content
|
47
51
|
payload[:tts] = tts
|
48
|
-
payload[:embeds] = (embeds || [embed])
|
52
|
+
payload[:embeds] = (embeds || [embed]).map { |e| e&.to_hash }.filter { _1 }
|
49
53
|
payload[:allowed_mentions] = allowed_mentions&.to_hash(@client.allowed_mentions) || @client.allowed_mentions.to_hash
|
50
54
|
payload[:components] = Component.to_payload(components) if components
|
51
55
|
payload[:flags] = (ephemeral ? 1 << 6 : 0)
|
52
56
|
|
53
57
|
ret = if @responded
|
54
|
-
_resp, data = @client.http.
|
58
|
+
_resp, data = @client.http.request(Route.new("/webhooks/#{@application_id}/#{@token}", "//webhooks/:webhook_id/:token", :post), payload).wait
|
55
59
|
webhook = Webhook::URLWebhook.new("/webhooks/#{@application_id}/#{@token}")
|
56
60
|
Webhook::Message.new(webhook, data, @client)
|
57
61
|
elsif @defered
|
58
|
-
@client.http.
|
62
|
+
@client.http.request(Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :patch), payload).wait
|
59
63
|
CallbackMessage.new(@client, payload, @application_id, @token)
|
60
64
|
else
|
61
|
-
@client.http.
|
65
|
+
@client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), { type: 4, data: payload }).wait
|
62
66
|
CallbackMessage.new(@client, payload, @application_id, @token)
|
63
67
|
end
|
64
68
|
@responded = true
|
@@ -66,6 +70,9 @@ module Discorb
|
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
73
|
+
#
|
74
|
+
# Represents of a callback message of interaction.
|
75
|
+
#
|
69
76
|
class CallbackMessage
|
70
77
|
# @private
|
71
78
|
def initialize(client, data, application_id, token)
|
@@ -103,7 +110,7 @@ module Discorb
|
|
103
110
|
payload[:attachments] = attachments.map(&:to_hash) if attachments != Discorb::Unset
|
104
111
|
files = [file] if file != Discorb::Unset
|
105
112
|
files = [] if files == Discorb::Unset
|
106
|
-
@client.http.
|
113
|
+
@client.http.multipart_request(Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :patch), payload, files, headers: headers).wait
|
107
114
|
end
|
108
115
|
end
|
109
116
|
|
@@ -118,7 +125,7 @@ module Discorb
|
|
118
125
|
#
|
119
126
|
def delete!
|
120
127
|
Async do
|
121
|
-
@client.http.
|
128
|
+
@client.http.request(Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :delete)).wait
|
122
129
|
end
|
123
130
|
end
|
124
131
|
end
|
@@ -127,7 +134,7 @@ module Discorb
|
|
127
134
|
#
|
128
135
|
# A module for response with update.
|
129
136
|
#
|
130
|
-
module
|
137
|
+
module UpdateResponder
|
131
138
|
#
|
132
139
|
# Response with `DEFERRED_UPDATE_MESSAGE`(`6`).
|
133
140
|
# @async
|
@@ -138,7 +145,7 @@ module Discorb
|
|
138
145
|
#
|
139
146
|
def defer_update(ephemeral: false)
|
140
147
|
Async do
|
141
|
-
@client.http.
|
148
|
+
@client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), {
|
142
149
|
type: 6,
|
143
150
|
data: {
|
144
151
|
flags: (ephemeral ? 1 << 6 : 0),
|
@@ -176,11 +183,33 @@ module Discorb
|
|
176
183
|
payload[:allowed_mentions] = allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
|
177
184
|
payload[:components] = Component.to_payload(components) if components
|
178
185
|
payload[:flags] = (ephemeral ? 1 << 6 : 0)
|
179
|
-
@client.http.
|
186
|
+
@client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), { type: 7, data: payload }).wait
|
180
187
|
end
|
181
188
|
end
|
182
189
|
end
|
183
190
|
|
191
|
+
#
|
192
|
+
# A module for response with modal.
|
193
|
+
#
|
194
|
+
module ModalResponder
|
195
|
+
#
|
196
|
+
# Response with `MODAL`(`9`).
|
197
|
+
#
|
198
|
+
# @param [String] title The title of the modal.
|
199
|
+
# @param [String] custom_id The custom id of the modal.
|
200
|
+
# @param [Array<Discorb::TextInput>] components The text inputs to send.
|
201
|
+
#
|
202
|
+
# @return [Async::Task<void>] The task.
|
203
|
+
#
|
204
|
+
def show_modal(title, custom_id, components)
|
205
|
+
payload = { title: title, custom_id: custom_id, components: Component.to_payload(components) }
|
206
|
+
@client.http.request(
|
207
|
+
Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post),
|
208
|
+
{ type: 9, data: payload }
|
209
|
+
).wait
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
184
213
|
private
|
185
214
|
|
186
215
|
def _set_data(*)
|
data/lib/discorb/interaction.rb
CHANGED
data/lib/discorb/invite.rb
CHANGED
@@ -105,7 +105,7 @@ module Discorb
|
|
105
105
|
#
|
106
106
|
def delete!(reason: nil)
|
107
107
|
Async do
|
108
|
-
@client.http.
|
108
|
+
@client.http.request(Route.new("/invites/#{@code}", "//invites/:code", :delete), audit_log_reason: reason)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|