discorb 0.13.2 → 0.15.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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/build_version.yml +1 -1
  4. data/.github/workflows/codeql-analysis.yml +70 -0
  5. data/.github/workflows/lint-push.yml +20 -0
  6. data/.github/workflows/lint.yml +16 -0
  7. data/.rubocop.yml +70 -0
  8. data/CODE_OF_CONDUCT.md +128 -0
  9. data/Changelog.md +34 -0
  10. data/Gemfile +7 -3
  11. data/README.md +1 -1
  12. data/Rakefile +22 -22
  13. data/discorb.gemspec +13 -1
  14. data/docs/faq.md +8 -8
  15. data/examples/commands/bookmarker.rb +2 -1
  16. data/examples/commands/hello.rb +1 -0
  17. data/examples/commands/inspect.rb +3 -2
  18. data/examples/components/authorization_button.rb +2 -1
  19. data/examples/components/select_menu.rb +2 -1
  20. data/examples/extension/main.rb +1 -0
  21. data/examples/extension/message_expander.rb +1 -0
  22. data/examples/simple/eval.rb +3 -2
  23. data/examples/simple/ping_pong.rb +1 -0
  24. data/examples/simple/rolepanel.rb +1 -0
  25. data/examples/simple/wait_for_message.rb +4 -3
  26. data/exe/discorb +8 -7
  27. data/lib/discorb/allowed_mentions.rb +64 -0
  28. data/lib/discorb/app_command/command.rb +274 -0
  29. data/lib/discorb/app_command/handler.rb +168 -0
  30. data/lib/discorb/app_command.rb +2 -404
  31. data/lib/discorb/asset.rb +3 -1
  32. data/lib/discorb/{file.rb → attachment.rb} +42 -35
  33. data/lib/discorb/audit_logs.rb +3 -3
  34. data/lib/discorb/channel.rb +65 -61
  35. data/lib/discorb/client.rb +36 -33
  36. data/lib/discorb/common.rb +29 -22
  37. data/lib/discorb/components/button.rb +106 -0
  38. data/lib/discorb/components/select_menu.rb +157 -0
  39. data/lib/discorb/components/text_input.rb +96 -0
  40. data/lib/discorb/components.rb +11 -276
  41. data/lib/discorb/dictionary.rb +13 -2
  42. data/lib/discorb/embed.rb +40 -33
  43. data/lib/discorb/emoji.rb +21 -5
  44. data/lib/discorb/emoji_table.rb +1 -1
  45. data/lib/discorb/error.rb +4 -6
  46. data/lib/discorb/event.rb +13 -11
  47. data/lib/discorb/exe/about.rb +1 -0
  48. data/lib/discorb/exe/irb.rb +4 -3
  49. data/lib/discorb/exe/new.rb +6 -7
  50. data/lib/discorb/exe/run.rb +2 -1
  51. data/lib/discorb/exe/setup.rb +8 -5
  52. data/lib/discorb/exe/show.rb +1 -0
  53. data/lib/discorb/extend.rb +19 -14
  54. data/lib/discorb/extension.rb +5 -1
  55. data/lib/discorb/gateway.rb +82 -29
  56. data/lib/discorb/guild.rb +58 -80
  57. data/lib/discorb/guild_template.rb +5 -5
  58. data/lib/discorb/http.rb +52 -170
  59. data/lib/discorb/integration.rb +32 -3
  60. data/lib/discorb/intents.rb +9 -4
  61. data/lib/discorb/interaction/autocomplete.rb +5 -4
  62. data/lib/discorb/interaction/command.rb +34 -9
  63. data/lib/discorb/interaction/components.rb +5 -2
  64. data/lib/discorb/interaction/modal.rb +33 -0
  65. data/lib/discorb/interaction/response.rb +41 -12
  66. data/lib/discorb/interaction/root.rb +1 -0
  67. data/lib/discorb/interaction.rb +2 -1
  68. data/lib/discorb/invite.rb +1 -1
  69. data/lib/discorb/log.rb +4 -3
  70. data/lib/discorb/member.rb +4 -6
  71. data/lib/discorb/message.rb +38 -241
  72. data/lib/discorb/message_meta.rb +157 -0
  73. data/lib/discorb/modules.rb +47 -23
  74. data/lib/discorb/permission.rb +2 -2
  75. data/lib/discorb/presence.rb +6 -3
  76. data/lib/discorb/rate_limit.rb +15 -21
  77. data/lib/discorb/role.rb +3 -3
  78. data/lib/discorb/sticker.rb +2 -2
  79. data/lib/discorb/user.rb +3 -3
  80. data/lib/discorb/utils/colored_puts.rb +1 -0
  81. data/lib/discorb/voice_state.rb +7 -2
  82. data/lib/discorb/webhook.rb +9 -6
  83. data/lib/discorb.rb +2 -1
  84. data/sig/discorb.rbs +5836 -6714
  85. data/template-replace/scripts/arrow.rb +1 -0
  86. data/template-replace/scripts/favicon.rb +1 -0
  87. data/template-replace/scripts/index.rb +2 -1
  88. data/template-replace/scripts/locale_ja.rb +5 -4
  89. data/template-replace/scripts/sidebar.rb +1 -0
  90. data/template-replace/scripts/version.rb +7 -10
  91. data/template-replace/scripts/yard_replace.rb +5 -4
  92. metadata +30 -5
