discorb 0.16.0 → 0.17.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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/build_main.yml +2 -2
  4. data/.github/workflows/build_version.yml +1 -1
  5. data/.github/workflows/codeql-analysis.yml +1 -1
  6. data/.github/workflows/lint-push.yml +3 -5
  7. data/.github/workflows/lint.yml +1 -1
  8. data/.github/workflows/spec.yml +30 -0
  9. data/.lefthook/commit-msg/validator.rb +5 -0
  10. data/.rspec +2 -0
  11. data/.rspec_parallel +2 -0
  12. data/.rubocop.yml +43 -6
  13. data/Changelog.md +14 -1
  14. data/Gemfile +14 -8
  15. data/Rakefile +41 -26
  16. data/bin/console +3 -3
  17. data/docs/Examples.md +1 -1
  18. data/docs/application_command.md +138 -46
  19. data/docs/cli/irb.md +2 -2
  20. data/docs/cli/new.md +14 -9
  21. data/docs/cli/run.md +7 -11
  22. data/docs/cli.md +17 -10
  23. data/docs/events.md +209 -211
  24. data/docs/extension.md +1 -2
  25. data/docs/faq.md +0 -1
  26. data/docs/tutorial.md +12 -12
  27. data/docs/voice_events.md +106 -106
  28. data/examples/commands/message.rb +63 -0
  29. data/examples/commands/permission.rb +18 -0
  30. data/examples/commands/slash.rb +44 -0
  31. data/examples/commands/user.rb +51 -0
  32. data/examples/components/authorization_button.rb +2 -2
  33. data/examples/components/select_menu.rb +2 -2
  34. data/examples/extension/main.rb +1 -1
  35. data/examples/extension/message_expander.rb +5 -2
  36. data/examples/simple/eval.rb +2 -2
  37. data/examples/simple/ping_pong.rb +1 -1
  38. data/examples/simple/rolepanel.rb +1 -1
  39. data/examples/simple/shard.rb +1 -1
  40. data/examples/simple/wait_for_message.rb +1 -1
  41. data/exe/discorb +31 -16
  42. data/lefthook.yml +45 -0
  43. data/lib/discorb/allowed_mentions.rb +1 -0
  44. data/lib/discorb/app_command/command.rb +127 -65
  45. data/lib/discorb/app_command/common.rb +25 -0
  46. data/lib/discorb/app_command/handler.rb +115 -33
  47. data/lib/discorb/app_command.rb +2 -1
  48. data/lib/discorb/application.rb +1 -0
  49. data/lib/discorb/asset.rb +1 -2
  50. data/lib/discorb/attachment.rb +1 -1
  51. data/lib/discorb/audit_logs.rb +11 -8
  52. data/lib/discorb/channel/base.rb +108 -0
  53. data/lib/discorb/channel/category.rb +32 -0
  54. data/lib/discorb/channel/container.rb +44 -0
  55. data/lib/discorb/channel/dm.rb +28 -0
  56. data/lib/discorb/channel/guild.rb +245 -0
  57. data/lib/discorb/channel/stage.rb +140 -0
  58. data/lib/discorb/channel/text.rb +345 -0
  59. data/lib/discorb/channel/thread.rb +321 -0
  60. data/lib/discorb/channel/voice.rb +79 -0
  61. data/lib/discorb/channel.rb +2 -1165
  62. data/lib/discorb/client.rb +38 -26
  63. data/lib/discorb/common.rb +2 -1
  64. data/lib/discorb/components/button.rb +2 -1
  65. data/lib/discorb/components/select_menu.rb +4 -2
  66. data/lib/discorb/components/text_input.rb +12 -2
  67. data/lib/discorb/components.rb +1 -1
  68. data/lib/discorb/embed.rb +22 -7
  69. data/lib/discorb/emoji.rb +30 -3
  70. data/lib/discorb/emoji_table.rb +4969 -3
  71. data/lib/discorb/event.rb +29 -4
  72. data/lib/discorb/exe/about.rb +1 -0
  73. data/lib/discorb/exe/irb.rb +2 -4
  74. data/lib/discorb/exe/new.rb +90 -23
  75. data/lib/discorb/exe/run.rb +8 -22
  76. data/lib/discorb/exe/setup.rb +25 -12
  77. data/lib/discorb/exe/show.rb +4 -3
  78. data/lib/discorb/extend.rb +1 -0
  79. data/lib/discorb/extension.rb +6 -3
  80. data/lib/discorb/flag.rb +11 -0
  81. data/lib/discorb/gateway.rb +67 -19
  82. data/lib/discorb/guild.rb +188 -56
  83. data/lib/discorb/guild_template.rb +10 -4
  84. data/lib/discorb/http.rb +16 -9
  85. data/lib/discorb/integration.rb +4 -1
  86. data/lib/discorb/intents.rb +1 -1
  87. data/lib/discorb/interaction/autocomplete.rb +28 -16
  88. data/lib/discorb/interaction/command.rb +36 -12
  89. data/lib/discorb/interaction/components.rb +5 -2
  90. data/lib/discorb/interaction/modal.rb +0 -1
  91. data/lib/discorb/interaction/response.rb +61 -22
  92. data/lib/discorb/interaction/root.rb +13 -13
  93. data/lib/discorb/interaction.rb +1 -0
  94. data/lib/discorb/invite.rb +5 -2
  95. data/lib/discorb/member.rb +25 -5
  96. data/lib/discorb/message.rb +47 -14
  97. data/lib/discorb/message_meta.rb +1 -0
  98. data/lib/discorb/modules.rb +56 -14
  99. data/lib/discorb/presence.rb +2 -2
  100. data/lib/discorb/rate_limit.rb +7 -2
  101. data/lib/discorb/reaction.rb +4 -4
  102. data/lib/discorb/role.rb +19 -4
  103. data/lib/discorb/shard.rb +1 -1
  104. data/lib/discorb/sticker.rb +8 -7
  105. data/lib/discorb/user.rb +2 -1
  106. data/lib/discorb/utils/colored_puts.rb +1 -0
  107. data/lib/discorb/voice_state.rb +10 -6
  108. data/lib/discorb/webhook.rb +36 -24
  109. data/lib/discorb.rb +5 -3
  110. data/po/yard.pot +9 -9
  111. data/sig/discorb.rbs +7232 -7235
  112. metadata +21 -5
  113. data/examples/commands/bookmarker.rb +0 -42
  114. data/examples/commands/hello.rb +0 -10
  115. data/examples/commands/inspect.rb +0 -25
