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,507 +1,537 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents a webhook.
6
- # @abstract
7
- #
8
- class Webhook
9
- # @return [String] The name of the webhook.
10
- attr_reader :name
11
- # @return [Discorb::Snowflake] The ID of the guild this webhook belongs to.
12
- attr_reader :guild_id
13
- # @return [Discorb::Snowflake] The ID of the channel this webhook belongs to.
14
- attr_reader :channel_id
15
- # @return [Discorb::User] The user that created this webhook.
16
- attr_reader :user
17
- # @return [Discorb::Asset] The avatar of the webhook.
18
- attr_reader :avatar
19
- # @return [Discorb::Snowflake] The application ID of the webhook.
20
- # @return [nil] If the webhook is not an application webhook.
21
- attr_reader :application_id
22
- # @return [String] The URL of the webhook.
23
- attr_reader :token
24
-
25
- #
26
- # Initializes a webhook.
27
- # @private
28
- #
29
- # @param [Discorb::Client] client The client.
30
- # @param [Hash] data The data of the webhook.
31
- #
32
- def initialize(client, data)
33
- @name = data[:name]
34
- @guild_id = data[:guild_id] && Snowflake.new(data[:guild_id])
35
- @channel_id = Snowflake.new(data[:channel_id])
36
- @id = Snowflake.new(data[:id])
37
- @user = data[:user]
38
- @name = data[:name]
39
- @avatar = Asset.new(self, data[:avatar])
40
- @token = ""
41
- @application_id = data[:application_id]
42
- @client = client
43
- @http = Discorb::HTTP.new(client)
44
- end
45
-
46
- def inspect
47
- "#<#{self.class} #{@name.inspect} id=#{@id}>"
48
- end
49
-
50
- #
51
- # Posts a message to the webhook.
52
- # @async
53
- #
54
- # @param [String] content The content of the message.
55
- # @param [Boolean] tts Whether the message should be sent as text-to-speech.
56
- # @param [Discorb::Embed] embed The embed to send.
57
- # @param [Array<Discorb::Embed>] embeds The embeds to send.
58
- # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
59
- # @param [Discorb::Attachment] attachment The attachment to send.
60
- # @param [Array<Discorb::Attachment>] attachment The attachments to send.
61
- # @param [String] username The username of the message.
62
- # @param [String] avatar_url The avatar URL of the message.
63
- # @param [Boolean] wait Whether to wait for the message to be sent.
64
- #
65
- # @return [Discorb::Webhook::Message] The message that was sent.
66
- # @return [Async::Task<nil>] If `wait` is false.
67
- #
68
- def post(
69
- content = nil,
70
- tts: false,
71
- embed: nil,
72
- embeds: nil,
73
- allowed_mentions: nil,
74
- attachment: nil,
75
- attachments: nil,
76
- username: nil,
77
- avatar_url: Discorb::Unset,
78
- wait: true
79
- )
80
- Async do
81
- payload = {}
82
- payload[:content] = content if content
83
- payload[:tts] = tts
84
- tmp_embed = if embed
85
- [embed]
86
- elsif embeds
87
- embeds
88
- end
89
- payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
90
- payload[:allowed_mentions] = allowed_mentions&.to_hash
91
- payload[:username] = username if username
92
- payload[:avatar_url] = avatar_url if avatar_url != Discorb::Unset
93
- attachments = [attachment] if attachment
94
- _resp, data = @http.multipart_request(
95
- Route.new(
96
- "#{url}?wait=#{wait}",
97
- "//webhooks/:webhook_id/:token",
98
- :post
99
- ),
100
- attachments,
101
- payload
102
- ).wait
103
- data && Webhook::Message.new(self, data)
104
- end
105
- end
106
-
107
- alias execute post
108
-
109
- #
110
- # Edits the webhook.
111
- # @async
112
- # @macro edit
113
- #
114
- # @param [String] name The new name of the webhook.
115
- # @param [Discorb::Image] avatar The new avatar of the webhook.
116
- # @param [Discorb::GuildChannel] channel The new channel of the webhook.
117
- #
118
- # @return [Async::Task<void>] The task.
119
- #
120
- def edit(name: Discorb::Unset, avatar: Discorb::Unset, channel: Discorb::Unset)
121
- Async do
122
- payload = {}
123
- payload[:name] = name if name != Discorb::Unset
124
- payload[:avatar] = avatar if avatar != Discorb::Unset
125
- payload[:channel_id] = Utils.try(channel, :id) if channel != Discorb::Unset
126
- @http.request(Route.new(url, "//webhooks/:webhook_id/:token", :patch), payload).wait
127
- end
128
- end
129
-
130
- alias modify edit
131
-
132
- #
133
- # Deletes the webhook.
134
- # @async
135
- #
136
- # @return [Async::Task<void>] The task.
137
- #
138
- def delete
139
- Async do
140
- @http.request(Route.new(url, "//webhooks/:webhook_id/:token", :delete)).wait
141
- self
142
- end
143
- end
144
-
145
- alias destroy delete
146
-
147
- #
148
- # Edits the webhook's message.
149
- # @async
150
- # @macro edit
151
- #
152
- # @param [Discorb::Webhook::Message] message The message to edit.
153
- # @param [String] content The new content of the message.
154
- # @param [Discorb::Embed] embed The new embed of the message.
155
- # @param [Array<Discorb::Embed>] embeds The new embeds of the message.
156
- # @param [Array<Discorb::Attachment>] attachments The attachments to remain.
157
- # @param [Discorb::Attachment] file The file to send.
158
- # @param [Array<Discorb::Attachment>] files The files to send.
159
- # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
160
- #
161
- # @return [Async::Task<void>] The task.
162
- #
163
- def edit_message(
164
- message, content = Discorb::Unset,
165
- embed: Discorb::Unset, embeds: Discorb::Unset,
166
- file: Discorb::Unset, files: Discorb::Unset,
167
- attachments: Discorb::Unset,
168
- allowed_mentions: Discorb::Unset
169
- )
170
- Async do
171
- payload = {}
172
- payload[:content] = content if content != Discorb::Unset
173
- payload[:embeds] = embed ? [embed.to_hash] : [] if embed != Discorb::Unset
174
- payload[:embeds] = embeds.map(&:to_hash) if embeds != Discorb::Unset
175
- payload[:attachments] = attachments.map(&:to_hash) if attachments != Discorb::Unset
176
- payload[:allowed_mentions] = allowed_mentions if allowed_mentions != Discorb::Unset
177
- files = [file] if file != Discorb::Unset
178
- _resp, data = @http.multipart_request(
179
- Route.new("#{url}/messages/#{Utils.try(message, :id)}", "//webhooks/:webhook_id/:token/messages/:message_id",
180
- :patch), payload, files
181
- ).wait
182
- message.send(:_set_data, data)
183
- message
184
- end
185
- end
186
-
187
- #
188
- # Deletes the webhook's message.
189
- #
190
- # @param [Discorb::Webhook::Message] message The message to delete.
191
- #
192
- # @return [Async::Task<void>] The task.
193
- #
194
- def delete_message(message)
195
- Async do
196
- @http.request(
197
- Route.new(
198
- "#{url}/messages/#{Utils.try(message, :id)}",
199
- "//webhooks/:webhook_id/:token/messages/:message_id", :delete
200
- )
201
- ).wait
202
- message
203
- end
204
- end
205
-
206
- #
207
- # Represents a webhook from URL.
208
- #
209
- class URLWebhook < Webhook
210
- # @return [String] The URL of the webhook.
211
- attr_reader :url
212
-
213
- #
214
- # Initializes the webhook from URL.
215
- #
216
- # @param [String] url The URL of the webhook.
217
- # @param [Discorb::Client] client The client to associate with the webhook.
218
- #
219
- def initialize(url, client: nil)
220
- @url = url
221
- @token = ""
222
- @http = Discorb::HTTP.new(client || Discorb::Client.new)
223
- end
224
- end
225
-
226
- #
227
- # Represents a bot created webhook.
228
- #
229
- class IncomingWebhook < Webhook
230
- # @!attribute [r] url
231
- # @return [String] The URL of the webhook.
232
-
233
- #
234
- # Initializes the incoming webhook.
235
- # @private
236
- #
237
- # @param [Discorb::Client] client The client.
238
- # @param [String] url The URL of the webhook.
239
- #
240
- def initialize(client, data)
241
- super
242
- @token = data[:token]
243
- end
244
-
245
- def url
246
- "https://discord.com/api/v9/webhooks/#{@id}/#{@token}"
247
- end
248
- end
249
-
250
- #
251
- # Represents a webhook of channel following.
252
- #
253
- class FollowerWebhook < Webhook
254
- # @!attribute [r] source_guild
255
- # Represents a source guild of follower webhook.
256
- # @return [Discorb::Guild, Discorb::Webhook::FollowerWebhook::Guild] The source guild of follower webhook.
257
- # @!attribute [r] source_channel
258
- # Represents a source channel of follower webhook.
259
- # @return [Discorb::Channel, Discorb::Webhook::FollowerWebhook::Channel] The source channel of follower webhook.
260
-
261
- #
262
- # Initializes the follower webhook.
263
- # @private
264
- #
265
- # @param [Discorb::Client] client The client.
266
- # @param [Hash] data The data of the follower webhook.
267
- #
268
- def initialize(client, data)
269
- super
270
- @source_guild = FollowerWebhook::Guild.new(data[:source_guild])
271
- @source_channel = FollowerWebhook::Channel.new(data[:source_channel])
272
- end
273
-
274
- def source_guild
275
- @client.guilds[@source_guild.id] || @source_guild
276
- end
277
-
278
- def source_channel
279
- @client.channels[@source_channel.id] || @source_channel
280
- end
281
-
282
- #
283
- # Represents a guild of follower webhook.
284
- #
285
- class Guild < DiscordModel
286
- # @return [Discorb::Snowflake] The ID of the guild.
287
- attr_reader :id
288
- # @return [String] The name of the guild.
289
- attr_reader :name
290
- # @return [Discorb::Asset] The icon of the guild.
291
- attr_reader :icon
292
-
293
- #
294
- # Initialize a new guild.
295
- # @private
296
- #
297
- # @param [Hash] data The data of the guild.
298
- #
299
- def initialize(data)
300
- @id = Snowflake.new(data[:id])
301
- @name = data[:name]
302
- @icon = Asset.new(self, data[:icon])
303
- end
304
-
305
- def inspect
306
- "#<#{self.class.name} #{@id}: #{@name}>"
307
- end
308
- end
309
-
310
- #
311
- # Represents a channel of follower webhook.
312
- #
313
- class Channel < DiscordModel
314
- # @return [Discorb::Snowflake] The ID of the channel.
315
- attr_reader :id
316
- # @return [String] The name of the channel.
317
- attr_reader :name
318
-
319
- #
320
- # Initialize a new channel.
321
- # @private
322
- #
323
- # @param [Hash] data The data of the channel.
324
- #
325
- def initialize(data)
326
- @id = Snowflake.new(data[:id])
327
- @name = data[:name]
328
- end
329
-
330
- def inspect
331
- "#<#{self.class.name} #{@id}: #{@name}>"
332
- end
333
- end
334
- end
335
-
336
- #
337
- # Represents a webhook from oauth2.
338
- #
339
- class ApplicationWebhook < Webhook
340
- end
341
-
342
- # private
343
-
344
- #
345
- # Represents a webhook message.
346
- #
347
- class Message < Discorb::Message
348
- # @return [Discorb::Snowflake] The ID of the channel.
349
- attr_reader :channel_id
350
- # @return [Discorb::Snowflake] The ID of the guild.
351
- attr_reader :guild_id
352
-
353
- #
354
- # Initializes the message.
355
- # @private
356
- #
357
- # @param [Discorb::Webhook] webhook The webhook.
358
- # @param [Hash] data The data of the message.
359
- # @param [Discorb::Client] client The client. This will be nil if it's created from {URLWebhook}.
360
- def initialize(webhook, data, client = nil)
361
- @client = client
362
- @webhook = webhook
363
- @data = data
364
- _set_data(data)
365
- end
366
-
367
- #
368
- # Edits the message.
369
- # @async
370
- # @macro edit
371
- #
372
- # @param (see Webhook#edit_message)
373
- #
374
- # @return [Async::Task<void>] The task.
375
- #
376
- def edit(...)
377
- Async do
378
- @webhook.edit_message(self, ...).wait
379
- end
380
- end
381
-
382
- #
383
- # Deletes the message.
384
- # @async
385
- #
386
- # @return [Async::Task<void>] The task.
387
- #
388
- def delete
389
- Async do
390
- @webhook.delete_message(self).wait
391
- end
392
- end
393
-
394
- private
395
-
396
- def _set_data(data)
397
- @id = Snowflake.new(data[:id])
398
- @type = Discorb::Message::MESSAGE_TYPE[data[:type]]
399
- @content = data[:content]
400
- @channel_id = Snowflake.new(data[:channel_id])
401
- @author = Author.new(data[:author])
402
- @attachments = data[:attachments].map { |a| Attachment.new(a) }
403
- @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : []
404
- @mentions = data[:mentions].map { |m| Mention.new(m) }
405
- @mention_roles = data[:mention_roles].map { |m| Snowflake.new(m) }
406
- @mention_everyone = data[:mention_everyone]
407
- @pinned = data[:pinned]
408
- @tts = data[:tts]
409
- @created_at = data[:edited_timestamp] && Time.iso8601(data[:timestamp])
410
- @updated_at = data[:edited_timestamp] && Time.iso8601(data[:edited_timestamp])
411
- @flags = Message::Flag.new(data[:flags])
412
- @webhook_id = Snowflake.new(data[:webhook_id])
413
- end
414
-
415
- #
416
- # Represents an author of webhook message.
417
- #
418
- class Author < DiscordModel
419
- # @return [Boolean] Whether the author is a bot.
420
- # @note This will be always `true`.
421
- attr_reader :bot
422
- alias bot? bot
423
- # @return [Discorb::Snowflake] The ID of the author.
424
- attr_reader :id
425
- # @return [String] The name of the author.
426
- attr_reader :username
427
- alias name username
428
- # @return [Discorb::Asset] The avatar of the author.
429
- attr_reader :avatar
430
- # @return [String] The discriminator of the author.
431
- attr_reader :discriminator
432
-
433
- #
434
- # Initializes the author.
435
- # @private
436
- #
437
- # @param [Hash] data The data of the author.
438
- #
439
- def initialize(data)
440
- @data = data
441
- @bot = data[:bot]
442
- @id = Snowflake.new(data[:id])
443
- @username = data[:username]
444
- @avatar = data[:avatar] ? Asset.new(self, data[:avatar]) : DefaultAvatar.new(data[:discriminator])
445
- @discriminator = data[:discriminator]
446
- end
447
-
448
- #
449
- # Format author with `Name#Discriminator` style.
450
- #
451
- # @return [String] Formatted author.
452
- #
453
- def to_s
454
- "#{@username}##{@discriminator}"
455
- end
456
-
457
- alias to_s_user to_s
458
-
459
- def inspect
460
- "#<#{self.class.name} #{self}>"
461
- end
462
- end
463
- end
464
-
465
- class << self
466
- #
467
- # Creates URLWebhook.
468
- #
469
- # @param [String] url The URL of the webhook.
470
- # @param [Discorb::Client] client The client to associate with the webhook.
471
- #
472
- # @return [Discorb::Webhook::URLWebhook] The URLWebhook.
473
- #
474
- def new(url, client: nil)
475
- if self == Webhook
476
- URLWebhook.new(url, client: client)
477
- else
478
- super
479
- end
480
- end
481
-
482
- #
483
- # Creates Webhook with discord data.
484
- # @private
485
- #
486
- # @param [Discorb::Client] client The client.
487
- # @param [Hash] data The data of the webhook.
488
- #
489
- # @return [Discorb::Webhook] The Webhook.
490
- #
491
- def from_data(client, data)
492
- case data[:type]
493
- when 1
494
- IncomingWebhook
495
- when 2
496
- FollowerWebhook
497
- when 3
498
- ApplicationWebhook
499
- end.new(client, data)
500
- end
501
-
502
- def from_url(url)
503
- URLWebhook.new(url)
504
- end
505
- end
506
- end
507
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a webhook.
6
+ # @abstract
7
+ #
8
+ class Webhook
9
+ # @return [String] The name of the webhook.
10
+ attr_reader :name
11
+ # @return [Discorb::Snowflake] The ID of the guild this webhook belongs to.
12
+ attr_reader :guild_id
13
+ # @return [Discorb::Snowflake] The ID of the channel this webhook belongs to.
14
+ attr_reader :channel_id
15
+ # @return [Discorb::User] The user that created this webhook.
16
+ attr_reader :user
17
+ # @return [Discorb::Asset] The avatar of the webhook.
18
+ attr_reader :avatar
19
+ # @return [Discorb::Snowflake] The application ID of the webhook.
20
+ # @return [nil] If the webhook is not an application webhook.
21
+ attr_reader :application_id
22
+ # @return [String] The URL of the webhook.
23
+ attr_reader :token
24
+
25
+ #
26
+ # Initializes a webhook.
27
+ # @private
28
+ #
29
+ # @param [Discorb::Client] client The client.
30
+ # @param [Hash] data The data of the webhook.
31
+ #
32
+ def initialize(client, data)
33
+ @name = data[:name]
34
+ @guild_id = data[:guild_id] && Snowflake.new(data[:guild_id])
35
+ @channel_id = Snowflake.new(data[:channel_id])
36
+ @id = Snowflake.new(data[:id])
37
+ @user = data[:user]
38
+ @name = data[:name]
39
+ @avatar = Asset.new(self, data[:avatar])
40
+ @token = ""
41
+ @application_id = data[:application_id]
42
+ @client = client
43
+ @http = Discorb::HTTP.new(client)
44
+ end
45
+
46
+ def inspect
47
+ "#<#{self.class} #{@name.inspect} id=#{@id}>"
48
+ end
49
+
50
+ #
51
+ # Posts a message to the webhook.
52
+ # @async
53
+ #
54
+ # @param [String] content The content of the message.
55
+ # @param [Boolean] tts Whether the message should be sent as text-to-speech.
56
+ # @param [Discorb::Embed] embed The embed to send.
57
+ # @param [Array<Discorb::Embed>] embeds The embeds to send.
58
+ # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
59
+ # @param [Discorb::Attachment] attachment The attachment to send.
60
+ # @param [Array<Discorb::Attachment>] attachment The attachments to send.
61
+ # @param [String] username The username of the message.
62
+ # @param [String] avatar_url The avatar URL of the message.
63
+ # @param [Boolean] wait Whether to wait for the message to be sent.
64
+ #
65
+ # @return [Discorb::Webhook::Message] The message that was sent.
66
+ # @return [Async::Task<nil>] If `wait` is false.
67
+ #
68
+ def post(
69
+ content = nil,
70
+ tts: false,
71
+ embed: nil,
72
+ embeds: nil,
73
+ allowed_mentions: nil,
74
+ attachment: nil,
75
+ attachments: nil,
76
+ username: nil,
77
+ avatar_url: Discorb::Unset,
78
+ wait: true
79
+ )
80
+ Async do
81
+ payload = {}
82
+ payload[:content] = content if content
83
+ payload[:tts] = tts
84
+ tmp_embed =
85
+ if embed
86
+ [embed]
87
+ elsif embeds
88
+ embeds
89
+ end
90
+ payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
91
+ payload[:allowed_mentions] = allowed_mentions&.to_hash
92
+ payload[:username] = username if username
93
+ payload[:avatar_url] = avatar_url if avatar_url != Discorb::Unset
94
+ attachments = [attachment] if attachment
95
+ _resp, data =
96
+ @http.multipart_request(
97
+ Route.new(
98
+ "#{url}?wait=#{wait}",
99
+ "//webhooks/:webhook_id/:token",
100
+ :post
101
+ ),
102
+ attachments,
103
+ payload
104
+ ).wait
105
+ data && Webhook::Message.new(self, data)
106
+ end
107
+ end
108
+
109
+ alias execute post
110
+
111
+ #
112
+ # Edits the webhook.
113
+ # @async
114
+ # @macro edit
115
+ #
116
+ # @param [String] name The new name of the webhook.
117
+ # @param [Discorb::Image] avatar The new avatar of the webhook.
118
+ # @param [Discorb::GuildChannel] channel The new channel of the webhook.
119
+ #
120
+ # @return [Async::Task<void>] The task.
121
+ #
122
+ def edit(
123
+ name: Discorb::Unset,
124
+ avatar: Discorb::Unset,
125
+ channel: Discorb::Unset
126
+ )
127
+ Async do
128
+ payload = {}
129
+ payload[:name] = name if name != Discorb::Unset
130
+ payload[:avatar] = avatar if avatar != Discorb::Unset
131
+ payload[:channel_id] = Utils.try(channel, :id) if channel !=
132
+ Discorb::Unset
133
+ @http.request(
134
+ Route.new(url, "//webhooks/:webhook_id/:token", :patch),
135
+ payload
136
+ ).wait
137
+ end
138
+ end
139
+
140
+ alias modify edit
141
+
142
+ #
143
+ # Deletes the webhook.
144
+ # @async
145
+ #
146
+ # @return [Async::Task<void>] The task.
147
+ #
148
+ def delete
149
+ Async do
150
+ @http.request(
151
+ Route.new(url, "//webhooks/:webhook_id/:token", :delete)
152
+ ).wait
153
+ self
154
+ end
155
+ end
156
+
157
+ alias destroy delete
158
+
159
+ #
160
+ # Edits the webhook's message.
161
+ # @async
162
+ # @macro edit
163
+ #
164
+ # @param [Discorb::Webhook::Message] message The message to edit.
165
+ # @param [String] content The new content of the message.
166
+ # @param [Discorb::Embed] embed The new embed of the message.
167
+ # @param [Array<Discorb::Embed>] embeds The new embeds of the message.
168
+ # @param [Array<Discorb::Attachment>] attachments The attachments to remain.
169
+ # @param [Discorb::Attachment] file The file to send.
170
+ # @param [Array<Discorb::Attachment>] files The files to send.
171
+ # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
172
+ #
173
+ # @return [Async::Task<void>] The task.
174
+ #
175
+ def edit_message(
176
+ message,
177
+ content = Discorb::Unset,
178
+ embed: Discorb::Unset,
179
+ embeds: Discorb::Unset,
180
+ file: Discorb::Unset,
181
+ files: Discorb::Unset,
182
+ attachments: Discorb::Unset,
183
+ allowed_mentions: Discorb::Unset
184
+ )
185
+ Async do
186
+ payload = {}
187
+ payload[:content] = content if content != Discorb::Unset
188
+ payload[:embeds] = embed ? [embed.to_hash] : [] if embed !=
189
+ Discorb::Unset
190
+ payload[:embeds] = embeds.map(&:to_hash) if embeds != Discorb::Unset
191
+ payload[:attachments] = attachments.map(&:to_hash) if attachments !=
192
+ Discorb::Unset
193
+ payload[:allowed_mentions] = allowed_mentions if allowed_mentions !=
194
+ Discorb::Unset
195
+ files = [file] if file != Discorb::Unset
196
+ _resp, data =
197
+ @http.multipart_request(
198
+ Route.new(
199
+ "#{url}/messages/#{Utils.try(message, :id)}",
200
+ "//webhooks/:webhook_id/:token/messages/:message_id",
201
+ :patch
202
+ ),
203
+ payload,
204
+ files
205
+ ).wait
206
+ message.send(:_set_data, data)
207
+ message
208
+ end
209
+ end
210
+
211
+ #
212
+ # Deletes the webhook's message.
213
+ #
214
+ # @param [Discorb::Webhook::Message] message The message to delete.
215
+ #
216
+ # @return [Async::Task<void>] The task.
217
+ #
218
+ def delete_message(message)
219
+ Async do
220
+ @http.request(
221
+ Route.new(
222
+ "#{url}/messages/#{Utils.try(message, :id)}",
223
+ "//webhooks/:webhook_id/:token/messages/:message_id",
224
+ :delete
225
+ )
226
+ ).wait
227
+ message
228
+ end
229
+ end
230
+
231
+ #
232
+ # Represents a webhook from URL.
233
+ #
234
+ class URLWebhook < Webhook
235
+ # @return [String] The URL of the webhook.
236
+ attr_reader :url
237
+
238
+ #
239
+ # Initializes the webhook from URL.
240
+ #
241
+ # @param [String] url The URL of the webhook.
242
+ # @param [Discorb::Client] client The client to associate with the webhook.
243
+ #
244
+ def initialize(url, client: nil)
245
+ @url = url
246
+ @token = ""
247
+ @http = Discorb::HTTP.new(client || Discorb::Client.new)
248
+ end
249
+ end
250
+
251
+ #
252
+ # Represents a bot created webhook.
253
+ #
254
+ class IncomingWebhook < Webhook
255
+ # @!attribute [r] url
256
+ # @return [String] The URL of the webhook.
257
+
258
+ #
259
+ # Initializes the incoming webhook.
260
+ # @private
261
+ #
262
+ # @param [Discorb::Client] client The client.
263
+ # @param [String] url The URL of the webhook.
264
+ #
265
+ def initialize(client, data)
266
+ super
267
+ @token = data[:token]
268
+ end
269
+
270
+ def url
271
+ "https://discord.com/api/v9/webhooks/#{@id}/#{@token}"
272
+ end
273
+ end
274
+
275
+ #
276
+ # Represents a webhook of channel following.
277
+ #
278
+ class FollowerWebhook < Webhook
279
+ # @!attribute [r] source_guild
280
+ # Represents a source guild of follower webhook.
281
+ # @return [Discorb::Guild, Discorb::Webhook::FollowerWebhook::Guild] The source guild of follower webhook.
282
+ # @!attribute [r] source_channel
283
+ # Represents a source channel of follower webhook.
284
+ # @return [Discorb::Channel, Discorb::Webhook::FollowerWebhook::Channel] The source channel of follower webhook.
285
+
286
+ #
287
+ # Initializes the follower webhook.
288
+ # @private
289
+ #
290
+ # @param [Discorb::Client] client The client.
291
+ # @param [Hash] data The data of the follower webhook.
292
+ #
293
+ def initialize(client, data)
294
+ super
295
+ @source_guild = FollowerWebhook::Guild.new(data[:source_guild])
296
+ @source_channel = FollowerWebhook::Channel.new(data[:source_channel])
297
+ end
298
+
299
+ def source_guild
300
+ @client.guilds[@source_guild.id] || @source_guild
301
+ end
302
+
303
+ def source_channel
304
+ @client.channels[@source_channel.id] || @source_channel
305
+ end
306
+
307
+ #
308
+ # Represents a guild of follower webhook.
309
+ #
310
+ class Guild < DiscordModel
311
+ # @return [Discorb::Snowflake] The ID of the guild.
312
+ attr_reader :id
313
+ # @return [String] The name of the guild.
314
+ attr_reader :name
315
+ # @return [Discorb::Asset] The icon of the guild.
316
+ attr_reader :icon
317
+
318
+ #
319
+ # Initialize a new guild.
320
+ # @private
321
+ #
322
+ # @param [Hash] data The data of the guild.
323
+ #
324
+ def initialize(data)
325
+ @id = Snowflake.new(data[:id])
326
+ @name = data[:name]
327
+ @icon = Asset.new(self, data[:icon])
328
+ end
329
+
330
+ def inspect
331
+ "#<#{self.class.name} #{@id}: #{@name}>"
332
+ end
333
+ end
334
+
335
+ #
336
+ # Represents a channel of follower webhook.
337
+ #
338
+ class Channel < DiscordModel
339
+ # @return [Discorb::Snowflake] The ID of the channel.
340
+ attr_reader :id
341
+ # @return [String] The name of the channel.
342
+ attr_reader :name
343
+
344
+ #
345
+ # Initialize a new channel.
346
+ # @private
347
+ #
348
+ # @param [Hash] data The data of the channel.
349
+ #
350
+ def initialize(data)
351
+ @id = Snowflake.new(data[:id])
352
+ @name = data[:name]
353
+ end
354
+
355
+ def inspect
356
+ "#<#{self.class.name} #{@id}: #{@name}>"
357
+ end
358
+ end
359
+ end
360
+
361
+ #
362
+ # Represents a webhook from oauth2.
363
+ #
364
+ class ApplicationWebhook < Webhook
365
+ end
366
+
367
+ # private
368
+
369
+ #
370
+ # Represents a webhook message.
371
+ #
372
+ class Message < Discorb::Message
373
+ # @return [Discorb::Snowflake] The ID of the channel.
374
+ attr_reader :channel_id
375
+ # @return [Discorb::Snowflake] The ID of the guild.
376
+ attr_reader :guild_id
377
+
378
+ #
379
+ # Initializes the message.
380
+ # @private
381
+ #
382
+ # @param [Discorb::Webhook] webhook The webhook.
383
+ # @param [Hash] data The data of the message.
384
+ # @param [Discorb::Client] client The client. This will be nil if it's created from {URLWebhook}.
385
+ def initialize(webhook, data, client = nil)
386
+ @client = client
387
+ @webhook = webhook
388
+ @data = data
389
+ _set_data(data)
390
+ end
391
+
392
+ #
393
+ # Edits the message.
394
+ # @async
395
+ # @macro edit
396
+ #
397
+ # @param (see Webhook#edit_message)
398
+ #
399
+ # @return [Async::Task<void>] The task.
400
+ #
401
+ def edit(...)
402
+ Async { @webhook.edit_message(self, ...).wait }
403
+ end
404
+
405
+ #
406
+ # Deletes the message.
407
+ # @async
408
+ #
409
+ # @return [Async::Task<void>] The task.
410
+ #
411
+ def delete
412
+ Async { @webhook.delete_message(self).wait }
413
+ end
414
+
415
+ private
416
+
417
+ def _set_data(data)
418
+ @id = Snowflake.new(data[:id])
419
+ @type = Discorb::Message::MESSAGE_TYPE[data[:type]]
420
+ @content = data[:content]
421
+ @channel_id = Snowflake.new(data[:channel_id])
422
+ @author = Author.new(data[:author])
423
+ @attachments = data[:attachments].map { |a| Attachment.new(a) }
424
+ @embeds =
425
+ data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : []
426
+ @mentions = data[:mentions].map { |m| Mention.new(m) }
427
+ @mention_roles = data[:mention_roles].map { |m| Snowflake.new(m) }
428
+ @mention_everyone = data[:mention_everyone]
429
+ @pinned = data[:pinned]
430
+ @tts = data[:tts]
431
+ @created_at = data[:edited_timestamp] && Time.iso8601(data[:timestamp])
432
+ @updated_at =
433
+ data[:edited_timestamp] && Time.iso8601(data[:edited_timestamp])
434
+ @flags = Message::Flag.new(data[:flags])
435
+ @webhook_id = Snowflake.new(data[:webhook_id])
436
+ end
437
+
438
+ #
439
+ # Represents an author of webhook message.
440
+ #
441
+ class Author < DiscordModel
442
+ # @return [Boolean] Whether the author is a bot.
443
+ # @note This will be always `true`.
444
+ attr_reader :bot
445
+ alias bot? bot
446
+ # @return [Discorb::Snowflake] The ID of the author.
447
+ attr_reader :id
448
+ # @return [String] The name of the author.
449
+ attr_reader :username
450
+ alias name username
451
+ # @return [Discorb::Asset] The avatar of the author.
452
+ attr_reader :avatar
453
+ # @return [String] The discriminator of the author.
454
+ attr_reader :discriminator
455
+
456
+ #
457
+ # Initializes the author.
458
+ # @private
459
+ #
460
+ # @param [Hash] data The data of the author.
461
+ #
462
+ def initialize(data)
463
+ @data = data
464
+ @bot = data[:bot]
465
+ @id = Snowflake.new(data[:id])
466
+ @username = data[:username]
467
+ @avatar =
468
+ (
469
+ if data[:avatar]
470
+ Asset.new(self, data[:avatar])
471
+ else
472
+ DefaultAvatar.new(data[:discriminator])
473
+ end
474
+ )
475
+ @discriminator = data[:discriminator]
476
+ end
477
+
478
+ #
479
+ # Format author with `Name#Discriminator` style.
480
+ #
481
+ # @return [String] Formatted author.
482
+ #
483
+ def to_s
484
+ "#{@username}##{@discriminator}"
485
+ end
486
+
487
+ alias to_s_user to_s
488
+
489
+ def inspect
490
+ "#<#{self.class.name} #{self}>"
491
+ end
492
+ end
493
+ end
494
+
495
+ class << self
496
+ #
497
+ # Creates URLWebhook.
498
+ #
499
+ # @param [String] url The URL of the webhook.
500
+ # @param [Discorb::Client] client The client to associate with the webhook.
501
+ #
502
+ # @return [Discorb::Webhook::URLWebhook] The URLWebhook.
503
+ #
504
+ def new(url, client: nil)
505
+ if self == Webhook
506
+ URLWebhook.new(url, client: client)
507
+ else
508
+ super
509
+ end
510
+ end
511
+
512
+ #
513
+ # Creates Webhook with discord data.
514
+ # @private
515
+ #
516
+ # @param [Discorb::Client] client The client.
517
+ # @param [Hash] data The data of the webhook.
518
+ #
519
+ # @return [Discorb::Webhook] The Webhook.
520
+ #
521
+ def from_data(client, data)
522
+ case data[:type]
523
+ when 1
524
+ IncomingWebhook
525
+ when 2
526
+ FollowerWebhook
527
+ when 3
528
+ ApplicationWebhook
529
+ end.new(client, data)
530
+ end
531
+
532
+ def from_url(url)
533
+ URLWebhook.new(url)
534
+ end
535
+ end
536
+ end
537
+ end