discorb 0.13.4 → 0.15.1

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 (93) 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 +74 -0
  8. data/Changelog.md +30 -0
  9. data/Gemfile +7 -3
  10. data/Rakefile +28 -22
  11. data/discorb.gemspec +1 -0
  12. data/docs/events.md +50 -0
  13. data/docs/faq.md +8 -8
  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 +71 -0
  27. data/lib/discorb/app_command/command.rb +336 -0
  28. data/lib/discorb/app_command/handler.rb +168 -0
  29. data/lib/discorb/app_command.rb +2 -426
  30. data/lib/discorb/application.rb +16 -7
  31. data/lib/discorb/asset.rb +11 -0
  32. data/lib/discorb/{file.rb → attachment.rb} +55 -33
  33. data/lib/discorb/audit_logs.rb +45 -7
  34. data/lib/discorb/channel.rb +65 -15
  35. data/lib/discorb/client.rb +34 -27
  36. data/lib/discorb/common.rb +19 -27
  37. data/lib/discorb/components/button.rb +105 -0
  38. data/lib/discorb/components/select_menu.rb +143 -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 +5 -0
  42. data/lib/discorb/embed.rb +73 -40
  43. data/lib/discorb/emoji.rb +48 -5
  44. data/lib/discorb/error.rb +9 -5
  45. data/lib/discorb/event.rb +36 -24
  46. data/lib/discorb/exe/about.rb +1 -0
  47. data/lib/discorb/exe/irb.rb +4 -3
  48. data/lib/discorb/exe/new.rb +6 -7
  49. data/lib/discorb/exe/run.rb +2 -1
  50. data/lib/discorb/exe/setup.rb +8 -5
  51. data/lib/discorb/exe/show.rb +1 -0
  52. data/lib/discorb/extend.rb +19 -14
  53. data/lib/discorb/extension.rb +5 -1
  54. data/lib/discorb/gateway.rb +112 -51
  55. data/lib/discorb/gateway_requests.rb +4 -7
  56. data/lib/discorb/guild.rb +73 -41
  57. data/lib/discorb/guild_template.rb +26 -5
  58. data/lib/discorb/http.rb +38 -18
  59. data/lib/discorb/integration.rb +24 -9
  60. data/lib/discorb/intents.rb +16 -11
  61. data/lib/discorb/interaction/autocomplete.rb +6 -5
  62. data/lib/discorb/interaction/command.rb +66 -12
  63. data/lib/discorb/interaction/components.rb +19 -3
  64. data/lib/discorb/interaction/modal.rb +33 -0
  65. data/lib/discorb/interaction/response.rb +45 -4
  66. data/lib/discorb/interaction/root.rb +16 -0
  67. data/lib/discorb/interaction.rb +2 -1
  68. data/lib/discorb/invite.rb +11 -7
  69. data/lib/discorb/log.rb +5 -5
  70. data/lib/discorb/member.rb +22 -3
  71. data/lib/discorb/message.rb +39 -234
  72. data/lib/discorb/message_meta.rb +186 -0
  73. data/lib/discorb/modules.rb +39 -15
  74. data/lib/discorb/permission.rb +16 -7
  75. data/lib/discorb/presence.rb +45 -9
  76. data/lib/discorb/rate_limit.rb +7 -4
  77. data/lib/discorb/reaction.rb +6 -0
  78. data/lib/discorb/role.rb +12 -0
  79. data/lib/discorb/sticker.rb +22 -14
  80. data/lib/discorb/user.rb +12 -1
  81. data/lib/discorb/utils/colored_puts.rb +1 -0
  82. data/lib/discorb/voice_state.rb +23 -2
  83. data/lib/discorb/webhook.rb +54 -3
  84. data/lib/discorb.rb +5 -2
  85. data/sig/discorb.rbs +838 -702
  86. data/template-replace/scripts/arrow.rb +1 -0
  87. data/template-replace/scripts/favicon.rb +1 -0
  88. data/template-replace/scripts/index.rb +2 -1
  89. data/template-replace/scripts/locale_ja.rb +5 -4
  90. data/template-replace/scripts/sidebar.rb +1 -0
  91. data/template-replace/scripts/version.rb +7 -10
  92. data/template-replace/scripts/yard_replace.rb +5 -4
  93. metadata +17 -3
@@ -14,12 +14,22 @@ module Discorb
14
14
  module Gateway
15
15
  #
16
16
  # Represents an event.
17
+ # @abstract
17
18
  #
18
19
  class GatewayEvent
