discordrb 3.4.3 → 3.5.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/.circleci/config.yml +44 -18
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -1
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -1
- data/.github/workflows/codeql.yml +65 -0
- data/.markdownlint.json +4 -0
- data/.rubocop.yml +8 -2
- data/CHANGELOG.md +390 -225
- data/LICENSE.txt +1 -1
- data/README.md +37 -25
- data/discordrb-webhooks.gemspec +4 -1
- data/discordrb.gemspec +9 -6
- data/lib/discordrb/api/application.rb +202 -0
- data/lib/discordrb/api/channel.rb +177 -11
- data/lib/discordrb/api/interaction.rb +54 -0
- data/lib/discordrb/api/invite.rb +2 -2
- data/lib/discordrb/api/server.rb +40 -19
- data/lib/discordrb/api/user.rb +8 -3
- data/lib/discordrb/api/webhook.rb +57 -0
- data/lib/discordrb/api.rb +19 -5
- data/lib/discordrb/bot.rb +317 -32
- data/lib/discordrb/cache.rb +27 -22
- data/lib/discordrb/commands/command_bot.rb +6 -4
- data/lib/discordrb/commands/container.rb +1 -1
- data/lib/discordrb/commands/parser.rb +2 -2
- data/lib/discordrb/commands/rate_limiter.rb +1 -1
- data/lib/discordrb/container.rb +132 -3
- data/lib/discordrb/data/attachment.rb +15 -0
- data/lib/discordrb/data/audit_logs.rb +3 -3
- data/lib/discordrb/data/channel.rb +167 -23
- data/lib/discordrb/data/component.rb +229 -0
- data/lib/discordrb/data/integration.rb +42 -3
- data/lib/discordrb/data/interaction.rb +800 -0
- data/lib/discordrb/data/invite.rb +1 -1
- data/lib/discordrb/data/member.rb +108 -33
- data/lib/discordrb/data/message.rb +99 -19
- data/lib/discordrb/data/overwrite.rb +13 -7
- data/lib/discordrb/data/role.rb +58 -1
- data/lib/discordrb/data/server.rb +82 -80
- data/lib/discordrb/data/user.rb +69 -9
- data/lib/discordrb/data/webhook.rb +97 -4
- data/lib/discordrb/data.rb +3 -0
- data/lib/discordrb/errors.rb +44 -3
- data/lib/discordrb/events/channels.rb +1 -1
- data/lib/discordrb/events/interactions.rb +482 -0
- data/lib/discordrb/events/message.rb +9 -6
- data/lib/discordrb/events/presence.rb +21 -14
- data/lib/discordrb/events/reactions.rb +0 -1
- data/lib/discordrb/events/threads.rb +96 -0
- data/lib/discordrb/gateway.rb +30 -17
- data/lib/discordrb/permissions.rb +59 -34
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +2 -2
- data/lib/discordrb/voice/network.rb +18 -7
- data/lib/discordrb/voice/sodium.rb +3 -1
- data/lib/discordrb/voice/voice_bot.rb +3 -3
- data/lib/discordrb/webhooks.rb +2 -0
- data/lib/discordrb.rb +37 -4
- metadata +48 -14
- data/.codeclimate.yml +0 -16
- data/.travis.yml +0 -32
- data/bin/travis_build_docs.sh +0 -17
@@ -49,11 +49,12 @@ module Discordrb::API::Channel
|
|
49
49
|
# Get a list of messages from a channel's history
|
50
50
|
# https://discord.com/developers/docs/resources/channel#get-channel-messages
|
51
51
|
def messages(token, channel_id, amount, before = nil, after = nil, around = nil)
|
52
|
+
query_string = URI.encode_www_form({ limit: amount, before: before, after: after, around: around }.compact)
|
52
53
|
Discordrb::API.request(
|
53
54
|
:channels_cid_messages,
|
54
55
|
channel_id,
|
55
56
|
:get,
|
56
|
-
"#{Discordrb::API.api_base}/channels/#{channel_id}/messages
|
57
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/messages?#{query_string}",
|
57
58
|
Authorization: token
|
58
59
|
)
|
59
60
|
end
|
@@ -71,11 +72,11 @@ module Discordrb::API::Channel
|
|
71
72
|
end
|
72
73
|
|
73
74
|
# Send a message to a channel
|
74
|
-
# https://
|
75
|
+
# https://discord.com/developers/docs/resources/channel#create-message
|
75
76
|
# @param attachments [Array<File>, nil] Attachments to use with `attachment://` in embeds. See
|
76
77
|
# https://discord.com/developers/docs/resources/channel#create-message-using-attachments-within-embeds
|
77
|
-
def create_message(token, channel_id, message, tts = false,
|
78
|
-
body = { content: message, tts: tts,
|
78
|
+
def create_message(token, channel_id, message, tts = false, embeds = nil, nonce = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
|
79
|
+
body = { content: message, tts: tts, embeds: embeds, nonce: nonce, allowed_mentions: allowed_mentions, message_reference: message_reference, components: components&.to_a }
|
79
80
|
body = if attachments
|
80
81
|
files = [*0...attachments.size].zip(attachments).to_h
|
81
82
|
{ **files, payload_json: body.to_json }
|
@@ -116,20 +117,20 @@ module Discordrb::API::Channel
|
|
116
117
|
|
117
118
|
# Edit a message
|
118
119
|
# https://discord.com/developers/docs/resources/channel#edit-message
|
119
|
-
def edit_message(token, channel_id, message_id, message, mentions = [],
|
120
|
+
def edit_message(token, channel_id, message_id, message, mentions = [], embeds = nil, components = nil)
|
120
121
|
Discordrb::API.request(
|
121
122
|
:channels_cid_messages_mid,
|
122
123
|
channel_id,
|
123
124
|
:patch,
|
124
125
|
"#{Discordrb::API.api_base}/channels/#{channel_id}/messages/#{message_id}",
|
125
|
-
{ content: message, mentions: mentions,
|
126
|
+
{ content: message, mentions: mentions, embeds: embeds, components: components }.to_json,
|
126
127
|
Authorization: token,
|
127
128
|
content_type: :json
|
128
129
|
)
|
129
130
|
end
|
130
131
|
|
131
132
|
# Delete a message
|
132
|
-
# https://
|
133
|
+
# https://discord.com/developers/docs/resources/channel#delete-message
|
133
134
|
def delete_message(token, channel_id, message_id, reason = nil)
|
134
135
|
Discordrb::API.request(
|
135
136
|
:channels_cid_messages_mid,
|
@@ -142,7 +143,7 @@ module Discordrb::API::Channel
|
|
142
143
|
end
|
143
144
|
|
144
145
|
# Delete messages in bulk
|
145
|
-
# https://
|
146
|
+
# https://discord.com/developers/docs/resources/channel#bulk-delete-messages
|
146
147
|
def bulk_delete_messages(token, channel_id, messages = [], reason = nil)
|
147
148
|
Discordrb::API.request(
|
148
149
|
:channels_cid_messages_bulk_delete,
|
@@ -201,7 +202,7 @@ module Discordrb::API::Channel
|
|
201
202
|
# https://discord.com/developers/docs/resources/channel#get-reactions
|
202
203
|
def get_reactions(token, channel_id, message_id, emoji, before_id, after_id, limit = 100)
|
203
204
|
emoji = URI.encode_www_form_component(emoji) unless emoji.ascii_only?
|
204
|
-
query_string =
|
205
|
+
query_string = URI.encode_www_form({ limit: limit || 100, before: before_id, after: after_id }.compact)
|
205
206
|
Discordrb::API.request(
|
206
207
|
:channels_cid_messages_mid_reactions_emoji,
|
207
208
|
channel_id,
|
@@ -223,6 +224,20 @@ module Discordrb::API::Channel
|
|
223
224
|
)
|
224
225
|
end
|
225
226
|
|
227
|
+
# Deletes all the reactions for a given emoji on a message
|
228
|
+
# https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji
|
229
|
+
def delete_all_emoji_reactions(token, channel_id, message_id, emoji)
|
230
|
+
emoji = URI.encode_www_form_component(emoji) unless emoji.ascii_only?
|
231
|
+
|
232
|
+
Discordrb::API.request(
|
233
|
+
:channels_cid_messages_mid_reactions_emoji,
|
234
|
+
channel_id,
|
235
|
+
:delete,
|
236
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/messages/#{message_id}/reactions/#{emoji}",
|
237
|
+
Authorization: token
|
238
|
+
)
|
239
|
+
end
|
240
|
+
|
226
241
|
# Update a channels permission for a role or member
|
227
242
|
# https://discord.com/developers/docs/resources/channel#edit-channel-permissions
|
228
243
|
def update_permission(token, channel_id, overwrite_id, allow, deny, type, reason = nil)
|
@@ -304,7 +319,7 @@ module Discordrb::API::Channel
|
|
304
319
|
end
|
305
320
|
|
306
321
|
# Pin a message
|
307
|
-
# https://
|
322
|
+
# https://discord.com/developers/docs/resources/channel#add-pinned-channel-message
|
308
323
|
def pin_message(token, channel_id, message_id, reason = nil)
|
309
324
|
Discordrb::API.request(
|
310
325
|
:channels_cid_pins_mid,
|
@@ -318,7 +333,7 @@ module Discordrb::API::Channel
|
|
318
333
|
end
|
319
334
|
|
320
335
|
# Unpin a message
|
321
|
-
# https://
|
336
|
+
# https://discord.com/developers/docs/resources/channel#delete-pinned-channel-message
|
322
337
|
def unpin_message(token, channel_id, message_id, reason = nil)
|
323
338
|
Discordrb::API.request(
|
324
339
|
:channels_cid_pins_mid,
|
@@ -331,6 +346,7 @@ module Discordrb::API::Channel
|
|
331
346
|
end
|
332
347
|
|
333
348
|
# Create an empty group channel.
|
349
|
+
# @deprecated Discord no longer supports bots in group DMs, this endpoint was repurposed and no longer works as implemented here.
|
334
350
|
# https://discord.com/developers/docs/resources/user#create-group-dm
|
335
351
|
def create_empty_group(token, bot_user_id)
|
336
352
|
Discordrb::API.request(
|
@@ -345,6 +361,7 @@ module Discordrb::API::Channel
|
|
345
361
|
end
|
346
362
|
|
347
363
|
# Create a group channel.
|
364
|
+
# @deprecated Discord no longer supports bots in group DMs, this endpoint was repurposed and no longer works as implemented here.
|
348
365
|
# https://discord.com/developers/docs/resources/channel#group-dm-add-recipient
|
349
366
|
def create_group(token, pm_channel_id, user_id)
|
350
367
|
Discordrb::API.request(
|
@@ -365,6 +382,7 @@ module Discordrb::API::Channel
|
|
365
382
|
end
|
366
383
|
|
367
384
|
# Add a user to a group channel.
|
385
|
+
# @deprecated Discord no longer supports bots in group DMs, this endpoint was repurposed and no longer works as implemented here.
|
368
386
|
# https://discord.com/developers/docs/resources/channel#group-dm-add-recipient
|
369
387
|
def add_group_user(token, group_channel_id, user_id)
|
370
388
|
Discordrb::API.request(
|
@@ -379,6 +397,7 @@ module Discordrb::API::Channel
|
|
379
397
|
end
|
380
398
|
|
381
399
|
# Remove a user from a group channel.
|
400
|
+
# @deprecated Discord no longer supports bots in group DMs, this endpoint was repurposed and no longer works as implemented here.
|
382
401
|
# https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient
|
383
402
|
def remove_group_user(token, group_channel_id, user_id)
|
384
403
|
Discordrb::API.request(
|
@@ -392,6 +411,7 @@ module Discordrb::API::Channel
|
|
392
411
|
end
|
393
412
|
|
394
413
|
# Leave a group channel.
|
414
|
+
# @deprecated Discord no longer supports bots in group DMs, this endpoint was repurposed and no longer works as implemented here.
|
395
415
|
# https://discord.com/developers/docs/resources/channel#deleteclose-channel
|
396
416
|
def leave_group(token, group_channel_id)
|
397
417
|
Discordrb::API.request(
|
@@ -430,4 +450,150 @@ module Discordrb::API::Channel
|
|
430
450
|
Authorization: token
|
431
451
|
)
|
432
452
|
end
|
453
|
+
|
454
|
+
# Start a thread based off a channel message.
|
455
|
+
# https://discord.com/developers/docs/resources/channel#start-thread-with-message
|
456
|
+
def start_thread_with_message(token, channel_id, message_id, name, auto_archive_duration)
|
457
|
+
Discordrb::API.request(
|
458
|
+
:channels_cid_messages_mid_threads,
|
459
|
+
channel_id,
|
460
|
+
:post,
|
461
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/messages/#{message_id}/threads",
|
462
|
+
{ name: name, auto_archive_duration: auto_archive_duration }.to_json,
|
463
|
+
Authorization: token,
|
464
|
+
content_type: :json
|
465
|
+
)
|
466
|
+
end
|
467
|
+
|
468
|
+
# Start a thread without an associated message.
|
469
|
+
# https://discord.com/developers/docs/resources/channel#start-thread-without-message
|
470
|
+
def start_thread_without_message(token, channel_id, name, auto_archive_duration, type = 11)
|
471
|
+
Discordrb::API.request(
|
472
|
+
:channels_cid_threads,
|
473
|
+
channel_id,
|
474
|
+
:post,
|
475
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/threads",
|
476
|
+
{ name: name, auto_archive_duration: auto_archive_duration, type: type },
|
477
|
+
Authorization: token,
|
478
|
+
content_type: :json
|
479
|
+
)
|
480
|
+
end
|
481
|
+
|
482
|
+
# Add the current user to a thread.
|
483
|
+
# https://discord.com/developers/docs/resources/channel#join-thread
|
484
|
+
def join_thread(token, channel_id)
|
485
|
+
Discordrb::API.request(
|
486
|
+
:channels_cid_thread_members_me,
|
487
|
+
channel_id,
|
488
|
+
:put,
|
489
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/thread-members/@me",
|
490
|
+
nil,
|
491
|
+
Authorization: token
|
492
|
+
)
|
493
|
+
end
|
494
|
+
|
495
|
+
# Add a user to a thread.
|
496
|
+
# https://discord.com/developers/docs/resources/channel#add-thread-member
|
497
|
+
def add_thread_member(token, channel_id, user_id)
|
498
|
+
Discordrb::API.request(
|
499
|
+
:channels_cid_thread_members_uid,
|
500
|
+
channel_id,
|
501
|
+
:put,
|
502
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/thread-members/#{user_id}",
|
503
|
+
nil,
|
504
|
+
Authorization: token
|
505
|
+
)
|
506
|
+
end
|
507
|
+
|
508
|
+
# Remove the current user from a thread.
|
509
|
+
# https://discord.com/developers/docs/resources/channel#leave-thread
|
510
|
+
def leave_thread(token, channel_id)
|
511
|
+
Discordrb::API.request(
|
512
|
+
:channels_cid_thread_members_me,
|
513
|
+
channel_id,
|
514
|
+
:delete,
|
515
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/thread-members/#{user_id}",
|
516
|
+
Authorization: token
|
517
|
+
)
|
518
|
+
end
|
519
|
+
|
520
|
+
# Remove a user from a thread.
|
521
|
+
# https://discord.com/developers/docs/resources/channel#remove-thread-member
|
522
|
+
def remove_thread_member(token, channel_id, user_id)
|
523
|
+
Discordrb::API.request(
|
524
|
+
:channels_cid_thread_members_uid,
|
525
|
+
channel_id,
|
526
|
+
:delete,
|
527
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/thread-members/#{user_id}",
|
528
|
+
Authorization: token
|
529
|
+
)
|
530
|
+
end
|
531
|
+
|
532
|
+
# Get the members of a thread.
|
533
|
+
# https://discord.com/developers/docs/resources/channel#list-thread-members
|
534
|
+
def list_thread_members(token, channel_id, before, limit)
|
535
|
+
query = URI.encode_www_form({ before: before, limit: limit }.compact)
|
536
|
+
|
537
|
+
Discordrb::API.request(
|
538
|
+
:channels_cid_thread_members,
|
539
|
+
channel_id,
|
540
|
+
:get,
|
541
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/thread-members?#{query}",
|
542
|
+
Authorization: token
|
543
|
+
)
|
544
|
+
end
|
545
|
+
|
546
|
+
# List active threads
|
547
|
+
# https://discord.com/developers/docs/resources/channel#list-active-threads
|
548
|
+
def list_active_threads(token, channel_id)
|
549
|
+
Discordrb::API.request(
|
550
|
+
:channels_cid_threads_active,
|
551
|
+
channel_id,
|
552
|
+
:get,
|
553
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/threads/active",
|
554
|
+
Authorization: token
|
555
|
+
)
|
556
|
+
end
|
557
|
+
|
558
|
+
# List public archived threads.
|
559
|
+
# https://discord.com/developers/docs/resources/channel#list-public-archived-threads
|
560
|
+
def list_public_archived_threads(token, channel_id, before = nil, limit = nil)
|
561
|
+
query = URI.encode_www_form({ before: before, limit: limit }.compact)
|
562
|
+
|
563
|
+
Discordrb::API.request(
|
564
|
+
:channels_cid_threads_archived_public,
|
565
|
+
channel_id,
|
566
|
+
:get,
|
567
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/threads/archived/public?#{query}",
|
568
|
+
Authorization: token
|
569
|
+
)
|
570
|
+
end
|
571
|
+
|
572
|
+
# List private archived threads.
|
573
|
+
# https://discord.com/developers/docs/resources/channel#list-private-archived-threads
|
574
|
+
def list_private_archived_threads(token, channel_id, before = nil, limit = nil)
|
575
|
+
query = URI.encode_www_form({ before: before, limit: limit }.compact)
|
576
|
+
|
577
|
+
Discordrb::API.request(
|
578
|
+
:channels_cid_threads_archived_private,
|
579
|
+
channel_id,
|
580
|
+
:get,
|
581
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/threads/archived/private?#{query}",
|
582
|
+
Authorization: token
|
583
|
+
)
|
584
|
+
end
|
585
|
+
|
586
|
+
# List joined private archived threads.
|
587
|
+
# https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads
|
588
|
+
def list_joined_private_archived_threads(token, channel_id, before = nil, limit = nil)
|
589
|
+
query = URI.encode_www_form({ before: before, limit: limit }.compact)
|
590
|
+
|
591
|
+
Discordrb::API.request(
|
592
|
+
:channels_cid_users_me_threads_archived_private,
|
593
|
+
channel_id,
|
594
|
+
:get,
|
595
|
+
"#{Discordrb::API.api_base}/channels/#{channel_id}/users/@me/threads/archived/private?#{query}",
|
596
|
+
Authorization: token
|
597
|
+
)
|
598
|
+
end
|
433
599
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# API calls for interactions.
|
4
|
+
module Discordrb::API::Interaction
|
5
|
+
module_function
|
6
|
+
|
7
|
+
# Respond to an interaction.
|
8
|
+
# https://discord.com/developers/docs/interactions/slash-commands#create-interaction-response
|
9
|
+
def create_interaction_response(interaction_token, interaction_id, type, content = nil, tts = nil, embeds = nil, allowed_mentions = nil, flags = nil, components = nil)
|
10
|
+
data = { tts: tts, content: content, embeds: embeds, allowed_mentions: allowed_mentions, flags: flags, components: components }.compact
|
11
|
+
|
12
|
+
Discordrb::API.request(
|
13
|
+
:interactions_iid_token_callback,
|
14
|
+
interaction_id,
|
15
|
+
:post,
|
16
|
+
"#{Discordrb::API.api_base}/interactions/#{interaction_id}/#{interaction_token}/callback",
|
17
|
+
{ type: type, data: data }.to_json,
|
18
|
+
content_type: :json
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create a response that results in a modal.
|
23
|
+
# https://discord.com/developers/docs/interactions/slash-commands#create-interaction-response
|
24
|
+
def create_interaction_modal_response(interaction_token, interaction_id, custom_id, title, components)
|
25
|
+
data = { custom_id: custom_id, title: title, components: components.to_a }.compact
|
26
|
+
|
27
|
+
Discordrb::API.request(
|
28
|
+
:interactions_iid_token_callback,
|
29
|
+
interaction_id,
|
30
|
+
:post,
|
31
|
+
"#{Discordrb::API.api_base}/interactions/#{interaction_id}/#{interaction_token}/callback",
|
32
|
+
{ type: 9, data: data }.to_json,
|
33
|
+
content_type: :json
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get the original response to an interaction.
|
38
|
+
# https://discord.com/developers/docs/interactions/slash-commands#get-original-interaction-response
|
39
|
+
def get_original_interaction_response(interaction_token, application_id)
|
40
|
+
Discordrb::API::Webhook.token_get_message(interaction_token, application_id, '@original')
|
41
|
+
end
|
42
|
+
|
43
|
+
# Edit the original response to an interaction.
|
44
|
+
# https://discord.com/developers/docs/interactions/slash-commands#edit-original-interaction-response
|
45
|
+
def edit_original_interaction_response(interaction_token, application_id, content = nil, embeds = nil, allowed_mentions = nil, components = nil)
|
46
|
+
Discordrb::API::Webhook.token_edit_message(interaction_token, application_id, '@original', content, embeds, allowed_mentions, components)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Delete the original response to an interaction.
|
50
|
+
# https://discord.com/developers/docs/interactions/slash-commands#delete-original-interaction-response
|
51
|
+
def delete_original_interaction_response(interaction_token, application_id)
|
52
|
+
Discordrb::API::Webhook.token_delete_message(interaction_token, application_id, '@original')
|
53
|
+
end
|
54
|
+
end
|
data/lib/discordrb/api/invite.rb
CHANGED
@@ -11,7 +11,7 @@ module Discordrb::API::Invite
|
|
11
11
|
:invite_code,
|
12
12
|
nil,
|
13
13
|
:get,
|
14
|
-
"#{Discordrb::API.api_base}/
|
14
|
+
"#{Discordrb::API.api_base}/invites/#{invite_code}#{counts ? '?with_counts=true' : ''}",
|
15
15
|
Authorization: token
|
16
16
|
)
|
17
17
|
end
|
@@ -36,7 +36,7 @@ module Discordrb::API::Invite
|
|
36
36
|
:invite_code,
|
37
37
|
nil,
|
38
38
|
:post,
|
39
|
-
"#{Discordrb::API.api_base}/
|
39
|
+
"#{Discordrb::API.api_base}/invites/#{invite_code}",
|
40
40
|
nil,
|
41
41
|
Authorization: token
|
42
42
|
)
|
data/lib/discordrb/api/server.rb
CHANGED
@@ -128,18 +128,20 @@ module Discordrb::API::Server
|
|
128
128
|
# Gets members from the server
|
129
129
|
# https://discord.com/developers/docs/resources/guild#list-guild-members
|
130
130
|
def resolve_members(token, server_id, limit, after = nil)
|
131
|
+
query_string = URI.encode_www_form({ limit: limit, after: after }.compact)
|
131
132
|
Discordrb::API.request(
|
132
133
|
:guilds_sid_members,
|
133
134
|
server_id,
|
134
135
|
:get,
|
135
|
-
"#{Discordrb::API.api_base}/guilds/#{server_id}/members
|
136
|
+
"#{Discordrb::API.api_base}/guilds/#{server_id}/members?#{query_string}",
|
136
137
|
Authorization: token
|
137
138
|
)
|
138
139
|
end
|
139
140
|
|
140
141
|
# Update a user properties
|
141
142
|
# https://discord.com/developers/docs/resources/guild#modify-guild-member
|
142
|
-
def update_member(token, server_id, user_id, nick:
|
143
|
+
def update_member(token, server_id, user_id, nick: :undef, roles: :undef, mute: :undef, deaf: :undef, channel_id: :undef,
|
144
|
+
communication_disabled_until: :undef, reason: nil)
|
143
145
|
Discordrb::API.request(
|
144
146
|
:guilds_sid_members_uid,
|
145
147
|
server_id,
|
@@ -149,8 +151,9 @@ module Discordrb::API::Server
|
|
149
151
|
nick: nick,
|
150
152
|
mute: mute,
|
151
153
|
deaf: deaf,
|
152
|
-
channel_id: channel_id
|
153
|
-
|
154
|
+
channel_id: channel_id,
|
155
|
+
communication_disabled_until: communication_disabled_until
|
156
|
+
}.reject { |_, v| v == :undef }.to_json,
|
154
157
|
Authorization: token,
|
155
158
|
content_type: :json,
|
156
159
|
'X-Audit-Log-Reason': reason
|
@@ -173,12 +176,13 @@ module Discordrb::API::Server
|
|
173
176
|
|
174
177
|
# Get a server's banned users
|
175
178
|
# https://discord.com/developers/docs/resources/guild#get-guild-bans
|
176
|
-
def bans(token, server_id)
|
179
|
+
def bans(token, server_id, limit = nil, before = nil, after = nil)
|
180
|
+
query_string = URI.encode_www_form({ limit: limit, before: before, after: after }.compact)
|
177
181
|
Discordrb::API.request(
|
178
182
|
:guilds_sid_bans,
|
179
183
|
server_id,
|
180
184
|
:get,
|
181
|
-
"#{Discordrb::API.api_base}/guilds/#{server_id}/bans",
|
185
|
+
"#{Discordrb::API.api_base}/guilds/#{server_id}/bans?#{query_string}",
|
182
186
|
Authorization: token
|
183
187
|
)
|
184
188
|
end
|
@@ -191,7 +195,7 @@ module Discordrb::API::Server
|
|
191
195
|
:guilds_sid_bans_uid,
|
192
196
|
server_id,
|
193
197
|
:put,
|
194
|
-
"#{Discordrb::API.api_base}/guilds/#{server_id}/bans/#{user_id}?
|
198
|
+
"#{Discordrb::API.api_base}/guilds/#{server_id}/bans/#{user_id}?delete_message_days=#{message_days}&reason=#{reason}",
|
195
199
|
nil,
|
196
200
|
Authorization: token
|
197
201
|
)
|
@@ -245,13 +249,28 @@ module Discordrb::API::Server
|
|
245
249
|
# sending TTS messages, embedding links, sending files, reading the history, mentioning everybody,
|
246
250
|
# connecting to voice, speaking and voice activity (push-to-talk isn't mandatory)
|
247
251
|
# https://discord.com/developers/docs/resources/guild#batch-modify-guild-role
|
248
|
-
|
252
|
+
# @param icon [:undef, File]
|
253
|
+
def update_role(token, server_id, role_id, name, colour, hoist = false, mentionable = false, packed_permissions = 104_324_161, reason = nil, icon = :undef)
|
254
|
+
data = { color: colour, name: name, hoist: hoist, mentionable: mentionable, permissions: packed_permissions }
|
255
|
+
|
256
|
+
if icon != :undef && icon
|
257
|
+
path_method = %i[original_filename path local_path].find { |meth| icon.respond_to?(meth) }
|
258
|
+
|
259
|
+
raise ArgumentError, 'File object must respond to original_filename, path, or local path.' unless path_method
|
260
|
+
raise ArgumentError, 'File must respond to read' unless icon.respond_to? :read
|
261
|
+
|
262
|
+
mime_type = MIME::Types.type_for(icon.__send__(path_method)).first&.to_s || 'image/jpeg'
|
263
|
+
data[:icon] = "data:#{mime_type};base64,#{Base64.encode64(icon.read).strip}"
|
264
|
+
elsif icon.nil?
|
265
|
+
data[:icon] = nil
|
266
|
+
end
|
267
|
+
|
249
268
|
Discordrb::API.request(
|
250
269
|
:guilds_sid_roles_rid,
|
251
270
|
server_id,
|
252
271
|
:patch,
|
253
272
|
"#{Discordrb::API.api_base}/guilds/#{server_id}/roles/#{role_id}",
|
254
|
-
|
273
|
+
data.to_json,
|
255
274
|
Authorization: token,
|
256
275
|
content_type: :json,
|
257
276
|
'X-Audit-Log-Reason': reason
|
@@ -375,7 +394,7 @@ module Discordrb::API::Server
|
|
375
394
|
end
|
376
395
|
|
377
396
|
# Create a server integration
|
378
|
-
# https://
|
397
|
+
# https://discord.com/developers/docs/resources/guild#create-guild-integration
|
379
398
|
def create_integration(token, server_id, type, id, reason = nil)
|
380
399
|
Discordrb::API.request(
|
381
400
|
:guilds_sid_integrations,
|
@@ -403,7 +422,7 @@ module Discordrb::API::Server
|
|
403
422
|
end
|
404
423
|
|
405
424
|
# Delete a server integration
|
406
|
-
# https://
|
425
|
+
# https://discord.com/developers/docs/resources/guild#delete-guild-integration
|
407
426
|
def delete_integration(token, server_id, integration_id, reason = nil)
|
408
427
|
Discordrb::API.request(
|
409
428
|
:guilds_sid_integrations_iid,
|
@@ -428,32 +447,34 @@ module Discordrb::API::Server
|
|
428
447
|
)
|
429
448
|
end
|
430
449
|
|
431
|
-
# Retrieves a server's
|
432
|
-
# https://discord.com/developers/docs/resources/guild#get-guild-
|
433
|
-
def
|
450
|
+
# Retrieves a server's widget information
|
451
|
+
# https://discord.com/developers/docs/resources/guild#get-guild-widget
|
452
|
+
def widget(token, server_id)
|
434
453
|
Discordrb::API.request(
|
435
454
|
:guilds_sid_embed,
|
436
455
|
server_id,
|
437
456
|
:get,
|
438
|
-
"#{Discordrb::API.api_base}/guilds/#{server_id}/
|
457
|
+
"#{Discordrb::API.api_base}/guilds/#{server_id}/widget",
|
439
458
|
Authorization: token
|
440
459
|
)
|
441
460
|
end
|
461
|
+
alias embed widget
|
442
462
|
|
443
|
-
# Modify a server's
|
444
|
-
# https://discord.com/developers/docs/resources/guild#modify-guild-
|
445
|
-
def
|
463
|
+
# Modify a server's widget settings
|
464
|
+
# https://discord.com/developers/docs/resources/guild#modify-guild-widget
|
465
|
+
def modify_widget(token, server_id, enabled, channel_id, reason = nil)
|
446
466
|
Discordrb::API.request(
|
447
467
|
:guilds_sid_embed,
|
448
468
|
server_id,
|
449
469
|
:patch,
|
450
|
-
"#{Discordrb::API.api_base}/guilds/#{server_id}/
|
470
|
+
"#{Discordrb::API.api_base}/guilds/#{server_id}/widget",
|
451
471
|
{ enabled: enabled, channel_id: channel_id }.to_json,
|
452
472
|
Authorization: token,
|
453
473
|
'X-Audit-Log-Reason': reason,
|
454
474
|
content_type: :json
|
455
475
|
)
|
456
476
|
end
|
477
|
+
alias modify_embed modify_widget
|
457
478
|
|
458
479
|
# Adds a custom emoji.
|
459
480
|
# https://discord.com/developers/docs/resources/emoji#create-guild-emoji
|
data/lib/discordrb/api/user.rb
CHANGED
@@ -132,9 +132,14 @@ module Discordrb::API::User
|
|
132
132
|
)
|
133
133
|
end
|
134
134
|
|
135
|
-
# Returns one of the "default" discord avatars from the CDN given a discriminator
|
136
|
-
|
137
|
-
|
135
|
+
# Returns one of the "default" discord avatars from the CDN given a discriminator or id since new usernames
|
136
|
+
# TODO: Maybe change this method again after discriminator removal ?
|
137
|
+
def default_avatar(discrim_id = 0, legacy: false)
|
138
|
+
index = if legacy
|
139
|
+
discrim_id.to_i % 5
|
140
|
+
else
|
141
|
+
(discrim_id.to_i >> 22) % 5
|
142
|
+
end
|
138
143
|
"#{Discordrb::API.cdn_url}/embed/avatars/#{index}.png"
|
139
144
|
end
|
140
145
|
|
@@ -27,6 +27,28 @@ module Discordrb::API::Webhook
|
|
27
27
|
)
|
28
28
|
end
|
29
29
|
|
30
|
+
# Execute a webhook via token.
|
31
|
+
# https://discord.com/developers/docs/resources/webhook#execute-webhook
|
32
|
+
def token_execute_webhook(webhook_token, webhook_id, wait = false, content = nil, username = nil, avatar_url = nil, tts = nil, file = nil, embeds = nil, allowed_mentions = nil, flags = nil, components = nil)
|
33
|
+
body = { content: content, username: username, avatar_url: avatar_url, tts: tts, embeds: embeds&.map(&:to_hash), allowed_mentions: allowed_mentions, flags: flags, components: components }
|
34
|
+
body = if file
|
35
|
+
{ file: file, payload_json: body.to_json }
|
36
|
+
else
|
37
|
+
body.to_json
|
38
|
+
end
|
39
|
+
|
40
|
+
headers = { content_type: :json } unless file
|
41
|
+
|
42
|
+
Discordrb::API.request(
|
43
|
+
:webhooks_wid,
|
44
|
+
webhook_id,
|
45
|
+
:post,
|
46
|
+
"#{Discordrb::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}?wait=#{wait}",
|
47
|
+
body,
|
48
|
+
headers
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
30
52
|
# Update a webhook
|
31
53
|
# https://discord.com/developers/docs/resources/webhook#modify-webhook
|
32
54
|
def update_webhook(token, webhook_id, data, reason = nil)
|
@@ -80,4 +102,39 @@ module Discordrb::API::Webhook
|
|
80
102
|
'X-Audit-Log-Reason': reason
|
81
103
|
)
|
82
104
|
end
|
105
|
+
|
106
|
+
# Get a message that was created by the webhook corresponding to the provided token.
|
107
|
+
# https://discord.com/developers/docs/resources/webhook#get-webhook-message
|
108
|
+
def token_get_message(webhook_token, webhook_id, message_id)
|
109
|
+
Discordrb::API.request(
|
110
|
+
:webhooks_wid_messages_mid,
|
111
|
+
webhook_id,
|
112
|
+
:get,
|
113
|
+
"#{Discordrb::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}"
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Edit a webhook message via webhook token
|
118
|
+
# https://discord.com/developers/docs/resources/webhook#edit-webhook-message
|
119
|
+
def token_edit_message(webhook_token, webhook_id, message_id, content = nil, embeds = nil, allowed_mentions = nil, components = nil)
|
120
|
+
Discordrb::API.request(
|
121
|
+
:webhooks_wid_messages,
|
122
|
+
webhook_id,
|
123
|
+
:patch,
|
124
|
+
"#{Discordrb::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}",
|
125
|
+
{ content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components }.to_json,
|
126
|
+
content_type: :json
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Delete a webhook message via webhook token.
|
131
|
+
# https://discord.com/developers/docs/resources/webhook#delete-webhook-message
|
132
|
+
def token_delete_message(webhook_token, webhook_id, message_id)
|
133
|
+
Discordrb::API.request(
|
134
|
+
:webhooks_wid_messages,
|
135
|
+
webhook_id,
|
136
|
+
:delete,
|
137
|
+
"#{Discordrb::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}"
|
138
|
+
)
|
139
|
+
end
|
83
140
|
end
|
data/lib/discordrb/api.rb
CHANGED
@@ -9,7 +9,7 @@ require 'discordrb/errors'
|
|
9
9
|
# List of methods representing endpoints in Discord's API
|
10
10
|
module Discordrb::API
|
11
11
|
# The base URL of the Discord REST API.
|
12
|
-
APIBASE = 'https://discord.com/api/
|
12
|
+
APIBASE = 'https://discord.com/api/v9'
|
13
13
|
|
14
14
|
# The URL of Discord's CDN
|
15
15
|
CDN_URL = 'https://cdn.discordapp.com'
|
@@ -94,9 +94,6 @@ module Discordrb::API
|
|
94
94
|
# Add a custom user agent
|
95
95
|
attributes.last[:user_agent] = user_agent if attributes.last.is_a? Hash
|
96
96
|
|
97
|
-
# Specify RateLimit precision
|
98
|
-
attributes.last[:x_ratelimit_precision] = 'millisecond' if attributes.last.is_a?(Hash)
|
99
|
-
|
100
97
|
# The most recent Discord rate limit requirements require the support of major parameters, where a particular route
|
101
98
|
# and major parameter combination (*not* the HTTP method) uniquely identifies a RL bucket.
|
102
99
|
key = [key, major_parameter].freeze
|
@@ -115,6 +112,15 @@ module Discordrb::API
|
|
115
112
|
response = raw_request(type, attributes)
|
116
113
|
rescue RestClient::Exception => e
|
117
114
|
response = e.response
|
115
|
+
|
116
|
+
if response.body && !e.is_a?(RestClient::TooManyRequests)
|
117
|
+
data = JSON.parse(response.body)
|
118
|
+
err_klass = Discordrb::Errors.error_class_for(data['code'] || 0)
|
119
|
+
e = err_klass.new(data['message'], data['errors'])
|
120
|
+
|
121
|
+
Discordrb::LOGGER.error(e.full_message)
|
122
|
+
end
|
123
|
+
|
118
124
|
raise e
|
119
125
|
rescue Discordrb::Errors::NoPermission => e
|
120
126
|
if e.respond_to?(:_rc_response)
|
@@ -137,7 +143,7 @@ module Discordrb::API
|
|
137
143
|
|
138
144
|
unless mutex.locked?
|
139
145
|
response = JSON.parse(e.response)
|
140
|
-
wait_seconds = response['retry_after'].
|
146
|
+
wait_seconds = response['retry_after'] ? response['retry_after'].to_f : e.response.headers[:retry_after].to_i
|
141
147
|
Discordrb::LOGGER.ratelimit("Locking RL mutex (key: #{key}) for #{wait_seconds} seconds due to Discord rate limiting")
|
142
148
|
trace("429 #{key.join(' ')}")
|
143
149
|
|
@@ -217,6 +223,14 @@ module Discordrb::API
|
|
217
223
|
"#{cdn_url}/app-assets/#{application_id}/achievements/#{achievement_id}/icons/#{icon_hash}.#{format}"
|
218
224
|
end
|
219
225
|
|
226
|
+
# @param role_id [String, Integer]
|
227
|
+
# @param icon_hash [String]
|
228
|
+
# @param format ['webp', 'png', 'jpeg']
|
229
|
+
# @return [String]
|
230
|
+
def role_icon_url(role_id, icon_hash, format = 'webp')
|
231
|
+
"#{cdn_url}/role-icons/#{role_id}/#{icon_hash}.#{format}"
|
232
|
+
end
|
233
|
+
|
220
234
|
# Login to the server
|
221
235
|
def login(email, password)
|
222
236
|
request(
|