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
data/lib/discorb/guild.rb CHANGED
@@ -21,7 +21,8 @@ module Discorb
21
21
  attr_reader :afk_timeout
22
22
  # @return [Discorb::Dictionary{Discorb::Snowflake => Discorb::Role}] A dictionary of roles in the guild.
23
23
  attr_reader :roles
24
- # @return [Discorb::Dictionary{Discorb::Snowflake => Discorb::CustomEmoji}] A dictionary of custom emojis in the guild.
24
+ # @return [Discorb::Dictionary{Discorb::Snowflake => Discorb::CustomEmoji}]
25
+ # A dictionary of custom emojis in the guild.
25
26
  attr_reader :emojis
26
27
  # @return [Array<Symbol>] features that are enabled in the guild.
27
28
  # @see https://discord.com/developers/docs/resources/guild#guild-object-guild-features Official Discord API docs
@@ -76,7 +77,8 @@ module Discorb
76
77
  attr_reader :welcome_screen
77
78
  # @return [:default, :explicit, :safe, :age_restricted] The nsfw level of the guild.
78
79
  attr_reader :nsfw_level
79
- # @return [Discorb::Dictionary{Discorb::Snowflake => Discorb::StageInstance}] A dictionary of stage instances in the guild.
80
+ # @return [Discorb::Dictionary{Discorb::Snowflake => Discorb::StageInstance}]
81
+ # A dictionary of stage instances in the guild.
80
82
  attr_reader :stage_instances
81
83
  # @return [:none, :low, :medium, :high, :very_high] The verification level of the guild.
82
84
  attr_reader :verification_level
@@ -100,6 +102,8 @@ module Discorb
100
102
  attr_reader :scheduled_events
101
103
  alias events scheduled_events
102
104
 
105
+ include Discorb::ChannelContainer
106
+
103
107
  # @!attribute [r] afk_channel
104
108
  # @return [Discorb::VoiceChannel] The AFK channel for this guild.
105
109
  # @macro client_cache
@@ -193,7 +197,13 @@ module Discorb
193
197
  #
194
198
  def fetch_scheduled_events(with_user_count: true)
195
199
  Async do
196
- _resp, events = @client.http.request(Route.new("/guilds/#{@id}/scheduled-events?with_user_count=#{with_user_count}", "//guilds/:guild_id/scheduled-events", :get)).wait
200
+ _resp, events = @client.http.request(
201
+ Route.new(
202
+ "/guilds/#{@id}/scheduled-events?with_user_count=#{with_user_count}",
203
+ "//guilds/:guild_id/scheduled-events",
204
+ :get
205
+ )
206
+ ).wait
197
207
  @scheduled_events = events.map { |e| ScheduledEvent.new(@client, e) }
198
208
  end
199
209
  end
@@ -209,7 +219,13 @@ module Discorb
209
219
  #
210
220
  def fetch_scheduled_event(id)
211
221
  Async do
212
- _resp, event = @client.http.request(Route.new("/guilds/#{@id}/scheduled-events/#{id}", "//guilds/:guild_id/scheduled-events/:scheduled_event_id", :get)).wait
222
+ _resp, event = @client.http.request(
223
+ Route.new(
224
+ "/guilds/#{@id}/scheduled-events/#{id}",
225
+ "//guilds/:guild_id/scheduled-events/:scheduled_event_id",
226
+ :get
227
+ )
228
+ ).wait
213
229
  rescue Discorb::NotFoundError
214
230
  return nil
215
231
  else
@@ -246,6 +262,7 @@ module Discorb
246
262
  payload = case type
247
263
  when :stage_instance
248
264
  raise ArgumentError, "channel must be provided for stage_instance events" unless channel
265
+
249
266
  {
250
267
  name: name,
251
268
  description: description,
@@ -257,6 +274,7 @@ module Discorb
257
274
  }
258
275
  when :voice
259
276
  raise ArgumentError, "channel must be provided for voice events" unless channel
