discordrb 3.4.0 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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`.
|