discorb 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +2 -2
  3. data/.rubocop.yml +12 -75
  4. data/Changelog.md +10 -0
  5. data/Rakefile +482 -454
  6. data/lib/discorb/allowed_mentions.rb +68 -72
  7. data/lib/discorb/app_command/command.rb +466 -398
  8. data/lib/discorb/app_command/common.rb +65 -25
  9. data/lib/discorb/app_command/handler.rb +304 -266
  10. data/lib/discorb/app_command.rb +5 -5
  11. data/lib/discorb/application.rb +198 -197
  12. data/lib/discorb/asset.rb +101 -101
  13. data/lib/discorb/attachment.rb +134 -119
  14. data/lib/discorb/audit_logs.rb +412 -385
  15. data/lib/discorb/automod.rb +279 -269
  16. data/lib/discorb/channel/base.rb +107 -108
  17. data/lib/discorb/channel/category.rb +32 -32
  18. data/lib/discorb/channel/container.rb +44 -44
  19. data/lib/discorb/channel/dm.rb +26 -28
  20. data/lib/discorb/channel/guild.rb +311 -246
  21. data/lib/discorb/channel/stage.rb +156 -140
  22. data/lib/discorb/channel/text.rb +430 -336
  23. data/lib/discorb/channel/thread.rb +374 -325
  24. data/lib/discorb/channel/voice.rb +85 -79
  25. data/lib/discorb/channel.rb +5 -5
  26. data/lib/discorb/client.rb +635 -621
  27. data/lib/discorb/color.rb +178 -182
  28. data/lib/discorb/common.rb +168 -164
  29. data/lib/discorb/components/button.rb +107 -106
  30. data/lib/discorb/components/select_menu.rb +157 -145
  31. data/lib/discorb/components/text_input.rb +103 -106
  32. data/lib/discorb/components.rb +68 -66
  33. data/lib/discorb/dictionary.rb +135 -135
  34. data/lib/discorb/embed.rb +404 -398
  35. data/lib/discorb/emoji.rb +309 -302
  36. data/lib/discorb/emoji_table.rb +16099 -8857
  37. data/lib/discorb/error.rb +131 -131
  38. data/lib/discorb/event.rb +360 -314
  39. data/lib/discorb/event_handler.rb +39 -39
  40. data/lib/discorb/exe/about.rb +17 -17
  41. data/lib/discorb/exe/irb.rb +72 -67
  42. data/lib/discorb/exe/new.rb +323 -315
  43. data/lib/discorb/exe/run.rb +69 -68
  44. data/lib/discorb/exe/setup.rb +57 -55
  45. data/lib/discorb/exe/show.rb +12 -12
  46. data/lib/discorb/extend.rb +25 -45
  47. data/lib/discorb/extension.rb +89 -83
  48. data/lib/discorb/flag.rb +126 -128
  49. data/lib/discorb/gateway.rb +984 -804
  50. data/lib/discorb/gateway_events.rb +670 -638
  51. data/lib/discorb/gateway_requests.rb +45 -48
  52. data/lib/discorb/guild.rb +2115 -1626
  53. data/lib/discorb/guild_template.rb +280 -241
  54. data/lib/discorb/http.rb +247 -232
  55. data/lib/discorb/image.rb +42 -42
  56. data/lib/discorb/integration.rb +169 -161
  57. data/lib/discorb/intents.rb +161 -163
  58. data/lib/discorb/interaction/autocomplete.rb +76 -62
  59. data/lib/discorb/interaction/command.rb +279 -224
  60. data/lib/discorb/interaction/components.rb +114 -104
  61. data/lib/discorb/interaction/modal.rb +36 -32
  62. data/lib/discorb/interaction/response.rb +379 -336
  63. data/lib/discorb/interaction/root.rb +271 -257
  64. data/lib/discorb/interaction.rb +5 -5
  65. data/lib/discorb/invite.rb +154 -153
  66. data/lib/discorb/member.rb +344 -311
  67. data/lib/discorb/message.rb +615 -544
  68. data/lib/discorb/message_meta.rb +197 -186
  69. data/lib/discorb/modules.rb +371 -290
  70. data/lib/discorb/permission.rb +305 -291
  71. data/lib/discorb/presence.rb +352 -346
  72. data/lib/discorb/rate_limit.rb +81 -76
  73. data/lib/discorb/reaction.rb +55 -54
  74. data/lib/discorb/role.rb +272 -240
  75. data/lib/discorb/shard.rb +76 -74
  76. data/lib/discorb/sticker.rb +193 -171
  77. data/lib/discorb/user.rb +205 -188
  78. data/lib/discorb/utils/colored_puts.rb +16 -16
  79. data/lib/discorb/utils.rb +12 -16
  80. data/lib/discorb/voice_state.rb +305 -281
  81. data/lib/discorb/webhook.rb +537 -507
  82. data/lib/discorb.rb +62 -56
  83. data/sig/discorb/application.rbs +2 -0
  84. data/sig/discorb/automod.rbs +10 -1
  85. data/sig/discorb/guild.rbs +2 -0
  86. data/sig/discorb/message.rbs +2 -0
  87. data/sig/discorb/user.rbs +22 -20
  88. metadata +2 -2