20
+ #
21
+ # Initializes a new instance of the GatewayEvent class.
19
22
  # @private
23
+ #
24
+ # @param [Hash] data The data of the event.
25
+ #
20
26
  def initialize(data)
21
27
  @data = data
22
28
  end
29
+
30
+ def inspect
31
+ "#<#{self.class}>"
32
+ end
23
33
  end
24
34
 
25
35
  #
@@ -61,7 +71,13 @@ module Discorb
61
71
  alias reactor fired_by
62
72
  alias from fired_by
63
73
 
74
+ #
75
+ # Initializes a new instance of the ReactionEvent class.
64
76
  # @private
77
+ #
78
+ # @param [Discorb::Client] client The client that instantiated the object.
79
+ # @param [Hash] data The data of the event.
80
+ #
65
81
  def initialize(client, data)
66
82
  @client = client
67
83
  @data = data
@@ -121,8 +137,15 @@ module Discorb
121
137
  # @macro client_cache
122
138
  # @return [Discorb::User] The user associated with the integration.
123
139
 
140
+ #
141
+ # Initialize a new instance of the IntegrationDeleteEvent class.
124
142
  # @private
125
- def initialize(client, data)
143
+ #
144
+ #
145
+ # @param [Hash] data The data of the event.
146
+ #
147
+ #
148
+ def initialize(_client, data)
126
149
  @id = Snowflake.new(data[:id])
127
150
  @guild_id = data[:guild_id]
128
151
  @user_id = data[:application_id]
@@ -157,7 +180,13 @@ module Discorb
157
180
  # @return [Discorb::Message] The message the reaction was sent in.
158
181
  attr_reader :message
159
182
 
183
+ #
184
+ # Initialize a new instance of the ReactionRemoveAllEvent class.
160
185
  # @private
186
+ #
187
+ # @param [Discorb::Client] client The client that instantiated the object.
188
+ # @param [Hash] data The data of the event.
189
+ #
161
190
  def initialize(client, data)
162
191
  @client = client
163
192
  @data = data
@@ -207,7 +236,13 @@ module Discorb
207
236
  # @return [Discorb::UnicodeEmoji, Discorb::PartialEmoji] The emoji that was reacted with.
208
237
  attr_reader :emoji
209
238
 
239
+ #
240
+ # Initialize a new instance of the ReactionRemoveEmojiEvent class.
210
241
  # @private
242
+ #
243
+ # @param [Discorb::Client] client The client that instantiated the object.
244
+ # @param [Hash] data The data of the event.
245
+ #
211
246
  def initialize(client, data)
212
247
  @client = client
213
248
  @data = data
@@ -246,7 +281,13 @@ module Discorb
246
281
  attr_reader :guild
247
282
  # @return [Discorb::ScheduledEvent] The scheduled event.
248
283
  attr_reader :scheduled_event
284
+ #
285
+ # Initialize a new instance of the ScheduledEventUserEvent class.
249
286
  # @private
287
+ #
288
+ # @param [Discorb::Client] client The client that instantiated the object.
289
+ # @param [Hash] data The data of the event.
290
+ #
250
291
  def initialize(client, data)
251
292
  @client = client
252
293
  @scheduled_event_id = Snowflake.new(data[:scheduled_event_id])
@@ -261,7 +302,6 @@ module Discorb
261
302
  #
262
303
  # Represents a `MESSAGE_UPDATE` event.
263
304
  #
264
-
265
305
  class MessageUpdateEvent < GatewayEvent
266
306
  # @return [Discorb::Message] The message before update.
267
307
  attr_reader :before
@@ -306,8 +346,8 @@ module Discorb
306
346
  @timestamp = Time.iso8601(data[:edited_timestamp])
307
347
  @mention_everyone = data[:mention_everyone]
308
348
  @mention_roles = data[:mention_roles].map { |r| guild.roles[r] } if data.key?(:mention_roles)
309
- @attachments = data[:attachments].map { |a| Attachment.new(a) } if data.key?(:attachments)
310
- @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.new(data: e) } : [] if data.key?(:embeds)
349
+ @attachments = data[:attachments].map { |a| Attachment.from_hash(a) } if data.key?(:attachments)
350
+ @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : [] if data.key?(:embeds)
311
351
  end
312
352
 
313
353
  def channel
@@ -343,7 +383,13 @@ module Discorb
343
383
  # @macro client_cache
344
384
  # @return [Discorb::Guild] The guild the message was sent in.
345
385
 
