discorb 0.19.0 → 0.20.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.
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