discorb 0.13.1 → 0.14.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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/build_version.yml +3 -3
  4. data/.github/workflows/codeql-analysis.yml +70 -0
  5. data/.github/workflows/lint-push.yml +18 -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 +33 -0
  10. data/Gemfile +7 -3
  11. data/README.md +1 -1
  12. data/Rakefile +35 -35
  13. data/discorb.gemspec +13 -1
  14. data/examples/commands/bookmarker.rb +2 -1
  15. data/examples/commands/hello.rb +1 -0
  16. data/examples/commands/inspect.rb +3 -2
  17. data/examples/components/authorization_button.rb +2 -1
  18. data/examples/components/select_menu.rb +2 -1
  19. data/examples/extension/main.rb +1 -0
  20. data/examples/extension/message_expander.rb +1 -0
  21. data/examples/simple/eval.rb +3 -2
  22. data/examples/simple/ping_pong.rb +1 -0
  23. data/examples/simple/rolepanel.rb +1 -0
  24. data/examples/simple/wait_for_message.rb +4 -3
  25. data/exe/discorb +8 -7
  26. data/lib/discorb/allowed_mentions.rb +64 -0
  27. data/lib/discorb/app_command/command.rb +274 -0
  28. data/lib/discorb/app_command/handler.rb +168 -0
  29. data/lib/discorb/app_command.rb +2 -404
  30. data/lib/discorb/asset.rb +3 -1
  31. data/lib/discorb/audit_logs.rb +3 -3
  32. data/lib/discorb/channel.rb +89 -53
  33. data/lib/discorb/client.rb +36 -33
  34. data/lib/discorb/common.rb +28 -21
  35. data/lib/discorb/components/button.rb +106 -0
  36. data/lib/discorb/components/select_menu.rb +157 -0
  37. data/lib/discorb/components/text_input.rb +96 -0
  38. data/lib/discorb/components.rb +11 -276
  39. data/lib/discorb/dictionary.rb +13 -2
  40. data/lib/discorb/embed.rb +2 -2
  41. data/lib/discorb/emoji.rb +21 -5
  42. data/lib/discorb/emoji_table.rb +1 -1
  43. data/lib/discorb/error.rb +4 -6
  44. data/lib/discorb/event.rb +13 -11
  45. data/lib/discorb/exe/about.rb +1 -0
  46. data/lib/discorb/exe/irb.rb +4 -3
  47. data/lib/discorb/exe/new.rb +6 -7
  48. data/lib/discorb/exe/run.rb +2 -1
  49. data/lib/discorb/exe/setup.rb +8 -5
  50. data/lib/discorb/exe/show.rb +1 -0
  51. data/lib/discorb/extend.rb +19 -14
  52. data/lib/discorb/extension.rb +5 -1
  53. data/lib/discorb/gateway.rb +75 -27
  54. data/lib/discorb/guild.rb +58 -80
  55. data/lib/discorb/guild_template.rb +5 -5
  56. data/lib/discorb/http.rb +34 -169
  57. data/lib/discorb/integration.rb +32 -3
  58. data/lib/discorb/intents.rb +1 -1
  59. data/lib/discorb/interaction/autocomplete.rb +5 -4
  60. data/lib/discorb/interaction/command.rb +34 -9
  61. data/lib/discorb/interaction/components.rb +5 -2
  62. data/lib/discorb/interaction/modal.rb +33 -0
  63. data/lib/discorb/interaction/response.rb +41 -12
  64. data/lib/discorb/interaction/root.rb +1 -0
  65. data/lib/discorb/interaction.rb +2 -1
  66. data/lib/discorb/invite.rb +1 -1
  67. data/lib/discorb/log.rb +4 -3
  68. data/lib/discorb/member.rb +4 -6
  69. data/lib/discorb/message.rb +31 -282
  70. data/lib/discorb/message_meta.rb +205 -0
  71. data/lib/discorb/modules.rb +11 -11
  72. data/lib/discorb/permission.rb +2 -2
  73. data/lib/discorb/presence.rb +6 -3
  74. data/lib/discorb/rate_limit.rb +15 -21
  75. data/lib/discorb/role.rb +3 -3
  76. data/lib/discorb/sticker.rb +2 -2
  77. data/lib/discorb/user.rb +3 -3
  78. data/lib/discorb/utils/colored_puts.rb +1 -0
  79. data/lib/discorb/voice_state.rb +7 -2
  80. data/lib/discorb/webhook.rb +8 -5
  81. data/lib/discorb.rb +1 -0
  82. data/template-replace/scripts/arrow.rb +1 -0
  83. data/template-replace/scripts/favicon.rb +1 -0
  84. data/template-replace/scripts/index.rb +2 -1
  85. data/template-replace/scripts/locale_ja.rb +5 -4
  86. data/template-replace/scripts/sidebar.rb +1 -0
  87. data/template-replace/scripts/version.rb +7 -10
  88. data/template-replace/scripts/yard_replace.rb +5 -4
  89. metadata +29 -4