386
+ #
387
+ # Initialize a new instance of the UnknownDeleteBulkMessage class.
346
388
  # @private
389
+ #
390
+ # @param [Discorb::Client] client The client that instantiated the object.
391
+ # @param [Hash] data The data of the event.
392
+ #
347
393
  def initialize(client, id, data)
348
394
  @client = client
349
395
  @id = id
@@ -375,7 +421,13 @@ module Discorb
375
421
  # @macro client_cache
376
422
  # @return [Discorb::Guild] The guild the message was sent in.
377
423
 
424
+ #
425
+ # Initialize a new instance of the InviteDeleteEvent class.
378
426
  # @private
427
+ #
428
+ # @param [Discorb::Client] client The client that instantiated the object.
429
+ # @param [Hash] data The data of the event.
430
+ #
379
431
  def initialize(client, data)
380
432
  @client = client
381
433
  @data = data
@@ -393,18 +445,6 @@ module Discorb
393
445
  end
394
446
  end
395
447
 
396
- class GuildIntegrationsUpdateEvent < GatewayEvent
397
- def initialize(client, data)
398
- @client = client
399
- @data = data
400
- @guild_id = Snowflake.new(data[:guild_id])
401
- end
402
-
403
- def guild
404
- @client.guilds[@guild_id]
405
- end
406
- end
407
-
408
448
  #
409
449
  # Represents a `TYPING_START` event.
410
450
  #
@@ -428,7 +468,13 @@ module Discorb
428
468
  # @macro client_cache
429
469
  # @return [Discorb::Member, Discorb::User] The member or user that started typing.
430
470
 
471
+ #
472
+ # Initialize a new instance of the TypingStartEvent class.
431
473
  # @private
474
+ #
475
+ # @param [Discorb::Client] client The client that instantiated the object.
476
+ # @param [Hash] data The data of the event.
477
+ #
432
478
  def initialize(client, data)
433
479
  @client = client
434
480
  @data = data
@@ -505,7 +551,13 @@ module Discorb
505
551
  # @macro client_cache
506
552
  # @return [Discorb::Guild] The guild where the webhook was updated.
507
553
 
554
+ #
555
+ # Initialize a new instance of the WebhooksUpdateEvent class.
508
556
  # @private
557
+ #
558
+ # @param [Discorb::Client] client The client that instantiated the object.
559
+ # @param [Hash] data The data of the event.
560
+ #
509
561
  def initialize(client, data)
510
562
  @client = client
511
563
  @data = data
@@ -528,26 +580,28 @@ module Discorb
528
580
  module Handler
529
581
  private
530
582
 
531
- def connect_gateway(reconnect, force_close: false)
583
+ def connect_gateway(reconnect)
532
584
  if reconnect
533
585
  @log.info "Reconnecting to gateway..."
534
586
  else
535
587
  @log.info "Connecting to gateway..."
536
588
  end
537
589
  Async do
538
- if @connection
590
+ if @connection && !@connection.closed?
539
591
  Async do
540
- if force_close
541
- @connection.force_close
542
- else
543
- @connection.close
544
- end
592
+ @connection.close
545
593
  end
546
594
  end
547
595
  @http = HTTP.new(self)
548
596
  _, gateway_response = @http.request(Route.new("/gateway", "//gateway", :get)).wait
549
597
  gateway_url = gateway_response[:url]
