discordrb 3.4.0 → 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 +419 -222
- 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 +182 -11
- data/lib/discordrb/api/interaction.rb +54 -0
- data/lib/discordrb/api/invite.rb +2 -2
- data/lib/discordrb/api/server.rb +42 -19
- data/lib/discordrb/api/user.rb +9 -3
- data/lib/discordrb/api/webhook.rb +57 -0
- data/lib/discordrb/api.rb +19 -5
- data/lib/discordrb/bot.rb +328 -33
- data/lib/discordrb/cache.rb +27 -22
- data/lib/discordrb/commands/command_bot.rb +14 -7
- 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/activity.rb +8 -1
- 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 +2 -2
- data/lib/discordrb/data/member.rb +108 -33
- data/lib/discordrb/data/message.rb +100 -20
- 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 +13 -4
- 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 +53 -19
- data/.codeclimate.yml +0 -16
- data/.travis.yml +0 -32
- data/bin/travis_build_docs.sh +0 -17
data/lib/discordrb/cache.rb
CHANGED
@@ -21,8 +21,7 @@ module Discordrb
|
|
21
21
|
|
22
22
|
@channels = {}
|
23
23
|
@pm_channels = {}
|
24
|
-
|
25
|
-
@restricted_channels = []
|
24
|
+
@thread_members = {}
|
26
25
|
end
|
27
26
|
|
28
27
|
# Returns or caches the available voice regions
|
@@ -42,28 +41,21 @@ module Discordrb
|
|
42
41
|
# @param id [Integer] The channel ID for which to search for.
|
43
42
|
# @param server [Server] The server for which to search the channel for. If this isn't specified, it will be
|
44
43
|
# inferred using the API
|
45
|
-
# @return [Channel] The channel identified by the ID.
|
44
|
+
# @return [Channel, nil] The channel identified by the ID.
|
45
|
+
# @raise Discordrb::Errors::NoPermission
|
46
46
|
def channel(id, server = nil)
|
47
47
|
id = id.resolve_id
|
48
48
|
|
49
|
-
raise Discordrb::Errors::NoPermission if @restricted_channels.include? id
|
50
|
-
|
51
49
|
debug("Obtaining data for channel with id #{id}")
|
52
50
|
return @channels[id] if @channels[id]
|
53
51
|
|
54
52
|
begin
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
return nil
|
59
|
-
end
|
60
|
-
channel = Channel.new(JSON.parse(response), self, server)
|
61
|
-
@channels[id] = channel
|
62
|
-
rescue Discordrb::Errors::NoPermission
|
63
|
-
debug "Tried to get access to restricted channel #{id}, blacklisting it"
|
64
|
-
@restricted_channels << id
|
65
|
-
raise
|
53
|
+
response = API::Channel.resolve(token, id)
|
54
|
+
rescue Discordrb::Errors::UnknownChannel
|
55
|
+
return nil
|
66
56
|
end
|
57
|
+
channel = Channel.new(JSON.parse(response), self, server)
|
58
|
+
@channels[id] = channel
|
67
59
|
end
|
68
60
|
|
69
61
|
alias_method :group_channel, :channel
|
@@ -79,7 +71,7 @@ module Discordrb
|
|
79
71
|
LOGGER.out("Resolving user #{id}")
|
80
72
|
begin
|
81
73
|
response = API::User.resolve(token, id)
|
82
|
-
rescue
|
74
|
+
rescue Discordrb::Errors::UnknownUser
|
83
75
|
return nil
|
84
76
|
end
|
85
77
|
user = User.new(JSON.parse(response), self)
|
@@ -111,7 +103,6 @@ module Discordrb
|
|
111
103
|
def member(server_or_id, user_id)
|
112
104
|
server_id = server_or_id.resolve_id
|
113
105
|
user_id = user_id.resolve_id
|
114
|
-
|
115
106
|
server = server_or_id.is_a?(Server) ? server_or_id : self.server(server_id)
|
116
107
|
|
117
108
|
return server.member(user_id) if server.member_cached?(user_id)
|
@@ -119,7 +110,7 @@ module Discordrb
|
|
119
110
|
LOGGER.out("Resolving member #{server_id} on server #{user_id}")
|
120
111
|
begin
|
121
112
|
response = API::Server.resolve_member(token, server_id, user_id)
|
122
|
-
rescue
|
113
|
+
rescue Discordrb::Errors::UnknownUser, Discordrb::Errors::UnknownMember
|
123
114
|
return nil
|
124
115
|
end
|
125
116
|
member = Member.new(JSON.parse(response), server, self)
|
@@ -156,10 +147,14 @@ module Discordrb
|
|
156
147
|
|
157
148
|
# Ensures a given server object is cached and if not, cache it from the given data hash.
|
158
149
|
# @param data [Hash] A data hash representing a server.
|
150
|
+
# @param force_cache [true, false] Whether the object in cache should be updated with the given
|
151
|
+
# data if it already exists.
|
159
152
|
# @return [Server] the server represented by the data hash.
|
160
|
-
def ensure_server(data)
|
153
|
+
def ensure_server(data, force_cache = false)
|
161
154
|
if @servers.include?(data['id'].to_i)
|
162
|
-
@servers[data['id'].to_i]
|
155
|
+
server = @servers[data['id'].to_i]
|
156
|
+
server.update_data(data) if force_cache
|
157
|
+
server
|
163
158
|
else
|
164
159
|
@servers[data['id'].to_i] = Server.new(data, self)
|
165
160
|
end
|
@@ -177,6 +172,16 @@ module Discordrb
|
|
177
172
|
end
|
178
173
|
end
|
179
174
|
|
175
|
+
# Ensures a given thread member object is cached.
|
176
|
+
# @param data [Hash] Thread member data.
|
177
|
+
def ensure_thread_member(data)
|
178
|
+
thread_id = data['id'].to_i
|
179
|
+
user_id = data['user_id'].to_i
|
180
|
+
|
181
|
+
@thread_members[thread_id] ||= {}
|
182
|
+
@thread_members[thread_id][user_id] = data.slice('join_timestamp', 'flags')
|
183
|
+
end
|
184
|
+
|
180
185
|
# Requests member chunks for a given server ID.
|
181
186
|
# @param id [Integer] The server ID to request chunks for.
|
182
187
|
def request_chunks(id)
|
@@ -194,7 +199,7 @@ module Discordrb
|
|
194
199
|
# @return [String] Only the code for the invite.
|
195
200
|
def resolve_invite_code(invite)
|
196
201
|
invite = invite.code if invite.is_a? Discordrb::Invite
|
197
|
-
invite = invite[invite.rindex('/') + 1
|
202
|
+
invite = invite[invite.rindex('/') + 1..] if invite.start_with?('http', 'discord.gg')
|
198
203
|
invite
|
199
204
|
end
|
200
205
|
|
@@ -44,9 +44,10 @@ module Discordrb::Commands
|
|
44
44
|
# @option attributes [Symbol, Array<Symbol>, false] :help_command The name of the command that displays info for
|
45
45
|
# other commands. Use an array if you want to have aliases. Default is "help". If none should be created, use
|
46
46
|
# `false` as the value.
|
47
|
-
# @option attributes [String] :command_doesnt_exist_message The message that should be displayed if a user attempts
|
47
|
+
# @option attributes [String, #call] :command_doesnt_exist_message The message that should be displayed if a user attempts
|
48
48
|
# to use a command that does not exist. If none is specified, no message will be displayed. In the message, you
|
49
|
-
# can use the string '%command%' that will be replaced with the name of the command.
|
49
|
+
# can use the string '%command%' that will be replaced with the name of the command. Anything responding to call
|
50
|
+
# such as a proc will be called with the event, and is expected to return a String or nil.
|
50
51
|
# @option attributes [String] :no_permission_message The message to be displayed when `NoPermission` error is raised.
|
51
52
|
# @option attributes [true, false] :spaces_allowed Whether spaces are allowed to occur between the prefix and the
|
52
53
|
# command. Default is false.
|
@@ -69,7 +70,9 @@ module Discordrb::Commands
|
|
69
70
|
# @option attributes [String] :quote_end Character that should end a quoted string (see
|
70
71
|
# :advanced_functionality). Default is '"' or the same as :quote_start. Set to an empty string to disable.
|
71
72
|
# @option attributes [true, false] :ignore_bots Whether the bot should ignore bot accounts or not. Default is false.
|
72
|
-
def initialize(attributes
|
73
|
+
def initialize(**attributes)
|
74
|
+
# TODO: This needs to be revisited. undefined attributes are treated
|
75
|
+
# as explicitly passed nils.
|
73
76
|
super(
|
74
77
|
log_mode: attributes[:log_mode],
|
75
78
|
token: attributes[:token],
|
@@ -84,7 +87,7 @@ module Discordrb::Commands
|
|
84
87
|
redact_token: attributes.key?(:redact_token) ? attributes[:redact_token] : true,
|
85
88
|
ignore_bots: attributes[:ignore_bots],
|
86
89
|
compress_mode: attributes[:compress_mode],
|
87
|
-
intents: attributes[:intents]
|
90
|
+
intents: attributes[:intents] || :all
|
88
91
|
)
|
89
92
|
|
90
93
|
@prefix = attributes[:prefix]
|
@@ -217,7 +220,11 @@ module Discordrb::Commands
|
|
217
220
|
(command && !command.attributes[:channels].nil?)
|
218
221
|
|
219
222
|
unless command
|
220
|
-
|
223
|
+
if @attributes[:command_doesnt_exist_message]
|
224
|
+
message = @attributes[:command_doesnt_exist_message]
|
225
|
+
message = message.call(event) if message.respond_to?(:call)
|
226
|
+
event.respond message.gsub('%command%', name.to_s) if message
|
227
|
+
end
|
221
228
|
return
|
222
229
|
end
|
223
230
|
return unless !check_permissions || channels?(event.channel, command.attributes[:channels])
|
@@ -330,7 +337,7 @@ module Discordrb::Commands
|
|
330
337
|
return nil if chain.empty?
|
331
338
|
|
332
339
|
args = chain.split(' ')
|
333
|
-
execute_command(args[0].to_sym, event, args[1
|
340
|
+
execute_command(args[0].to_sym, event, args[1..])
|
334
341
|
end
|
335
342
|
|
336
343
|
# Sets the permission level of a user
|
@@ -438,7 +445,7 @@ module Discordrb::Commands
|
|
438
445
|
def standard_prefix_trigger(message, prefix)
|
439
446
|
return nil unless message.start_with? prefix
|
440
447
|
|
441
|
-
message[prefix.length
|
448
|
+
message[prefix.length..]
|
442
449
|
end
|
443
450
|
|
444
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
|
|
@@ -17,7 +17,7 @@ module Discordrb
|
|
17
17
|
# @return [String] the activity's name
|
18
18
|
attr_reader :name
|
19
19
|
|
20
|
-
# @return [Integer, nil] activity type. Can be {GAME}, {STREAMING}, {LISTENING}, {CUSTOM}
|
20
|
+
# @return [Integer, nil] activity type. Can be {GAME}, {STREAMING}, {LISTENING}, {CUSTOM}, or {COMPETING}
|
21
21
|
attr_reader :type
|
22
22
|
|
23
23
|
# @return [String, nil] stream URL, when the activity type is {STREAMING}
|
@@ -67,6 +67,8 @@ module Discordrb
|
|
67
67
|
WATCHING = 3
|
68
68
|
# Type indicating the activity is a custom status
|
69
69
|
CUSTOM = 4
|
70
|
+
# Type indicating the activity is for a competitive game
|
71
|
+
COMPETING = 5
|
70
72
|
|
71
73
|
# @!visibility private
|
72
74
|
def initialize(data, bot)
|
@@ -260,5 +262,10 @@ module Discordrb
|
|
260
262
|
def custom_status
|
261
263
|
@activities.select { |act| act.type == Activity::CUSTOM }
|
262
264
|
end
|
265
|
+
|
266
|
+
# @return [Array<Activity>] all activities of type {Activity::COMPETING}
|
267
|
+
def competing
|
268
|
+
@activities.select { |act| act.type == Activity::COMPETING }
|
269
|
+
end
|
263
270
|
end
|
264
271
|
end
|
@@ -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`.
|