discorb 0.13.2 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
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