550
- endpoint = Async::HTTP::Endpoint.parse("#{gateway_url}?v=9&encoding=json&compress=zlib-stream",
598
+ gateway_version = if @intents.to_h[:message_content].nil?
599
+ warn "message_content intent not set, using gateway version 9. You should specify `message_content` intent for preventing unexpected changes in the future."
600
+ 9
601
+ else
602
+ 10
603
+ end
604
+ endpoint = Async::HTTP::Endpoint.parse("#{gateway_url}?v=#{gateway_version}&encoding=json&compress=zlib-stream",
551
605
  alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
552
606
  begin
553
607
  @connection = Async::WebSocket::Client.connect(endpoint, headers: [["User-Agent", Discorb::USER_AGENT]], handler: RawConnection)
@@ -578,7 +632,8 @@ module Discorb
578
632
  Errno::ECONNRESET,
579
633
  IOError => e
580
634
  @log.error "Gateway connection closed accidentally: #{e.class}: #{e.message}"
581
- connect_gateway(true, force_close: true)
635
+ @connection.force_close
636
+ connect_gateway(true)
582
637
  else # should never happen
583
638
  connect_gateway(true)
584
639
  end
@@ -593,13 +648,13 @@ module Discorb
593
648
  when 4014
594
649
  raise ClientError.new("Disallowed intents were specified"), cause: nil
595
650
  when 4002, 4003, 4005, 4007
596
- raise ClientError.new(<<~EOS), cause: e
597
- Disconnected from gateway, probably due to library issues.
598
- #{e.message}
651
+ raise ClientError.new(<<~ERROR), cause: e
652
+ Disconnected from gateway, probably due to library issues.
653
+ #{e.message}
599
654
 
600
- Please report this to the library issue tracker.
601
- https://github.com/discorb-lib/discorb/issues
602
- EOS
655
+ Please report this to the library issue tracker.
656
+ https://github.com/discorb-lib/discorb/issues
657
+ ERROR
603
658
  when 1001
604
659
  @log.info "Gateway closed with code 1001, reconnecting."
605
660
  connect_gateway(true)
@@ -608,8 +663,9 @@ module Discorb
608
663
  @log.debug "#{e.message}"
609
664
  connect_gateway(false)
610
665
  end
611
- rescue => e
666
+ rescue StandardError => e
612
667
  @log.error "Discord WebSocket error: #{e.full_message}"
668
+ @connection.force_close
613
669
  connect_gateway(false)
614
670
  end
615
671
  end
@@ -622,7 +678,7 @@ module Discorb
622
678
  end
623
679
 
624
680
  def handle_gateway(payload, reconnect)
625
- Async do |task|
681
+ Async do |_task|
626
682
  data = payload[:d]
627
683
  @last_s = payload[:s] if payload[:s]
628
684
  @log.debug "Received message with opcode #{payload[:op]} from gateway:"
@@ -648,7 +704,7 @@ module Discorb
648
704
  send_gateway(2, **payload)
649
705
  end
650
706
  when 7
651
- @log.info "Received opcode 7, reconnecting"
707
+ @log.info "Received opcode 7, stopping tasks"
652
708
  @tasks.map(&:stop)
653
709
  when 9
654
710
  @log.warn "Received opcode 9, closed connection"
@@ -673,7 +729,7 @@ module Discorb
673
729
  end
674
730
 
675
731
  def handle_heartbeat
676
- Async do |task|
732
+ Async do |_task|
677
733
  interval = @heartbeat_interval
678
734
  sleep((interval / 1000.0 - 1) * rand)
679
735
  loop do
@@ -700,9 +756,7 @@ module Discorb
700
756
  @session_id = data[:session_id]
701
757
  @user = ClientUser.new(self, data[:user])
702
758
  @uncached_guilds = data[:guilds].map { |g| g[:id] }
703
- if @uncached_guilds == [] or !@intents.guilds
704
- ready
705
- end
759
+ ready if (@uncached_guilds == []) || !@intents.guilds
706
760
  dispatch(:ready)
707
761
  @tasks << handle_heartbeat
708
762
  when "GUILD_CREATE"
@@ -714,7 +768,7 @@ module Discorb
714
768
  ready
715
769
  end
716
770
  elsif @guilds.has?(data[:id])
717
- @guilds[data[:id]].send(:_set_data, data)
771
+ @guilds[data[:id]].send(:_set_data, data, true)
718
772
  dispatch(:guild_available, guild)
719
773
  else
720
774
  guild = Guild.new(self, data, true)
@@ -737,7 +791,7 @@ module Discorb
737
791
  return @log.warn "Unknown guild id #{data[:id]}, ignoring" unless (guild = @guilds.delete(data[:id]))
738
792
 
739
793
  dispatch(:guild_delete, guild)
740
- if guild.has?(:unavailable)
794
+ if data[:unavailable]
741
795
  dispatch(:guild_destroy, guild)
742
796
  else
743
797
  dispatch(:guild_leave, guild)
@@ -811,7 +865,7 @@ module Discorb
811
865
 
812
866
  if (member = thread.members[data[:id]])
813
867
  old = ThreadChannel::Member.new(self, member.instance_variable_get(:@data))
814
- member._set_data(data)
868
+ member.send(:_set_data, data)
815
869
  else
816
870
  old = nil
817
871
  member = ThreadChannel::Member.new(self, data)
@@ -898,14 +952,13 @@ module Discorb
898
952
  guild.emojis.delete(emoji)
899
953
  end
900
954
  when "GUILD_INTEGRATIONS_UPDATE"
901
- # dispatch(:guild_integrations_update, GuildIntegrationsUpdateEvent.new(self, data))
902
- # Currently not implemented
955
+ dispatch(:guild_integrations_update, @guilds[data[:guild_id]])
903
956
  when "INTEGRATION_CREATE"
904
957
  dispatch(:integration_create, Integration.new(self, data, data[:guild_id]))
905
958
  when "INTEGRATION_UPDATE"
906
959
  return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
907
960
 
908
- before = Integration.new(self, data, data[:guild_id])
961
+ integration = Integration.new(self, data, data[:guild_id])
909
962
  dispatch(:integration_update, integration)
910
963
  when "INTEGRATION_DELETE"
911
964
  return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
@@ -1091,12 +1144,12 @@ module Discorb
1091
1144
  (target_reaction = target_message.reactions.find { |r| data[:emoji][:id].nil? ? r.name == data[:emoji][:name] : r.id == data[:emoji][:id] })
1092
1145
  target_message.reactions.delete(target_reaction)
1093
1146
  end
1094
- dispatch(:reaction_remove_emoji, ReactionRemoveEmojiEvent.new(data))
1147
+ dispatch(:reaction_remove_emoji, ReactionRemoveEmojiEvent.new(self, data))
1095
1148
  when "TYPING_START"
1096
1149
  dispatch(:typing_start, TypingStartEvent.new(self, data))
1097
1150
  when "INTERACTION_CREATE"
1098
1151
  interaction = Interaction.make_interaction(self, data)
1099
- dispatch(:integration_create, interaction)
1152
+ dispatch(:interaction_create, interaction)
1100
1153
 
1101
1154
  dispatch(interaction.class.event_name, interaction)
1102
1155
  when "RESUMED"
@@ -1114,15 +1167,15 @@ module Discorb
1114
1167
  old = event.dup
1115
1168
  event.send(:_set_data, data)
1116
1169
  dispatch(:scheduled_event_update, old, event)
1117
- if old.status != event.status
1170
+ if old.status == event.status
1171
+ dispatch(:scheduled_event_edit, old, event)
1172
+ else
1118
1173
  case event.status
1119
1174
  when :active
1120
1175
  dispatch(:scheduled_event_start, event)
1121
1176
  when :completed
1122
1177
  dispatch(:scheduled_event_end, event)
1123
1178
  end
1124
- else
1125
- dispatch(:scheduled_event_edit, old, event)
1126
1179
  end
1127
1180
  when "GUILD_SCHEDULED_EVENT_DELETE"
1128
1181
  @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
@@ -1175,6 +1228,10 @@ module Discorb
1175
1228
  @closed = false
1176
1229
  end
1177
1230
 
1231
+ def inspect
1232
+ "<#{self.class.name} #{io.fileno}>"
1233
+ end
1234
+
1178
1235
  def closed?
1179
1236
  @closed
1180
1237
  end
@@ -1182,15 +1239,19 @@ module Discorb
1182
1239
  def close
1183
1240
  super
1184
1241
  @closed = true
1185
- rescue
1242
+ rescue StandardError
1186
1243
  force_close
1187
1244
  end
1188
1245
 
1189
1246
  def force_close
1190
- @framer.instance_variable_get(:@stream).close
1247
+ io.close
1191
1248
  @closed = true
1192
1249
  end
1193
1250
 
1251
+ def io
1252
+ @framer.instance_variable_get(:@stream).instance_variable_get(:@io).instance_variable_get(:@io).instance_variable_get(:@io)
1253
+ end
1254
+
1194
1255
  def parse(buffer)
1195
1256
  # noop
1196
1257
  buffer.to_s
@@ -5,7 +5,9 @@ module Discorb
5
5
  # Represents an activity for Gateway Command.
6
6
  #
7
7
  class Activity
8
- @types = {
8
+ # @private
9
+ # @return [{Symbol => Integer}] The mapping of activity types.
10
+ TYPES = {
9
11
  playing: 0,
10
12
  streaming: 1,
11
13
  listening: 2,
@@ -22,7 +24,7 @@ module Discorb
22
24
  #
23
25
  def initialize(name, type = :playing, url = nil)
24
26
  @name = name
25
- @type = self.class.types[type]
27
+ @type = TYPES[type] or raise ArgumentError, "Invalid activity type: #{type}"
26
28
  @url = url
27
29
  end
28
30
 
@@ -42,10 +44,5 @@ module Discorb
42
44
  def inspect
43
45
  "#<#{self.class} @type=#{@type}>"
44
46
  end
45
-
46
- class << self
47
- # @private
48
- attr_reader :types
49
- end
50
47
  end
51
48
  end
data/lib/discorb/guild.rb CHANGED
@@ -115,27 +115,36 @@ module Discorb
115
115
  # @!attribute [r] me
116
116
  # @return [Discorb::Member] The client's member in the guild.
117
117
 
118
- @mfa_levels = %i[none elevated].freeze
119
- @nsfw_levels = %i[default explicit safe age_restricted].freeze
120
- @verification_levels = %i[none low medium high very_high].freeze
121
- @default_message_notifications = %i[all_messages only_mentions].freeze
122
- @explicit_content_filter = %i[disabled_in_text members_without_roles all_members].freeze
118
+ # @private
119
+ # @return [Array<Symbol>] The mapping of mfa_level.
120
+ MFA_LEVELS = %i[none elevated].freeze
121
+ # @private
122
+ # @return [Array<Symbol>] The mapping of nsfw_level.
123
+ NSFW_LEVELS = %i[default explicit safe age_restricted].freeze
124
+ # @private
125
+ # @return [Array<Symbol>] The mapping of verification_level.
126
+ VERIFICATION_LEVELS = %i[none low medium high very_high].freeze
127
+ # @private
128
+ # @return [Array<Symbol>] The mapping of default_message_notifications.
129
+ DEFAULT_MESSAGE_NOTIFICATIONS = %i[all_messages only_mentions].freeze
130
+ # @private
131
+ # @return [Array<Symbol>] The mapping of explicit_content_filter.
132
+ EXPLICIT_CONTENT_FILTER = %i[disabled_in_text members_without_roles all_members].freeze
123
133
 
134
+ #
135
+ # Creates a new guild object.
124
136
  # @private
137
+ #
138
+ # @param [Discorb::Client] client The client that owns this guild.
139
+ # @param [Hash] data The data of the guild.
140
+ # @param [Boolean] is_create_event Whether the guild is created by a `GUILD_CREATE` event.
141
+ #
125
142
  def initialize(client, data, is_create_event)
126
143
  @client = client
127
144
  @data = {}
128
145
  _set_data(data, is_create_event)
129
146
  end
130
147
 
131
- # @private
132
- def update!
133
- Async do
134
- _, data = @client.get("/guilds/#{@id}").wait
135
- _set_data(data, false)
136
- end
137
- end
138
-
139
148
  def afk_channel
140
149
  @client.channels[@afk_channel_id]
141
150
  end
@@ -242,9 +251,9 @@ module Discorb
242
251
  description: description,
243
252
  scheduled_start_time: start_time.iso8601,
244
253
  scheduled_end_time: end_time&.iso8601,
245
- privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level),
254
+ privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
246
255
  channel_id: channel&.id,
247
- entity_type: Discorb::ScheduledEvent.entity_type.key(:stage_instance),
256
+ entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:stage_instance),
248
257
  }
249
258
  when :voice
250
259
  raise ArgumentError, "channel must be provided for voice events" unless channel
@@ -253,9 +262,9 @@ module Discorb
253
262
  description: description,
254
263
  scheduled_start_time: start_time.iso8601,
255
264
  scheduled_end_time: end_time&.iso8601,
256
- privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level),
265
+ privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
257
266
  channel_id: channel&.id,
