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,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