discorb 0.13.1 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|