258
- entity_type: Discorb::ScheduledEvent.entity_type.key(:voice),
267
+ entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:voice),
259
268
  }
260
269
  when :external
261
270
  raise ArgumentError, "location must be provided for external events" unless location
@@ -265,8 +274,8 @@ module Discorb
265
274
  description: description,
266
275
  scheduled_start_time: start_time.iso8601,
267
276
  scheduled_end_time: end_time.iso8601,
268
- privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level),
269
- entity_type: Discorb::ScheduledEvent.entity_type.key(:external),
277
+ privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
278
+ entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:external),
270
279
  entity_metadata: {
271
280
  location: location,
272
281
  },
@@ -614,7 +623,7 @@ module Discorb
614
623
  #
615
624
  def fetch_members(limit: 0, after: nil)
616
625
  Async do
617
- unless limit == 0
626
+ unless limit.zero?
618
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
619
628
  next data[:members].map { |m| Member.new(@client, @id, m[:user], m) }
620
629
  end
@@ -625,9 +634,7 @@ module Discorb
625
634
  _resp, data = @client.http.request(Route.new("/guilds/#{@id}/members?#{URI.encode_www_form(params)}", "//guilds/:guild_id/members", :get)).wait
626
635
  ret += data.map { |m| Member.new(@client, @id, m[:user], m) }