@@ -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
@@ -292,7 +292,7 @@ module Discorb
292
292
  default_auto_archive_duration ||= archive_in
293
293
  payload[:default_auto_archive_duration] = default_auto_archive_duration if default_auto_archive_duration != Discorb::Unset
294
294
 
295
- @client.http.patch("/channels/#{@id}", payload, audit_log_reason: reason).wait
295
+ @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
296
296
  self
297
297
  end
298
298
  end
@@ -313,7 +313,7 @@ module Discorb
313
313
  payload = {}
314
314
  payload[:name] = name
315
315
  payload[:avatar] = avatar.to_s if avatar
316
- _resp, data = @client.http.post("/channels/#{@id}/webhooks", payload).wait
316
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/webhooks", "//channels/:channel_id/webhooks", :post), payload).wait
317
317
  Webhook.new([@client, data])
318
318
  end
319
319
  end
@@ -326,7 +326,7 @@ module Discorb
326
326
  #
327
327
  def fetch_webhooks
328
328
  Async do
329
- _resp, data = @client.http.get("/channels/#{@id}/webhooks").wait
329
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/webhooks", "//channels/:channel_id/webhooks", :get)).wait
330
330
  data.map { |webhook| Webhook.new([@client, webhook]) }
331
331
  end
332
332
  end
@@ -354,7 +354,7 @@ module Discorb
354
354
 
355
355
  message_ids = messages.map { |m| Discorb::Utils.try(m, :id).to_s }
356
356
 
357
- @client.http.post("/channels/#{@id}/messages/bulk-delete", { messages: message_ids }).wait
357
+ @client.http.request(Route.new("/channels/#{@id}/messages/bulk-delete", "//channels/:channel_id/messages/bulk-delete", :post), { messages: message_ids }).wait
358
358
  end
359
359
  end
360
360
 
@@ -384,7 +384,7 @@ module Discorb
384
384
  deny: deny_value,
385
385
  type: target.is_a?(Member) ? 1 : 0,
386
386
  }
387
- @client.http.put("/channels/#{@id}/permissions/#{target.id}", payload, audit_log_reason: reason).wait
387
+ @client.http.request(Route.new("/channels/#{@id}/permissions/#{target.id}", "//channels/:channel_id/permissions/:target_id", :put), payload, audit_log_reason: reason).wait
388
388
  end
389
389
  end
390
390
 
@@ -404,7 +404,7 @@ module Discorb
404
404
  #
405
405
  def delete_permissions(target, reason: nil)
406
406
  Async do
407
- @client.http.delete("/channels/#{@id}/permissions/#{target.id}", audit_log_reason: reason).wait
407
+ @client.http.request(Route.new("/channels/#{@id}/permissions/#{target.id}", "//channels/:channel_id/permissions/:target_id", :delete), audit_log_reason: reason).wait
408
408
  end
409
409
  end
410
410
 
@@ -420,7 +420,7 @@ module Discorb
420
420
  #
421
421
  def fetch_invites
422
422
  Async do
423
- _resp, data = @client.http.get("/channels/#{@id}/invites").wait
423
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/invites", "//channels/:channel_id/invites", :get)).wait
424
424
  data.map { |invite| Invite.new(@client, invite) }
425
425
  end
426
426
  end
@@ -440,7 +440,7 @@ module Discorb
440
440
  #
441
441
  def create_invite(max_age: nil, max_uses: nil, temporary: false, unique: false, reason: nil)
442
442
  Async do