277
+
260
278
  {
261
279
  name: name,
262
280
  description: description,
@@ -269,6 +287,7 @@ module Discorb
269
287
  when :external
270
288
  raise ArgumentError, "location must be provided for external events" unless location
271
289
  raise ArgumentError, "end_time must be provided for external events" unless end_time
290
+
272
291
  {
273
292
  name: name,
274
293
  description: description,
@@ -283,7 +302,9 @@ module Discorb
283
302
  else
284
303
  raise ArgumentError, "Invalid scheduled event type: #{type}"
285
304
  end
286
- _resp, event = @client.http.request(Route.new("/guilds/#{@id}/scheduled-events", "//guilds/:guild_id/scheduled-events", :post), payload).wait
305
+ _resp, event = @client.http.request(
306
+ Route.new("/guilds/#{@id}/scheduled-events", "//guilds/:guild_id/scheduled-events", :post), payload
307
+ ).wait
287
308
  Discorb::ScheduledEvent.new(@client, event)
288
309
  end
289
310
  end
@@ -293,7 +314,8 @@ module Discorb
293
314
  # @async
294
315
  # @note This querys the API every time. We recommend using {#emojis} instead.
295
316
  #
296
- # @return [Async::Task<Discorb::Dictionary{Discorb::Snowflake => Discorb::CustomEmoji}>] A dictionary of emoji in the guild.
317
+ # @return [Async::Task<Discorb::Dictionary{Discorb::Snowflake => Discorb::CustomEmoji}>]
318
+ # A dictionary of emoji in the guild.
297
319
  #
298
320
  def fetch_emoji_list
299
321
  Async do
@@ -321,7 +343,8 @@ module Discorb
321
343
  # @return [Async::Task<Discorb::CustomEmoji>] The emoji with the given id.
322
344
  #
323
345
  def fetch_emoji(id)
324
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/emojis/#{id}", "//guilds/:guild_id/emojis/:emoji_id", :get)).wait
346
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/emojis/#{id}",
347
+ "//guilds/:guild_id/emojis/:emoji_id", :get)).wait
325
348
  @emojis[e[:id]] = CustomEmoji.new(@client, self, data)
326
349
  end
327
350
 
@@ -338,10 +361,10 @@ module Discorb
338
361
  def create_emoji(name, image, roles: [])
339
362
  _resp, data = @client.http.request(Route.new("/guilds/#{@id}/emojis", "//guilds/:guild_id/emojis", :post),
340
363
  {
341
- name: name,
342
- image: image.to_s,
343
- roles: roles.map { |r| Discorb::Utils.try(r, :id) },
344
- }).wait
364
+ name: name,
365
+ image: image.to_s,
366
+ roles: roles.map { |r| Discorb::Utils.try(r, :id) },
367
+ }).wait
345
368
  @emojis[data[:id]] = CustomEmoji.new(@client, self, data)
346
369
  end
347
370
 
@@ -353,7 +376,8 @@ module Discorb
353
376
  #
354
377
  def fetch_webhooks
355
378
  Async do
356
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/webhooks", "//guilds/:guild_id/webhooks", :get)).wait
379
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/webhooks", "//guilds/:guild_id/webhooks",
380
+ :get)).wait
357
381
  data.map { |webhook| Webhook.new([@client, webhook]) }
358
382
  end
359
383
  end
@@ -366,7 +390,8 @@ module Discorb
366
390
  #
367
391
  def fetch_audit_log
368
392
  Async do
369
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/audit-logs", "//guilds/:guild_id/audit-logs", :get)).wait
393
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/audit-logs", "//guilds/:guild_id/audit-logs",
394
+ :get)).wait
370
395
  AuditLog.new(@client, data, self)
371
396
  end
372
397
  end
@@ -379,7 +404,8 @@ module Discorb
379
404
  #
380
405
  def fetch_channels
381
406
  Async do
382
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :get)).wait
407
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels",
408
+ :get)).wait
383
409
  data.map { |c| Channel.make_channel(@client, c) }
384
410
  end
385
411
  end
@@ -394,14 +420,23 @@ module Discorb
394
420
  # @param [Integer] slowmode Alias for `rate_limit_per_user`.
395
421
  # @param [Integer] position The position of the channel.
396
422
  # @param [Boolean] nsfw Whether the channel is nsfw.
397
- # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites A list of permission overwrites.
423
+ # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites
424
+ # A list of permission overwrites.
398
425
  # @param [Discorb::CategoryChannel] parent The parent of the channel.
399
426
  # @param [String] reason The reason for creating the channel.
400
427
  #