@@ -174,7 +174,7 @@ module Discorb
174
174
  #
175
175
  def delete!(reason: nil)
176
176
  Async do
177
- @client.http.delete(base_url.wait.to_s, audit_log_reason: reason).wait
177
+ @client.http.request(Route.new(base_url.wait.to_s, "//webhooks/:webhook_id/:token", :delete), audit_log_reason: reason).wait
178
178
  @deleted = true
179
179
  self
180
180
  end
@@ -201,7 +201,7 @@ module Discorb
201
201
  }
202
202
  payload[:lock_permissions] = lock_permissions
203
203
  payload[:parent_id] = parent&.id if parent != Discorb::Unset
204
- @client.http.patch("/guilds/#{@guild_id}/channels", payload, audit_log_reason: reason).wait
204
+ @client.http.request(Route.new("/guilds/#{@guild_id}/channels", "//guilds/:guild_id/channels", :patch), payload, audit_log_reason: reason).wait
205
205
  end
206
206
  end
207
207
 
@@ -211,9 +211,9 @@ module Discorb
211
211
  @guild_id = data[:guild_id]
212
212
  @position = data[:position]
213
213
  @permission_overwrites = if data[:permission_overwrites]
214
- data[:permission_overwrites].map do |ow|
214
+ data[:permission_overwrites].to_h do |ow|
215
215
  [(ow[:type] == 1 ? guild.roles : guild.members)[ow[:id]], PermissionOverwrite.new(ow[:allow], ow[:deny])]
216
- end.to_h
216
+ end
217
217
  else
218
218
  {}
219
219
  end
@@ -239,17 +239,15 @@ module Discorb
239
239
  # @return [Time] The time when the last pinned message was pinned.
240
240
  attr_reader :last_pin_timestamp
241
241
  alias last_pinned_at last_pin_timestamp
242
- # @return [Array<Discorb::ThreadChannel>] The threads in the channel.
243
- attr_reader :threads
244
242
 
245
243
  include Messageable
246
244
 
247
245
  @channel_type = 0
248
246
 
249
- # @private
250
- def initialize(client, data, no_cache: false)
251
- super
252
- @threads = Dictionary.new
247
+ # @!attribute [r] threads
248
+ # @return [Array<Discorb::ThreadChannel>] The threads in the channel.
249
+ def threads
250
+ guild.threads.select { |thread| thread.parent == self }
253
251
  end
254
252
 
255
253
  #
@@ -292,7 +290,7 @@ module Discorb
292
290
  default_auto_archive_duration ||= archive_in
293
291
  payload[:default_auto_archive_duration] = default_auto_archive_duration if default_auto_archive_duration != Discorb::Unset
294
292
 
295
- @client.http.patch("/channels/#{@id}", payload, audit_log_reason: reason).wait
293
+ @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
296
294
  self
297
295
  end
298
296
  end
@@ -313,7 +311,7 @@ module Discorb
313
311
  payload = {}
314
312
  payload[:name] = name
315
313
  payload[:avatar] = avatar.to_s if avatar
316
- _resp, data = @client.http.post("/channels/#{@id}/webhooks", payload).wait
314
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/webhooks", "//channels/:channel_id/webhooks", :post), payload).wait
317
315
  Webhook.new([@client, data])