@@ -1,385 +1,412 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents a Discord audit log.
6
- #
7
- class AuditLog < DiscordModel
8
- # @return [Array<Discorb::Webhook>] The webhooks in this audit log.
9
- attr_reader :webhooks
10
- # @return [Array<Discorb::User>] The users in this audit log.
11
- attr_reader :users
12
- # @return [Array<Discorb::ThreadChannel>] The threads in this audit log.
13
- attr_reader :threads
14
- # @return [Array<Discorb::AuditLog::Entry>] The entries in this audit log.
15
- attr_reader :entries
16
-
17
- #
18
- # Initializes a new instance of the AuditLog class.
19
- # @private
20
- #
21
- def initialize(client, data, guild)
22
- @client = client
23
- @guild = guild
24
- @webhooks = data[:webhooks].map { |webhook| Webhook.from_data(@client, webhook) }
25
- @users = data[:users].map { |user| client.users[user[:id]] || User.new(@client, user) }
26
- @threads = data[:threads].map do |thread|
27
- client.channels[thread[:id]] || Channel.make_channel(@client, thread, no_cache: true)
28
- end
29
- @entries = data[:audit_log_entries].map { |entry| AuditLog::Entry.new(@client, entry, guild.id) }
30
- end
31
-
32
- def inspect
33
- "<#{self.class} #{@entries.length} entries>"
34
- end
35
-
36
- #
37
- # Gets an entry from entries.
38
- #
39
- # @param [Integer] index The index of the entry.
40
- #
41
- # @return [Discorb::AuditLog::Entry] The entry.
42
- # @return [nil] If the index is out of range.
43
- #
44
- def [](index)
45
- @entries[index]
46
- end
47
-
48
- #
49
- # Represents an entry in an audit log.
50
- #
51
- class Entry < DiscordModel
52
- # @return [Discorb::Snowflake] The ID of the entry.
53
- attr_reader :id
54
- # @return [Discorb::Snowflake] The ID of the user who performed the action.
55
- attr_reader :user_id
56
- # @return [Discorb::Snowflake] The ID of the target of the action.
57
- attr_reader :target_id
58
- # @return [Symbol] The type of the entry.
59
- # These symbols will be used:
60
- #
61
- # * `:guild_update`
62
- # * `:channel_create`
63
- # * `:channel_update`
64
- # * `:channel_delete`
65
- # * `:channel_overwrite_create`
66
- # * `:channel_overwrite_update`
67
- # * `:channel_overwrite_delete`
68
- # * `:member_kick`
69
- # * `:member_prune`
70
- # * `:member_ban_add`
71
- # * `:member_ban_remove`
72
- # * `:member_update`
73
- # * `:member_role_update`
74
- # * `:member_move`
75
- # * `:member_disconnect`
76
- # * `:bot_add`
77
- # * `:role_create`
78
- # * `:role_update`
79
- # * `:role_delete`
80
- # * `:invite_create`
81
- # * `:invite_update`
82
- # * `:invite_delete`
83
- # * `:webhook_create`
84
- # * `:webhook_update`
85
- # * `:webhook_delete`
86
- # * `:emoji_create`
87
- # * `:emoji_update`
88
- # * `:emoji_delete`
89
- # * `:message_delete`
90
- # * `:message_bulk_delete`
91
- # * `:message_pin`
92
- # * `:message_unpin`
93
- # * `:integration_create`
94
- # * `:integration_update`
95
- # * `:integration_delete`
96
- # * `:stage_instance_create`
97
- # * `:stage_instance_update`
98
- # * `:stage_instance_delete`
99
- # * `:sticker_create`
100
- # * `:sticker_update`
101
- # * `:sticker_delete`
102
- # * `:guild_scheduled_event_create`
103
- # * `:guild_scheduled_event_update`
104
- # * `:guild_scheduled_event_delete`
105
- # * `:thread_create`
106
- # * `:thread_update`
107
- # * `:thread_delete`
108
- # * `:application_command_permission_update``
109
- attr_reader :type
110
- # @return [Discorb::AuditLog::Entry::Changes] The changes in this entry.
111
- attr_reader :changes
112
- # @return [Discorb::Channel, Discorb::Role, Discorb::Member, Discorb::Guild, Discorb::Message, Discorb::Snowflake]
113
- # The target of the entry.
114
- attr_reader :target
115
- # @return [Hash{Symbol => Object}] The optional data for this entry.
116
- # @note You can use dot notation to access the data.
117
- attr_reader :options
118
-
119
- # @!attribute [r] user
120
- # @return [Discorb::User] The user who performed the action.
121
-
122
- #
123
- # @return [{Integer => Symbol}] The map of events to their respective changes.
124
- # @private
125
- #
126
- EVENTS = {
127
- 1 => :guild_update,
128
- 10 => :channel_create,
129
- 11 => :channel_update,
130
- 12 => :channel_delete,
131
- 13 => :channel_overwrite_create,
132
- 14 => :channel_overwrite_update,
133
- 15 => :channel_overwrite_delete,
134
- 20 => :member_kick,
135
- 21 => :member_prune,
136
- 22 => :member_ban_add,
137
- 23 => :member_ban_remove,
138
- 24 => :member_update,
139
- 25 => :member_role_update,
140
- 26 => :member_move,
141
- 27 => :member_disconnect,
142
- 28 => :bot_add,
143
- 30 => :role_create,
144
- 31 => :role_update,
145
- 32 => :role_delete,
146
- 40 => :invite_create,
147
- 41 => :invite_update,
148
- 42 => :invite_delete,
149
- 50 => :webhook_create,
150
- 51 => :webhook_update,
151
- 52 => :webhook_delete,
152
- 60 => :emoji_create,
153
- 61 => :emoji_update,
154
- 62 => :emoji_delete,
155
- 72 => :message_delete,
156
- 73 => :message_bulk_delete,
157
- 74 => :message_pin,
158
- 75 => :message_unpin,
159
- 80 => :integration_create,
160
- 81 => :integration_update,
161
- 82 => :integration_delete,
162
- 83 => :stage_instance_create,
163
- 84 => :stage_instance_update,
164
- 85 => :stage_instance_delete,
165
- 90 => :sticker_create,
166
- 91 => :sticker_update,
167
- 92 => :sticker_delete,
168
- 100 => :guild_scheduled_event_create,
169
- 101 => :guild_scheduled_event_update,
170
- 102 => :guild_scheduled_event_delete,
171
- 110 => :thread_create,
172
- 111 => :thread_update,
173
- 112 => :thread_delete,
174
- 121 => :application_command_permission_update,
175
- 140 => :automod_rule_create,
176
- 141 => :automod_rule_update,
177
- 142 => :automod_rule_delete,
178
- 143 => :automod_block_message,
179
- }.freeze
180
-
181
- #
182
- # The converter for the change.
183
- # @private
184
- #
185
- CONVERTERS = {
186
- channel: ->(client, id, _guild_id) { client.channels[id] },
187
- thread: ->(client, id, _guild_id) { client.channels[id] },
188
- role: ->(client, id, guild_id) { client.guilds[guild_id]&.roles&.[](id) },
189
- member: ->(client, id, guild_id) { client.guilds[guild_id]&.members&.[](id) },
190
- guild: ->(client, id, _guild_id) { client.guilds[id] },
191
- message: ->(client, id, _guild_id) { client.messages[id] },
192
- }.freeze
193
-
194
- #
195
- # Initializes a new AuditLog entry.
196
- # @private
197
- #
198
- def initialize(client, data, guild_id)
199
- @client = client
200
- @guild_id = Snowflake.new(guild_id)
201
- @id = Snowflake.new(data[:id])
202
- @user_id = Snowflake.new(data[:user_id])
203
- @target_id = Snowflake.new(data[:target_id])
204
- @type = EVENTS[data[:action_type]] || :unknown
205
- @target = CONVERTERS[@type.to_s.split("_")[0].to_sym]&.call(client, @target_id, @gui)
206
- @target ||= Snowflake.new(data[:target_id])
207
- @changes = data[:changes] && Changes.new(data[:changes])
208
- @reason = data[:reason]
209
- data[:options]&.each do |option, value|
210
- define_singleton_method(option) { value }
211
- if option.end_with?("_id") && CONVERTERS.key?(option.to_s.split("_")[0].to_sym)
212
- define_singleton_method(option.to_s.sub("_id", "")) do
213
- CONVERTERS[option.to_s.split("_")[0].to_sym]&.call(client, value, @guild_id)
214
- end
215
- end
216
- end
217
- @options = data[:options] || {}
218
- end
219
-
220
- def user
221
- @client.users[@user_id]
222
- end
223
-
224
- #
225
- # Get a change with the given key.
226
- #
227
- # @param [Symbol] key The key to get.
228
- #
229
- # @return [Discorb::AuditLog::Entry::Change] The change with the given key.
230
- # @return [nil] The change with the given key does not exist.
231
- #
232
- def [](key)
233
- @changes[key]
234
- end
235
-
236
- def inspect
237
- "#<#{self.class} #{@changes&.data&.length || "No"} changes>"
238
- end
239
-
240
- class << self
241
- attr_reader :events, :converts
242
- end
243
-
244
- #
245
- # Represents the changes in an audit log entry.
246
- #
247
- class Changes < DiscordModel
248
- attr_reader :data
249
-
250
- #
251
- # Initializes a new changes object.
252
- # @private
253
- #
254
- # @param [Hash] data The data to initialize with.
255
- #
256
- def initialize(data)
257
- @data = data.to_h { |d| [d[:key].to_sym, d] }
258
- @data.each do |k, v|
259
- define_singleton_method(k) { Change.new(v) }
260
- end
261
- end
262
-
263
- #
264
- # Formats the changes into a string.
265
- #
266
- def inspect
267
- "#<#{self.class} #{@data.length} changes>"
268
- end
269
-
270
- #
271
- # Get keys of changes.
272
- #
273
- # @return [Array<Symbol>] The keys of the changes.
274
- #
275
- def keys
276
- @data.keys
277
- end
278
-
279
- #
280
- # Get a change with the given key.
281
- #
282
- # @param [Symbol] key The key to get.
283
- #
284
- # @return [Discorb::AuditLog::Entry::Change] The change with the given key.
285
- # @return [nil] The change with the given key does not exist.
286
- #
287
- def [](key)
288
- @data[key.to_sym]
289
- end
290
- end
291
-
292
- #
293
- # Represents a change in an audit log entry.
294
- # @note This instance will try to call a method of {#new_value} if the method wasn't defined.
295
- #
296
- class Change < DiscordModel
297
- # @return [Symbol] The key of the change.
298
- attr_reader :key
299
- # @return [Object] The old value of the change.
300
- attr_reader :old_value
301
- # @return [Object] The new value of the change.
302
- attr_reader :new_value
303
-
304
- #
305
- # Initializes a new change object.
306
- # @private
307
- #
308
- def initialize(data)
309
- @key = data[:key].to_sym
310
- method = case @key.to_s
311
- when /.*_id$/, "id"
312
- ->(v) { Snowflake.new(v) }
313
- when "permissions"
314
- ->(v) { Discorb::Permission.new(v.to_i) }
315
- when "status"
316
- ->(v) { Discorb::ScheduledEvent::STATUS[v] }
317
- when "entity_type"
318
- ->(v) { Discorb::ScheduledEvent::ENTITY_TYPE[v] }
319
- when "privacy_level"
320
- ->(v) { Discorb::StageInstance::PRIVACY_LEVEL[v] || Discorb::ScheduledEvent::PRIVACY_LEVEL[v] }
321
- else
322
- ->(v) { v }
323
- end
324
- @old_value = method.call(data[:old_value])
325
- @new_value = method.call(data[:new_value])
326
- end
327
-
328
- #
329
- # Send a message to the new value.
330
- #
331
- def method_missing(method, ...)
332
- @new_value.__send__(method, ...)
333
- end
334
-
335
- #
336
- # Format the change into a string.
337
- #
338
- # @return [String] The string representation of the change.
339
- #
340
- def inspect
341
- "#<#{self.class} #{@key.inspect} #{@old_value.inspect} -> #{@new_value.inspect}>"
342
- end
343
-
344
- #
345
- # Whether the change responds to the given method.
346
- #
347
- # @return [Boolean] Whether the change responds to the given method.
348
- #
349
- def respond_to_missing?(method, include_private = false)
350
- @new_value.respond_to?(method, include_private)
351
- end
352
- end
353
- end
354
-
355
- #
356
- # Represents an integration in an audit log entry.
357
- #
358
- class Integration < DiscordModel
359
- # @return [Discorb::Snowflake] The ID of the integration.
360
- attr_reader :id
361
- # @return [Symbol] The type of the integration.
362
- attr_reader :type
363
- # @return [String] The name of the integration.
364
- attr_reader :name
365
- # @return [Discorb::Integration::Account] The account of the integration.
366
- attr_reader :account
367
-
368
- #
369
- # Initializes a new integration object.
370
- # @private
371
- #
372
- def initialize(data)
373
- @id = Snowflake.new(data[:id])
374
- @type = data[:type].to_sym
375
- @name = data[:name]
376
- @data = data
377
- @account = Discorb::Integration::Account.new(@data[:account]) if @data[:account]
378
- end
379
-
380
- def inspect
381
- "#<#{self.class} #{@id}>"
382
- end
383
- end
384
- end
385
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a Discord audit log.
6
+ #
7
+ class AuditLog < DiscordModel
8
+ # @return [Array<Discorb::Webhook>] The webhooks in this audit log.
9
+ attr_reader :webhooks
10
+ # @return [Array<Discorb::User>] The users in this audit log.
11
+ attr_reader :users
12
+ # @return [Array<Discorb::ThreadChannel>] The threads in this audit log.
13
+ attr_reader :threads
14
+ # @return [Array<Discorb::AuditLog::Entry>] The entries in this audit log.
15
+ attr_reader :entries
16
+
17
+ #
18
+ # Initializes a new instance of the AuditLog class.
19
+ # @private
20
+ #
21
+ def initialize(client, data, guild)
22
+ @client = client
23
+ @guild = guild
24
+ @webhooks =
25
+ data[:webhooks].map { |webhook| Webhook.from_data(@client, webhook) }
26
+ @users =
27
+ data[:users].map do |user|
28
+ client.users[user[:id]] || User.new(@client, user)
29
+ end
30
+ @threads =
31
+ data[:threads].map do |thread|
32
+ client.channels[thread[:id]] ||
33
+ Channel.make_channel(@client, thread, no_cache: true)
34
+ end
35
+ @entries =
36
+ data[:audit_log_entries].map do |entry|
37
+ AuditLog::Entry.new(@client, entry, guild.id)
38
+ end
39
+ end
40
+
41
+ def inspect
42
+ "<#{self.class} #{@entries.length} entries>"
43
+ end
44
+
45
+ #
46
+ # Gets an entry from entries.
47
+ #
48
+ # @param [Integer] index The index of the entry.
49
+ #
50
+ # @return [Discorb::AuditLog::Entry] The entry.
51
+ # @return [nil] If the index is out of range.
52
+ #
53
+ def [](index)
54
+ @entries[index]
55
+ end
56
+
57
+ #
58
+ # Represents an entry in an audit log.
59
+ #
60
+ class Entry < DiscordModel
61
+ # @return [Discorb::Snowflake] The ID of the entry.
62
+ attr_reader :id
63
+ # @return [Discorb::Snowflake] The ID of the user who performed the action.
64
+ attr_reader :user_id
65
+ # @return [Discorb::Snowflake] The ID of the target of the action.
66
+ attr_reader :target_id
67
+ # @return [Symbol] The type of the entry.
68
+ # These symbols will be used:
69
+ #
70
+ # * `:guild_update`
71
+ # * `:channel_create`
72
+ # * `:channel_update`
73
+ # * `:channel_delete`
74
+ # * `:channel_overwrite_create`
75
+ # * `:channel_overwrite_update`
76
+ # * `:channel_overwrite_delete`
77
+ # * `:member_kick`
78
+ # * `:member_prune`
79
+ # * `:member_ban_add`
80
+ # * `:member_ban_remove`
81
+ # * `:member_update`
82
+ # * `:member_role_update`
83
+ # * `:member_move`
84
+ # * `:member_disconnect`
85
+ # * `:bot_add`
86
+ # * `:role_create`
87
+ # * `:role_update`
88
+ # * `:role_delete`
89
+ # * `:invite_create`
90
+ # * `:invite_update`
91
+ # * `:invite_delete`
92
+ # * `:webhook_create`
93
+ # * `:webhook_update`
94
+ # * `:webhook_delete`
95
+ # * `:emoji_create`
96
+ # * `:emoji_update`
97
+ # * `:emoji_delete`
98
+ # * `:message_delete`
99
+ # * `:message_bulk_delete`
100
+ # * `:message_pin`
101
+ # * `:message_unpin`
102
+ # * `:integration_create`
103
+ # * `:integration_update`
104
+ # * `:integration_delete`
105
+ # * `:stage_instance_create`
106
+ # * `:stage_instance_update`
107
+ # * `:stage_instance_delete`
108
+ # * `:sticker_create`
109
+ # * `:sticker_update`
110
+ # * `:sticker_delete`
111
+ # * `:guild_scheduled_event_create`
112
+ # * `:guild_scheduled_event_update`
113
+ # * `:guild_scheduled_event_delete`
114
+ # * `:thread_create`
115
+ # * `:thread_update`
116
+ # * `:thread_delete`
117
+ # * `:application_command_permission_update``
118
+ attr_reader :type
119
+ # @return [Discorb::AuditLog::Entry::Changes] The changes in this entry.
120
+ attr_reader :changes
121
+ # @return [Discorb::Channel, Discorb::Role, Discorb::Member, Discorb::Guild, Discorb::Message, Discorb::Snowflake]
122
+ # The target of the entry.
123
+ attr_reader :target
124
+ # @return [Hash{Symbol => Object}] The optional data for this entry.
125
+ # @note You can use dot notation to access the data.
126
+ attr_reader :options
127
+
128
+ # @!attribute [r] user
129
+ # @return [Discorb::User] The user who performed the action.
130
+
131
+ #
132
+ # @return [{Integer => Symbol}] The map of events to their respective changes.
133
+ # @private
134
+ #
135
+ EVENTS = {
136
+ 1 => :guild_update,
137
+ 10 => :channel_create,
138
+ 11 => :channel_update,
139
+ 12 => :channel_delete,
140
+ 13 => :channel_overwrite_create,
141
+ 14 => :channel_overwrite_update,
142
+ 15 => :channel_overwrite_delete,
143
+ 20 => :member_kick,
144
+ 21 => :member_prune,
145
+ 22 => :member_ban_add,
146
+ 23 => :member_ban_remove,
147
+ 24 => :member_update,
148
+ 25 => :member_role_update,
149
+ 26 => :member_move,
150
+ 27 => :member_disconnect,
151
+ 28 => :bot_add,
152
+ 30 => :role_create,
153
+ 31 => :role_update,
154
+ 32 => :role_delete,
155
+ 40 => :invite_create,
156
+ 41 => :invite_update,
157
+ 42 => :invite_delete,
158
+ 50 => :webhook_create,
159
+ 51 => :webhook_update,
160
+ 52 => :webhook_delete,
161
+ 60 => :emoji_create,
162
+ 61 => :emoji_update,
163
+ 62 => :emoji_delete,
164
+ 72 => :message_delete,
165
+ 73 => :message_bulk_delete,
166
+ 74 => :message_pin,
167
+ 75 => :message_unpin,
168
+ 80 => :integration_create,
169
+ 81 => :integration_update,
170
+ 82 => :integration_delete,
171
+ 83 => :stage_instance_create,
172
+ 84 => :stage_instance_update,
173
+ 85 => :stage_instance_delete,
174
+ 90 => :sticker_create,
175
+ 91 => :sticker_update,
176
+ 92 => :sticker_delete,
177
+ 100 => :guild_scheduled_event_create,
178
+ 101 => :guild_scheduled_event_update,
179
+ 102 => :guild_scheduled_event_delete,
180
+ 110 => :thread_create,
181
+ 111 => :thread_update,
182
+ 112 => :thread_delete,
183
+ 121 => :application_command_permission_update,
184
+ 140 => :automod_rule_create,
185
+ 141 => :automod_rule_update,
186
+ 142 => :automod_rule_delete,
187
+ 143 => :automod_block_message
188
+ }.freeze
189
+
190
+ #
191
+ # The converter for the change.
192
+ # @private
193
+ #
194
+ CONVERTERS = {
195
+ channel: ->(client, id, _guild_id) { client.channels[id] },
196
+ thread: ->(client, id, _guild_id) { client.channels[id] },
197
+ role: ->(client, id, guild_id) do
198
+ client.guilds[guild_id]&.roles&.[](id)
199
+ end,
200
+ member: ->(client, id, guild_id) do
201
+ client.guilds[guild_id]&.members&.[](id)
202
+ end,
203
+ guild: ->(client, id, _guild_id) { client.guilds[id] },
204
+ message: ->(client, id, _guild_id) { client.messages[id] }
205
+ }.freeze
206
+
207
+ #
208
+ # Initializes a new AuditLog entry.
209
+ # @private
210
+ #
211
+ def initialize(client, data, guild_id)
212
+ @client = client
213
+ @guild_id = Snowflake.new(guild_id)
214
+ @id = Snowflake.new(data[:id])
215
+ @user_id = Snowflake.new(data[:user_id])
216
+ @target_id = Snowflake.new(data[:target_id])
217
+ @type = EVENTS[data[:action_type]] || :unknown
218
+ @target =
219
+ CONVERTERS[@type.to_s.split("_")[0].to_sym]&.call(
220
+ client,
221
+ @target_id,
222
+ @gui
223
+ )
224
+ @target ||= Snowflake.new(data[:target_id])
225
+ @changes = data[:changes] && Changes.new(data[:changes])
226
+ @reason = data[:reason]
227
+ data[:options]&.each do |option, value|
228
+ define_singleton_method(option) { value }
229
+ if option.end_with?("_id") &&
230
+ CONVERTERS.key?(option.to_s.split("_")[0].to_sym)
231
+ define_singleton_method(option.to_s.sub("_id", "")) do
232
+ CONVERTERS[option.to_s.split("_")[0].to_sym]&.call(
233
+ client,
234
+ value,
235
+ @guild_id
236
+ )
237
+ end
238
+ end
239
+ end
240
+ @options = data[:options] || {}
241
+ end
242
+
243
+ def user
244
+ @client.users[@user_id]
245
+ end
246
+
247
+ #
248
+ # Get a change with the given key.
249
+ #
250
+ # @param [Symbol] key The key to get.
251
+ #
252
+ # @return [Discorb::AuditLog::Entry::Change] The change with the given key.
253
+ # @return [nil] The change with the given key does not exist.
254
+ #
255
+ def [](key)
256
+ @changes[key]
257
+ end
258
+
259
+ def inspect
260
+ "#<#{self.class} #{@changes&.data&.length || "No"} changes>"
261
+ end
262
+
263
+ class << self
264
+ attr_reader :events, :converts
265
+ end
266
+
267
+ #
268
+ # Represents the changes in an audit log entry.
269
+ #
270
+ class Changes < DiscordModel
271
+ attr_reader :data
272
+
273
+ #
274
+ # Initializes a new changes object.
275
+ # @private
276
+ #
277
+ # @param [Hash] data The data to initialize with.
278
+ #
279
+ def initialize(data)
280
+ @data = data.to_h { |d| [d[:key].to_sym, d] }
281
+ @data.each { |k, v| define_singleton_method(k) { Change.new(v) } }
282
+ end
283
+
284
+ #
285
+ # Formats the changes into a string.
286
+ #
287
+ def inspect
288
+ "#<#{self.class} #{@data.length} changes>"
289
+ end
290
+
291
+ #
292
+ # Get keys of changes.
293
+ #
294
+ # @return [Array<Symbol>] The keys of the changes.
295
+ #
296
+ def keys
297
+ @data.keys
298
+ end
299
+
300
+ #
301
+ # Get a change with the given key.
302
+ #
303
+ # @param [Symbol] key The key to get.
304
+ #
305
+ # @return [Discorb::AuditLog::Entry::Change] The change with the given key.
306
+ # @return [nil] The change with the given key does not exist.
307
+ #
308
+ def [](key)
309
+ @data[key.to_sym]
310
+ end
311
+ end
312
+
313
+ #
314
+ # Represents a change in an audit log entry.
315
+ # @note This instance will try to call a method of {#new_value} if the method wasn't defined.
316
+ #
317
+ class Change < DiscordModel
318
+ # @return [Symbol] The key of the change.
319
+ attr_reader :key
320
+ # @return [Object] The old value of the change.
321
+ attr_reader :old_value
322
+ # @return [Object] The new value of the change.
323
+ attr_reader :new_value
324
+
325
+ #
326
+ # Initializes a new change object.
327
+ # @private
328
+ #
329
+ def initialize(data)
330
+ @key = data[:key].to_sym
331
+ method =
332
+ case @key.to_s
333
+ when /.*_id$/, "id"
334
+ ->(v) { Snowflake.new(v) }
335
+ when "permissions"
336
+ ->(v) { Discorb::Permission.new(v.to_i) }
337
+ when "status"
338
+ ->(v) { Discorb::ScheduledEvent::STATUS[v] }
339
+ when "entity_type"
340
+ ->(v) { Discorb::ScheduledEvent::ENTITY_TYPE[v] }
341
+ when "privacy_level"
342
+ ->(v) do
343
+ Discorb::StageInstance::PRIVACY_LEVEL[v] ||
344
+ Discorb::ScheduledEvent::PRIVACY_LEVEL[v]
345
+ end
346
+ else
347
+ ->(v) { v }
348
+ end
349
+ @old_value = method.call(data[:old_value])
350
+ @new_value = method.call(data[:new_value])
351
+ end
352
+
353
+ #
354
+ # Send a message to the new value.
355
+ #
356
+ def method_missing(method, ...)
357
+ @new_value.__send__(method, ...)
358
+ end
359
+
360
+ #
361
+ # Format the change into a string.
362
+ #
363
+ # @return [String] The string representation of the change.
364
+ #
365
+ def inspect
366
+ "#<#{self.class} #{@key.inspect} #{@old_value.inspect} -> #{@new_value.inspect}>"
367
+ end
368
+
369
+ #
370
+ # Whether the change responds to the given method.
371
+ #
372
+ # @return [Boolean] Whether the change responds to the given method.
373
+ #
374
+ def respond_to_missing?(method, include_private = false)
375
+ @new_value.respond_to?(method, include_private)
376
+ end
377
+ end
378
+ end
379
+
380
+ #
381
+ # Represents an integration in an audit log entry.
382
+ #
383
+ class Integration < DiscordModel
384
+ # @return [Discorb::Snowflake] The ID of the integration.
385
+ attr_reader :id
386
+ # @return [Symbol] The type of the integration.
387
+ attr_reader :type
388
+ # @return [String] The name of the integration.
389
+ attr_reader :name
390
+ # @return [Discorb::Integration::Account] The account of the integration.
391
+ attr_reader :account
392
+
393
+ #
394
+ # Initializes a new integration object.
395
+ # @private
396
+ #
397
+ def initialize(data)
398
+ @id = Snowflake.new(data[:id])
399
+ @type = data[:type].to_sym
400
+ @name = data[:name]
401
+ @data = data
402
+ @account = Discorb::Integration::Account.new(@data[:account]) if @data[
403
+ :account
404
+ ]
405
+ end
406
+
407
+ def inspect
408
+ "#<#{self.class} #{@id}>"
409
+ end
410
+ end
411
+ end
412
+ end