401
428
  # @return [Async::Task<Discorb::TextChannel>] The created text channel.
402
429
  #
403
430
  def create_text_channel(
404
- name, topic: nil, rate_limit_per_user: nil, slowmode: nil, position: nil, nsfw: nil, permission_overwrites: nil, parent: nil, reason: nil
431
+ name,
432
+ topic: nil,
433
+ rate_limit_per_user: nil,
434
+ slowmode: nil,
435
+ position: nil,
436
+ nsfw: nil,
437
+ permission_overwrites: nil,
438
+ parent: nil,
439
+ reason: nil
405
440
  )
406
441
  Async do
407
442
  payload = { type: TextChannel.channel_type }
@@ -422,7 +457,8 @@ module Discorb
422
457
  end
423
458
  end
424
459
  payload[:parent_id] = parent.id if parent
425
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post), payload, audit_log_reason: reason).wait
460
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post),
461
+ payload, audit_log_reason: reason).wait
426
462
  payload[:parent_id] = parent&.id
427
463
  Channel.make_channel(@client, data)
428
464
  end
@@ -436,7 +472,8 @@ module Discorb
436
472
  # @param [Integer] bitrate The bitrate of the channel.
437
473
  # @param [Integer] user_limit The user limit of the channel.
438
474
  # @param [Integer] position The position of the channel.
439
- # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites A list of permission overwrites.
475
+ # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites
476
+ # A list of permission overwrites.
440
477
  # @param [Discorb::CategoryChannel] parent The parent of the channel.
441
478
  # @param [String] reason The reason for creating the channel.
442
479
  #
@@ -462,7 +499,8 @@ module Discorb
462
499
  end
463
500
  end
464
501
  payload[:parent_id] = parent.id if parent
465
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post), payload, audit_log_reason: reason).wait
502
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post),
503
+ payload, audit_log_reason: reason).wait
466
504
  payload[:parent_id] = parent&.id
467
505
  Channel.make_channel(@client, data)
468
506
  end
@@ -473,7 +511,8 @@ module Discorb
473
511
  #
474
512
  # @param [String] name The name of the channel.
475
513
  # @param [Integer] position The position of the channel.
476
- # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites A list of permission overwrites.
514
+ # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites
515
+ # A list of permission overwrites.
477
516
  # @param [Discorb::CategoryChannel] parent The parent of the channel.
478
517
  # @param [String] reason The reason for creating the channel.
479
518
  #
@@ -495,7 +534,8 @@ module Discorb
495
534
  end
496
535
  end
497
536
  payload[:parent_id] = parent&.id
498
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post), payload, audit_log_reason: reason).wait
537
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post),
538
+ payload, audit_log_reason: reason).wait
499
539
  Channel.make_channel(@client, data)
500
540
  end
501
541
  end
@@ -509,7 +549,8 @@ module Discorb
509
549
  # @param [String] name The name of the channel.
510
550
  # @param [Integer] bitrate The bitrate of the channel.
511
551
  # @param [Integer] position The position of the channel.
512
- # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites A list of permission overwrites.
552
+ # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites
553
+ # A list of permission overwrites.
513
554
  # @param [Discorb::CategoryChannel] parent The parent of the channel.
514
555
  # @param [String] reason The reason for creating the channel.
515
556
  #
@@ -532,7 +573,8 @@ module Discorb
532
573
  end
533
574
  end
534
575
  payload[:parent_id] = parent&.id
535
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post), payload, audit_log_reason: reason).wait
576
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post),
577
+ payload, audit_log_reason: reason).wait
536
578
  Channel.make_channel(@client, data)
537
579
  end
538
580
  end
@@ -547,14 +589,23 @@ module Discorb
547
589
  # @param [Integer] slowmode Alias for `rate_limit_per_user`.
548
590
  # @param [Integer] position The position of the channel.
549
591
  # @param [Boolean] nsfw Whether the channel is nsfw.
550
- # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites A list of permission overwrites.
592
+ # @param [Hash{Discorb::Role, Discorb::Member => Discorb::PermissionOverwrite}] permission_overwrites
593
+ # A list of permission overwrites.
551
594
  # @param [Discorb::CategoryChannel] parent The parent of the channel.
552
595
  # @param [String] reason The reason for creating the channel.
553
596
  #