318
316
  end
319
317
  end
@@ -326,7 +324,7 @@ module Discorb
326
324
  #
327
325
  def fetch_webhooks
328
326
  Async do
329
- _resp, data = @client.http.get("/channels/#{@id}/webhooks").wait
327
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/webhooks", "//channels/:channel_id/webhooks", :get)).wait
330
328
  data.map { |webhook| Webhook.new([@client, webhook]) }
331
329
  end
332
330
  end
@@ -354,7 +352,7 @@ module Discorb
354
352
 
355
353
  message_ids = messages.map { |m| Discorb::Utils.try(m, :id).to_s }
356
354
 
357
- @client.http.post("/channels/#{@id}/messages/bulk-delete", { messages: message_ids }).wait
355
+ @client.http.request(Route.new("/channels/#{@id}/messages/bulk-delete", "//channels/:channel_id/messages/bulk-delete", :post), { messages: message_ids }).wait
358
356
  end
359
357
  end
360
358
 
@@ -384,7 +382,7 @@ module Discorb
384
382
  deny: deny_value,
385
383
  type: target.is_a?(Member) ? 1 : 0,
386
384
  }
387
- @client.http.put("/channels/#{@id}/permissions/#{target.id}", payload, audit_log_reason: reason).wait
385
+ @client.http.request(Route.new("/channels/#{@id}/permissions/#{target.id}", "//channels/:channel_id/permissions/:target_id", :put), payload, audit_log_reason: reason).wait
388
386
  end
389
387
  end
390
388
 
@@ -404,7 +402,7 @@ module Discorb
404
402
  #
405
403
  def delete_permissions(target, reason: nil)
406
404
  Async do
407
- @client.http.delete("/channels/#{@id}/permissions/#{target.id}", audit_log_reason: reason).wait
405
+ @client.http.request(Route.new("/channels/#{@id}/permissions/#{target.id}", "//channels/:channel_id/permissions/:target_id", :delete), audit_log_reason: reason).wait
408
406
  end
409
407
  end
410
408
 
@@ -420,7 +418,7 @@ module Discorb
420
418
  #
421
419
  def fetch_invites
422
420
  Async do
423
- _resp, data = @client.http.get("/channels/#{@id}/invites").wait
421
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/invites", "//channels/:channel_id/invites", :get)).wait
424
422
  data.map { |invite| Invite.new(@client, invite) }
425
423
  end
426
424
  end
@@ -440,7 +438,7 @@ module Discorb
440
438
  #
441
439
  def create_invite(max_age: nil, max_uses: nil, temporary: false, unique: false, reason: nil)
442
440
  Async do