443
- _resp, data = @client.http.post("/channels/#{@id}/invites", {
443
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/invites", "//channels/:channel_id/invites", :post), {
444
444
  max_age: max_age,
445
445
  max_uses: max_uses,
446
446
  temporary: temporary,
@@ -461,7 +461,7 @@ module Discorb
461
461
  #
462
462
  def follow_from(target, reason: nil)
463
463
  Async do
464
- @client.http.post("/channels/#{target.id}/followers", { webhook_channel_id: @id }, audit_log_reason: reason).wait
464
+ @client.http.request(Route.new("/channels/#{target.id}/followers", "//channels/:channel_id/followers", :post), { webhook_channel_id: @id }, audit_log_reason: reason).wait
465
465
  end
466
466
  end
467
467
 
@@ -476,7 +476,7 @@ module Discorb
476
476
  #
477
477
  def follow_to(target, reason: nil)
478
478
  Async do
479
- @client.http.post("/channels/#{@id}/followers", { webhook_channel_id: target.id }, audit_log_reason: reason).wait
479
+ @client.http.request(Route.new("/channels/#{@id}/followers", "//channels/:channel_id/followers", :post), { webhook_channel_id: target.id }, audit_log_reason: reason).wait
480
480
  end
481
481
  end
482
482
 
@@ -497,17 +497,15 @@ module Discorb
497
497
  def start_thread(name, message: nil, auto_archive_duration: 1440, public: true, rate_limit_per_user: nil, slowmode: nil, reason: nil)
498
498
  Async do
499
499
  _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
500
+ @client.http.request(Route.new("/channels/#{@id}/threads", "//channels/:channel_id/threads", :post), {
501
+ name: name,
502
+ auto_archive_duration: auto_archive_duration,
503
+ type: public ? 11 : 10,
504
+ rate_limit_per_user: rate_limit_per_user || slowmode,
505
+ },
506
+ audit_log_reason: reason).wait
509
507
  else
510
- @client.http.post("/channels/#{@id}/messages/#{Utils.try(message, :id)}/threads", {
508
+ @client.http.request(Route.new("/channels/#{@id}/messages/#{Utils.try(message, :id)}/threads", "//channels/:channel_id/messages/:message_id/threads", :post), {
511
509
  name: name, auto_archive_duration: auto_archive_duration,
512
510
  }, audit_log_reason: reason).wait
513
511
  end
@@ -525,7 +523,7 @@ module Discorb
525
523
  #
526
524
  def fetch_archived_public_threads
527
525
  Async do
528
- _resp, data = @client.http.get("/channels/#{@id}/threads/archived/public").wait
526
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/threads/archived/public", "//channels/:channel_id/threads/archived/public", :get)).wait
529
527
  data.map { |thread| Channel.make_channel(@client, thread) }
530
528
  end
531
529
  end
@@ -538,7 +536,7 @@ module Discorb
538
536
  #
539
537
  def fetch_archived_private_threads
540
538
  Async do
541
- _resp, data = @client.http.get("/channels/#{@id}/threads/archived/private").wait
539
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/threads/archived/private", "//channels/:channel_id/threads/archived/private", :get)).wait
542
540
  data.map { |thread| Channel.make_channel(@client, thread) }
543
541
  end
544
542
  end
@@ -558,7 +556,7 @@ module Discorb
558
556
  before = 0
559
557
  threads = []
560
558
  loop do
561
- _resp, data = @client.http.get("/channels/#{@id}/users/@me/threads/archived/private?before=#{before}").wait
559
+ _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
560
  threads += data[:threads].map { |thread| Channel.make_channel(@client, thread) }
563
561
  before = data[:threads][-1][:id]
564
562
 
@@ -566,7 +564,7 @@ module Discorb
566
564
  end
567
565
  threads
568
566
  else
569
- _resp, data = @client.http.get("/channels/#{@id}/users/@me/threads/archived/private?limit=#{limit}&before=#{before}").wait
567
+ _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
568
  data.map { |thread| Channel.make_channel(@client, thread) }
571
569
  end
572
570
  end
@@ -603,6 +601,11 @@ module Discorb
603
601
  # @return [nil] If the user limit is not set.
604
602
  attr_reader :user_limit
605
603
 
604
+ # @!attribute [r] members
605
+ # @return [Array<Discorb::Member>] The members in the voice channel.
606
+ # @!attribute [r] voice_states
607
+ # @return [Array<Discorb::VoiceState>] The voice states associated with the voice channel.
608
+
606
609
  include Connectable
607
610
 
608
611
  @channel_type = 2
@@ -629,13 +632,21 @@ module Discorb
629
632
  payload[:user_limit] = user_limit if user_limit != Discorb::Unset
630
633
  payload[:rtc_region] = rtc_region if rtc_region != Discorb::Unset
631
634
 
632
- @client.http.patch("/channels/#{@id}", payload, audit_log_reason: reason).wait
635
+ @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
633
636
  self
634
637
  end
635
638
  end
636
639
 
637
640
  alias modify edit
638
641
 
642
+ def voice_states
643
+ guild.voice_states.select { |state| state.channel&.id == @id }
644
+ end
645
+
646
+ def members
647
+ voice_states.map(&:member)
648
+ end
649
+
639
650
  private
640
651
 
641
652
  def _set_data(data)
@@ -694,7 +705,7 @@ module Discorb
694
705
  payload[:position] = position if position != Discorb::Unset
695
706
  payload[:bitrate] = bitrate if bitrate != Discorb::Unset
696
707
  payload[:rtc_region] = rtc_region if rtc_region != Discorb::Unset
697
- @client.http.patch("/channels/#{@id}", payload, audit_log_reason: reason).wait
708
+ @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
698
709
  self
699
710
  end
700
711
  end
@@ -713,7 +724,7 @@ module Discorb
713
724
  #
714
725
  def start(topic, public: false, reason: nil)
715
726
  Async do
716
- _resp, data = @client.http.post("/stage-instances", { channel_id: @id, topic: topic, public: public ? 2 : 1 }, audit_log_reason: reason).wait
727
+ _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
717
728
  StageInstance.new(@client, data)
718
729
  end
719
730
  end
@@ -727,7 +738,7 @@ module Discorb
727
738
  #
728
739
  def fetch_stage_instance
729
740
  Async do
730
- _resp, data = @client.http.get("/stage-instances/#{@id}").wait
741
+ _resp, data = @client.http.request(Route.new("/stage-instances/#{@id}", "//stage-instances/:stage_instance_id", :get)).wait
731
742
  rescue Discorb::NotFoundError
732
743
  nil
733
744
  else
@@ -735,6 +746,22 @@ module Discorb
735
746
  end
736
747
  end
737
748
 
749
+ def voice_states
750
+ guild.voice_states.select { |state| state.channel&.id == @id }
751
+ end
752
+
753
+ def members
754
+ voice_states.map(&:member)
755
+ end
756
+
757
+ def speakers
758
+ voice_states.filter { |state| !state.suppress? }.map(&:member)
759
+ end
760
+
761
+ def audiences
762
+ voice_states.filter(&:suppress?).map(&:member)
763
+ end
764
+
738
765
  private
739
766
 
740
767
  def _set_data(data)
@@ -795,7 +822,6 @@ module Discorb
795
822
  # @macro members_intent
796
823
  # @return [Discorb::Member] The owner of the thread.
797
824
 
798
-
799
825
  include Messageable
800
826
  @channel_type = nil
801
827
 
@@ -835,7 +861,7 @@ module Discorb
835
861
  auto_archive_duration ||= archive_in
836
862
  payload[:auto_archive_duration] = auto_archive_duration if auto_archive_duration != Discorb::Unset
837
863
  payload[:locked] = locked if locked != Discorb::Unset
838
- @client.http.patch("/channels/#{@id}", payload, audit_log_reason: reason).wait
864
+ @client.http.request(Route.new("/channels/#{@id}", "//channels/:channel_id", :patch), payload, audit_log_reason: reason).wait
839
865
  self
840
866
  end
841
867
  end
@@ -924,9 +950,9 @@ module Discorb
924
950
  def add_member(member = :me)
925
951
  Async do
926
952
  if member == :me
927
- @client.http.post("/channels/#{@id}/thread-members/@me").wait
953
+ @client.http.request(Route.new("/channels/#{@id}/thread-members/@me", "//channels/:channel_id/thread-members/@me", :post)).wait
928
954
  else
929
- @client.http.post("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}").wait
955
+ @client.http.request(Route.new("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}", "//channels/:channel_id/thread-members/:user_id", :post)).wait
930
956
  end
931
957
  end
932
958
  end
@@ -943,9 +969,9 @@ module Discorb
943
969
  def remove_member(member = :me)
944
970
  Async do
945
971
  if member == :me
946
- @client.http.delete("/channels/#{@id}/thread-members/@me").wait
972
+ @client.http.request(Route.new("/channels/#{@id}/thread-members/@me", "//channels/:channel_id/thread-members/@me", :delete)).wait
947
973
  else
948
- @client.http.delete("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}").wait
974
+ @client.http.request(Route.new("/channels/#{@id}/thread-members/#{Utils.try(member, :id)}", "//channels/:channel_id/thread-members/:user_id", :delete)).wait
949
975
  end
950
976
  end
951
977
  end
@@ -959,19 +985,28 @@ module Discorb
959
985
  #
960
986
  def fetch_members
961
987
  Async do
962
- _resp, data = @client.http.get("/channels/#{@id}/thread-members").wait
988
+ _resp, data = @client.http.request(Route.new("/channels/#{@id}/thread-members", "//channels/:channel_id/thread-members", :get)).wait
963
989
  data.map { |d| @members[d[:id]] = Member.new(@client, d) }
964
990
  end
965
991
  end
966
992
 
993
+ #
994
+ # Represents a thread in news channel(aka announcement channel).
995
+ #
967
996
  class News < ThreadChannel
968
997
  @channel_type = 10
969
998
  end
970
999
 
1000
+ #
1001
+ # Represents a public thread in text channel.
1002
+ #
971
1003
  class Public < ThreadChannel
972
1004
  @channel_type = 11
973
1005
  end
974
1006
 
1007
+ #
1008
+ # Represents a private thread in text channel.
1009
+ #
975
1010
  class Private < ThreadChannel
976
1011
  @channel_type = 12
977
1012
  end
@@ -981,7 +1016,7 @@ module Discorb
981
1016
  end
982
1017
 
983
1018
  #
984
- # Repre
1019
+ # Represents a member in a thread.
985
1020
  #
986
1021
  class Member < DiscordModel
987
1022
  attr_reader :joined_at
@@ -1033,25 +1068,30 @@ module Discorb
1033
1068
  end
1034
1069
  end
1035
1070
 
1071
+ #
1072
+ # Represents a category in a guild.
1073
+ #
1036
1074
  class CategoryChannel < GuildChannel
1037
- attr_reader :channels
1038
-
1039
1075
  @channel_type = 4
1040
1076
 
1077
+ def channels
1078
+ @client.channels.values.filter { |channel| channel.parent == self }
1079
+ end
1080
+
1041
1081
  def text_channels
1042
- @channels.filter { |c| c.is_a? TextChannel }
1082
+ channels.filter { |c| c.is_a? TextChannel }
1043
1083
  end
1044
1084
 
1045
1085
  def voice_channels
1046
- @channels.filter { |c| c.is_a? VoiceChannel }
1086
+ channels.filter { |c| c.is_a? VoiceChannel }
1047
1087
  end
1048
1088
 
1049
1089
  def news_channel
1050
- @channels.filter { |c| c.is_a? NewsChannel }
1090
+ channels.filter { |c| c.is_a? NewsChannel }
1051
1091
  end
1052
1092
 
1053
1093
  def stage_channels
1054
- @channels.filter { |c| c.is_a? StageChannel }
1094
+ channels.filter { |c| c.is_a? StageChannel }
1055
1095
  end
1056
1096
 
1057
1097
  def create_text_channel(*args, **kwargs)
@@ -1069,15 +1109,11 @@ module Discorb
1069
1109
  def create_stage_channel(*args, **kwargs)
1070
1110
  guild.create_stage_channel(*args, parent: self, **kwargs)
1071
1111
  end
1072
-
1073
- private
1074
-
1075
- def _set_data(data)
1076
- @channels = @client.channels.values.filter { |channel| channel.parent == self }
1077
- super
1078
- end
1079
1112
  end
1080
1113
 
1114
+ #
1115
+ # Represents a DM channel.
1116
+ #
1081
1117
  class DMChannel < Channel
1082
1118
  include Messageable
1083
1119
 
@@ -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
@@ -4,9 +4,9 @@ module Discorb
4
4
  # @return [String] The API base URL.
5
5
  API_BASE_URL = "https://discord.com/api/v9"
6
6
  # @return [String] The version of discorb.
7
- VERSION = "0.13.1"
7
+ VERSION = "0.14.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