554
597
  # @return [Async::Task<Discorb::NewsChannel>] The created news channel.
555
598
  #
556
599
  def create_news_channel(
557
- name, topic: nil, rate_limit_per_user: nil, slowmode: nil, position: nil, nsfw: nil, permission_overwrites: nil, parent: nil, reason: nil
600
+ name,
601
+ topic: nil,
602
+ rate_limit_per_user: nil,
603
+ slowmode: nil,
604
+ position: nil,
605
+ nsfw: nil,
606
+ permission_overwrites: nil,
607
+ parent: nil,
608
+ reason: nil
558
609
  )
559
610
  Async do
560
611
  payload = { type: NewsChannel.channel_type }
@@ -575,7 +626,8 @@ module Discorb
575
626
  end
576
627
  payload[:nsfw] = nsfw unless nsfw.nil?
577
628
  payload[:parent_id] = parent&.id
578
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post), payload, audit_log_reason: reason).wait
629
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/channels", "//guilds/:guild_id/channels", :post),
630
+ payload, audit_log_reason: reason).wait
579
631
  Channel.make_channel(@client, data)
580
632
  end
581
633
  end
@@ -588,7 +640,8 @@ module Discorb
588
640
  #
589
641
  def fetch_active_threads
590
642
  Async do
591
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/threads/active", "//guilds/:guild_id/threads/active", :get)).wait
643
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/threads/active",
644
+ "//guilds/:guild_id/threads/active", :get)).wait
592
645
  data[:threads].map { |t| Channel.make_thread(@client, t) }
593
646
  end
594
647
  end
@@ -604,7 +657,8 @@ module Discorb
604
657
  #
605
658
  def fetch_member(id)
606
659
  Async do
607
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/members/#{id}", "//guilds/:guild_id/members/:user_id", :get)).wait
660
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/members/#{id}",
661
+ "//guilds/:guild_id/members/:user_id", :get)).wait
608
662
  rescue Discorb::NotFoundError
609
663
  nil
610
664
  else
@@ -624,14 +678,24 @@ module Discorb
624
678
  def fetch_members(limit: 0, after: nil)
625
679
  Async do
626
680
  unless limit.zero?
627
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/members?#{URI.encode_www_form({ after: after, limit: limit })}", "//guilds/:guild_id/members", :get)).wait
681
+ _resp, data = @client.http.request(
682
+ Route.new(
683
+ "/guilds/#{@id}/members?#{URI.encode_www_form(
684
+ {
685
+ after: after,
686
+ limit: limit,
687
+ }
688
+ )}", "//guilds/:guild_id/members", :get
689
+ )
690
+ ).wait
628
691
  next data[:members].map { |m| Member.new(@client, @id, m[:user], m) }
629
692
  end
630
693
  ret = []
631
694
  after = 0
632
695
  loop do
633
696
  params = { after: after, limit: 100 }
634
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/members?#{URI.encode_www_form(params)}", "//guilds/:guild_id/members", :get)).wait
697
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/members?#{URI.encode_www_form(params)}",
698
+ "//guilds/:guild_id/members", :get)).wait
635
699
  ret += data.map { |m| Member.new(@client, @id, m[:user], m) }
636
700
  after = data.last[:user][:id]
637
701
  break if data.length != 1000
@@ -653,7 +717,16 @@ module Discorb
653
717
  #
654
718
  def fetch_members_named(name, limit: 1)
655
719
  Async do
656
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/members/search?#{URI.encode_www_form({ query: name, limit: limit })}", "//guilds/:guild_id/members/search", :get)).wait
720
+ _resp, data = @client.http.request(
721
+ Route.new(
722
+ "/guilds/#{@id}/members/search?#{URI.encode_www_form(
723
+ {
724
+ query: name,
725
+ limit: limit,
726
+ }
727
+ )}", "//guilds/:guild_id/members/search", :get
728
+ )
729
+ ).wait
657
730
  data.map { |d| Member.new(@client, @id, d[:user], d) }
658
731
  end
659
732
  end
@@ -682,7 +755,10 @@ module Discorb
682
755
  #
683
756
  def edit_nickname(nickname, reason: nil)
684
757
  Async do