627
636
  after = data.last[:user][:id]
628
- if data.length != 1000
629
- break
630
- end
637
+ break if data.length != 1000
631
638
  end
632
639
  ret
633
640
  end
@@ -860,7 +867,7 @@ module Discorb
860
867
  def fetch_voice_regions
861
868
  Async do
862
869
  _resp, data = @client.http.request(Route.new("/guilds/#{@id}/voice", "//guilds/:guild_id/voice", :get)).wait
863
- data.map { |d| VoiceRegion.new(@client, d) }
870
+ data.map { |d| VoiceRegion.new(d) }
864
871
  end
865
872
  end
866
873
 
@@ -873,7 +880,7 @@ module Discorb
873
880
  def fetch_invites
874
881
  Async do
875
882
  _resp, data = @client.http.request(Route.new("/guilds/#{@id}/invites", "//guilds/:guild_id/invites", :get)).wait
876
- data.map { |d| Invite.new(@client, d) }
883
+ data.map { |d| Invite.new(@client, d, false) }
877
884
  end
878
885
  end
879
886
 
@@ -886,7 +893,7 @@ module Discorb
886
893
  def fetch_integrations
887
894
  Async do
888
895
  _resp, data = @client.http.request(Route.new("/guilds/#{@id}/integrations", "//guilds/:guild_id/integrations", :get)).wait
