onyxcord 1.1.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 +7 -0
- data/.devcontainer/Dockerfile +13 -0
- data/.devcontainer/devcontainer.json +29 -0
- data/.devcontainer/postcreate.sh +4 -0
- data/.github/CONTRIBUTING.md +13 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- data/.github/pull_request_template.md +37 -0
- data/.github/workflows/ci.yml +78 -0
- data/.github/workflows/codeql.yml +65 -0
- data/.github/workflows/deploy.yml +54 -0
- data/.github/workflows/release.yml +51 -0
- data/.gitignore +16 -0
- data/.markdownlint.json +4 -0
- data/.overcommit.yml +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +129 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +305 -0
- data/Rakefile +17 -0
- data/bin/console +15 -0
- data/bin/setup +7 -0
- data/lib/onyxcord/allowed_mentions.rb +43 -0
- data/lib/onyxcord/api/application.rb +316 -0
- data/lib/onyxcord/api/channel.rb +700 -0
- data/lib/onyxcord/api/interaction.rb +67 -0
- data/lib/onyxcord/api/invite.rb +44 -0
- data/lib/onyxcord/api/server.rb +775 -0
- data/lib/onyxcord/api/user.rb +158 -0
- data/lib/onyxcord/api/webhook.rb +163 -0
- data/lib/onyxcord/api.rb +335 -0
- data/lib/onyxcord/await.rb +51 -0
- data/lib/onyxcord/bot.rb +1971 -0
- data/lib/onyxcord/cache.rb +326 -0
- data/lib/onyxcord/colour_rgb.rb +43 -0
- data/lib/onyxcord/commands/command_bot.rb +511 -0
- data/lib/onyxcord/commands/container.rb +112 -0
- data/lib/onyxcord/commands/events.rb +11 -0
- data/lib/onyxcord/commands/parser.rb +327 -0
- data/lib/onyxcord/commands/rate_limiter.rb +144 -0
- data/lib/onyxcord/configuration.rb +125 -0
- data/lib/onyxcord/container.rb +988 -0
- data/lib/onyxcord/data/activity.rb +271 -0
- data/lib/onyxcord/data/application.rb +341 -0
- data/lib/onyxcord/data/attachment.rb +91 -0
- data/lib/onyxcord/data/audit_logs.rb +438 -0
- data/lib/onyxcord/data/avatar_decoration.rb +26 -0
- data/lib/onyxcord/data/call.rb +22 -0
- data/lib/onyxcord/data/channel.rb +1355 -0
- data/lib/onyxcord/data/channel_tag.rb +69 -0
- data/lib/onyxcord/data/collectibles.rb +47 -0
- data/lib/onyxcord/data/component.rb +583 -0
- data/lib/onyxcord/data/embed.rb +258 -0
- data/lib/onyxcord/data/emoji.rb +123 -0
- data/lib/onyxcord/data/install_params.rb +24 -0
- data/lib/onyxcord/data/integration.rb +144 -0
- data/lib/onyxcord/data/interaction.rb +1141 -0
- data/lib/onyxcord/data/invite.rb +137 -0
- data/lib/onyxcord/data/member.rb +528 -0
- data/lib/onyxcord/data/message.rb +612 -0
- data/lib/onyxcord/data/message_activity.rb +41 -0
- data/lib/onyxcord/data/overwrite.rb +109 -0
- data/lib/onyxcord/data/poll.rb +365 -0
- data/lib/onyxcord/data/primary_server.rb +60 -0
- data/lib/onyxcord/data/profile.rb +79 -0
- data/lib/onyxcord/data/reaction.rb +64 -0
- data/lib/onyxcord/data/recipient.rb +34 -0
- data/lib/onyxcord/data/role.rb +449 -0
- data/lib/onyxcord/data/role_connection_data.rb +69 -0
- data/lib/onyxcord/data/role_subscription.rb +41 -0
- data/lib/onyxcord/data/scheduled_event.rb +513 -0
- data/lib/onyxcord/data/server.rb +1614 -0
- data/lib/onyxcord/data/server_preview.rb +68 -0
- data/lib/onyxcord/data/snapshot.rb +112 -0
- data/lib/onyxcord/data/team.rb +98 -0
- data/lib/onyxcord/data/timestamp.rb +69 -0
- data/lib/onyxcord/data/user.rb +324 -0
- data/lib/onyxcord/data/voice_region.rb +46 -0
- data/lib/onyxcord/data/voice_state.rb +41 -0
- data/lib/onyxcord/data/webhook.rb +238 -0
- data/lib/onyxcord/data.rb +57 -0
- data/lib/onyxcord/errors.rb +246 -0
- data/lib/onyxcord/event_executor.rb +80 -0
- data/lib/onyxcord/events/await.rb +48 -0
- data/lib/onyxcord/events/bans.rb +60 -0
- data/lib/onyxcord/events/channels.rb +225 -0
- data/lib/onyxcord/events/generic.rb +129 -0
- data/lib/onyxcord/events/guilds.rb +269 -0
- data/lib/onyxcord/events/integrations.rb +100 -0
- data/lib/onyxcord/events/interactions.rb +624 -0
- data/lib/onyxcord/events/invites.rb +127 -0
- data/lib/onyxcord/events/lifetime.rb +31 -0
- data/lib/onyxcord/events/members.rb +110 -0
- data/lib/onyxcord/events/message.rb +399 -0
- data/lib/onyxcord/events/polls.rb +118 -0
- data/lib/onyxcord/events/presence.rb +131 -0
- data/lib/onyxcord/events/raw.rb +74 -0
- data/lib/onyxcord/events/reactions.rb +218 -0
- data/lib/onyxcord/events/roles.rb +87 -0
- data/lib/onyxcord/events/scheduled_events.rb +171 -0
- data/lib/onyxcord/events/threads.rb +100 -0
- data/lib/onyxcord/events/typing.rb +73 -0
- data/lib/onyxcord/events/voice_server_update.rb +48 -0
- data/lib/onyxcord/events/voice_state_update.rb +106 -0
- data/lib/onyxcord/events/webhooks.rb +65 -0
- data/lib/onyxcord/gateway.rb +890 -0
- data/lib/onyxcord/id_object.rb +39 -0
- data/lib/onyxcord/light/data.rb +62 -0
- data/lib/onyxcord/light/integrations.rb +73 -0
- data/lib/onyxcord/light/light_bot.rb +58 -0
- data/lib/onyxcord/light.rb +8 -0
- data/lib/onyxcord/logger.rb +120 -0
- data/lib/onyxcord/message_components.rb +70 -0
- data/lib/onyxcord/paginator.rb +60 -0
- data/lib/onyxcord/permissions.rb +255 -0
- data/lib/onyxcord/rate_limiter/gateway.rb +42 -0
- data/lib/onyxcord/rate_limiter/rest.rb +89 -0
- data/lib/onyxcord/version.rb +7 -0
- data/lib/onyxcord/voice/encoder.rb +115 -0
- data/lib/onyxcord/voice/network.rb +380 -0
- data/lib/onyxcord/voice/opcodes.rb +29 -0
- data/lib/onyxcord/voice/sodium.rb +157 -0
- data/lib/onyxcord/voice/timer.rb +19 -0
- data/lib/onyxcord/voice/voice_bot.rb +386 -0
- data/lib/onyxcord/webhooks.rb +14 -0
- data/lib/onyxcord/websocket.rb +62 -0
- data/lib/onyxcord.rb +180 -0
- data/onyxcord-webhooks.gemspec +30 -0
- data/onyxcord.gemspec +50 -0
- metadata +421 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'onyxcord/events/generic'
|
|
4
|
+
require 'onyxcord/data'
|
|
5
|
+
|
|
6
|
+
module OnyxCord::Events
|
|
7
|
+
# Generic subclass for interaction events
|
|
8
|
+
class InteractionCreateEvent < Event
|
|
9
|
+
# Struct to allow accessing data via [] or methods.
|
|
10
|
+
Resolved = Struct.new('Resolved', :channels, :members, :messages, :roles, :users, :attachments) # rubocop:disable Lint/StructNewOverride
|
|
11
|
+
|
|
12
|
+
# @return [Interaction] The interaction for this event.
|
|
13
|
+
attr_reader :interaction
|
|
14
|
+
|
|
15
|
+
# @!attribute [r] type
|
|
16
|
+
# @return [Integer]
|
|
17
|
+
# @see Interaction#type
|
|
18
|
+
# @!attribute [r] server
|
|
19
|
+
# @return [Server, nil]
|
|
20
|
+
# @see Interaction#server
|
|
21
|
+
# @!attribute [r] server_id
|
|
22
|
+
# @return [Integer]
|
|
23
|
+
# @see Interaction#server_id
|
|
24
|
+
# @!attribute [r] channel
|
|
25
|
+
# @return [Channel]
|
|
26
|
+
# @see Interaction#channel
|
|
27
|
+
# @!attribute [r] channel_id
|
|
28
|
+
# @return [Integer]
|
|
29
|
+
# @see Interaction#channel_id
|
|
30
|
+
# @!attribute [r] user
|
|
31
|
+
# @return [User]
|
|
32
|
+
# @see Interaction#user
|
|
33
|
+
# @!attribute [r] user_locale
|
|
34
|
+
# @return [String]
|
|
35
|
+
# @see Interaction#user_locale
|
|
36
|
+
# @!attribute [r] context
|
|
37
|
+
# @return [Integer]
|
|
38
|
+
# @see Interaction#context
|
|
39
|
+
# @!attribute [r] user_integration?
|
|
40
|
+
# @return [true, false]
|
|
41
|
+
# @see Interaction#user_integration?
|
|
42
|
+
# @!attribute [r] server_integration?
|
|
43
|
+
# @return [true, false]
|
|
44
|
+
# @see Interaction#server_integration?
|
|
45
|
+
delegate :type, :server, :server_id, :channel, :channel_id, :user, :user_locale, :context, :user_integration?, :server_integration?, to: :interaction
|
|
46
|
+
|
|
47
|
+
# @!visibility private
|
|
48
|
+
def initialize(data, bot)
|
|
49
|
+
@bot = bot
|
|
50
|
+
@interaction = OnyxCord::Interaction.new(data, @bot)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @see Interaction#respond
|
|
54
|
+
def respond(...)
|
|
55
|
+
@interaction.respond(...)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @see Interaction#defer
|
|
59
|
+
def defer(...)
|
|
60
|
+
@interaction.defer(...)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @see Interaction#update_message
|
|
64
|
+
def update_message(...)
|
|
65
|
+
@interaction.update_message(...)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @see Interaction#show_modal
|
|
69
|
+
def show_modal(...)
|
|
70
|
+
@interaction.show_modal(...)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @see Interaction#edit_response
|
|
74
|
+
def edit_response(...)
|
|
75
|
+
@interaction.edit_response(...)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @see Interaction#delete_response
|
|
79
|
+
def delete_response
|
|
80
|
+
@interaction.delete_response
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# @see Interaction#send_message
|
|
84
|
+
def send_message(...)
|
|
85
|
+
@interaction.send_message(...)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @see Interaction#edit_message
|
|
89
|
+
def edit_message(...)
|
|
90
|
+
@interaction.edit_message(...)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# @see Interaction#delete_message
|
|
94
|
+
def delete_message(...)
|
|
95
|
+
@interaction.delete_message(...)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# @see Interaction#defer_update
|
|
99
|
+
def defer_update
|
|
100
|
+
@interaction.defer_update
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @see Interaction#get_component
|
|
104
|
+
def get_component(...)
|
|
105
|
+
@interaction.get_component(...)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
# @!visibility private
|
|
111
|
+
def process_resolved(resolved_data)
|
|
112
|
+
resolved_data['users']&.each do |id, data|
|
|
113
|
+
@resolved[:users][id.to_i] = @bot.ensure_user(data)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
resolved_data['roles']&.each do |id, data|
|
|
117
|
+
@resolved[:roles][id.to_i] = OnyxCord::Role.new(data, @bot)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
resolved_data['channels']&.each do |id, data|
|
|
121
|
+
data['guild_id'] = @interaction.server_id
|
|
122
|
+
@resolved[:channels][id.to_i] = OnyxCord::Channel.new(data, @bot)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
resolved_data['members']&.each do |id, data|
|
|
126
|
+
data['user'] = resolved_data['users'][id]
|
|
127
|
+
data['guild_id'] = @interaction.server_id
|
|
128
|
+
@resolved[:members][id.to_i] = OnyxCord::Member.new(data, nil, @bot)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
resolved_data['messages']&.each do |id, data|
|
|
132
|
+
@resolved[:messages][id.to_i] = OnyxCord::Message.new(data, @bot)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
resolved_data['attachments']&.each do |id, data|
|
|
136
|
+
@resolved[:attachments][id.to_i] = OnyxCord::Attachment.new(data, nil, @bot)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Event handler for INTERACTION_CREATE events.
|
|
142
|
+
class InteractionCreateEventHandler < EventHandler
|
|
143
|
+
# @!visibility private
|
|
144
|
+
def matches?(event)
|
|
145
|
+
return false unless event.is_a? InteractionCreateEvent
|
|
146
|
+
|
|
147
|
+
[
|
|
148
|
+
matches_all(@attributes[:type], event.type) do |a, e|
|
|
149
|
+
a == case a
|
|
150
|
+
when String, Symbol
|
|
151
|
+
OnyxCord::Interactions::TYPES[e.to_sym]
|
|
152
|
+
else
|
|
153
|
+
e
|
|
154
|
+
end
|
|
155
|
+
end,
|
|
156
|
+
|
|
157
|
+
matches_all(@attributes[:server], event.interaction) do |a, e|
|
|
158
|
+
a.resolve_id == e.server_id
|
|
159
|
+
end,
|
|
160
|
+
|
|
161
|
+
matches_all(@attributes[:channel], event.interaction) do |a, e|
|
|
162
|
+
a.resolve_id == e.channel_id
|
|
163
|
+
end,
|
|
164
|
+
|
|
165
|
+
matches_all(@attributes[:user], event.user) do |a, e|
|
|
166
|
+
a.resolve_id == e.id
|
|
167
|
+
end
|
|
168
|
+
].reduce(true, &:&)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Event for ApplicationCommand interactions.
|
|
173
|
+
class ApplicationCommandEvent < InteractionCreateEvent
|
|
174
|
+
# @return [Symbol] The name of the command.
|
|
175
|
+
attr_reader :command_name
|
|
176
|
+
|
|
177
|
+
# @return [Integer] The ID of the command.
|
|
178
|
+
attr_reader :command_id
|
|
179
|
+
|
|
180
|
+
# @return [Symbol, nil] The name of the subcommand group relevant to this event.
|
|
181
|
+
attr_reader :subcommand_group
|
|
182
|
+
|
|
183
|
+
# @return [Symbol, nil] The name of the subcommand relevant to this event.
|
|
184
|
+
attr_reader :subcommand
|
|
185
|
+
|
|
186
|
+
# @return [Resolved] The resolved channels, roles, users, members, and attachments for this event.
|
|
187
|
+
attr_reader :resolved
|
|
188
|
+
|
|
189
|
+
# @return [Hash<Symbol, Object>] Arguments provided to the command, mapped as `Name => Value`.
|
|
190
|
+
attr_reader :options
|
|
191
|
+
|
|
192
|
+
# @return [Integer, nil] The target of this command when it is a context command.
|
|
193
|
+
attr_reader :target_id
|
|
194
|
+
|
|
195
|
+
# @!visibility private
|
|
196
|
+
def initialize(data, bot)
|
|
197
|
+
super
|
|
198
|
+
|
|
199
|
+
command_data = data['data']
|
|
200
|
+
|
|
201
|
+
@command_id = command_data['id'].to_i
|
|
202
|
+
@command_name = command_data['name'].to_sym
|
|
203
|
+
@command_server_id = command_data['guild_id']
|
|
204
|
+
|
|
205
|
+
@target_id = command_data['target_id']&.to_i
|
|
206
|
+
@resolved = Resolved.new({}, {}, {}, {}, {}, {})
|
|
207
|
+
process_resolved(command_data['resolved']) if command_data['resolved']
|
|
208
|
+
|
|
209
|
+
options = command_data['options'] || []
|
|
210
|
+
|
|
211
|
+
if options.empty?
|
|
212
|
+
@options = {}
|
|
213
|
+
return
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
case options[0]['type']
|
|
217
|
+
when 2
|
|
218
|
+
options = options[0]
|
|
219
|
+
@subcommand_group = options['name'].to_sym
|
|
220
|
+
@subcommand = options['options'][0]['name'].to_sym
|
|
221
|
+
options = options['options'][0]['options']
|
|
222
|
+
when 1
|
|
223
|
+
options = options[0]
|
|
224
|
+
@subcommand = options['name'].to_sym
|
|
225
|
+
options = options['options']
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
@options = transform_options_hash(options || {})
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# @return [true, false] Whether or not the application command that was executed
|
|
232
|
+
# has been registered globally. If this is false, then the application command
|
|
233
|
+
# that was executed is only available in the invoking server.
|
|
234
|
+
def global_command?
|
|
235
|
+
@command_server_id.nil?
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# @return [Message, User, nil] The target of this command, for context commands.
|
|
239
|
+
def target
|
|
240
|
+
return nil unless @target_id
|
|
241
|
+
|
|
242
|
+
@resolved.find { |data| data.key?(@target_id) }[@target_id]
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
private
|
|
246
|
+
|
|
247
|
+
def transform_options_hash(hash)
|
|
248
|
+
hash.to_h { |opt| [opt['name'], opt['options'] || opt['value']] }
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Event handler for ApplicationCommandEvents.
|
|
253
|
+
class ApplicationCommandEventHandler < EventHandler
|
|
254
|
+
# @return [Hash]
|
|
255
|
+
attr_reader :subcommands
|
|
256
|
+
|
|
257
|
+
# @!visibility private
|
|
258
|
+
def initialize(attributes, block)
|
|
259
|
+
super
|
|
260
|
+
|
|
261
|
+
@subcommands = {}
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# @param name [Symbol, String]
|
|
265
|
+
# @yieldparam [SubcommandBuilder]
|
|
266
|
+
# @return [ApplicationCommandEventHandler]
|
|
267
|
+
def group(name)
|
|
268
|
+
raise ArgumentError, 'Unable to mix subcommands and groups' if @subcommands.any? { |n, v| n == name && v.is_a?(Proc) }
|
|
269
|
+
|
|
270
|
+
builder = SubcommandBuilder.new(name)
|
|
271
|
+
yield builder
|
|
272
|
+
|
|
273
|
+
@subcommands.merge!(builder.to_h)
|
|
274
|
+
self
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# @param name [String, Symbol]
|
|
278
|
+
# @yieldparam [SubcommandBuilder]
|
|
279
|
+
# @return [ApplicationCommandEventHandler]
|
|
280
|
+
def subcommand(name, &block)
|
|
281
|
+
raise ArgumentError, 'Unable to mix subcommands and groups' if @subcommands.any? { |n, v| n == name && v.is_a?(Hash) }
|
|
282
|
+
|
|
283
|
+
@subcommands[name.to_sym] = block
|
|
284
|
+
|
|
285
|
+
self
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# @!visibility private
|
|
289
|
+
# @param event [Event]
|
|
290
|
+
def call(event)
|
|
291
|
+
return unless matches?(event)
|
|
292
|
+
|
|
293
|
+
if event.subcommand_group
|
|
294
|
+
unless (cmd = @subcommands.dig(event.subcommand_group, event.subcommand))
|
|
295
|
+
OnyxCord::LOGGER.debug("Received an event for an unhandled subcommand `#{event.command_name} #{event.subcommand_group} #{event.subcommand}'")
|
|
296
|
+
return
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
cmd.call(event)
|
|
300
|
+
elsif event.subcommand
|
|
301
|
+
unless (cmd = @subcommands[event.subcommand])
|
|
302
|
+
OnyxCord::LOGGER.debug("Received an event for an unhandled subcommand `#{event.command_name} #{event.subcommand}'")
|
|
303
|
+
return
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
cmd.call(event)
|
|
307
|
+
else
|
|
308
|
+
@block.call(event)
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# @!visibility private
|
|
313
|
+
def matches?(event)
|
|
314
|
+
return false unless event.is_a? ApplicationCommandEvent
|
|
315
|
+
|
|
316
|
+
[
|
|
317
|
+
matches_all(@attributes[:name], event.command_name) do |a, e|
|
|
318
|
+
a.to_sym == e.to_sym
|
|
319
|
+
end
|
|
320
|
+
].reduce(true, &:&)
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Builder for adding subcommands to an ApplicationCommandHandler
|
|
325
|
+
class SubcommandBuilder
|
|
326
|
+
# @!visibility private
|
|
327
|
+
# @param group [String, Symbol, nil]
|
|
328
|
+
def initialize(group = nil)
|
|
329
|
+
@group = group&.to_sym
|
|
330
|
+
@subcommands = {}
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# @param name [Symbol, String]
|
|
334
|
+
# @yieldparam [ApplicationCommandEvent]
|
|
335
|
+
def subcommand(name, &block)
|
|
336
|
+
@subcommands[name.to_sym] = block
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
# @!visibility private
|
|
340
|
+
def to_h
|
|
341
|
+
@group ? { @group => @subcommands } : @subcommands
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# An event for when a user interacts with a component.
|
|
346
|
+
class ComponentEvent < InteractionCreateEvent
|
|
347
|
+
# @return [String] User provided data for this button.
|
|
348
|
+
attr_reader :custom_id
|
|
349
|
+
|
|
350
|
+
# @return [Interactions::Message, nil] The message the button originates from.
|
|
351
|
+
attr_reader :message
|
|
352
|
+
|
|
353
|
+
# @!visibility private
|
|
354
|
+
def initialize(data, bot)
|
|
355
|
+
super
|
|
356
|
+
|
|
357
|
+
@message = @interaction.message
|
|
358
|
+
@custom_id = data['data']['custom_id']
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
# Generic handler for component events.
|
|
363
|
+
class ComponentEventHandler < InteractionCreateEventHandler
|
|
364
|
+
def matches?(event)
|
|
365
|
+
return false unless super
|
|
366
|
+
return false unless event.is_a? ComponentEvent
|
|
367
|
+
|
|
368
|
+
[
|
|
369
|
+
matches_all(@attributes[:custom_id], event.custom_id) do |a, e|
|
|
370
|
+
# Match regexp and strings
|
|
371
|
+
case a
|
|
372
|
+
when Regexp
|
|
373
|
+
a.match?(e)
|
|
374
|
+
else
|
|
375
|
+
a == e
|
|
376
|
+
end
|
|
377
|
+
end,
|
|
378
|
+
matches_all(@attributes[:message], event.message) do |a, e|
|
|
379
|
+
case a
|
|
380
|
+
when String, Integer
|
|
381
|
+
a.resolve_id == e.id
|
|
382
|
+
else
|
|
383
|
+
a.id == e.id
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
].reduce(&:&)
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# An event for when a user interacts with a button component.
|
|
391
|
+
class ButtonEvent < ComponentEvent
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Event handler for a Button interaction event.
|
|
395
|
+
class ButtonEventHandler < ComponentEventHandler
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
# Event for when a user interacts with a select string component.
|
|
399
|
+
class StringSelectEvent < ComponentEvent
|
|
400
|
+
# @return [Array<String>] Selected values.
|
|
401
|
+
attr_reader :values
|
|
402
|
+
|
|
403
|
+
# @!visibility private
|
|
404
|
+
def initialize(data, bot)
|
|
405
|
+
super
|
|
406
|
+
|
|
407
|
+
@values = data['data']['values']
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# Event handler for a select string component.
|
|
412
|
+
class StringSelectEventHandler < ComponentEventHandler
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# An event for when a user submits a modal.
|
|
416
|
+
class ModalSubmitEvent < ComponentEvent
|
|
417
|
+
# @return [Array<Component>] an array of partial component objects that were in the modal.
|
|
418
|
+
attr_reader :components
|
|
419
|
+
|
|
420
|
+
# @return [Resolved] The resolved channels, roles, users, members, and attachments for the modal.
|
|
421
|
+
attr_reader :resolved
|
|
422
|
+
|
|
423
|
+
# @!visibility private
|
|
424
|
+
def initialize(data, bot)
|
|
425
|
+
super
|
|
426
|
+
|
|
427
|
+
@components = @interaction.components
|
|
428
|
+
@resolved = Resolved.new({}, {}, {}, {}, {}, {})
|
|
429
|
+
process_resolved(data['data']['resolved']) if data['data']['resolved']
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# Get the value of an input passed to the modal.
|
|
433
|
+
# @param custom_id [String] The custom ID of the component to look for.
|
|
434
|
+
# @return [String, nil] The selected value for the component.
|
|
435
|
+
def value(custom_id)
|
|
436
|
+
get_component(custom_id)&.value
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
# Get the selected values from a select menu or file upload component.
|
|
440
|
+
# @param custom_id [String] The custom ID of the component to look for.
|
|
441
|
+
# @return [Array<String>, nil] The values that were chosen for the component.
|
|
442
|
+
def values(custom_id)
|
|
443
|
+
get_component(custom_id)&.values
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Get the attachments that a user uploaded in this modal.
|
|
447
|
+
# @param custom_id [String] The custom ID of the file upload component to get attachments for.
|
|
448
|
+
# @return [Array<Attachment>] the attachments that were uploaded to the file upload component.
|
|
449
|
+
def attachments(custom_id)
|
|
450
|
+
values(custom_id)&.map { |id| @resolved[:attachments][id.to_i] } || []
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# Event handler for a modal submission.
|
|
455
|
+
class ModalSubmitEventHandler < ComponentEventHandler
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
# Event for when a user interacts with a select user component.
|
|
459
|
+
class UserSelectEvent < ComponentEvent
|
|
460
|
+
# @return [Array<User>] Selected values.
|
|
461
|
+
attr_reader :values
|
|
462
|
+
|
|
463
|
+
# @!visibility private
|
|
464
|
+
def initialize(data, bot)
|
|
465
|
+
super
|
|
466
|
+
|
|
467
|
+
@values = data['data']['values'].map { |e| bot.user(e) }
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# Event handler for a select user component.
|
|
472
|
+
class UserSelectEventHandler < ComponentEventHandler
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
# Event for when a user interacts with a select role component.
|
|
476
|
+
class RoleSelectEvent < ComponentEvent
|
|
477
|
+
# @return [Array<Role>] Selected values.
|
|
478
|
+
attr_reader :values
|
|
479
|
+
|
|
480
|
+
# @!visibility private
|
|
481
|
+
def initialize(data, bot)
|
|
482
|
+
super
|
|
483
|
+
|
|
484
|
+
@values = data['data']['values'].map { |e| bot.server(data['guild_id']).role(e) }
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
# Event handler for a select role component.
|
|
489
|
+
class RoleSelectEventHandler < ComponentEventHandler
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# Event for when a user interacts with a select mentionable component.
|
|
493
|
+
class MentionableSelectEvent < ComponentEvent
|
|
494
|
+
# @return [Hash<Symbol => Array<User>, Symbol => Array<Role>>] Selected values.
|
|
495
|
+
attr_reader :values
|
|
496
|
+
|
|
497
|
+
# @!visibility private
|
|
498
|
+
def initialize(data, bot)
|
|
499
|
+
super
|
|
500
|
+
|
|
501
|
+
users = data['data']['resolved']['users'].map { |_, user| @bot.ensure_user(user) }
|
|
502
|
+
roles = data['data']['resolved']['roles'] ? data['data']['resolved']['roles'].keys.map { |e| bot.server(data['guild_id']).role(e) } : []
|
|
503
|
+
@values = { users: users, roles: roles }
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
# Event handler for a select mentionable component.
|
|
508
|
+
class MentionableSelectEventHandler < ComponentEventHandler
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
# Event for when a user interacts with a select channel component.
|
|
512
|
+
class ChannelSelectEvent < ComponentEvent
|
|
513
|
+
# @return [Array<Channel>] Selected values.
|
|
514
|
+
attr_reader :values
|
|
515
|
+
|
|
516
|
+
# @!visibility private
|
|
517
|
+
def initialize(data, bot)
|
|
518
|
+
super
|
|
519
|
+
|
|
520
|
+
@values = data['data']['values'].map { |e| bot.channel(e, bot.server(data['guild_id'])) }
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
# Event handler for a select channel component.
|
|
525
|
+
class ChannelSelectEventHandler < ComponentEventHandler
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
# Event handler for an autocomplete option choices.
|
|
529
|
+
class AutocompleteEventHandler < InteractionCreateEventHandler
|
|
530
|
+
def matches?(event)
|
|
531
|
+
return false unless super
|
|
532
|
+
return false unless event.is_a?(AutocompleteEvent)
|
|
533
|
+
|
|
534
|
+
[
|
|
535
|
+
matches_all(@attributes[:name], event.focused) { |a, e| a == e },
|
|
536
|
+
matches_all(@attributes[:command_id], event.command_id) { |a, e| a&.to_i == e },
|
|
537
|
+
matches_all(@attributes[:subcommand], event.subcommand) { |a, e| a&.to_sym == e },
|
|
538
|
+
matches_all(@attributes[:command_name], event.command_name) { |a, e| a&.to_sym == e },
|
|
539
|
+
matches_all(@attributes[:subcommand_group], event.subcommand_group) { |a, e| a&.to_sym == e },
|
|
540
|
+
matches_all(@attributes[:server], event.server_id) { |a, e| a&.resolve_id == e }
|
|
541
|
+
].reduce(&:&)
|
|
542
|
+
end
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
# An event for an autocomplete option choice.
|
|
546
|
+
class AutocompleteEvent < ApplicationCommandEvent
|
|
547
|
+
# @return [String] Name of the currently focused option.
|
|
548
|
+
attr_reader :focused
|
|
549
|
+
|
|
550
|
+
# @return [Hash] An empty hash that can be used to return choices by adding K/V pairs.
|
|
551
|
+
attr_reader :choices
|
|
552
|
+
|
|
553
|
+
# @!visibility private
|
|
554
|
+
def initialize(data, bot)
|
|
555
|
+
super
|
|
556
|
+
|
|
557
|
+
@choices = {}
|
|
558
|
+
|
|
559
|
+
options = data['data']['options']
|
|
560
|
+
|
|
561
|
+
options = case options[0]['type']
|
|
562
|
+
when 1
|
|
563
|
+
options[0]['options']
|
|
564
|
+
when 2
|
|
565
|
+
options[0]['options'][0]['options']
|
|
566
|
+
else
|
|
567
|
+
options
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
@focused = options.find { |opt| opt.key?('focused') }['name']
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
# Respond to this interaction with autocomplete choices.
|
|
574
|
+
# @param choices [Array<Hash>, Hash, nil] Autocomplete choices to return.
|
|
575
|
+
def respond(choices:)
|
|
576
|
+
@interaction.show_autocomplete_choices(choices || [])
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
# An event for whenever an application command's permissions are updated.
|
|
581
|
+
class ApplicationCommandPermissionsUpdateEvent < Event
|
|
582
|
+
# @return [Integer] the ID of the server where the command permissions were updated.
|
|
583
|
+
attr_reader :server_id
|
|
584
|
+
|
|
585
|
+
# @return [Integer, nil] the ID of the application command that was updated.
|
|
586
|
+
attr_reader :command_id
|
|
587
|
+
|
|
588
|
+
# @return [Array<ApplicationCommand::Permission>] the permissions that were updated.
|
|
589
|
+
attr_reader :permissions
|
|
590
|
+
|
|
591
|
+
# @return [Integer] the ID of the application whose commands were updated.
|
|
592
|
+
attr_reader :application_id
|
|
593
|
+
|
|
594
|
+
# @!visibility private
|
|
595
|
+
def initialize(data, bot)
|
|
596
|
+
@bot = bot
|
|
597
|
+
@server_id = data['guild_id'].to_i
|
|
598
|
+
@application_id = data['application_id'].to_i
|
|
599
|
+
@command_id = data['id'].to_i if data['id'].to_i != @application_id
|
|
600
|
+
@permissions = data['permissions'].map do |permission|
|
|
601
|
+
OnyxCord::ApplicationCommand::Permission.new(permission, data, bot)
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
# @return [Server] the server where the command's permissions were updated.
|
|
606
|
+
def server
|
|
607
|
+
@bot.server(@server_id)
|
|
608
|
+
end
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
# Event handler for the APPLICATION_COMMAND_PERMISSIONS_UPDATE event.
|
|
612
|
+
class ApplicationCommandPermissionsUpdateEventHandler < EventHandler
|
|
613
|
+
# @!visibility private
|
|
614
|
+
def matches?(event)
|
|
615
|
+
return false unless event.is_a?(ApplicationCommandPermissionsUpdateEvent)
|
|
616
|
+
|
|
617
|
+
[
|
|
618
|
+
matches_all(@attributes[:server], event.server_id) { |a, e| a.resolve_id == e },
|
|
619
|
+
matches_all(@attributes[:command_id], event.command_id) { |a, e| a.resolve_id == e },
|
|
620
|
+
matches_all(@attributes[:application_id], event.application_id) { |a, e| a.resolve_id == e }
|
|
621
|
+
].reduce(&:&)
|
|
622
|
+
end
|
|
623
|
+
end
|
|
624
|
+
end
|