685
- @client.http.request(Route.new("/guilds/#{@id}/members/@me/nick", "//guilds/:guild_id/members/@me/nick", :patch), { nick: nickname }, audit_log_reason: reason).wait
758
+ @client.http.request(
759
+ Route.new("/guilds/#{@id}/members/@me/nick", "//guilds/:guild_id/members/@me/nick",
760
+ :patch), { nick: nickname }, audit_log_reason: reason,
761
+ ).wait
686
762
  end
687
763
  end
688
764
 
@@ -701,7 +777,10 @@ module Discorb
701
777
  #
702
778
  def kick_member(member, reason: nil)
703
779
  Async do
704
- @client.http.request(Route.new("/guilds/#{@id}/members/#{member.id}", "//guilds/:guild_id/members/:user_id", :delete), audit_log_reason: reason).wait
780
+ @client.http.request(
781
+ Route.new("/guilds/#{@id}/members/#{member.id}", "//guilds/:guild_id/members/:user_id",
782
+ :delete), {}, audit_log_reason: reason,
783
+ ).wait
705
784
  end
706
785
  end
707
786
 
@@ -709,12 +788,24 @@ module Discorb
709
788
  # Fetch a list of bans in the guild.
710
789
  # @async
711
790
  #
791
+ # @param [Integer] limit The number of bans to fetch.
792
+ # @param [Discorb::Snowflake] before The ID of the ban to fetch before.
793
+ # @param [Discorb::Snowflake] after The ID of the ban to fetch after.
794
+ # @param [Discorb::Snowflake] around The ID of the ban to fetch around.
795
+ #
712
796
  # @return [Async::Task<Array<Discorb::Guild::Ban>>] The list of bans.
713
797
  #
714
- def fetch_bans
798
+ def fetch_bans(limit = 50, before: nil, after: nil, around: nil)
715
799
  Async do
716
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/bans", "//guilds/:guild_id/bans", :get)).wait
717
- data.map { |d| Ban.new(@client, self, d) }
800
+ params = {
801
+ limit: limit,
802
+ before: Discorb::Utils.try(after, :id),
803
+ after: Discorb::Utils.try(around, :id),
804
+ around: Discorb::Utils.try(before, :id),
805
+ }.filter { |_k, v| !v.nil? }.to_h
806
+ _resp, bans = @client.http.request(Route.new("/guilds/#{@id}/bans?#{URI.encode_www_form(params)}",
807
+ "//guilds/:guild_id/bans", :get)).wait
808
+ bans.map { |d| Ban.new(@client, self, d) }
718
809
  end
719
810
  end
720
811
 
@@ -729,7 +820,8 @@ module Discorb
729
820
  #
730
821
  def fetch_ban(user)
731
822
  Async do
732
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/bans/#{user.id}", "//guilds/:guild_id/bans/:user_id", :get)).wait
823
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/bans/#{user.id}",
824
+ "//guilds/:guild_id/bans/:user_id", :get)).wait
733
825
  rescue Discorb::NotFoundError
734
826
  nil
735
827
  else
@@ -763,7 +855,15 @@ module Discorb
763
855
  #
764
856
  def ban_member(member, delete_message_days: 0, reason: nil)
765
857
  Async do
766
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/bans", "//guilds/:guild_id/bans", :post), { user: member.id, delete_message_days: delete_message_days }, audit_log_reason: reason).wait
858
+ _resp, data = @client.http.request(
859
+ Route.new("/guilds/#{@id}/bans",
860
+ "//guilds/:guild_id/bans",
861
+ :post),
862
+ {
863
+ user: member.id,
864
+ delete_message_days: delete_message_days,
865
+ }, audit_log_reason: reason,
866
+ ).wait
767
867
  Ban.new(@client, self, data)
768
868
  end
769
869
  end
@@ -779,7 +879,8 @@ module Discorb
779
879
  #
780
880
  def unban_user(user, reason: nil)
781
881
  Async do
782
- @client.http.request(Route.new("/guilds/#{@id}/bans/#{user.id}", "//guilds/:guild_id/bans/:user_id", :delete), audit_log_reason: reason).wait
882
+ @client.http.request(Route.new("/guilds/#{@id}/bans/#{user.id}", "//guilds/:guild_id/bans/:user_id", :delete),
883
+ {}, audit_log_reason: reason).wait
783
884
  end
784
885
  end
785
886
 