@@ -1,1168 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "async"
4
-
5
- module Discorb
6
- #
7
- # Represents a channel of Discord.
8
- # @abstract
9
- #
10
- class Channel < DiscordModel
11
- # @return [Discorb::Snowflake] The ID of the channel.
12
- attr_reader :id
13
- # @return [String] The name of the channel.
14
- attr_reader :name
15
-
16
- # @!attribute [r] type
17
- # @return [Integer] The type of the channel as integer.
18
-
19
- @channel_type = nil
20
- @subclasses = []
21
-
22
- #
23
- # Initializes a new instance of the Channel class.
24
- # @private
25
- #
26
- def initialize(client, data, no_cache: false)
27
- @client = client
28
- @data = {}
29
- @no_cache = no_cache
30
- _set_data(data)
31
- end
32
-
33
- #
34
- # Checks if the channel is other channel.
35
- #
36
- # @param [Discorb::Channel] other The channel to check.
37
- #
38
- # @return [Boolean] True if the channel is other channel.
39
- #
40
- def ==(other)
41
- return false unless other.respond_to?(:id)
42
-
43
- @id == other.id
44
- end
45
-
46
- def inspect
47
- "#<#{self.class} \"##{@name}\" id=#{@id}>"
48
- end
49
-
50
- #
51
- # Returns the descendants of the Channel class.
52
- # @private
53
- #
54
- def self.descendants
55
- ObjectSpace.each_object(Class).select { |klass| klass < self }
56
- end
57
-
58
- #
59
- # Creates a new instance of the Channel class or instance of its descendants.
60
- # @private
61
- #
62
- # @param [Discorb::Client] client The client that instantiated the object.
63
- # @param [Hash] data The data of the object.
64
- # @param [Boolean] no_cache Whether to disable cache the object.
65
- #
66
- def self.make_channel(client, data, no_cache: false)
67
- descendants.each do |klass|
68
- return klass.new(client, data, no_cache: no_cache) if !klass.channel_type.nil? && klass.channel_type == data[:type]
69
- end
70
- client.logger.warn("Unknown channel type #{data[:type]}, initialized GuildChannel")
71
- GuildChannel.new(client, data)
72
- end
73
-
74
- class << self
75
- #
76
- # @private
77
- # @return [Integer] The type of the channel.
78
- #
79
- attr_reader :channel_type
80
- end
81
-
82
- def type
83
- self.class.channel_type
84
- end
85
-
86
- #
87
- # Returns the channel id to request.
88
- # @private
89
- #
90
- # @return [Async::Task<Discorb::Snowflake>] A task that resolves to the channel id.
91
- #
92
- def channel_id
93
- Async do
94
- @id
95
- end
96
- end
97
-
98
- private
99
-
100
- def _set_data(data)
101
- @id = Snowflake.new(data[:id])
102
- @name = data[:name]
103
- @client.channels[@id] = self if !@no_cache && !(data[:no_cache])
104
- @data.update(data)
105
- end
106
- end
107
-
108
- #
109
- # Represents a channel in guild.
110
- # @abstract
111
- #
112
- class GuildChannel < Channel
113
- # @return [Integer] The position of the channel as integer.
114
- attr_reader :position
115
- # @return [Hash{Discorb::Role, Discorb::Member => PermissionOverwrite}] The permission overwrites of the channel.
116
- attr_reader :permission_overwrites
117
-
118
- # @!attribute [r] mention
119
- # @return [String] The mention of the channel.
120
- #
121
- # @!attribute [r] parent
122
- # @macro client_cache
123
- # @return [Discorb::CategoryChannel] The parent of channel.
124
- # @return [nil] If the channel is not a child of category.
125
- #
126
- # @!attribute [r] guild
127
- # @return [Discorb::Guild] The guild of channel.
128
- # @macro client_cache
129
-
130
- include Comparable
131
- @channel_type = nil
132
-
133
- #
134
- # Compares position of two channels.
135
- #
136
- # @param [Discorb::GuildChannel] other The channel to compare.
137
- #
138
- # @return [-1, 0, 1] -1 if the channel is at lower than the other, 1 if the channel is at highter than the other.
139
- #
140
- def <=>(other)
141
- return 0 unless other.respond_to?(:position)
142
-
143
- @position <=> other.position
144
- end
145
-
146
- #
147
- # Checks if the channel is same as another.
148
- #
149
- # @param [Discorb::GuildChannel] other The channel to check.
150
- #
151
- # @return [Boolean] `true` if the channel is same as another.
152
- #
153
- def ==(other)
154
- return false unless other.respond_to?(:id)
155
-
156
- @id == other.id
157
- end
158
-
159
- #
160
- # Stringifies the channel.
161
- #
162
- # @return [String] The name of the channel with `#`.
163
- #
164
- def to_s
165
- "##{@name}"
166
- end
167
-
168
- def mention
169
- "<##{@id}>"
170
- end
171
-
172
- def parent
173
- return nil unless @parent_id
174
-
175
- @client.channels[@parent_id]
176
- end
177
-
178
- alias category parent
179
-
180
- def guild
181
- @client.guilds[@guild_id]
182
- end
183
-
184
- def inspect
185
- "#<#{self.class} \"##{@name}\" id=#{@id}>"
186
- end
187
-
188
- #
189
- # Deletes the channel.
190
- # @async
191
- #
192
- # @param [String] reason The reason of deleting the channel.
193
- #
194
- # @return [Async::Task<self>] The deleted channel.
195
- #
196
- def delete!(reason: nil)
197
- Async do
198
- @client.http.request(Route.new(base_url.wait.to_s, "//webhooks/:webhook_id/:token", :delete), audit_log_reason: reason).wait
199
- @deleted = true
200
- self
201
- end
202
- end
203
-
204
- alias close! delete!
205
- alias destroy! delete!
206
-
207
- #
208
- # Moves the channel to another position.
209
- # @async
210
- #
211
- # @param [Integer] position The position to move the channel.
212
- # @param [Boolean] lock_permissions Whether to lock the permissions of the channel.
213
- # @param [Discorb::CategoryChannel] parent The parent of channel.
214
- # @param [String] reason The reason of moving the channel.
215
- #
216
- # @return [Async::Task<self>] The moved channel.
217
- #
218
- def move(position, lock_permissions: false, parent: Discorb::Unset, reason: nil)
219
- Async do
220
- payload = {
221
- position: position,
222
- }
223
- payload[:lock_permissions] = lock_permissions
224
- payload[:parent_id] = parent&.id if parent != Discorb::Unset
225
- @client.http.request(Route.new("/guilds/#{@guild_id}/channels", "//guilds/:guild_id/channels", :patch), payload, audit_log_reason: reason).wait
226
- end
227
- end
228
-
229
- private
230
-
231
- def _set_data(data)
232
- @guild_id = data[:guild_id]
233
- @position = data[:position]
234
- @permission_overwrites = if data[:permission_overwrites]
235
- data[:permission_overwrites].to_h do |ow|
236
- [(ow[:type] == 1 ? guild.roles : guild.members)[ow[:id]], PermissionOverwrite.new(ow[:allow], ow[:deny])]
237
- end
238
- else
239
- {}
240
- end
241
- @parent_id = data[:parent_id]
242
-
243
- super
244
- end
245
- end
246
-
247
- #
248
- # Represents a text channel.
249
- #
250
- class TextChannel < GuildChannel
251
- # @return [String] The topic of the channel.
252
- attr_reader :topic
253
- # @return [Boolean] Whether the channel is nsfw.
254
- attr_reader :nsfw
255
- # @return [Discorb::Snowflake] The id of the last message.
256
- attr_reader :last_message_id
257
- # @return [Integer] The rate limit per user (Slowmode) in the channel.
258
- attr_reader :rate_limit_per_user
259
- alias slowmode rate_limit_per_user
260
- # @return [Time] The time when the last pinned message was pinned.
261
- attr_reader :last_pin_timestamp
262
- alias last_pinned_at last_pin_timestamp
263
-
264
- include Messageable
265
-
266
- @channel_type = 0
267
-
268
- # @!attribute [r] threads
269
- # @return [Array<Discorb::ThreadChannel>] The threads in the channel.
270
- def threads
271
- guild.threads.select { |thread| thread.parent == self }
272
- end
273
-
274
- #
275
- # Edits the channel.
276
- # @async
277
- # @macro edit
278
- #
279
- # @param [String] name The name of the channel.
280
- # @param [Integer] position The position of the channel.
281
- # @param [Discorb::CategoryChannel, nil] category The parent of channel. Specify `nil` to remove the parent.
282
- # @param [Discorb::CategoryChannel, nil] parent Alias of `category`.
283
- # @param [String] topic The topic of the channel.
284
- # @param [Boolean] nsfw Whether the channel is nsfw.
285
- # @param [Boolean] announce Whether the channel is announce channel.
286
- # @param [Integer] rate_limit_per_user The rate limit per user (Slowmode) in the channel.
287
- # @param [Integer] slowmode Alias of `rate_limit_per_user`.
288
- # @param [Integer] default_auto_archive_duration The default auto archive duration of the channel.
289
- # @param [Integer] archive_in Alias of `default_auto_archive_duration`.
290
- # @param [String] reason The reason of editing the channel.
291
- #
292
- # @return [Async::Task<self>] The edited channel.
293
- #
294
- def edit(name: Discorb::Unset, position: Discorb::Unset, category: Discorb::Unset, parent: Discorb::Unset,
295
- topic: Discorb::Unset, nsfw: Discorb::Unset, announce: Discorb::Unset,
296
- rate_limit_per_user: Discorb::Unset, slowmode: Discorb::Unset, default_auto_archive_duration: Discorb::Unset,
297
- archive_in: Discorb::Unset, reason: nil)
298
- Async do
299
- payload = {}
300
- payload[:name] = name if name != Discorb::Unset
301
- payload[:announce] = announce ? 5 : 0 if announce != Discorb::Unset
302
- payload[:position] = position if position != Discorb::Unset
303
- payload[:topic] = topic || "" if topic != Discorb::Unset
304
- payload[:nsfw] = nsfw if nsfw != Discorb::Unset
305
-
306
- slowmode = rate_limit_per_user if slowmode == Discorb::Unset
307
- payload[:rate_limit_per_user] = slowmode || 0 if slowmode != Discorb::Unset
308
- parent = category if parent == Discorb::Unset
309
- payload[:parent_id] = parent&.id if parent != Discorb::Unset
310
-
311
- default_auto_archive_duration ||= archive_in
312
- payload[:default_auto_archive_duration] = default_auto_archive_duration if default_auto_archive_duration != Discorb::Unset
313
-
314
- @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
315
- self
316
- end
317
- end
318
-
319
- alias modify edit
320
-
321
- #
322
- # Create webhook in the channel.
323
- # @async
324
- #
325
- # @param [String] name The name of the webhook.
326
- # @param [Discorb::Image] avatar The avatar of the webhook.
327
- #
328
- # @return [Async::Task<Discorb::Webhook::IncomingWebhook>] The created webhook.
329
- #
330
- def create_webhook(name, avatar: nil)
331
- Async do
332
- payload = {}
333
- payload[:name] = name
334
- payload[:avatar] = avatar.to_s if avatar
335
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/webhooks", "//channels/:channel_id/webhooks", :post), payload).wait
336
- Webhook.new([@client, data])
337
- end
338
- end
339
-
340
- #
341
- # Fetch webhooks in the channel.
342
- # @async
343
- #
344
- # @return [Async::Task<Array<Discorb::Webhook>>] The webhooks in the channel.
345
- #
346
- def fetch_webhooks
347
- Async do
348
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/webhooks", "//channels/:channel_id/webhooks", :get)).wait
349
- data.map { |webhook| Webhook.new([@client, webhook]) }
350
- end
351
- end
352
-
353
- #
354
- # Bulk delete messages in the channel.
355
- # @async
356
- #
357
- # @param [Discorb::Message] messages The messages to delete.
358
- # @param [Boolean] force Whether to ignore the validation for message (14 days limit).
359
- #
360
- # @return [Async::Task<void>] The task.
361
- #
362
- def delete_messages!(*messages, force: false)
363
- Async do
364
- messages = messages.first if messages.length == 1 && messages.first.is_a?(Array)
365
- unless force
366
- time = Time.now
367
- messages.delete_if do |message|
368
- next false unless message.is_a?(Message)
369
-
370
- time - message.created_at > 60 * 60 * 24 * 14
371
- end
372
- end
373
-
374
- message_ids = messages.map { |m| Discorb::Utils.try(m, :id).to_s }
375
-
376
- @client.http.request(Route.new("/channels/#{@id}/messages/bulk-delete", "//channels/:channel_id/messages/bulk-delete", :post), { messages: message_ids }).wait
377
- end
378
- end
379
-
380
- alias bulk_delete! delete_messages!
381
- alias destroy_messages! delete_messages!
382
-
383
- #
384
- # Set the channel's permission overwrite.
385
- # @async
386
- #
387
- # @param [Discorb::Role, Discorb::Member] target The target of the overwrite.
388
- # @param [String] reason The reason of setting the overwrite.
389
- # @param [{Symbol => Boolean}] perms The permission overwrites to replace.
390
- #
391
- # @return [Async::Task<void>] The task.
392
- #
393
- def set_permissions(target, reason: nil, **perms)
394
- Async do
395
- allow_value = @permission_overwrites[target]&.allow_value.to_i
396
- deny_value = @permission_overwrites[target]&.deny_value.to_i
397
- perms.each do |perm, value|
398
- allow_value[Discorb::Permission.bits[perm]] = 1 if value == true
399
- deny_value[Discorb::Permission.bits[perm]] = 1 if value == false
400
- end
401
- payload = {
402
- allow: allow_value,
403
- deny: deny_value,
404
- type: target.is_a?(Member) ? 1 : 0,
405
- }
406
- @client.http.request(Route.new("/channels/#{@id}/permissions/#{target.id}", "//channels/:channel_id/permissions/:target_id", :put), payload, audit_log_reason: reason).wait
407
- end
408
- end
409
-
410
- alias modify_permissions set_permissions
411
- alias modify_permisssion set_permissions
412
- alias edit_permissions set_permissions
413
- alias edit_permission set_permissions
414
-
415
- #
416
- # Delete the channel's permission overwrite.
417
- # @async
418
- #
419
- # @param [Discorb::Role, Discorb::Member] target The target of the overwrite.
420
- # @param [String] reason The reason of deleting the overwrite.
421
- #
422
- # @return [Async::Task<void>] The task.
423
- #
424
- def delete_permissions(target, reason: nil)
425
- Async do
426
- @client.http.request(Route.new("/channels/#{@id}/permissions/#{target.id}", "//channels/:channel_id/permissions/:target_id", :delete), audit_log_reason: reason).wait
427
- end
428
- end
429
-
430
- alias delete_permission delete_permissions
431
- alias destroy_permissions delete_permissions
432
- alias destroy_permission delete_permissions
433
-
434
- #
435
- # Fetch the channel's invites.
436
- # @async
437
- #
438
- # @return [Async::Task<Array<Discorb::Invite>>] The invites in the channel.
439
- #
440
- def fetch_invites
441
- Async do
442
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/invites", "//channels/:channel_id/invites", :get)).wait
443
- data.map { |invite| Invite.new(@client, invite, false) }
444
- end
445
- end
446
-
447
- #
448
- # Create an invite in the channel.
449
- # @async
450
- #
451
- # @param [Integer] max_age The max age of the invite.
452
- # @param [Integer] max_uses The max uses of the invite.
453
- # @param [Boolean] temporary Whether the invite is temporary.
454
- # @param [Boolean] unique Whether the invite is unique.
455
- # @note if it's `false` it may return existing invite.
456
- # @param [String] reason The reason of creating the invite.
457
- #
458
- # @return [Async::Task<Invite>] The created invite.
459
- #
460
- def create_invite(max_age: nil, max_uses: nil, temporary: false, unique: false, reason: nil)
461
- Async do
462
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/invites", "//channels/:channel_id/invites", :post), {
463
- max_age: max_age,
464
- max_uses: max_uses,
465
- temporary: temporary,
466
- unique: unique,
467
- }, audit_log_reason: reason).wait
468
- Invite.new(@client, data, false)
469
- end
470
- end
471
-
472
- #
473
- # Follow the existing announcement channel.
474
- # @async
475
- #
476
- # @param [Discorb::NewsChannel] target The channel to follow.
477
- # @param [String] reason The reason of following the channel.
478
- #
479
- # @return [Async::Task<void>] The task.
480
- #
481
- def follow_from(target, reason: nil)
482
- Async do
483
- @client.http.request(Route.new("/channels/#{target.id}/followers", "//channels/:channel_id/followers", :post), { webhook_channel_id: @id }, audit_log_reason: reason).wait
484
- end
485
- end
486
-
487
- #
488
- # Follow the existing announcement channel from self.
489
- # @async
490
- #
491
- # @param [Discorb::TextChannel] target The channel to follow to.
492
- # @param [String] reason The reason of following the channel.
493
- #
494
- # @return [Async::Task<void>] The task.
495
- #
496
- def follow_to(target, reason: nil)
497
- Async do
498
- @client.http.request(Route.new("/channels/#{@id}/followers", "//channels/:channel_id/followers", :post), { webhook_channel_id: target.id }, audit_log_reason: reason).wait
499
- end
500
- end
501
-
502
- #
503
- # Start thread in the channel.
504
- # @async
505
- #
506
- # @param [String] name The name of the thread.
507
- # @param [Discorb::Message] message The message to start the thread.
508
- # @param [Integer] auto_archive_duration The duration of auto-archiving.
509
- # @param [Boolean] public Whether the thread is public.
510
- # @param [Integer] rate_limit_per_user The rate limit per user.
511
- # @param [Integer] slowmode Alias of `rate_limit_per_user`.
512
- # @param [String] reason The reason of starting the thread.
513
- #
514
- # @return [Async::Task<Discorb::ThreadChannel>] The started thread.
515
- #
516
- def start_thread(name, message: nil, auto_archive_duration: 1440, public: true, rate_limit_per_user: nil, slowmode: nil, reason: nil)
517
- Async do
518
- _resp, data = if message.nil?
519
- @client.http.request(Route.new("/channels/#{@id}/threads", "//channels/:channel_id/threads", :post), {
520
- name: name,
521
- auto_archive_duration: auto_archive_duration,
522
- type: public ? 11 : 10,
523
- rate_limit_per_user: rate_limit_per_user || slowmode,
524
- },
525
- audit_log_reason: reason).wait
526
- else
527
- @client.http.request(Route.new("/channels/#{@id}/messages/#{Utils.try(message, :id)}/threads", "//channels/:channel_id/messages/:message_id/threads", :post), {
528
- name: name, auto_archive_duration: auto_archive_duration,
529
- }, audit_log_reason: reason).wait
530
- end
531
- Channel.make_channel(@client, data)
532
- end
533
- end
534
-
535
- alias create_thread start_thread
536
-
537
- #
538
- # Fetch archived threads in the channel.
539
- # @async
540
- #
541
- # @return [Async::Task<Array<Discorb::ThreadChannel>>] The archived threads in the channel.
542
- #
543
- def fetch_archived_public_threads
544
- Async do
545
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/threads/archived/public", "//channels/:channel_id/threads/archived/public", :get)).wait
546
- data.map { |thread| Channel.make_channel(@client, thread) }
547
- end
548
- end
549
-
550
- #
551
- # Fetch archived private threads in the channel.
552
- # @async
553
- #
554
- # @return [Async::Task<Array<Discorb::ThreadChannel>>] The archived private threads in the channel.
555
- #
556
- def fetch_archived_private_threads
557
- Async do
558
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/threads/archived/private", "//channels/:channel_id/threads/archived/private", :get)).wait
559
- data.map { |thread| Channel.make_channel(@client, thread) }
560
- end
561
- end
562
-
563
- #
564
- # Fetch joined archived private threads in the channel.
565
- # @async
566
- #
567
- # @param [Integer] limit The limit of threads to fetch.
568
- # @param [Time] before <description>
569
- #
570
- # @return [Async::Task<Array<Discorb::ThreadChannel>>] The joined archived private threads in the channel.
571
- #
572
- def fetch_joined_archived_private_threads(limit: nil, before: nil)
573
- Async do
574
- if limit.nil?
575
- before = 0
576
- threads = []
577
- loop do
578
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/users/@me/threads/archived/private?before=#{before}", "//channels/:channel_id/users/@me/threads/archived/private", :get)).wait
579
- threads += data[:threads].map { |thread| Channel.make_channel(@client, thread) }
580
- before = data[:threads][-1][:id]
581
-
582
- break unless data[:has_more]
583
- end
584
- threads
585
- else
586
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/users/@me/threads/archived/private?limit=#{limit}&before=#{before}", "//channels/:channel_id/users/@me/threads/archived/private", :get)).wait
587
- data.map { |thread| Channel.make_channel(@client, thread) }
588
- end
589
- end
590
- end
591
-
592
- private
593
-
594
- def _set_data(data)
595
- @topic = data[:topic]
596
- @nsfw = data[:nsfw]
597
- @last_message_id = data[:last_message_id]
598
- @rate_limit_per_user = data[:rate_limit_per_user]
599
- @last_pin_timestamp = data[:last_pin_timestamp] && Time.iso8601(data[:last_pin_timestamp])
600
- super
601
- end
602
- end
603
-
604
- #
605
- # Represents a news channel (announcement channel).
606
- #
607
- class NewsChannel < TextChannel
608
- include Messageable
609
-
610
- @channel_type = 5
611
- end
612
-
613
- #
614
- # Represents a voice channel.
615
- #
616
- class VoiceChannel < GuildChannel
617
- # @return [Integer] The bitrate of the voice channel.
618
- attr_reader :bitrate
619
- # @return [Integer] The user limit of the voice channel.
620
- # @return [nil] If the user limit is not set.
621
- attr_reader :user_limit
622
-
623
- # @!attribute [r] members
624
- # @return [Array<Discorb::Member>] The members in the voice channel.
625
- # @!attribute [r] voice_states
626
- # @return [Array<Discorb::VoiceState>] The voice states associated with the voice channel.
627
-
628
- include Connectable
629
-
630
- @channel_type = 2
631
- #
632
- # Edit the voice channel.
633
- # @async
634
- # @macro edit
635
- #
636
- # @param [String] name The name of the voice channel.
637
- # @param [Integer] position The position of the voice channel.
638
- # @param [Integer] bitrate The bitrate of the voice channel.
639
- # @param [Integer] user_limit The user limit of the voice channel.
640
- # @param [Symbol] rtc_region The region of the voice channel.
641
- # @param [String] reason The reason of editing the voice channel.
642
- #
643
- # @return [Async::Task<self>] The edited voice channel.
644
- #
645
- def edit(name: Discorb::Unset, position: Discorb::Unset, bitrate: Discorb::Unset, user_limit: Discorb::Unset, rtc_region: Discorb::Unset, reason: nil)
646
- Async do
647
- payload = {}
648
- payload[:name] = name if name != Discorb::Unset
649
- payload[:position] = position if position != Discorb::Unset
650
- payload[:bitrate] = bitrate if bitrate != Discorb::Unset
651
- payload[:user_limit] = user_limit if user_limit != Discorb::Unset
652
- payload[:rtc_region] = rtc_region if rtc_region != Discorb::Unset
653
-
654
- @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
655
- self
656
- end
657
- end
658
-
659
- alias modify edit
660
-
661
- def voice_states
662
- guild.voice_states.select { |state| state.channel&.id == @id }
663
- end
664
-
665
- def members
666
- voice_states.map(&:member)
667
- end
668
-
669
- private
670
-
671
- def _set_data(data)
672
- @bitrate = data[:bitrate]
673
- @user_limit = (data[:user_limit]).zero? ? nil : data[:user_limit]
674
- @rtc_region = data[:rtc_region]&.to_sym
675
- @video_quality_mode = data[:video_quality_mode] == 1 ? :auto : :full
676
- super
677
- end
678
- end
679
-
680
- #
681
- # Represents a stage channel.
682
- #
683
- class StageChannel < GuildChannel
684
- # @return [Integer] The bitrate of the voice channel.
685
- attr_reader :bitrate
686
- # @return [Integer] The user limit of the voice channel.
687
- attr_reader :user_limit
688
- #
689
- # @private
690
- # @return [Discorb::Dictionary{Discorb::Snowflake => StageInstance}] The stage instances associated with the stage channel.
691
- #
692
- attr_reader :stage_instances
693
-
694
- include Connectable
695
-
696
- # @!attribute [r] stage_instance
697
- # @return [Discorb::StageInstance] The stage instance of the channel.
698
-
699
- @channel_type = 13
700
- #
701
- # Initialize a new stage channel.
702
- # @private
703
- #
704
- def initialize(...)
705
- @stage_instances = Dictionary.new
706
- super(...)
707
- end
708
-
709
- def stage_instance
710
- @stage_instances[0]
711
- end
712
-
713
- #
714
- # Edit the stage channel.
715
- # @async
716
- # @macro edit
717
- #
718
- # @param [String] name The name of the stage channel.
719
- # @param [Integer] position The position of the stage channel.
720
- # @param [Integer] bitrate The bitrate of the stage channel.
721
- # @param [Symbol] rtc_region The region of the stage channel.
722
- # @param [String] reason The reason of editing the stage channel.
723
- #
724
- # @return [Async::Task<self>] The edited stage channel.
725
- #
726
- def edit(name: Discorb::Unset, position: Discorb::Unset, bitrate: Discorb::Unset, rtc_region: Discorb::Unset, reason: nil)
727
- Async do
728
- payload = {}
729
- payload[:name] = name if name != Discorb::Unset
730
- payload[:position] = position if position != Discorb::Unset
731
- payload[:bitrate] = bitrate if bitrate != Discorb::Unset
732
- payload[:rtc_region] = rtc_region if rtc_region != Discorb::Unset
733
- @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
734
- self
735
- end
736
- end
737
-
738
- alias modify edit
739
-
740
- #
741
- # Start a stage instance.
742
- # @async
743
- #
744
- # @param [String] topic The topic of the stage instance.
745
- # @param [Boolean] public Whether the stage instance is public or not.
746
- # @param [String] reason The reason of starting the stage instance.
747
- #
748
- # @return [Async::Task<Discorb::StageInstance>] The started stage instance.
749
- #
750
- def start(topic, public: false, reason: nil)
751
- Async do
752
- _resp, data = @client.http.request(Route.new("/stage-instances", "//stage-instances", :post), { channel_id: @id, topic: topic, public: public ? 2 : 1 }, audit_log_reason: reason).wait
753
- StageInstance.new(@client, data)
754
- end
755
- end
756
-
757
- #
758
- # Fetch a current stage instance.
759
- # @async
760
- #
761
- # @return [Async::Task<StageInstance>] The current stage instance.
762
- # @return [Async::Task<nil>] If there is no current stage instance.
763
- #
764
- def fetch_stage_instance
765
- Async do
766
- _resp, data = @client.http.request(Route.new("/stage-instances/#{@id}", "//stage-instances/:stage_instance_id", :get)).wait
767
- rescue Discorb::NotFoundError
768
- nil
769
- else
770
- StageInstance.new(@client, data)
771
- end
772
- end
773
-
774
- def voice_states
775
- guild.voice_states.select { |state| state.channel&.id == @id }
776
- end
777
-
778
- def members
779
- voice_states.map(&:member)
780
- end
781
-
782
- def speakers
783
- voice_states.filter { |state| !state.suppress? }.map(&:member)
784
- end
785
-
786
- def audiences
787
- voice_states.filter(&:suppress?).map(&:member)
788
- end
789
-
790
- private
791
-
792
- def _set_data(data)
793
- @bitrate = data[:bitrate]
794
- @user_limit = data[:user_limit]
795
- @topic = data[:topic]
796
- @rtc_region = data[:rtc_region]&.to_sym
797
- super
798
- end
799
- end
800
-
801
- #
802
- # Represents a thread.
803
- # @abstract
804
- #
805
- class ThreadChannel < Channel
806
- # @return [Discorb::Snowflake] The ID of the channel.
807
- # @note This ID is same as the starter message's ID
808
- attr_reader :id
809
- # @return [String] The name of the thread.
810
- attr_reader :name
811
- # @return [Integer] The number of messages in the thread.
812
- # @note This will stop counting at 50.
813
- attr_reader :message_count
814
- # @return [Integer] The number of recipients in the thread.
815
- # @note This will stop counting at 50.
816
- attr_reader :member_count
817
- alias recipient_count member_count
818
- # @return [Integer] The rate limit per user (slowmode) in the thread.
819
- attr_reader :rate_limit_per_user
820
- alias slowmode rate_limit_per_user
821
- # @return [Array<Discorb::ThreadChannel::Member>] The members of the thread.
822
- attr_reader :members
823
- # @return [Time] The time the thread was archived.
824
- # @return [nil] If the thread is not archived.
825
- attr_reader :archived_timestamp
826
- alias archived_at archived_timestamp
827
- # @return [Integer] Auto archive duration in seconds.
828
- attr_reader :auto_archive_duration
829
- alias archive_in auto_archive_duration
830
- # @return [Boolean] Whether the thread is archived or not.
831
- attr_reader :archived
832
- alias archived? archived
833
-
834
- # @!attribute [r] parent
835
- # @macro client_cache
836
- # @return [Discorb::GuildChannel] The parent channel of the thread.
837
- # @!attribute [r] me
838
- # @return [Discorb::ThreadChannel::Member] The bot's member in the thread.
839
- # @return [nil] If the bot is not in the thread.
840
- # @!attribute [r] joined?
841
- # @return [Boolean] Whether the bot is in the thread or not.
842
- # @!attribute [r] guild
843
- # @macro client_cache
844
- # @return [Discorb::Guild] The guild of the thread.
845
- # @!attribute [r] owner
846
- # @macro client_cache
847
- # @macro members_intent
848
- # @return [Discorb::Member] The owner of the thread.
849
-
850
- include Messageable
851
- @channel_type = nil
852
-
853
- #
854
- # Initialize a new thread channel.
855
- # @private
856
- #
857
- # @param [Discorb::Client] client The client.
858
- # @param [Hash] data The data of the thread channel.
859
- # @param [Boolean] no_cache Whether to disable the cache.
860
- #
861
- def initialize(client, data, no_cache: false)
862
- @members = Dictionary.new
863
- super
864
- @client.channels[@id] = self unless no_cache
865
- end
866
-
867
- #
868
- # Edit the thread.
869
- # @async
870
- # @macro edit
871
- #
872
- # @param [String] name The name of the thread.
873
- # @param [Boolean] archived Whether the thread is archived or not.
874
- # @param [Integer] auto_archive_duration The auto archive duration in seconds.
875
- # @param [Integer] archive_in Alias of `auto_archive_duration`.
876
- # @param [Boolean] locked Whether the thread is locked or not.
877
- # @param [String] reason The reason of editing the thread.
878
- #
879
- # @return [Async::Task<self>] The edited thread.
880
- #
881
- # @see #archive
882
- # @see #lock
883
- # @see #unarchive
884
- # @see #unlock
885
- #
886
- def edit(name: Discorb::Unset, archived: Discorb::Unset, auto_archive_duration: Discorb::Unset, archive_in: Discorb::Unset, locked: Discorb::Unset, reason: nil)
887
- Async do
888
- payload = {}
889
- payload[:name] = name if name != Discorb::Unset
890
- payload[:archived] = archived if archived != Discorb::Unset
891
- auto_archive_duration ||= archive_in
892
- payload[:auto_archive_duration] = auto_archive_duration if auto_archive_duration != Discorb::Unset
893
- payload[:locked] = locked if locked != Discorb::Unset
894
- @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
895
- self
896
- end
897
- end
898
-
899
- #
900
- # Helper method to archive the thread.
901
- #
902
- # @param [String] reason The reason of archiving the thread.
903
- #
904
- # @return [self] The archived thread.
905
- #
906
- def archive(reason: nil)
907
- edit(archived: true, reason: reason)
908
- end
909
-
910
- #
911
- # Helper method to lock the thread.
912
- #
913
- # @param [String] reason The reason of locking the thread.
914
- #
915
- # @return [self] The locked thread.
916
- #
917
- def lock(reason: nil)
918
- edit(archived: true, locked: true, reason: reason)
919
- end
920
-
921
- #
922
- # Helper method to unarchive the thread.
923
- #
924
- # @param [String] reason The reason of unarchiving the thread.
925
- #
926
- # @return [self] The unarchived thread.
927
- #
928
- def unarchive(reason: nil)
929
- edit(archived: false, reason: reason)
930
- end
931
-
932
- #
933
- # Helper method to unlock the thread.
934
- #
935
- # @param [String] reason The reason of unlocking the thread.
936
- #
937
- # @return [self] The unlocked thread.
938
- #
939
- # @note This method won't unarchive the thread. Use {#unarchive} instead.
940
- #
941
- def unlock(reason: nil)
942
- edit(archived: !unarchive, locked: false, reason: reason)
943
- end
944
-
945
- def parent
946
- return nil unless @parent_id
947
-
948
- @client.channels[@parent_id]
949
- end
950
-
951
- alias channel parent
952
-
953
- def me
954
- @members[@client.user.id]
955
- end
956
-
957
- def joined?
958
- !!me
959
- end
960
-
961
- def guild
962
- @client.guilds[@guild]
963
- end
964
-
965
- def owner
966
- guild.members[@owner_id]
967
- end
968
-
969
- def inspect
970
- "#<#{self.class} \"##{@name}\" id=#{@id}>"
971
- end
972
-
973
- #
974
- # Add a member to the thread.
975
- #
976
- # @param [Discorb::Member, :me] member The member to add. If `:me` is given, the bot will be added.
977
- #
978
- # @return [Async::Task<void>] The task.
979
- #
980
- def add_member(member = :me)
981
- Async do
982
- if member == :me
983
- @client.http.request(Route.new("/channels/#{@id}/thread-members/@me", "//channels/:channel_id/thread-members/@me", :post)).wait
984
- else
985
- @client.http.request(Route.new("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}", "//channels/:channel_id/thread-members/:user_id", :post)).wait
986
- end
987
- end
988
- end
989
-
990
- alias join add_member
991
-
992
- #
993
- # Remove a member from the thread.
994
- #
995
- # @param [Discorb::Member, :me] member The member to remove. If `:me` is given, the bot will be removed.
996
- #
997
- # @return [Async::Task<void>] The task.
998
- #
999
- def remove_member(member = :me)
1000
- Async do
1001
- if member == :me
1002
- @client.http.request(Route.new("/channels/#{@id}/thread-members/@me", "//channels/:channel_id/thread-members/@me", :delete)).wait
1003
- else
1004
- @client.http.request(Route.new("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}", "//channels/:channel_id/thread-members/:user_id", :delete)).wait
1005
- end
1006
- end
1007
- end
1008
-
1009
- alias leave remove_member
1010
-
1011
- #
1012
- # Fetch members in the thread.
1013
- #
1014
- # @return [Array<Discorb::ThreadChannel::Member>] The members in the thread.
1015
- #
1016
- def fetch_members
1017
- Async do
1018
- _resp, data = @client.http.request(Route.new("/channels/#{@id}/thread-members", "//channels/:channel_id/thread-members", :get)).wait
1019
- data.map { |d| @members[d[:id]] = Member.new(@client, d) }
1020
- end
1021
- end
1022
-
1023
- #
1024
- # Represents a thread in news channel(aka announcement channel).
1025
- #
1026
- class News < ThreadChannel
1027
- @channel_type = 10
1028
- end
1029
-
1030
- #
1031
- # Represents a public thread in text channel.
1032
- #
1033
- class Public < ThreadChannel
1034
- @channel_type = 11
1035
- end
1036
-
1037
- #
1038
- # Represents a private thread in text channel.
1039
- #
1040
- class Private < ThreadChannel
1041
- @channel_type = 12
1042
- end
1043
-
1044
- class << self
1045
- attr_reader :channel_type
1046
- end
1047
-
1048
- #
1049
- # Represents a member in a thread.
1050
- #
1051
- class Member < DiscordModel
1052
- attr_reader :joined_at
1053
-
1054
- def initialize(cilent, data)
1055
- @cilent = cilent
1056
- @thread_id = data[:id]
1057
- @user_id = data[:user_id]
1058
- @joined_at = Time.iso8601(data[:join_timestamp])
1059
- end
1060
-
1061
- def thread
1062
- @client.channels[@thread_id]
1063
- end
1064
-
1065
- def member
1066
- thread && thread.members[@user_id]
1067
- end
1068
-
1069
- def id
1070
- @user_id
1071
- end
1072
-
1073
- def user
1074
- @cilent.users[@user_id]
1075
- end
1076
-
1077
- def inspect
1078
- "#<#{self.class} id=#{@id.inspect}>"
1079
- end
1080
- end
1081
-
1082
- private
1083
-
1084
- def _set_data(data)
1085
- @id = Snowflake.new(data[:id])
1086
- @name = data[:name]
1087
- @guild_id = data[:guild_id]
1088
- @parent_id = data[:parent_id]
1089
- @archived = data[:thread_metadata][:archived]
1090
- @owner_id = data[:owner_id]
1091
- @archived_timestamp = data[:thread_metadata][:archived_timestamp] && Time.iso8601(data[:thread_metadata][:archived_timestamp])
1092
- @auto_archive_duration = data[:thread_metadata][:auto_archive_duration]
1093
- @locked = data[:thread_metadata][:locked]
1094
- @member_count = data[:member_count]
1095
- @message_count = data[:message_count]
1096
- @members[@client.user.id] = ThreadChannel::Member.new(@client, data[:member].merge({ id: data[:id], user_id: @client.user.id })) if data[:member]
1097
- @data.merge!(data)
1098
- end
1099
- end
1100
-
1101
- #
1102
- # Represents a category in a guild.
1103
- #
1104
- class CategoryChannel < GuildChannel
1105
- @channel_type = 4
1106
-
1107
- def channels
1108
- @client.channels.values.filter { |channel| channel.parent == self }
1109
- end
1110
-
1111
- def text_channels
1112
- channels.filter { |c| c.is_a? TextChannel }
1113
- end
1114
-
1115
- def voice_channels
1116
- channels.filter { |c| c.is_a? VoiceChannel }
1117
- end
1118
-
1119
- def news_channel
1120
- channels.filter { |c| c.is_a? NewsChannel }
1121
- end
1122
-
1123
- def stage_channels
1124
- channels.filter { |c| c.is_a? StageChannel }
1125
- end
1126
-
1127
- def create_text_channel(*args, **kwargs)
1128
- guild.create_text_channel(*args, parent: self, **kwargs)
1129
- end
1130
-
1131
- def create_voice_channel(*args, **kwargs)
1132
- guild.create_voice_channel(*args, parent: self, **kwargs)
1133
- end
1134
-
1135
- def create_news_channel(*args, **kwargs)
1136
- guild.create_news_channel(*args, parent: self, **kwargs)
1137
- end
1138
-
1139
- def create_stage_channel(*args, **kwargs)
1140
- guild.create_stage_channel(*args, parent: self, **kwargs)
1141
- end
1142
- end
1143
-
1144
- #
1145
- # Represents a DM channel.
1146
- #
1147
- class DMChannel < Channel
1148
- include Messageable
1149
-
1150
- #
1151
- # Returns the channel id to request.
1152
- # @private
1153
- #
1154
- # @return [Async::Task<Discorb::Snowflake>] A task that resolves to the channel id.
1155
- #
1156
- def channel_id
1157
- Async do
1158
- @id
1159
- end
1160
- end
1161
-
1162
- private
1163
-
1164
- def _set_data(data)
1165
- @id = Snowflake.new(data)
1166
- end
1167
- end
3
+ %w[base guild text voice category stage thread dm].each do |name|
4
+ require_relative "channel/#{name}"
1168
5
  end