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
@@ -70,7 +70,9 @@ module Discordrb::Commands
|
|
70
70
|
# @option attributes [String] :quote_end Character that should end a quoted string (see
|
71
71
|
# :advanced_functionality). Default is '"' or the same as :quote_start. Set to an empty string to disable.
|
72
72
|
# @option attributes [true, false] :ignore_bots Whether the bot should ignore bot accounts or not. Default is false.
|
73
|
-
def initialize(attributes
|
73
|
+
def initialize(**attributes)
|
74
|
+
# TODO: This needs to be revisited. undefined attributes are treated
|
75
|
+
# as explicitly passed nils.
|
74
76
|
super(
|
75
77
|
log_mode: attributes[:log_mode],
|
76
78
|
token: attributes[:token],
|
@@ -85,7 +87,7 @@ module Discordrb::Commands
|
|
85
87
|
redact_token: attributes.key?(:redact_token) ? attributes[:redact_token] : true,
|
86
88
|
ignore_bots: attributes[:ignore_bots],
|
87
89
|
compress_mode: attributes[:compress_mode],
|
88
|
-
intents: attributes[:intents]
|
90
|
+
intents: attributes[:intents] || :all
|
89
91
|
)
|
90
92
|
|
91
93
|
@prefix = attributes[:prefix]
|
@@ -335,7 +337,7 @@ module Discordrb::Commands
|
|
335
337
|
return nil if chain.empty?
|
336
338
|
|
337
339
|
args = chain.split(' ')
|
338
|
-
execute_command(args[0].to_sym, event, args[1
|
340
|
+
execute_command(args[0].to_sym, event, args[1..])
|
339
341
|
end
|
340
342
|
|
341
343
|
# Sets the permission level of a user
|
@@ -443,7 +445,7 @@ module Discordrb::Commands
|
|
443
445
|
def standard_prefix_trigger(message, prefix)
|
444
446
|
return nil unless message.start_with? prefix
|
445
447
|
|
446
|
-
message[prefix.length
|
448
|
+
message[prefix.length..]
|
447
449
|
end
|
448
450
|
|
449
451
|
def required_permissions?(member, required, channel = nil)
|
@@ -86,7 +86,7 @@ module Discordrb::Commands
|
|
86
86
|
# Adds all commands from another container into this one. Existing commands will be overwritten.
|
87
87
|
# @param container [Module] A module that `extend`s {CommandContainer} from which the commands will be added.
|
88
88
|
def include_commands(container)
|
89
|
-
handlers = container.instance_variable_get
|
89
|
+
handlers = container.instance_variable_get :@commands
|
90
90
|
return unless handlers
|
91
91
|
|
92
92
|
@commands ||= {}
|
@@ -246,7 +246,7 @@ module Discordrb::Commands
|
|
246
246
|
|
247
247
|
first_space = command.index ' '
|
248
248
|
command_name = first_space ? command[0..first_space - 1] : command
|
249
|
-
arguments = first_space ? command[first_space + 1
|
249
|
+
arguments = first_space ? command[first_space + 1..] : ''
|
250
250
|
|
251
251
|
# Append a previous sign if none is present
|
252
252
|
arguments += @attributes[:previous] unless arguments.include? @attributes[:previous]
|
@@ -318,7 +318,7 @@ module Discordrb::Commands
|
|
318
318
|
arg.split ' '
|
319
319
|
end
|
320
320
|
|
321
|
-
chain = chain[chain_args_index + 1
|
321
|
+
chain = chain[chain_args_index + 1..]
|
322
322
|
end
|
323
323
|
|
324
324
|
[chain_args, chain]
|
@@ -125,7 +125,7 @@ module Discordrb::Commands
|
|
125
125
|
# Adds all the buckets from another RateLimiter onto this one.
|
126
126
|
# @param limiter [Module] Another {RateLimiter} module
|
127
127
|
def include_buckets(limiter)
|
128
|
-
buckets = limiter.instance_variable_get(
|
128
|
+
buckets = limiter.instance_variable_get(:@buckets) || {}
|
129
129
|
@buckets ||= {}
|
130
130
|
@buckets.merge! buckets
|
131
131
|
end
|
data/lib/discordrb/container.rb
CHANGED
@@ -13,6 +13,7 @@ require 'discordrb/events/guilds'
|
|
13
13
|
require 'discordrb/events/await'
|
14
14
|
require 'discordrb/events/bans'
|
15
15
|
require 'discordrb/events/reactions'
|
16
|
+
require 'discordrb/events/interactions'
|
16
17
|
|
17
18
|
require 'discordrb/await'
|
18
19
|
|
@@ -522,6 +523,118 @@ module Discordrb
|
|
522
523
|
register_event(InviteDeleteEvent, attributes, block)
|
523
524
|
end
|
524
525
|
|
526
|
+
# This **event** is raised whenever an interaction event is received.
|
527
|
+
# @param attributes [Hash] The event's attributes.
|
528
|
+
# @option attributes [Integer, Symbol, String] :type The interaction type, can be the integer value or the name
|
529
|
+
# of the key in {Discordrb::Interaction::TYPES}.
|
530
|
+
# @option attributes [String, Integer, Server, nil] :server The server where this event was created. `nil` for DM channels.
|
531
|
+
# @option attributes [String, Integer, Channel] :channel The channel where this event was created.
|
532
|
+
# @option attributes [String, Integer, User] :user The user that triggered this event.
|
533
|
+
# @yield The block is executed when the event is raised.
|
534
|
+
# @yieldparam event [InteractionCreateEvent] The event that was raised.
|
535
|
+
# @return [InteractionCreateEventHandler] The event handler that was registered.
|
536
|
+
def interaction_create(attributes = {}, &block)
|
537
|
+
register_event(InteractionCreateEvent, attributes, block)
|
538
|
+
end
|
539
|
+
|
540
|
+
# This **event** is raised whenever an application command (slash command) is executed.
|
541
|
+
# @param name [Symbol] The name of the application command this handler is for.
|
542
|
+
# @param attributes [Hash] The event's attributes.
|
543
|
+
# @yield The block is executed when the event is raised.
|
544
|
+
# @yieldparam event [ApplicationCommandEvent] The event that was raised.
|
545
|
+
# @return [ApplicationCommandEventHandler] The event handler that was registered.
|
546
|
+
def application_command(name, attributes = {}, &block)
|
547
|
+
@application_commands ||= {}
|
548
|
+
|
549
|
+
unless block
|
550
|
+
@application_commands[name] ||= ApplicationCommandEventHandler.new(attributes, nil)
|
551
|
+
return @application_commands[name]
|
552
|
+
end
|
553
|
+
|
554
|
+
@application_commands[name] = ApplicationCommandEventHandler.new(attributes, block)
|
555
|
+
end
|
556
|
+
|
557
|
+
# This **event** is raised whenever an button interaction is created.
|
558
|
+
# @param attributes [Hash] The event's attributes.
|
559
|
+
# @option attributes [String, Regexp] :custom_id A custom_id to match against.
|
560
|
+
# @option attributes [String, Integer, Message] :message The message to filter for.
|
561
|
+
# @yield The block is executed when the event is raised.
|
562
|
+
# @yieldparam event [ButtonEvent] The event that was raised.
|
563
|
+
# @return [ButtonEventHandler] The event handler that was registered.
|
564
|
+
def button(attributes = {}, &block)
|
565
|
+
register_event(ButtonEvent, attributes, block)
|
566
|
+
end
|
567
|
+
|
568
|
+
# This **event** is raised whenever an select string interaction is created.
|
569
|
+
# @param attributes [Hash] The event's attributes.
|
570
|
+
# @option attributes [String, Regexp] :custom_id A custom_id to match against.
|
571
|
+
# @option attributes [String, Integer, Message] :message The message to filter for.
|
572
|
+
# @yield The block is executed when the event is raised.
|
573
|
+
# @yieldparam event [StringSelectEvent] The event that was raised.
|
574
|
+
# @return [StringSelectEventHandler] The event handler that was registered.
|
575
|
+
def string_select(attributes = {}, &block)
|
576
|
+
register_event(StringSelectEvent, attributes, block)
|
577
|
+
end
|
578
|
+
|
579
|
+
alias_method :select_menu, :string_select
|
580
|
+
|
581
|
+
# This **event** is raised whenever a modal is submitted.
|
582
|
+
# @param attributes [Hash] The event's attributes.
|
583
|
+
# @option attributes [String, Regexp] :custom_id A custom_id to match against.
|
584
|
+
# @option attributes [String, Integer, Message] :message The message to filter for.
|
585
|
+
# @option attributes [String, Integer, Server, nil] :server The server where this event was created. `nil` for DM channels.
|
586
|
+
# @option attributes [String, Integer, Channel] :channel The channel where this event was created.
|
587
|
+
# @option attributes [String, Integer, User] :user The user that triggered this event. # @yield The block is executed when the event is raised.
|
588
|
+
# @yieldparam event [ModalSubmitEvent] The event that was raised.
|
589
|
+
# @return [ModalSubmitEventHandler] The event handler that was registered.
|
590
|
+
def modal_submit(attributes = {}, &block)
|
591
|
+
register_event(ModalSubmitEvent, attributes, block)
|
592
|
+
end
|
593
|
+
|
594
|
+
# This **event** is raised whenever an select user interaction is created.
|
595
|
+
# @param attributes [Hash] The event's attributes.
|
596
|
+
# @option attributes [String, Regexp] :custom_id A custom_id to match against.
|
597
|
+
# @option attributes [String, Integer, Message] :message The message to filter for.
|
598
|
+
# @yield The block is executed when the event is raised.
|
599
|
+
# @yieldparam event [UserSelectEvent] The event that was raised.
|
600
|
+
# @return [UserSelectEventHandler] The event handler that was registered.
|
601
|
+
def user_select(attributes = {}, &block)
|
602
|
+
register_event(UserSelectEvent, attributes, block)
|
603
|
+
end
|
604
|
+
|
605
|
+
# This **event** is raised whenever an select role interaction is created.
|
606
|
+
# @param attributes [Hash] The event's attributes.
|
607
|
+
# @option attributes [String, Regexp] :custom_id A custom_id to match against.
|
608
|
+
# @option attributes [String, Integer, Message] :message The message to filter for.
|
609
|
+
# @yield The block is executed when the event is raised.
|
610
|
+
# @yieldparam event [RoleSelectEvent] The event that was raised.
|
611
|
+
# @return [RoleSelectEventHandler] The event handler that was registered.
|
612
|
+
def role_select(attributes = {}, &block)
|
613
|
+
register_event(RoleSelectEvent, attributes, block)
|
614
|
+
end
|
615
|
+
|
616
|
+
# This **event** is raised whenever an select mentionable interaction is created.
|
617
|
+
# @param attributes [Hash] The event's attributes.
|
618
|
+
# @option attributes [String, Regexp] :custom_id A custom_id to match against.
|
619
|
+
# @option attributes [String, Integer, Message] :message The message to filter for.
|
620
|
+
# @yield The block is executed when the event is raised.
|
621
|
+
# @yieldparam event [MentionableSelectEvent] The event that was raised.
|
622
|
+
# @return [MentionableSelectEventHandler] The event handler that was registered.
|
623
|
+
def mentionable_select(attributes = {}, &block)
|
624
|
+
register_event(MentionableSelectEvent, attributes, block)
|
625
|
+
end
|
626
|
+
|
627
|
+
# This **event** is raised whenever an select channel interaction is created.
|
628
|
+
# @param attributes [Hash] The event's attributes.
|
629
|
+
# @option attributes [String, Regexp] :custom_id A custom_id to match against.
|
630
|
+
# @option attributes [String, Integer, Message] :message The message to filter for.
|
631
|
+
# @yield The block is executed when the event is raised.
|
632
|
+
# @yieldparam event [ChannelSelectEvent] The event that was raised.
|
633
|
+
# @return [ChannelSelectEventHandler] The event handler that was registered.
|
634
|
+
def channel_select(attributes = {}, &block)
|
635
|
+
register_event(ChannelSelectEvent, attributes, block)
|
636
|
+
end
|
637
|
+
|
525
638
|
# This **event** is raised for every dispatch received over the gateway, whether supported by discordrb or not.
|
526
639
|
# @param attributes [Hash] The event's attributes.
|
527
640
|
# @option attributes [String, Symbol, Regexp] :type Matches the event type of the dispatch.
|
@@ -552,9 +665,16 @@ module Discordrb
|
|
552
665
|
@event_handlers[clazz].delete(handler)
|
553
666
|
end
|
554
667
|
|
668
|
+
# Remove an application command handler
|
669
|
+
# @param name [String, Symbol] The name of the command handler to remove.
|
670
|
+
def remove_application_command_handler(name)
|
671
|
+
@application_commands.delete(name)
|
672
|
+
end
|
673
|
+
|
555
674
|
# Removes all events from this event handler.
|
556
675
|
def clear!
|
557
676
|
@event_handlers&.clear
|
677
|
+
@application_commands&.clear
|
558
678
|
end
|
559
679
|
|
560
680
|
# Adds an event handler to this container. Usually, it's more expressive to just use one of the shorthand adder
|
@@ -570,11 +690,19 @@ module Discordrb
|
|
570
690
|
# Adds all event handlers from another container into this one. Existing event handlers will be overwritten.
|
571
691
|
# @param container [Module] A module that `extend`s {EventContainer} from which the handlers will be added.
|
572
692
|
def include_events(container)
|
573
|
-
|
574
|
-
|
693
|
+
application_command_handlers = container.instance_variable_get(:@application_commands)
|
694
|
+
handlers = container.instance_variable_get :@event_handlers
|
695
|
+
return unless handlers || application_command_handlers
|
575
696
|
|
576
697
|
@event_handlers ||= {}
|
577
|
-
@event_handlers.merge!(handlers) { |_, old, new| old + new }
|
698
|
+
@event_handlers.merge!(handlers || {}) { |_, old, new| old + new }
|
699
|
+
|
700
|
+
@application_commands ||= {}
|
701
|
+
|
702
|
+
@application_commands.merge!(application_command_handlers || {}) do |_, old, new|
|
703
|
+
old.subcommands.merge!(new.subcommands)
|
704
|
+
old
|
705
|
+
end
|
578
706
|
end
|
579
707
|
|
580
708
|
alias_method :include!, :include_events
|
@@ -612,6 +740,7 @@ module Discordrb
|
|
612
740
|
|
613
741
|
include Discordrb::Events
|
614
742
|
|
743
|
+
# @return [EventHandler]
|
615
744
|
def register_event(clazz, attributes, block)
|
616
745
|
handler = EventContainer.handler_class(clazz).new(attributes, block)
|
617
746
|
|
@@ -27,6 +27,16 @@ module Discordrb
|
|
27
27
|
# @return [Integer, nil] the height of an image file, in pixels, or `nil` if the file is not an image.
|
28
28
|
attr_reader :height
|
29
29
|
|
30
|
+
# @return [String, nil] the attachment's description.
|
31
|
+
attr_reader :description
|
32
|
+
|
33
|
+
# @return [String, nil] the attachment's media type.
|
34
|
+
attr_reader :content_type
|
35
|
+
|
36
|
+
# @return [true, false] whether this attachment is ephemeral.
|
37
|
+
attr_reader :ephemeral
|
38
|
+
alias_method :ephemeral?, :ephemeral
|
39
|
+
|
30
40
|
# @!visibility private
|
31
41
|
def initialize(data, message, bot)
|
32
42
|
@bot = bot
|
@@ -41,6 +51,11 @@ module Discordrb
|
|
41
51
|
|
42
52
|
@width = data['width']
|
43
53
|
@height = data['height']
|
54
|
+
|
55
|
+
@description = data['description']
|
56
|
+
@content_type = data['content_type']
|
57
|
+
|
58
|
+
@ephemeral = data['ephemeral']
|
44
59
|
end
|
45
60
|
|
46
61
|
# @return [true, false] whether this file is an image file.
|
@@ -177,7 +177,7 @@ module Discordrb
|
|
177
177
|
|
178
178
|
# The inspect method is overwritten to give more useful output
|
179
179
|
def inspect
|
180
|
-
"<AuditLogs::Entry id=#{@id} action=#{@action} reason=#{@reason} action_type=#{@action_type} target_type=#{@target_type} count=#{@count} days=#{@days} members_removed=#{@members_removed}>"
|
180
|
+
"<AuditLogs::Entry id=#{@id} key=#{@key} action=#{@action} reason=#{@reason} action_type=#{@action_type} target_type=#{@target_type} count=#{@count} days=#{@days} members_removed=#{@members_removed}>"
|
181
181
|
end
|
182
182
|
|
183
183
|
# Process action changes
|
@@ -219,8 +219,8 @@ module Discordrb
|
|
219
219
|
@old = Permissions.new(@old) if @old && @key == 'permissions'
|
220
220
|
@new = Permissions.new(@new) if @new && @key == 'permissions'
|
221
221
|
|
222
|
-
@old = @old.map { |o| Overwrite.new(o['id'], type: o['type']
|
223
|
-
@new = @new.map { |o| Overwrite.new(o['id'], type: o['type']
|
222
|
+
@old = @old.map { |o| Overwrite.new(o['id'], type: o['type'], allow: o['allow'], deny: o['deny']) } if @old && @key == 'permission_overwrites'
|
223
|
+
@new = @new.map { |o| Overwrite.new(o['id'], type: o['type'], allow: o['allow'], deny: o['deny']) } if @new && @key == 'permission_overwrites'
|
224
224
|
end
|
225
225
|
|
226
226
|
# @return [Channel, nil] the channel that was previously used in the server widget. Only present if the key for this change is `widget_channel_id`.
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'discordrb/webhooks/view'
|
4
|
+
require 'time'
|
5
|
+
|
3
6
|
module Discordrb
|
4
7
|
# A Discord channel, including data like the topic
|
5
8
|
class Channel
|
@@ -13,23 +16,28 @@ module Discordrb
|
|
13
16
|
group: 3,
|
14
17
|
category: 4,
|
15
18
|
news: 5,
|
16
|
-
store: 6
|
19
|
+
store: 6,
|
20
|
+
news_thread: 10,
|
21
|
+
public_thread: 11,
|
22
|
+
private_thread: 12,
|
23
|
+
stage_voice: 13,
|
24
|
+
directory: 14,
|
25
|
+
forum: 15
|
17
26
|
}.freeze
|
18
27
|
|
19
28
|
# @return [String] this channel's name.
|
20
29
|
attr_reader :name
|
21
30
|
|
22
|
-
# @return [
|
23
|
-
|
24
|
-
|
25
|
-
# @return [Integer, nil] the ID of the parent channel, if this channel is inside a category
|
31
|
+
# @return [Integer, nil] the ID of the parent channel, if this channel is inside a category. If this channel is a
|
32
|
+
# thread, this is the text channel it is a child to.
|
26
33
|
attr_reader :parent_id
|
27
34
|
|
28
35
|
# @return [Integer] the type of this channel
|
29
36
|
# @see TYPES
|
30
37
|
attr_reader :type
|
31
38
|
|
32
|
-
# @return [Integer, nil] the ID of the owner of the group channel or nil if this is not a group channel.
|
39
|
+
# @return [Integer, nil] the ID of the owner of the group channel or nil if this is not a group channel. If this
|
40
|
+
# channel is a thread, this is the member that started the thread.
|
33
41
|
attr_reader :owner_id
|
34
42
|
|
35
43
|
# @return [Array<Recipient>, nil] the array of recipients of the private messages, or nil if this is not a Private channel
|
@@ -56,6 +64,35 @@ module Discordrb
|
|
56
64
|
attr_reader :rate_limit_per_user
|
57
65
|
alias_method :slowmode_rate, :rate_limit_per_user
|
58
66
|
|
67
|
+
# @return [Integer, nil] An approximate count of messages sent in a thread. Stops counting at 50.
|
68
|
+
attr_reader :message_count
|
69
|
+
|
70
|
+
# @return [Integer, nil] An approximate count of members in a thread. Stops counting at 50.
|
71
|
+
attr_reader :member_count
|
72
|
+
|
73
|
+
# @return [true, false, nil] Whether or not this thread is archived.
|
74
|
+
attr_reader :archived
|
75
|
+
|
76
|
+
# @return [Integer, nil] How long after the last message before a thread is automatically archived.
|
77
|
+
attr_reader :auto_archive_duration
|
78
|
+
|
79
|
+
# @return [Time, nil] The timestamp of when this threads status last changed.
|
80
|
+
attr_reader :archive_timestamp
|
81
|
+
|
82
|
+
# @return [true, false, nil] Whether this thread is locked or not.
|
83
|
+
attr_reader :locked
|
84
|
+
alias_method :locked?, :locked
|
85
|
+
|
86
|
+
# @return [Time, nil] When the current user joined this thread.
|
87
|
+
attr_reader :join_timestamp
|
88
|
+
|
89
|
+
# @return [Integer, nil] Member flags for this thread, used for notifications.
|
90
|
+
attr_reader :member_flags
|
91
|
+
|
92
|
+
# @return [true, false] For private threads, determines whether non-moderators can add other non-moderators to
|
93
|
+
# a thread.
|
94
|
+
attr_reader :invitable
|
95
|
+
|
59
96
|
# @return [true, false] whether or not this channel is a PM or group channel.
|
60
97
|
def private?
|
61
98
|
pm? || group?
|
@@ -99,15 +136,44 @@ module Discordrb
|
|
99
136
|
end
|
100
137
|
else
|
101
138
|
@name = data['name']
|
102
|
-
@
|
139
|
+
@server_id = server&.id || data['guild_id'].to_i
|
140
|
+
@server = server
|
103
141
|
end
|
104
142
|
|
105
143
|
@nsfw = data['nsfw'] || false
|
106
144
|
@rate_limit_per_user = data['rate_limit_per_user'] || 0
|
145
|
+
@message_count = data['message_count']
|
146
|
+
@member_count = data['member_count']
|
147
|
+
|
148
|
+
if (metadata = data['thread_metadata'])
|
149
|
+
@archived = metadata['archived']
|
150
|
+
@auto_archive_duration = metadata['auto_archive_duration']
|
151
|
+
@archive_timestamp = Time.iso8601(metadata['archive_timestamp'])
|
152
|
+
@locked = metadata['locked']
|
153
|
+
@invitable = metadata['invitable']
|
154
|
+
end
|
155
|
+
|
156
|
+
if (member = data['member'])
|
157
|
+
@member_join = Time.iso8601(member['join_timestamp'])
|
158
|
+
@member_flags = member['flags']
|
159
|
+
end
|
107
160
|
|
108
161
|
process_permission_overwrites(data['permission_overwrites'])
|
109
162
|
end
|
110
163
|
|
164
|
+
# @return [Server, nil] the server this channel is on. If this channel is a PM channel, it will be nil.
|
165
|
+
# @raise [Discordrb::Errors::NoPermission] This can happen when receiving interactions for servers in which the bot is not
|
166
|
+
# authorized with the `bot` scope.
|
167
|
+
def server
|
168
|
+
return @server if @server
|
169
|
+
return nil if private?
|
170
|
+
|
171
|
+
@server = @bot.server(@server_id)
|
172
|
+
raise Discordrb::Errors::NoPermission, 'The bot does not have access to this server' unless @server
|
173
|
+
|
174
|
+
@server
|
175
|
+
end
|
176
|
+
|
111
177
|
# @return [true, false] whether or not this channel is a text channel
|
112
178
|
def text?
|
113
179
|
@type.zero?
|
@@ -143,6 +209,26 @@ module Discordrb
|
|
143
209
|
@type == 6
|
144
210
|
end
|
145
211
|
|
212
|
+
# @return [true, false] whether or not this channel is a news thread.
|
213
|
+
def news_thread?
|
214
|
+
@type == 10
|
215
|
+
end
|
216
|
+
|
217
|
+
# @return [true, false] whether or not this channel is a public thread.
|
218
|
+
def public_thread?
|
219
|
+
@type == 11
|
220
|
+
end
|
221
|
+
|
222
|
+
# @return [true, false] whether or not this channel is a private thread.
|
223
|
+
def private_thread?
|
224
|
+
@type == 12
|
225
|
+
end
|
226
|
+
|
227
|
+
# @return [true, false] whether or not this channel is a thread.
|
228
|
+
def thread?
|
229
|
+
news_thread? || public_thread? || private_thread?
|
230
|
+
end
|
231
|
+
|
146
232
|
# @return [Channel, nil] the category channel, if this channel is in a category
|
147
233
|
def category
|
148
234
|
@bot.channel(@parent_id) if @parent_id
|
@@ -199,7 +285,7 @@ module Discordrb
|
|
199
285
|
ids = if parent
|
200
286
|
parent.children
|
201
287
|
else
|
202
|
-
|
288
|
+
server.channels.reject(&:parent_id).select { |c| c.type == @type }
|
203
289
|
end.sort_by(&:position).map(&:id)
|
204
290
|
|
205
291
|
# Move our channel ID after the target ID by deleting it,
|
@@ -225,7 +311,7 @@ module Discordrb
|
|
225
311
|
move_argument << hash
|
226
312
|
end
|
227
313
|
|
228
|
-
API::Server.update_channel_positions(@bot.token, @
|
314
|
+
API::Server.update_channel_positions(@bot.token, @server_id, move_argument)
|
229
315
|
end
|
230
316
|
|
231
317
|
# Sets whether this channel is NSFW
|
@@ -262,9 +348,9 @@ module Discordrb
|
|
262
348
|
|
263
349
|
# Sets the amount of time (in seconds) users have to wait in between sending messages.
|
264
350
|
# @param rate [Integer]
|
265
|
-
# @raise [ArgumentError] if value isn't between 0 and
|
351
|
+
# @raise [ArgumentError] if value isn't between 0 and 21600
|
266
352
|
def rate_limit_per_user=(rate)
|
267
|
-
raise ArgumentError, 'rate_limit_per_user must be between 0 and
|
353
|
+
raise ArgumentError, 'rate_limit_per_user must be between 0 and 21600' unless rate.between?(0, 21_600)
|
268
354
|
|
269
355
|
update_channel_data(rate_limit_per_user: rate)
|
270
356
|
end
|
@@ -341,9 +427,10 @@ module Discordrb
|
|
341
427
|
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
342
428
|
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
343
429
|
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
430
|
+
# @param components [View, Array<Hash>] Interaction components to associate with this message.
|
344
431
|
# @return [Message] the message that was sent.
|
345
|
-
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil)
|
346
|
-
@bot.send_message(@id, content, tts, embed, attachments, allowed_mentions, message_reference)
|
432
|
+
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
|
433
|
+
@bot.send_message(@id, content, tts, embed, attachments, allowed_mentions, message_reference, components)
|
347
434
|
end
|
348
435
|
|
349
436
|
alias_method :send, :send_message
|
@@ -356,8 +443,9 @@ module Discordrb
|
|
356
443
|
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
357
444
|
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
358
445
|
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
359
|
-
|
360
|
-
|
446
|
+
# @param components [View, Array<Hash>] Interaction components to associate with this message.
|
447
|
+
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil)
|
448
|
+
@bot.send_temporary_message(@id, content, timeout, tts, embed, attachments, allowed_mentions, message_reference, components)
|
361
449
|
end
|
362
450
|
|
363
451
|
# Convenience method to send a message with an embed.
|
@@ -372,13 +460,17 @@ module Discordrb
|
|
372
460
|
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
373
461
|
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
374
462
|
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
463
|
+
# @param components [View, Array<Hash>] Interaction components to associate with this message.
|
375
464
|
# @yield [embed] Yields the embed to allow for easy building inside a block.
|
376
465
|
# @yieldparam embed [Discordrb::Webhooks::Embed] The embed from the parameters, or a new one.
|
377
466
|
# @return [Message] The resulting message.
|
378
|
-
def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil)
|
467
|
+
def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil, components = nil)
|
379
468
|
embed ||= Discordrb::Webhooks::Embed.new
|
380
|
-
|
381
|
-
|
469
|
+
view = Discordrb::Webhooks::View.new
|
470
|
+
|
471
|
+
yield(embed, view) if block_given?
|
472
|
+
|
473
|
+
send_message(message, tts, embed, attachments, allowed_mentions, message_reference, components || view.to_a)
|
382
474
|
end
|
383
475
|
|
384
476
|
# Sends multiple messages to a channel
|
@@ -518,9 +610,9 @@ module Discordrb
|
|
518
610
|
# @return [Array<Member>] the users in this channel
|
519
611
|
def users
|
520
612
|
if text?
|
521
|
-
|
613
|
+
server.online_members(include_idle: true).select { |u| u.can_read_messages? self }
|
522
614
|
elsif voice?
|
523
|
-
|
615
|
+
server.voice_states.filter_map { |id, voice_state| server.member(id) if !voice_state.voice_channel.nil? && voice_state.voice_channel.id == @id }
|
524
616
|
end
|
525
617
|
end
|
526
618
|
|
@@ -554,9 +646,11 @@ module Discordrb
|
|
554
646
|
# @param message_id [Integer] The ID of the message to retrieve.
|
555
647
|
# @return [Message, nil] the retrieved message, or `nil` if it couldn't be found.
|
556
648
|
def load_message(message_id)
|
649
|
+
raise ArgumentError, 'message_id cannot be nil' if message_id.nil?
|
650
|
+
|
557
651
|
response = API::Channel.message(@bot.token, @id, message_id)
|
558
652
|
Message.new(JSON.parse(response), @bot)
|
559
|
-
rescue
|
653
|
+
rescue Discordrb::Errors::UnknownMessage
|
560
654
|
nil
|
561
655
|
end
|
562
656
|
|
@@ -742,9 +836,59 @@ module Discordrb
|
|
742
836
|
invites.map { |invite_data| Invite.new(invite_data, @bot) }
|
743
837
|
end
|
744
838
|
|
839
|
+
# Start a thread.
|
840
|
+
# @param name [String] The name of the thread.
|
841
|
+
# @param auto_archive_duration [60, 1440, 4320, 10080] How long before a thread is automatically
|
842
|
+
# archived.
|
843
|
+
# @param message [Message, Integer, String] The message to reference when starting this thread.
|
844
|
+
# @param type [Symbol, Integer] The type of thread to create. Can be a key from {TYPES} or the value.
|
845
|
+
# @return [Channel]
|
846
|
+
def start_thread(name, auto_archive_duration, message: nil, type: 11)
|
847
|
+
message_id = message&.id || message
|
848
|
+
type = TYPES[type] || type
|
849
|
+
|
850
|
+
data = if message
|
851
|
+
API::Channel.start_thread_with_message(@bot.token, @id, message_id, name, auto_archive_duration)
|
852
|
+
else
|
853
|
+
API::Channel.start_thread_without_message(@bot.token, @id, name, auto_archive_duration, type)
|
854
|
+
end
|
855
|
+
|
856
|
+
Channel.new(JSON.parse(data), @bot, @server)
|
857
|
+
end
|
858
|
+
|
859
|
+
# @!group Threads
|
860
|
+
|
861
|
+
# Join this thread.
|
862
|
+
def join_thread
|
863
|
+
@bot.join_thread(@id)
|
864
|
+
end
|
865
|
+
|
866
|
+
# Leave this thread
|
867
|
+
def leave_thread
|
868
|
+
@bot.leave_thread(@id)
|
869
|
+
end
|
870
|
+
|
871
|
+
# Members in the thread.
|
872
|
+
def members
|
873
|
+
@bot.thread_members[@id].collect { |id| @server_id ? @bot.member(@server_id, id) : @bot.user(id) }
|
874
|
+
end
|
875
|
+
|
876
|
+
# Add a member to the thread
|
877
|
+
# @param member [Member, Integer, String] The member, or ID of the member, to add to this thread.
|
878
|
+
def add_member(member)
|
879
|
+
@bot.add_thread_member(@id, member)
|
880
|
+
end
|
881
|
+
|
882
|
+
# @param member [Member, Integer, String] The member, or ID of the member, to remove from a thread.
|
883
|
+
def remove_member(member)
|
884
|
+
@bot.remove_thread_member(@id, member)
|
885
|
+
end
|
886
|
+
|
887
|
+
# @!endgroup
|
888
|
+
|
745
889
|
# The default `inspect` method is overwritten to give more useful output.
|
746
890
|
def inspect
|
747
|
-
"<Channel name=#{@name} id=#{@id} topic=\"#{@topic}\" type=#{@type} position=#{@position} server=#{@server}>"
|
891
|
+
"<Channel name=#{@name} id=#{@id} topic=\"#{@topic}\" type=#{@type} position=#{@position} server=#{@server || @server_id}>"
|
748
892
|
end
|
749
893
|
|
750
894
|
# Adds a recipient to a group channel.
|
@@ -790,7 +934,7 @@ module Discordrb
|
|
790
934
|
|
791
935
|
# @return [String] a URL that a user can use to navigate to this channel in the client
|
792
936
|
def link
|
793
|
-
"https://discord.com/channels/#{@
|
937
|
+
"https://discord.com/channels/#{@server_id || '@me'}/#{@channel.id}"
|
794
938
|
end
|
795
939
|
|
796
940
|
alias_method :jump_link, :link
|