@@ -815,7 +916,8 @@ module Discorb
815
916
  payload[:color] = color.to_i if color
816
917
  payload[:hoist] = hoist if hoist
817
918
  payload[:mentionable] = mentionable if mentionable
818
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/roles", "//guilds/:guild_id/roles", :post), payload, audit_log_reason: reason).wait
919
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/roles", "//guilds/:guild_id/roles", :post),
920
+ payload, audit_log_reason: reason).wait
819
921
  Role.new(@client, self, data)
820
922
  end
821
923
  end
@@ -836,7 +938,8 @@ module Discorb
836
938
  include_roles: @id.to_s,
837
939
  }
838
940
  param[:include_roles] = roles.map(&:id).map(&:to_s).join(";") if roles.any?
839
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/prune?#{URI.encode_www_form(params)}", "//guilds/:guild_id/prune", :get)).wait
941
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/prune?#{URI.encode_www_form(params)}",
942
+ "//guilds/:guild_id/prune", :get)).wait
840
943
  data[:pruned]
841
944
  end
842
945
  end
@@ -853,7 +956,8 @@ module Discorb
853
956
  #
854
957
  def prune(days = 7, roles: [], reason: nil)
855
958
  Async do
856
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/prune", "//guilds/:guild_id/prune", :post), { days: days, roles: roles.map(&:id) }, audit_log_reason: reason).wait
959
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/prune", "//guilds/:guild_id/prune", :post),
960
+ { days: days, roles: roles.map(&:id) }, audit_log_reason: reason).wait
857
961
  data[:pruned]
858
962
  end
859
963
  end
@@ -892,7 +996,8 @@ module Discorb
892
996
  #
893
997
  def fetch_integrations
894
998
  Async do
895
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/integrations", "//guilds/:guild_id/integrations", :get)).wait
999
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/integrations", "//guilds/:guild_id/integrations",
1000
+ :get)).wait
896
1001
  data.map { |d| Integration.new(@client, d, @id) }
897
1002
  end
898
1003
  end
@@ -918,7 +1023,8 @@ module Discorb
918
1023
  #
919
1024
  def fetch_vanity_invite
920
1025
  Async do
921
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/vanity-url", "//guilds/:guild_id/vanity-url", :get)).wait
1026
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/vanity-url", "//guilds/:guild_id/vanity-url",
1027
+ :get)).wait
922
1028
  VanityInvite.new(@client, self, data)
923
1029
  end
924
1030
  end
@@ -931,7 +1037,8 @@ module Discorb
931
1037
  #
932
1038
  def fetch_welcome_screen
933
1039
  Async do
934
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/welcome-screen", "//guilds/:guild_id/welcome-screen", :get)).wait
1040
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/welcome-screen",
1041
+ "//guilds/:guild_id/welcome-screen", :get)).wait
935
1042
  WelcomeScreen.new(@client, self, data)
936
1043
  end
937
1044
  end
@@ -944,7 +1051,8 @@ module Discorb
944
1051
  #
945
1052
  def fetch_stickers
946
1053
  Async do
947
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/stickers", "//guilds/:guild_id/stickers", :get)).wait
1054
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/stickers", "//guilds/:guild_id/stickers",
1055
+ :get)).wait
948
1056
  data.map { |d| Sticker::GuildSticker.new(@client, d) }
949
1057
  end
950
1058
  end
@@ -960,7 +1068,8 @@ module Discorb
960
1068
  #
961
1069
  def fetch_sticker(id)
962
1070
  Async do
963
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/stickers/#{id}", "//guilds/:guild_id/stickers/:sticker_id", :get)).wait
1071
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/stickers/#{id}",
1072
+ "//guilds/:guild_id/stickers/:sticker_id", :get)).wait
964
1073
  rescue Discorb::NotFoundError
965
1074
  nil
966
1075
  else
@@ -976,7 +1085,8 @@ module Discorb
976
1085
  #
977
1086
  def fetch_templates
978
1087
  Async do
979
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/templates", "//guilds/:guild_id/templates", :get)).wait
1088
+ _resp, data = @client.http.request(Route.new("/guilds/#{@id}/templates", "//guilds/:guild_id/templates",
1089
+ :get)).wait
980
1090
  data.map { |d| GuildTemplate.new(@client, d) }