443
- _resp, data = @client.http.post("/channels/#{@id}/invites", {
441
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/invites", "//channels/:channel_id/invites", :post), {
444
442
  max_age: max_age,
445
443
  max_uses: max_uses,
446
444
  temporary: temporary,
@@ -461,7 +459,7 @@ module Discorb
461
459
  #
462
460
  def follow_from(target, reason: nil)
463
461
  Async do
464
- @client.http.post("/channels/#{target.id}/followers", { webhook_channel_id: @id }, audit_log_reason: reason).wait
462
+ @client.http.request(Route.new("/channels/#{target.id}/followers", "//channels/:channel_id/followers", :post), { webhook_channel_id: @id }, audit_log_reason: reason).wait
465
463
  end
466
464
  end
467
465
 
@@ -476,7 +474,7 @@ module Discorb
476
474
  #
477
475
  def follow_to(target, reason: nil)
478
476
  Async do
479
- @client.http.post("/channels/#{@id}/followers", { webhook_channel_id: target.id }, audit_log_reason: reason).wait
477
+ @client.http.request(Route.new("/channels/#{@id}/followers", "//channels/:channel_id/followers", :post), { webhook_channel_id: target.id }, audit_log_reason: reason).wait
480
478
  end
481
479
  end
482
480
 
@@ -497,17 +495,15 @@ module Discorb
497
495
  def start_thread(name, message: nil, auto_archive_duration: 1440, public: true, rate_limit_per_user: nil, slowmode: nil, reason: nil)
498
496
  Async do
499
497
  _resp, data = if message.nil?
500
- @client.http.post(
501
- "/channels/#{@id}/threads", {
502
- name: name,
503
- auto_archive_duration: auto_archive_duration,
504
- type: public ? 11 : 10,
505
- rate_limit_per_user: rate_limit_per_user || slowmode,
506
- },
507
- audit_log_reason: reason,
508
- ).wait
498
+ @client.http.request(Route.new("/channels/#{@id}/threads", "//channels/:channel_id/threads", :post), {
499
+ name: name,
500
+ auto_archive_duration: auto_archive_duration,
501
+ type: public ? 11 : 10,
502
+ rate_limit_per_user: rate_limit_per_user || slowmode,
503
+ },
504
+ audit_log_reason: reason).wait
509
505
  else
510
- @client.http.post("/channels/#{@id}/messages/#{Utils.try(message, :id)}/threads", {
506
+ @client.http.request(Route.new("/channels/#{@id}/messages/#{Utils.try(message, :id)}/threads", "//channels/:channel_id/messages/:message_id/threads", :post), {
511
507
  name: name, auto_archive_duration: auto_archive_duration,
512
508
  }, audit_log_reason: reason).wait
513
509
  end
@@ -525,7 +521,7 @@ module Discorb
525
521
  #
526
522
  def fetch_archived_public_threads
527
523
  Async do
528
- _resp, data = @client.http.get("/channels/#{@id}/threads/archived/public").wait
524
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/threads/archived/public", "//channels/:channel_id/threads/archived/public", :get)).wait
529
525
  data.map { |thread| Channel.make_channel(@client, thread) }
530
526
  end
531
527
  end
@@ -538,7 +534,7 @@ module Discorb
538
534
  #
539
535
  def fetch_archived_private_threads
540
536
  Async do
541
- _resp, data = @client.http.get("/channels/#{@id}/threads/archived/private").wait
537
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/threads/archived/private", "//channels/:channel_id/threads/archived/private", :get)).wait
542
538
  data.map { |thread| Channel.make_channel(@client, thread) }
543
539
  end
544
540
  end
@@ -558,7 +554,7 @@ module Discorb
558
554
  before = 0
559
555
  threads = []
560
556
  loop do
561
- _resp, data = @client.http.get("/channels/#{@id}/users/@me/threads/archived/private?before=#{before}").wait
557
+ _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
562
558
  threads += data[:threads].map { |thread| Channel.make_channel(@client, thread) }
563
559
  before = data[:threads][-1][:id]
564
560
 
@@ -566,7 +562,7 @@ module Discorb
566
562
  end
567
563
  threads
568
564
  else
569
- _resp, data = @client.http.get("/channels/#{@id}/users/@me/threads/archived/private?limit=#{limit}&before=#{before}").wait
565
+ _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
570
566
  data.map { |thread| Channel.make_channel(@client, thread) }
571
567
  end
572
568
  end
@@ -634,7 +630,7 @@ module Discorb
634
630
  payload[:user_limit] = user_limit if user_limit != Discorb::Unset
635
631
  payload[:rtc_region] = rtc_region if rtc_region != Discorb::Unset
636
632
 
637
- @client.http.patch("/channels/#{@id}", payload, audit_log_reason: reason).wait
633
+ @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
638
634
  self
639
635
  end
640
636
  end
@@ -707,7 +703,7 @@ module Discorb
707
703
  payload[:position] = position if position != Discorb::Unset
708
704
  payload[:bitrate] = bitrate if bitrate != Discorb::Unset
709
705
  payload[:rtc_region] = rtc_region if rtc_region != Discorb::Unset
710
- @client.http.patch("/channels/#{@id}", payload, audit_log_reason: reason).wait
706
+ @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
711
707
  self
712
708
  end
713
709
  end
@@ -726,7 +722,7 @@ module Discorb
726
722
  #
727
723
  def start(topic, public: false, reason: nil)
728
724
  Async do
729
- _resp, data = @client.http.post("/stage-instances", { channel_id: @id, topic: topic, public: public ? 2 : 1 }, audit_log_reason: reason).wait
725
+ _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
730
726
  StageInstance.new(@client, data)
731
727
  end
732
728
  end
@@ -740,7 +736,7 @@ module Discorb
740
736
  #
741
737
  def fetch_stage_instance
742
738
  Async do
743
- _resp, data = @client.http.get("/stage-instances/#{@id}").wait
739
+ _resp, data = @client.http.request(Route.new("/stage-instances/#{@id}", "//stage-instances/:stage_instance_id", :get)).wait
744
740
  rescue Discorb::NotFoundError
745
741
  nil
746
742
  else
@@ -761,7 +757,7 @@ module Discorb
761
757
  end
762
758
 
763
759
  def audiences
764
- voice_states.filter { |state| state.suppress? }.map(&:member)
760
+ voice_states.filter(&:suppress?).map(&:member)
765
761
  end
766
762
 
767
763
  private
@@ -831,8 +827,6 @@ module Discorb
831
827
  def initialize(client, data, no_cache: false)
832
828
  @members = Dictionary.new
833
829
  super
834
- @client.channels[@parent_id].threads[@id] = self
835
-
836
830
  @client.channels[@id] = self unless no_cache
837
831
  end
838
832
 
@@ -863,7 +857,7 @@ module Discorb
863
857
  auto_archive_duration ||= archive_in
864
858
  payload[:auto_archive_duration] = auto_archive_duration if auto_archive_duration != Discorb::Unset
865
859
  payload[:locked] = locked if locked != Discorb::Unset
866
- @client.http.patch("/channels/#{@id}", payload, audit_log_reason: reason).wait
860
+ @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
867
861
  self
868
862
  end
869
863
  end
@@ -952,9 +946,9 @@ module Discorb
952
946
  def add_member(member = :me)
953
947
  Async do
954
948
  if member == :me
955
- @client.http.post("/channels/#{@id}/thread-members/@me").wait
949
+ @client.http.request(Route.new("/channels/#{@id}/thread-members/@me", "//channels/:channel_id/thread-members/@me", :post)).wait
956
950
  else
957
- @client.http.post("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}").wait
951
+ @client.http.request(Route.new("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}", "//channels/:channel_id/thread-members/:user_id", :post)).wait
958
952
  end
959
953
  end
960
954
  end
@@ -971,9 +965,9 @@ module Discorb
971
965
  def remove_member(member = :me)
972
966
  Async do
973
967
  if member == :me
974
- @client.http.delete("/channels/#{@id}/thread-members/@me").wait
968
+ @client.http.request(Route.new("/channels/#{@id}/thread-members/@me", "//channels/:channel_id/thread-members/@me", :delete)).wait
975
969
  else
976
- @client.http.delete("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}").wait
970
+ @client.http.request(Route.new("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}", "//channels/:channel_id/thread-members/:user_id", :delete)).wait
977
971
  end
978
972
  end
979
973
  end
@@ -987,19 +981,28 @@ module Discorb
987
981
  #
988
982
  def fetch_members
989
983
  Async do
990
- _resp, data = @client.http.get("/channels/#{@id}/thread-members").wait
984
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/thread-members", "//channels/:channel_id/thread-members", :get)).wait
991
985
  data.map { |d| @members[d[:id]] = Member.new(@client, d) }
992
986
  end
993
987
  end
994
988
 
989
+ #
990
+ # Represents a thread in news channel(aka announcement channel).
991
+ #
995
992
  class News < ThreadChannel
996
993
  @channel_type = 10
997
994
  end
998
995
 
996
+ #
997
+ # Represents a public thread in text channel.
998
+ #
999
999
  class Public < ThreadChannel
1000
1000
  @channel_type = 11
1001
1001
  end
1002
1002
 
1003
+ #
1004
+ # Represents a private thread in text channel.
1005
+ #
1003
1006
  class Private < ThreadChannel
1004
1007
  @channel_type = 12
1005
1008
  end
@@ -1009,7 +1012,7 @@ module Discorb
1009
1012
  end
1010
1013
 
1011
1014
  #
1012
- # Repre
1015
+ # Represents a member in a thread.
1013
1016
  #
1014
1017
  class Member < DiscordModel
1015
1018
  attr_reader :joined_at
@@ -1061,25 +1064,30 @@ module Discorb
1061
1064
  end
1062
1065
  end
1063
1066
 
1067
+ #
1068
+ # Represents a category in a guild.
1069
+ #
1064
1070
  class CategoryChannel < GuildChannel
1065
- attr_reader :channels
1066
-
1067
1071
  @channel_type = 4
1068
1072
 
1073
+ def channels
1074
+ @client.channels.values.filter { |channel| channel.parent == self }
1075
+ end
1076
+
1069
1077
  def text_channels
1070
- @channels.filter { |c| c.is_a? TextChannel }
1078
+ channels.filter { |c| c.is_a? TextChannel }
1071
1079
  end
1072
1080
 
1073
1081
  def voice_channels
1074
- @channels.filter { |c| c.is_a? VoiceChannel }
1082
+ channels.filter { |c| c.is_a? VoiceChannel }
1075
1083
  end
1076
1084
 
1077
1085
  def news_channel
1078
- @channels.filter { |c| c.is_a? NewsChannel }
1086
+ channels.filter { |c| c.is_a? NewsChannel }
1079
1087
  end
1080
1088
 
1081
1089
  def stage_channels
1082
- @channels.filter { |c| c.is_a? StageChannel }
1090
+ channels.filter { |c| c.is_a? StageChannel }
1083
1091
  end
1084
1092
 
1085
1093
  def create_text_channel(*args, **kwargs)
@@ -1097,15 +1105,11 @@ module Discorb
1097
1105
  def create_stage_channel(*args, **kwargs)
1098
1106
  guild.create_stage_channel(*args, parent: self, **kwargs)
1099
1107
  end
1100
-
1101
- private
1102
-
1103
- def _set_data(data)
1104
- @channels = @client.channels.values.filter { |channel| channel.parent == self }
1105
- super
1106
- end
1107
1108
  end
1108
1109
 
1110
+ #
1111
+ # Represents a DM channel.
1112
+ #
1109
1113
  class DMChannel < Channel
1110
1114
  include Messageable
1111
1115
 
@@ -63,7 +63,7 @@ module Discorb
63
63
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions that the client is using.
64
64
  # @param [Discorb::Intents] intents The intents that the client is currently using.
65
65
  # @param [Integer] message_caches The number of messages to cache.
66
- # @param [#puts] log The IO object to use for logging.
66
+ # @param [#write] log The IO object to use for logging.
67
67
  # @param [Boolean] colorize_log Whether to colorize the log.
68
68
  # @param [:debug, :info, :warn, :error, :critical] log_level The log level.
69
69
  # @param [Boolean] wait_until_ready Whether to delay event dispatch until ready.
@@ -186,10 +186,8 @@ module Discorb
186
186
  @log.debug "Dispatching event #{event_name}"
187
187
  events.each do |block|
188
188
  Async do
189
- Async(annotation: "Discorb event: #{event_name}") do |task|
190
- if block.is_a?(Discorb::EventHandler)
191
- @events[event_name].delete(block) if block.metadata[:once]
192
- end
189
+ Async(annotation: "Discorb event: #{event_name}") do |_task|
190
+ @events[event_name].delete(block) if block.is_a?(Discorb::EventHandler) && block.metadata[:once]
193
191
  block.call(*args)
194
192
  @log.debug "Dispatched proc with ID #{block.id.inspect}"
195
193
  rescue StandardError, ScriptError => e
@@ -212,7 +210,7 @@ module Discorb
212
210
  #
213
211
  def fetch_user(id)
214
212
  Async do
215
- _resp, data = http.get("/users/#{id}").wait
213
+ _resp, data = @http.request(Route.new("/users/#{id}", "//users/:user_id", :get)).wait
216
214
  User.new(self, data)
217
215
  end
218
216
  end
@@ -229,7 +227,7 @@ module Discorb
229
227
  #
230
228
  def fetch_channel(id)
231
229
  Async do
232
- _resp, data = http.get("/channels/#{id}").wait
230
+ _resp, data = @http.request(Route.new("/channels/#{id}", "//channels/:channel_id", :get)).wait
233
231
  Channel.make_channel(self, data)
234
232
  end
235
233
  end
@@ -246,7 +244,7 @@ module Discorb
246
244
  #
247
245
  def fetch_guild(id)
248
246
  Async do
249
- _resp, data = http.get("/guilds/#{id}").wait
247
+ _resp, data = @http.request(Route.new("/guilds/#{id}", "//guilds/:guild_id", :get)).wait
250
248
  Guild.new(self, data, false)
251
249
  end
252
250
  end
@@ -261,9 +259,9 @@ module Discorb
261
259
  #
262
260
  # @return [Async::Task<Discorb::Invite>] The invite.
263
261
  #
264
- def fetch_invite(code, with_count: false, with_expiration: false)
262
+ def fetch_invite(code, with_count: true, with_expiration: true)
265
263
  Async do
266
- _resp, data = http.get("/invites/#{code}?with_count=#{with_count}&with_expiration=#{with_expiration}").wait
264
+ _resp, data = @http.request(Route.new("/invites/#{code}?with_count=#{with_count}&with_expiration=#{with_expiration}", "//invites/:code", :get)).wait
267
265
  Invite.new(self, data, false)
268
266
  end
269
267
  end
@@ -281,7 +279,7 @@ module Discorb
281
279
  Async do
282
280
  next @application if @application && !force
283
281
 
284
- _resp, data = http.get("/oauth2/applications/@me").wait
282
+ _resp, data = @http.request(Route.new("/oauth2/applications/@me", "//oauth2/applications/@me", :get)).wait
285
283
  @application = Application.new(self, data)
286
284
  @application
287
285
  end
@@ -295,8 +293,8 @@ module Discorb
295
293
  #
296
294
  def fetch_nitro_sticker_packs
297
295
  Async do
298
- _resp, data = http.get("/stickers-packs").wait
299
- data.map { |pack| Sticker::Pack.new(self, pack) }
296
+ _resp, data = @http.request(Route.new("/sticker-packs", "//sticker-packs", :get)).wait
297
+ data[:sticker_packs].map { |pack| Sticker::Pack.new(self, pack) }
300
298
  end
301
299
  end
302
300
 
@@ -305,18 +303,14 @@ module Discorb
305
303
  #
306
304
  # @param [Discorb::Activity] activity The activity to update.
307
305
  # @param [:online, :idle, :dnd, :invisible] status The status to update.
308
- # @param [String] afk Whether to set the client as AFK.
309
306
  #
310
- def update_presence(activity = nil, status: nil, afk: false)
307
+ def update_presence(activity = nil, status: nil)
311
308
  payload = {
312
309
  activities: [],
313
310
  status: status,
314
- afk: nil,
315
311
  since: nil,
316
312
  }
317
- if !activity.nil?
318
- payload[:activities] = [activity.to_hash]
319
- end
313
+ payload[:activities] = [activity.to_hash] unless activity.nil?
320
314
  payload[:status] = status unless status.nil?
321
315
  if @connection
322
316
  Async do
@@ -374,10 +368,11 @@ module Discorb
374
368
  # @param [Object] ... The arguments to pass to the `ext#initialize`.
375
369
  #
376
370
  def load_extension(ext, ...)
377
- if ext.is_a?(Class)
371
+ case ext
372
+ when Class
378
373
  raise ArgumentError, "#{ext} is not a extension" unless ext < Discorb::Extension
379
374
  ins = ext.new(self, ...)
380
- elsif ext.is_a?(Discorb::Extension)
375
+ when Discorb::Extension
381
376
  ins = ext
382
377
  else
383
378
  raise ArgumentError, "#{ext} is not a extension"
@@ -398,12 +393,20 @@ module Discorb
398
393
  ins.class.commands.each do |cmd|
399
394
  cmd.define_singleton_method(:extension) { ins.class.name }
400
395
  cmd.replace_block(ins)
396
+ cmd.block.define_singleton_method(:self_replaced) { true }
401
397
  @commands << cmd
402
398
  end
403
399
 
404
400
  cls = ins.class
405
401
  cls.loaded(self, ...) if cls.respond_to? :loaded
406
- @bottom_commands += ins.class.bottom_commands
402
+ ins.class.bottom_commands.each do |cmd|
403
+ unless cmd.respond_to? :self_replaced
404
+ cmd.define_singleton_method(:extension) { ins.class.name }
405
+ cmd.replace_block(ins)
406
+ cmd.block.define_singleton_method(:self_replaced) { true }
407
+ end
408
+ @bottom_commands << cmd
409
+ end
407
410
  @extensions[ins.class.name] = ins
408
411
  ins
409
412
  end
@@ -463,7 +466,7 @@ module Discorb
463
466
  ::File.open(options[:log_file], "a")
464
467
  end
465
468
  @log.level = options[:log_level].to_sym
466
- @log.colorize_log = options[:log_color] == nil ? @log.out.isatty : options[:log_color]
469
+ @log.colorize_log = options[:log_color].nil? ? @log.out.isatty : options[:log_color]
467
470
  end
468
471
  end
469
472
  end
@@ -473,29 +476,29 @@ module Discorb
473
476
  if guilds = ENV["DISCORB_SETUP_GUILDS"]
474
477
  guild_ids = guilds.split(",")
475
478
  end
476
- if guild_ids == ["global"]
477
- guild_ids = false
478
- end
479
+ guild_ids = false if guild_ids == ["global"]
479
480
  setup_commands(token, guild_ids: guild_ids).wait
480
- @events[:setup]&.each do |event|
481
- event.call
481
+ if ENV["DISCORB_SETUP_SCRIPT"] == "true"
482
+ @events[:setup]&.each do |event|
483
+ event.call
484
+ end
485
+ self.on_setup if respond_to? :on_setup
482
486
  end
483
- self.on_setup if respond_to? :on_setup
484
487
  end
485
488
 
486
489
  def start_client(token)
487
- Async do |task|
488
- Signal.trap(:SIGINT) {
490
+ Async do |_task|
491
+ Signal.trap(:SIGINT) do
489
492
  @log.info "SIGINT received, closing..."
490
493
  Signal.trap(:SIGINT, "DEFAULT")
491
494
  close!
492
- }
495
+ end
493
496
  @token = token.to_s
494
497
  @close_condition = Async::Condition.new
495
498
  @main_task = Async do
496
499
  @status = :running
497
500
  connect_gateway(false).wait
498
- rescue
501
+ rescue StandardError
499
502
  @status = :stopped
500
503
  @close_condition.signal
501
504
  raise
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Discorb
4
4
  # @return [String] The API base URL.
5
- API_BASE_URL = "https://discord.com/api/v9"
5
+ API_BASE_URL = "https://discord.com/api/v10"
6
6
  # @return [String] The version of discorb.
7
- VERSION = "0.13.2"
7
+ VERSION = "0.15.0"
8
8
  # @return [String] The user agent for the bot.
9
- USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}"
9
+ USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}".freeze
10
10
 
11
11
  #
12
12
  # @abstract
@@ -26,9 +26,6 @@ module Discorb
26
26
  end
27
27
 
28
28
  # @private
29
- def inspect
30
- super
31
- end
32
29
 
33
30
  def hash
34
31
  @id.hash
@@ -111,32 +108,42 @@ module Discorb
111
108
  end
112
109
 
113
110
  def inspect
114
- "#<#{self.class} #{to_s}>"
111
+ "#<#{self.class} #{self}>"
115
112
  end
116
113
 
117
114
  alias id to_s
118
115
  end
119
116
 
120
- # @return [Object] Object that represents nil.
121
- # This is used as a default value for optional parameters.
122
- Unset = Object.new
123
- class << Unset
124
- def method_missing(*)
125
- self
117
+ #
118
+ # Represents an endpoint.
119
+ # @private
120
+ #
121
+ class Route
122
+ attr_reader :url, :key, :method
123
+
124
+ def initialize(url, key, method)
125
+ @url = url
126
+ @key = key
127
+ @method = method
126
128
  end
127
129
 
128
- def or(other)
129
- other
130
+ def hash
131
+ @url.hash
130
132
  end
131
- end
132
133
 
133
- module DefineOr
134
- refine Object do
135
- def or(other)
136
- self
137
- end
134
+ def identifier
135
+ "#{@method} #{@key}"
136
+ end
137
+
138
+ def major_param
139
+ param_type = @key.split("/").find { |k| k.start_with?(":") }
140
+ return "" unless param_type
141
+ param = url.gsub(API_BASE_URL, "").split("/")[@key.split("/").index(param_type) - 1]
142
+ %w[:channel_id :guild_id :webhook_id].include?(param_type) ? param : ""
138
143
  end
139
144
  end
140
145
 
141
- using DefineOr
146
+ # @return [Object] Object that represents unspecified value.
147
+ # This is used as a default value for optional parameters.
148
+ Unset = Object.new
142
149
  end