889
- data.map { |d| Integration.new(@client, d) }
896
+ data.map { |d| Integration.new(@client, d, @id) }
890
897
  end
891
898
  end
892
899
 
@@ -1014,7 +1021,14 @@ module Discorb
1014
1021
  # @!attribute [r] url
1015
1022
  # @return [String] The vanity URL.
1016
1023
 
1024
+ #
1025
+ # Initialize a new instance of the {VanityInvite} class.
1017
1026
  # @private
1027
+ #
1028
+ # @param [Discorb::Client] client The client.
1029
+ # @param [Discorb::Guild] guild The guild.
1030
+ # @param [Hash] data The data of the invite.
1031
+ #
1018
1032
  def initialize(client, guild, data)
1019
1033
  @client = client
1020
1034
  @guild = guild
@@ -1049,7 +1063,14 @@ module Discorb
1049
1063
  # @!attribute [r] json_url
1050
1064
  # @return [String] The JSON URL.
1051
1065
 
1066
+ #
1067
+ # Initialize a new instance of the {Widget} class.
1052
1068
  # @private
1069
+ #
1070
+ # @param [Discorb::Client] client The client.
1071
+ # @param [Discorb::Snowflake] guild_id The guild ID.
1072
+ # @param [Hash] data The data from Discord.
1073
+ #
1053
1074
  def initialize(client, guild_id, data)
1054
1075
  @client = client
1055
1076
  @enabled = data[:enabled]
@@ -1113,7 +1134,14 @@ module Discorb
1113
1134
  # @return [String] The reason for the ban.
1114
1135
  attr_reader :reason
1115
1136
 
1137
+ #
1138
+ # Initialize a new instance of the {Ban} class.
1116
1139
  # @private
1140
+ #
1141
+ # @param [Discorb::Client] client The client.
1142
+ # @param [Discorb::Guild] guild The guild.
1143
+ # @param [Hash] data The data from Discord.
1144
+ #
1117
1145
  def initialize(client, guild, data)
1118
1146
  @client = client
1119
1147
  @guild = guild
@@ -1123,9 +1151,6 @@ module Discorb
1123
1151
  end
1124
1152
 
1125
1153
  class << self
1126
- # @private
1127
- attr_reader :nsfw_levels, :mfa_levels, :verification_levels, :default_message_notifications, :explicit_content_filter
1128
-
1129
1154
  #
1130
1155
  # Returns a banner url from the guild's ID.
1131
1156
  #
@@ -1152,9 +1177,9 @@ module Discorb
1152
1177
  @unavailable = false
1153
1178
  @name = data[:name]
1154
1179
  @members = Discorb::Dictionary.new
1155
- data[:members].each do |m|
1180
+ data[:members]&.each do |m|
1156
1181
  Member.new(@client, @id, m[:user], m)
1157
- end if data[:members]
1182
+ end
1158
1183
  @splash = data[:splash] && Asset.new(self, data[:splash], path: "splashes/#{@id}")