981
1091
  end
982
1092
  end
@@ -1004,7 +1114,10 @@ module Discorb
1004
1114
  #
1005
1115
  def create_template(name, description = nil, reason: nil)
1006
1116
  Async do
1007
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/templates", "//guilds/:guild_id/templates", :post), { name: name, description: description }, audit_log_reason: reason).wait
1117
+ _resp, data = @client.http.request(
1118
+ Route.new("/guilds/#{@id}/templates", "//guilds/:guild_id/templates",
1119
+ :post), { name: name, description: description }, audit_log_reason: reason,
1120
+ ).wait
1008
1121
  GuildTemplate.new(@client, data)
1009
1122
  end
1010
1123
  end
@@ -1098,7 +1211,8 @@ module Discorb
1098
1211
  payload = {}
1099
1212
  payload[:enabled] = enabled unless enabled.nil?
1100
1213
  payload[:channel_id] = channel.id if channel_id
1101
- @client.http.request(Route.new("/guilds/#{@guild_id}/widget", "//guilds/:guild_id/widget", :patch), payload, audit_log_reason: reason).wait
1214
+ @client.http.request(Route.new("/guilds/#{@guild_id}/widget", "//guilds/:guild_id/widget", :patch), payload,
1215
+ audit_log_reason: reason).wait
1102
1216
  end
1103
1217
  end
1104
1218
 
@@ -1118,10 +1232,12 @@ module Discorb
1118
1232
  # @return [String] The iframe HTML.
1119
1233
  #
1120
1234
  def iframe(theme: "dark", width: 350, height: 500)