1159
1184
  @discovery_splash = data[:discovery_splash] && Asset.new(self, data[:discovery_splash], path: "discovery-splashes/#{@id}")
1160
1185
  @owner_id = data[:owner_id]
@@ -1172,10 +1197,10 @@ module Discorb
1172
1197
  @emojis[e[:id]] = CustomEmoji.new(@client, self, e)
1173
1198
  end
1174
1199
  @features = data[:features].map { |f| f.downcase.to_sym }
1175
- @mfa_level = self.class.mfa_levels[data[:mfa_level]]
1176
- @verification_level = self.class.verification_levels[data[:verification_level]]
1177
- @default_message_notifications = self.class.default_message_notifications[data[:default_message_notifications]]
1178
- @explicit_content_filter = self.class.explicit_content_filter[data[:explicit_content_filter]]
1200
+ @mfa_level = MFA_LEVELS[data[:mfa_level]]
1201
+ @verification_level = VERIFICATION_LEVELS[data[:verification_level]]
1202
+ @default_message_notifications = DEFAULT_MESSAGE_NOTIFICATIONS[data[:default_message_notifications]]
1203
+ @explicit_content_filter = EXPLICIT_CONTENT_FILTER[data[:explicit_content_filter]]
1179
1204
  @system_channel_id = data[:system_channel_id]
1180
1205
  @system_channel_flag = SystemChannelFlag.new(0b111 - data[:system_channel_flags])
1181
1206
  @rules_channel_id = data[:rules_channel_id]
@@ -1190,7 +1215,7 @@ module Discorb
1190
1215
  @approximate_member_count = data[:approximate_member_count]
1191
1216
  @approximate_presence_count = data[:approximate_presence_count]
1192
1217
  @welcome_screen = data[:welcome_screen].nil? ? nil : WelcomeScreen.new(@client, self, data[:welcome_screen])
1193
- @nsfw_level = self.class.nsfw_levels[data[:nsfw_level]]
1218
+ @nsfw_level = NSFW_LEVELS[data[:nsfw_level]]
1194
1219
  return unless is_create_event
1195
1220
 
1196
1221
  @stickers = data[:stickers].nil? ? [] : data[:stickers].map { |s| Sticker::GuildSticker.new(self, s) }
@@ -1200,13 +1225,13 @@ module Discorb
1200
1225
  tmp_channels = data[:channels].filter { |c| !c.key?(:thread_metadata) }.map do |c|
1201
1226
  Channel.make_channel(@client, c.merge({ guild_id: @id }))
1202
1227
  end
1203
- @channels = Dictionary.new(tmp_channels.map { |c| [c.id, c] }.to_h, sort: ->(c) { c[1].position })
1204
- @voice_states = Dictionary.new(data[:voice_states].map { |v| [Snowflake.new(v[:user_id]), VoiceState.new(@client, v.merge({ guild_id: @id }))] }.to_h)
1228
+ @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 }))] })
1205
1230
  @threads = data[:threads] ? data[:threads].map { |t| Channel.make_channel(@client, t) } : []
1206
- @presences = Dictionary.new(data[:presences].map { |pr| [Snowflake.new(pr[:user][:id]), Presence.new(@client, pr)] }.to_h)
1231
+ @presences = Dictionary.new(data[:presences].to_h { |pr| [Snowflake.new(pr[:user][:id]), Presence.new(@client, pr)] })
1207
1232
  @max_presences = data[:max_presences]
1208
- @stage_instances = Dictionary.new(data[:stage_instances].map { |s| [Snowflake.new(s[:id]), StageInstance.new(@client, s)] }.to_h)
1209
- @scheduled_events = Dictionary.new(data[:guild_scheduled_events].map { |s| [Snowflake.new(s[:id]), ScheduledEvent.new(@client, s)] }.to_h)
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)] })
1210
1235
  @data.update(data)
1211
1236
  end
1212
1237
  end
@@ -1241,7 +1266,14 @@ module Discorb
1241
1266
  # @return [Discorb::Guild] The guild the welcome screen belongs to.
1242
1267
  attr_reader :guild
1243
1268
 
1269
+ #
1270
+ # Initializes the welcome screen.
1244
1271
  # @private
1272
+ #
1273
+ # @param [Discorb::Client] client The client.
1274
+ # @param [Discorb::Guild] guild The guild the welcome screen belongs to.
1275
+ # @param [Hash] data The data of the welcome screen.
1276
+ #
1245
1277
  def initialize(client, guild, data)
1246
1278
  @client = client
1247
1279
  @description = data[:description]