1235
+ # rubocop:disable Layout/LineLength
1121
1236
  [
1122
1237
  %(<iframe src="https://canary.discord.com/widget?id=#{@guild_id}&theme=#{theme}" width="#{width}" height="#{height}"),
1123
1238
  %(allowtransparency="true" frameborder="0" sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"></iframe>),
1124
1239
  ].join
1240
+ # rubocop:enable Layout/LineLength
1125
1241
  end
1126
1242
  end
1127
1243
 
@@ -1148,6 +1264,10 @@ module Discorb
1148
1264
  @reason = data[:reason]
1149
1265
  @user = @client.users[data[:user][:id]] || User.new(@client, data[:user])
1150
1266
  end
1267
+
1268
+ def inspect
1269
+ "<#{self.class.name} #{@user}>"
1270
+ end
1151
1271
  end
1152
1272
 
1153
1273
  class << self
@@ -1181,7 +1301,8 @@ module Discorb
1181
1301
  Member.new(@client, @id, m[:user], m)
1182
1302
  end
1183
1303
  @splash = data[:splash] && Asset.new(self, data[:splash], path: "splashes/#{@id}")
1184
- @discovery_splash = data[:discovery_splash] && Asset.new(self, data[:discovery_splash], path: "discovery-splashes/#{@id}")
1304
+ @discovery_splash = data[:discovery_splash] && Asset.new(self, data[:discovery_splash],
1305
+ path: "discovery-splashes/#{@id}")
1185
1306
  @owner_id = data[:owner_id]
1186
1307
  @permissions = Permission.new(data[:permissions].to_i)
1187
1308
  @afk_channel_id = data[:afk_channel_id]
@@ -1226,12 +1347,20 @@ module Discorb
1226
1347
  Channel.make_channel(@client, c.merge({ guild_id: @id }))
1227
1348
  end
1228
1349
  @channels = Dictionary.new(tmp_channels.to_h { |c| [c.id, c] }, sort: ->(c) { c[1].position })
1229
- @voice_states = Dictionary.new(data[:voice_states].to_h { |v| [Snowflake.new(v[:user_id]), VoiceState.new(@client, v.merge({ guild_id: @id }))] })
1350
+ @voice_states = Dictionary.new(data[:voice_states].to_h do |v|
1351
+ [Snowflake.new(v[:user_id]), VoiceState.new(@client, v.merge({ guild_id: @id }))]
1352
+ end)
1230
1353
  @threads = data[:threads] ? data[:threads].map { |t| Channel.make_channel(@client, t) } : []
1231
- @presences = Dictionary.new(data[:presences].to_h { |pr| [Snowflake.new(pr[:user][:id]), Presence.new(@client, pr)] })
1354
+ @presences = Dictionary.new(data[:presences].to_h do |pr|
1355
+ [Snowflake.new(pr[:user][:id]), Presence.new(@client, pr)]
1356
+ end)
1232
1357
  @max_presences = data[:max_presences]
1233
- @stage_instances = Dictionary.new(data[:stage_instances].to_h { |s| [Snowflake.new(s[:id]), StageInstance.new(@client, s)] })
1234
- @scheduled_events = Dictionary.new(data[:guild_scheduled_events].to_h { |s| [Snowflake.new(s[:id]), ScheduledEvent.new(@client, s)] })
1358
+ @stage_instances = Dictionary.new(data[:stage_instances].to_h do |s|
1359
+ [Snowflake.new(s[:id]), StageInstance.new(@client, s)]
1360
+ end)
1361
+ @scheduled_events = Dictionary.new(data[:guild_scheduled_events].to_h do |s|
1362
+ [Snowflake.new(s[:id]), ScheduledEvent.new(@client, s)]
1363
+ end)
1235
1364
  @data.update(data)
1236
1365
  end
1237
1366
  end
@@ -1367,7 +1496,10 @@ module Discorb
1367
1496
  payload[:enabled] = enabled unless enabled == Discorb::Unset
1368
1497
  payload[:welcome_channels] = channels.map(&:to_hash) unless channels == Discorb::Unset
1369
1498
  payload[:description] = description unless description == Discorb::Unset
1370
- @client.http.request(Route.new("/guilds/#{@guild.id}/welcome-screen", "//guilds/:guild_id/welcome-screen", :patch), payload, audit_log_reason: reason).wait
1499
+ @client.http.request(
1500
+ Route.new("/guilds/#{@guild.id}/welcome-screen", "//guilds/:guild_id/welcome-screen",
1501
+ :patch), payload, audit_log_reason: reason,
1502
+ ).wait
1371
1503
  end
1372
1504
  end
1373
1505
  end
@@ -64,7 +64,10 @@ module Discorb
64
64
  payload = {}
65
65
  payload[:name] = name if name
66
66
  payload[:description] = description if description != Discorb::Unset
67
- @client.http.request(Route.new("/guilds/#{@source_guild_id}/templates/#{@code}", "//guilds/:guild_id/templates/:code", :patch), payload).wait
67
+ @client.http.request(
68
+ Route.new("/guilds/#{@source_guild_id}/templates/#{@code}", "//guilds/:guild_id/templates/:code",
69
+ :patch), payload
70
+ ).wait
68
71
  end
69
72
  end
70
73
 
@@ -78,7 +81,8 @@ module Discorb
78
81
  #
79
82
  def update
80
83
  Async do
81
- _resp, data = @client.http.request(Route.new("/guilds/#{@source_guild_id}/templates/#{@code}", "//guilds/:guild_id/templates/:code", :put)).wait
84
+ _resp, data = @client.http.request(Route.new("/guilds/#{@source_guild_id}/templates/#{@code}",
85
+ "//guilds/:guild_id/templates/:code", :put)).wait
82
86
  _set_data(data)
83
87
  end
84
88
  end
@@ -91,7 +95,8 @@ module Discorb
91
95
  #
92
96
  def delete!
93
97
  Async do
94
- @client.http.request(Route.new("/guilds/#{@source_guild_id}/templates/#{@code}", "//guilds/:guild_id/templates/:code", :delete)).wait
98
+ @client.http.request(Route.new("/guilds/#{@source_guild_id}/templates/#{@code}",
99
+ "//guilds/:guild_id/templates/:code", :delete)).wait
95
100
  end
96
101
  end
97
102
 
@@ -109,7 +114,8 @@ module Discorb
109
114
  attr_reader :roles
110
115
  # @return [Discorb::SystemChannelFlag] The flag for the system channel.
111
116
  attr_reader :system_channel_flags
112
- # @return [Discorb::Dictionary{Discorb::Snowflake => Discorb::GuildChannel}] A dictionary of channels in the guild.
117
+ # @return [Discorb::Dictionary{Discorb::Snowflake => Discorb::GuildChannel}]
118
+ # A dictionary of channels in the guild.
113
119
  attr_reader :channels
114
120
  # @return [String] The description of the guild.
115
121
  attr_reader :description