discorb 0.17.1 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/lint.yml +1 -3
  3. data/.github/workflows/validate.yml +21 -0
  4. data/Changelog.md +10 -0
  5. data/Gemfile +6 -0
  6. data/Rakefile +210 -98
  7. data/Steepfile +28 -0
  8. data/docs/events.md +42 -6
  9. data/docs/tutorial.md +7 -7
  10. data/docs/voice_events.md +2 -2
  11. data/examples/commands/message.rb +12 -7
  12. data/examples/commands/permission.rb +2 -1
  13. data/examples/commands/slash.rb +23 -19
  14. data/examples/commands/user.rb +15 -12
  15. data/examples/components/authorization_button.rb +2 -1
  16. data/examples/components/select_menu.rb +4 -1
  17. data/examples/extension/main.rb +1 -0
  18. data/examples/extension/message_expander.rb +1 -0
  19. data/examples/sig/commands/message.rbs +5 -0
  20. data/examples/simple/eval.rb +1 -0
  21. data/examples/simple/ping_pong.rb +1 -0
  22. data/examples/simple/rolepanel.rb +16 -5
  23. data/examples/simple/shard.rb +2 -1
  24. data/examples/simple/wait_for_message.rb +3 -0
  25. data/exe/discorb +3 -3
  26. data/lib/discorb/allowed_mentions.rb +1 -1
  27. data/lib/discorb/app_command/command.rb +12 -13
  28. data/lib/discorb/app_command/handler.rb +20 -6
  29. data/lib/discorb/audit_logs.rb +6 -2
  30. data/lib/discorb/automod.rb +269 -0
  31. data/lib/discorb/channel/guild.rb +2 -1
  32. data/lib/discorb/channel/stage.rb +1 -1
  33. data/lib/discorb/channel/text.rb +11 -20
  34. data/lib/discorb/channel/thread.rb +15 -11
  35. data/lib/discorb/client.rb +12 -10
  36. data/lib/discorb/color.rb +37 -60
  37. data/lib/discorb/common.rb +1 -1
  38. data/lib/discorb/dictionary.rb +1 -1
  39. data/lib/discorb/embed.rb +4 -3
  40. data/lib/discorb/emoji.rb +2 -2
  41. data/lib/discorb/exe/about.rb +1 -1
  42. data/lib/discorb/exe/new.rb +1 -5
  43. data/lib/discorb/extension.rb +0 -4
  44. data/lib/discorb/flag.rb +2 -2
  45. data/lib/discorb/gateway.rb +21 -582
  46. data/lib/discorb/gateway_events.rb +638 -0
  47. data/lib/discorb/guild.rb +136 -17
  48. data/lib/discorb/guild_template.rb +1 -1
  49. data/lib/discorb/http.rb +47 -25
  50. data/lib/discorb/intents.rb +27 -18
  51. data/lib/discorb/interaction/command.rb +14 -10
  52. data/lib/discorb/interaction/response.rb +74 -14
  53. data/lib/discorb/member.rb +3 -3
  54. data/lib/discorb/message.rb +13 -11
  55. data/lib/discorb/message_meta.rb +2 -3
  56. data/lib/discorb/modules.rb +3 -2
  57. data/lib/discorb/presence.rb +4 -2
  58. data/lib/discorb/reaction.rb +2 -2
  59. data/lib/discorb/role.rb +1 -1
  60. data/lib/discorb/sticker.rb +3 -3
  61. data/lib/discorb/user.rb +2 -2
  62. data/lib/discorb/voice_state.rb +5 -5
  63. data/lib/discorb/webhook.rb +15 -6
  64. data/lib/discorb.rb +2 -2
  65. data/rbs_collection.lock.yaml +88 -96
  66. data/rbs_collection.yaml +21 -17
  67. data/sig/async.rbs +11 -5
  68. data/sig/discorb/activity.rbs +23 -0
  69. data/sig/discorb/allowed_mentions.rbs +44 -0
  70. data/sig/discorb/app_command/base.rbs +282 -0
  71. data/sig/discorb/app_command/handler.rbs +171 -0
  72. data/sig/discorb/application.rbs +142 -0
  73. data/sig/discorb/asset.rbs +32 -0
  74. data/sig/discorb/attachment.rbs +91 -0
  75. data/sig/discorb/audit_log.rbs +231 -0
  76. data/sig/discorb/automod.rbs +128 -0
  77. data/sig/discorb/avatar.rbs +26 -0
  78. data/sig/discorb/channel/base.rbs +179 -0
  79. data/sig/discorb/channel/category.rbs +56 -0
  80. data/sig/discorb/channel/container.rbs +29 -0
  81. data/sig/discorb/channel/dm.rbs +14 -0
  82. data/sig/discorb/channel/news.rbs +20 -0
  83. data/sig/discorb/channel/stage.rbs +77 -0
  84. data/sig/discorb/channel/text.rbs +158 -0
  85. data/sig/discorb/channel/thread.rbs +185 -0
  86. data/sig/discorb/channel/voice.rbs +41 -0
  87. data/sig/discorb/client.rbs +2495 -0
  88. data/sig/discorb/color.rbs +142 -0
  89. data/sig/discorb/component/base.rbs +28 -0
  90. data/sig/discorb/component/button.rbs +65 -0
  91. data/sig/discorb/component/select_menu.rbs +107 -0
  92. data/sig/discorb/component/text_input.rbs +69 -0
  93. data/sig/discorb/connectable.rbs +8 -0
  94. data/sig/discorb/custom_emoji.rbs +90 -0
  95. data/sig/discorb/dictionary.rbs +85 -0
  96. data/sig/discorb/discord_model.rbs +15 -0
  97. data/sig/discorb/embed.rbs +279 -0
  98. data/sig/discorb/emoji.rbs +13 -0
  99. data/sig/discorb/error.rbs +73 -0
  100. data/sig/discorb/event_handler.rbs +27 -0
  101. data/sig/discorb/extension.rbs +1734 -0
  102. data/sig/discorb/flag.rbs +72 -0
  103. data/sig/discorb/gateway.rbs +481 -0
  104. data/sig/discorb/guild.rbs +870 -0
  105. data/sig/discorb/guild_template.rbs +174 -0
  106. data/sig/discorb/http.rbs +147 -0
  107. data/sig/discorb/image.rbs +20 -0
  108. data/sig/discorb/integration.rbs +118 -0
  109. data/sig/discorb/intents.rbs +97 -0
  110. data/sig/discorb/interaction/autocomplete.rbs +9 -0
  111. data/sig/discorb/interaction/base.rbs +66 -0
  112. data/sig/discorb/interaction/command.rbs +66 -0
  113. data/sig/discorb/interaction/message_component.rbs +140 -0
  114. data/sig/discorb/interaction/modal.rbs +50 -0
  115. data/sig/discorb/interaction/responder.rbs +157 -0
  116. data/sig/discorb/invite.rbs +86 -0
  117. data/sig/discorb/member.rbs +187 -0
  118. data/sig/discorb/message.rbs +469 -0
  119. data/sig/discorb/messageable.rbs +153 -0
  120. data/sig/discorb/partial_emoji.rbs +35 -0
  121. data/sig/discorb/permissions.rbs +149 -0
  122. data/sig/discorb/presence.rbs +237 -0
  123. data/sig/discorb/reaction.rbs +33 -0
  124. data/sig/discorb/role.rbs +145 -0
  125. data/sig/discorb/scheduled_event.rbs +148 -0
  126. data/sig/discorb/shard.rbs +62 -0
  127. data/sig/discorb/snowflake.rbs +56 -0
  128. data/sig/discorb/stage_instance.rbs +63 -0
  129. data/sig/discorb/sticker.rbs +116 -0
  130. data/sig/discorb/system_channel_flag.rbs +17 -0
  131. data/sig/discorb/unicode_emoji.rbs +49 -0
  132. data/sig/discorb/user.rbs +93 -0
  133. data/sig/discorb/utils.rbs +8 -0
  134. data/sig/discorb/voice_region.rbs +30 -0
  135. data/sig/discorb/voice_state.rbs +71 -0
  136. data/sig/discorb/webhook.rbs +327 -0
  137. data/sig/discorb/welcome_screen.rbs +78 -0
  138. data/sig/discorb.rbs +5 -8661
  139. data/sig/manifest.yaml +3 -0
  140. data/sig/override.rbs +19 -0
  141. metadata +80 -3
data/lib/discorb/guild.rb CHANGED
@@ -226,9 +226,6 @@ module Discorb
226
226
  :get
227
227
  )
228
228
  ).wait
229
- rescue Discorb::NotFoundError
230
- return nil
231
- else
232
229
  ScheduledEvent.new(@client, event)
233
230
  end
234
231
  end
@@ -343,9 +340,16 @@ module Discorb
343
340
  # @return [Async::Task<Discorb::CustomEmoji>] The emoji with the given id.
344
341
  #
345
342
  def fetch_emoji(id)
346
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/emojis/#{id}",
347
- "//guilds/:guild_id/emojis/:emoji_id", :get)).wait
348
- @emojis[e[:id]] = CustomEmoji.new(@client, self, data)
343
+ Async do
344
+ _resp, data = @client.http.request(
345
+ Route.new(
346
+ "/guilds/#{@id}/emojis/#{id}",
347
+ "//guilds/:guild_id/emojis/:emoji_id",
348
+ :get
349
+ )
350
+ ).wait
351
+ @emojis[e[:id]] = CustomEmoji.new(@client, self, data)
352
+ end
349
353
  end
350
354
 
351
355
  #
@@ -359,13 +363,17 @@ module Discorb
359
363
  # @return [Async::Task<Discorb::CustomEmoji>] The created emoji.
360
364
  #
361
365
  def create_emoji(name, image, roles: [])
362
- _resp, data = @client.http.request(Route.new("/guilds/#{@id}/emojis", "//guilds/:guild_id/emojis", :post),
363
- {
364
- name: name,
365
- image: image.to_s,
366
- roles: roles.map { |r| Discorb::Utils.try(r, :id) },
367
- }).wait
368
- @emojis[data[:id]] = CustomEmoji.new(@client, self, data)
366
+ Async do
367
+ _resp, data = @client.http.request(
368
+ Route.new("/guilds/#{@id}/emojis", "//guilds/:guild_id/emojis", :post),
369
+ {
370
+ name: name,
371
+ image: image.to_s,
372
+ roles: roles.map { |r| Discorb::Utils.try(r, :id) },
373
+ }
374
+ ).wait
375
+ @emojis[data[:id]] = CustomEmoji.new(@client, self, data)
376
+ end
369
377
  end
370
378
 
371
379
  #
@@ -378,7 +386,7 @@ module Discorb
378
386
  Async do
379
387
  _resp, data = @client.http.request(Route.new("/guilds/#{@id}/webhooks", "//guilds/:guild_id/webhooks",
380
388
  :get)).wait
381
- data.map { |webhook| Webhook.new([@client, webhook]) }
389
+ data.map { |webhook| Webhook.from_data(@client, webhook) }
382
390
  end
383
391
  end
384
392
 
@@ -698,7 +706,7 @@ module Discorb
698
706
  "//guilds/:guild_id/members", :get)).wait
699
707
  ret += data.map { |m| Member.new(@client, @id, m[:user], m) }
700
708
  after = data.last[:user][:id]
701
- break if data.length != 1000
709
+ break if data.length != 100
702
710
  end
703
711
  ret
704
712
  end
@@ -1122,6 +1130,100 @@ module Discorb
1122
1130
  end
1123
1131
  end
1124
1132
 
1133
+ #
1134
+ # Fetch the automod rules in the guild.
1135
+ # @async
1136
+ #
1137
+ # @return [Async::Task<Array<Discorb::AutoModRule>>] The automod rules.
1138
+ #
1139
+ def fetch_automod_rules
1140
+ Async do
1141
+ _resp, data = @client.http.request(
1142
+ Route.new("/guilds/#{@id}/auto-moderation/rules", "//guilds/:guild_id/auto-moderation/rules", :get)
1143
+ )
1144
+ data.map { |d| AutoModRule.new(@client, d) }
1145
+ end
1146
+ end
1147
+
1148
+ alias fetch_automod_rule_list fetch_automod_rules
1149
+
1150
+ #
1151
+ # Fetch the automod rule by ID.
1152
+ #
1153
+ # @param [#to_s] id The ID of the automod rule.
1154
+ #
1155
+ # @return [Async::Task<Array<Discord::AutoModRule>>] The automod rule.
1156
+ #
1157
+ def fetch_automod_rule(id)
1158
+ Async do
1159
+ _resp, data = @client.http.request(
1160
+ Route.new(
1161
+ "/guilds/#{@id}/auto-moderation/rules/#{id}",
1162
+ "//guilds/:guild_id/auto-moderation/rules/:rule_id",
1163
+ :get
1164
+ )
1165
+ ).wait
1166
+ AutoModRule.new(@client, data)
1167
+ end
1168
+ end
1169
+
1170
+ #
1171
+ # Create a new automod rule in the guild.
1172
+ # @async
1173
+ #
1174
+ # @param [String] name The name of the rule.
1175
+ # @param [Symbol] trigger_type The trigger type of the rule. See {Discorb::AutoModRule::TRIGGER_TYPES}.
1176
+ # @param [Array<Discorb::AutoModRule::Action>] actions The actions of the rule.
1177
+ # @param [Symbol] event_type The event type of the rule. See {Discorb::AutoModRule::EVENT_TYPES}.
1178
+ # @param [Boolean] enabled Whether the rule is enabled or not.
1179
+ # @param [Array<Discorb::Role>] exempt_roles The roles that are exempt from the rule.
1180
+ # @param [Array<Discorb::Channel>] exempt_channels The channels that are exempt from the rule.
1181
+ # @param [Array<String>] keyword_filter The keywords to filter.
1182
+ # @param [Symbol] presets The preset of the rule. See {Discorb::AutoModRule::PRESET_TYPES}.
1183
+ # @param [String] reason The reason for creating the rule.
1184
+ #
1185
+ # @return [Async::Task<Discorb::AutoModRule>] The automod rule.
1186
+ #
1187
+ def create_automod_rule(
1188
+ name,
1189
+ trigger_type,
1190
+ actions,
1191
+ event_type = :send_message,
1192
+ enabled: false,
1193
+ exempt_roles: [],
1194
+ exempt_channels: [],
1195
+ keyword_filter: nil,
1196
+ presets: nil,
1197
+ reason: nil
1198
+ )
1199
+ Async do
1200
+ payload = {
1201
+ name: name,
1202
+ event_type: Discorb::AutoModRule::EVENT_TYPES.key(event_type),
1203
+ trigger_type: Discorb::AutoModRule::TRIGGER_TYPES.key(trigger_type),
1204
+ metadata: {
1205
+ keyword_filter: keyword_filter,
1206
+ presets: Discorb::AutoModRule::PRESET_TYPES.key(presets),
1207
+ },
1208
+ actions: actions.map(&:to_hash),
1209
+ enabled: enabled,
1210
+ exempt_roles: exempt_roles.map(&:id),
1211
+ exempt_channels: exempt_channels.map(&:id),
1212
+ }
1213
+
1214
+ _resp, data = @client.http.request(
1215
+ Route.new(
1216
+ "/guilds/#{@id}/auto-moderation/rules",
1217
+ "//guilds/:guild_id/auto-moderation/rules",
1218
+ :post
1219
+ ),
1220
+ payload,
1221
+ audit_log_reason: reason
1222
+ )
1223
+ Discorb::AutoModRule.new(@client, data)
1224
+ end
1225
+ end
1226
+
1125
1227
  #
1126
1228
  # Represents a vanity invite.
1127
1229
  #
@@ -1339,7 +1441,7 @@ module Discorb
1339
1441
  @nsfw_level = NSFW_LEVELS[data[:nsfw_level]]
1340
1442
  return unless is_create_event
1341
1443
 
1342
- @stickers = data[:stickers].nil? ? [] : data[:stickers].map { |s| Sticker::GuildSticker.new(self, s) }
1444
+ @stickers = data[:stickers].nil? ? [] : data[:stickers].map { |s| Sticker::GuildSticker.new(@client, s) }
1343
1445
  @joined_at = Time.iso8601(data[:joined_at])
1344
1446
  @large = data[:large]
1345
1447
  @member_count = data[:member_count]
@@ -1407,7 +1509,24 @@ module Discorb
1407
1509
  @client = client
1408
1510
  @description = data[:description]
1409
1511
  @guild = guild
1410
- @channels = data[:channels].map { |c| WelcomeScreen::Channel.new(client, c, nil) }
1512
+ @channels = data[:channels].map do |c|
1513
+ WelcomeScreen::Channel.new(
1514
+ client.channels[c[:channel_id]],
1515
+ c,
1516
+ c[:emoji_name] &&
1517
+ if c[:emoji_id]
1518
+ (client.emojis[c[:emoji_id]] ||
1519
+ Discorb::PartialEmoji.new(
1520
+ {
1521
+ name: c[:emoji_name],
1522
+ id: c[:emoji_id],
1523
+ }
1524
+ ))
1525
+ else
1526
+ Discorb::UnicodeEmoji.new(c[:emoji_name])
1527
+ end
1528
+ )
1529
+ end
1411
1530
  end
1412
1531
 
1413
1532
  #
@@ -19,7 +19,7 @@ module Discorb
19
19
  attr_reader :created_at
20
20
  # @return [Time] The time this template was last updated.
21
21
  attr_reader :updated_at
22
- # @return [Discorb::Guild] The guild where the template was created.
22
+ # @return [Discorb::Snowflake] The ID of guild where the template was created.
23
23
  attr_reader :source_guild_id
24
24
  # @return [Discorb::GuildTemplate::TemplateGuild] The guild where the template was created.
25
25
  attr_reader :serialized_source_guild
data/lib/discorb/http.rb CHANGED
@@ -27,7 +27,6 @@ module Discorb
27
27
  #
28
28
  # @param [Discorb::Route] path The path to the resource.
29
29
  # @param [String, Hash] body The body of the request. Defaults to an empty string.
30
- # @param [Hash] headers The headers to send with the request.
31
30
  # @param [String] audit_log_reason The audit log reason to send with the request.
32
31
  # @param [Hash] kwargs The keyword arguments.
33
32
  #
@@ -36,18 +35,28 @@ module Discorb
36
35
  #
37
36
  # @raise [Discorb::HTTPError] The request was failed.
38
37
  #
39
- def request(path, body = "", headers: nil, audit_log_reason: nil, **kwargs)
38
+ def request(path, body = "", audit_log_reason: nil, **kwargs)
40
39
  Async do |_task|
41
40
  @ratelimit_handler.wait(path)
42
41
  resp = if %i[post patch put].include? path.method
43
- http.send(path.method, get_path(path), get_body(body), get_headers(headers, body, audit_log_reason),
44
- **kwargs)
42
+ http.send(
43
+ path.method,
44
+ get_path(path),
45
+ get_body(body),
46
+ get_headers(body, audit_log_reason),
47
+ **kwargs,
48
+ )
45
49
  else
46
- http.send(path.method, get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
50
+ http.send(
51
+ path.method,
52
+ get_path(path),
53
+ get_headers(body, audit_log_reason),
54
+ **kwargs,
55
+ )
47
56
  end
48
57
  data = get_response_data(resp)
49
58
  @ratelimit_handler.save(path, resp)
50
- handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
59
+ handle_response(resp, data, path, body, nil, audit_log_reason, kwargs)
51
60
  end
52
61
  end
53
62
 
@@ -58,7 +67,6 @@ module Discorb
58
67
  # @param [Discorb::Route] path The path to the resource.
59
68
  # @param [String, Hash] body The body of the request.
60
69
  # @param [Array<Discorb::Attachment>] files The files to upload.
61
- # @param [Hash] headers The headers to send with the request.
62
70
  # @param [String] audit_log_reason The audit log reason to send with the request.
63
71
  # @param [Hash] kwargs The keyword arguments.
64
72
  #
@@ -67,14 +75,15 @@ module Discorb
67
75
  #
68
76
  # @raise [Discorb::HTTPError] The request was failed.
69
77
  #
70
- def multipart_request(path, body, files, headers: nil, audit_log_reason: nil, **kwargs)
78
+ def multipart_request(path, body, files, audit_log_reason: nil, **kwargs)
71
79
  Async do |_task|
72
80
  @ratelimit_handler.wait(path)
73
81
  req = Net::HTTP.const_get(path.method.to_s.capitalize).new(
74
82
  get_path(path),
75
- get_headers(headers, body, audit_log_reason),
83
+ get_headers(body, audit_log_reason),
76
84
  **kwargs,
77
85
  )
86
+ # @type var data: Array[untyped]
78
87
  data = [
79
88
  ["payload_json", get_body(body)],
80
89
  ]
@@ -83,10 +92,13 @@ module Discorb
83
92
 
84
93
  if file.created_by == :discord
85
94
  request_io = StringIO.new(
86
- cdn_http.get(URI.parse(file.url).path, {
87
- "Content-Type" => nil,
88
- "User-Agent" => Discorb::USER_AGENT,
89
- }).body
95
+ cdn_http.get(
96
+ (URI.parse(file.url).path || raise("Could not parse url")),
97
+ {
98
+ "Content-Type" => nil,
99
+ "User-Agent" => Discorb::USER_AGENT,
100
+ }
101
+ ).body
90
102
  )
91
103
  data << ["files[#{i}]", request_io, { filename: file.filename, content_type: file.content_type }]
92
104
  else
@@ -97,10 +109,11 @@ module Discorb
97
109
  session = Net::HTTP.new("discord.com", 443)
98
110
  session.use_ssl = true
99
111
  resp = session.request(req)
100
- files&.then { _1.filter(&:will_close).each { |f| f.io.close } }
101
- data = get_response_data(resp)
112
+ resp_data = get_response_data(resp)
102
113
  @ratelimit_handler.save(path, resp)
103
- handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
114
+ response = handle_response(resp, resp_data, path, body, files, audit_log_reason, kwargs)
115
+ files&.then { _1.filter(&:will_close).each { |f| f.io.close } }
116
+ response
104
117
  end
105
118
  end
106
119
 
@@ -110,12 +123,16 @@ module Discorb
110
123
 
111
124
  private
112
125
 
113
- def handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
126
+ def handle_response(resp, data, path, body, files, audit_log_reason, kwargs)
114
127
  case resp.code
115
128
  when "429"
116
129
  @client.logger.info("Rate limit exceeded for #{path.method} #{path.url}, waiting #{data[:retry_after]} seconds")
117
130
  sleep(data[:retry_after])
118
- request(path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
131
+ if files
132
+ multipart_request(path, body, files, audit_log_reason: audit_log_reason, **kwargs).wait
133
+ else
134
+ request(path, body, audit_log_reason: audit_log_reason, **kwargs).wait
135
+ end
119
136
  when "400"
120
137
  raise BadRequestError.new(resp, data)
121
138
  when "401"
@@ -129,14 +146,19 @@ module Discorb
129
146
  end
130
147
  end
131
148
 
132
- def get_headers(headers, body = "", audit_log_reason = nil)
149
+ def get_headers(body = "", audit_log_reason = nil)
133
150
  ret = if body.nil? || body == ""
134
- { "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}" }
151
+ {
152
+ "User-Agent" => USER_AGENT,
153
+ "authorization" => "Bot #{@client.token}",
154
+ }
135
155
  else
136
- { "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}",
137
- "content-type" => "application/json", }
156
+ {
157
+ "User-Agent" => USER_AGENT,
158
+ "authorization" => "Bot #{@client.token}",
159
+ "content-type" => "application/json",
160
+ }
138
161
  end
139
- ret.merge!(headers) if !headers.nil? && headers.length.positive?
140
162
  ret["X-Audit-Log-Reason"] = audit_log_reason unless audit_log_reason.nil?
141
163
  ret
142
164
  end
@@ -153,7 +175,7 @@ module Discorb
153
175
 
154
176
  def get_path(path)
155
177
  full_path = if path.url.start_with?("https://")
156
- path.url
178
+ path.url
157
179
  else
158
180
  API_BASE_URL + path.url
159
181
  end
@@ -166,7 +188,7 @@ module Discorb
166
188
  data = JSON.parse(resp.body, symbolize_names: true)
167
189
  rescue JSON::ParserError, TypeError
168
190
  data = if resp.body.nil? || resp.body.empty?
169
- nil
191
+ {}
170
192
  else
171
193
  resp.body
172
194
  end
@@ -23,6 +23,8 @@ module Discorb
23
23
  dm_typing: 1 << 14,
24
24
  message_content: 1 << 15,
25
25
  scheduled_events: 1 << 16,
26
+ automod_configuration: 1 << 20,
27
+ automod_execution: 1 << 21,
26
28
  }.freeze
27
29
 
28
30
  #
@@ -44,29 +46,34 @@ module Discorb
44
46
  # @param dm_typing [Boolean] Whether dm typing related events are enabled.
45
47
  # @param message_content [Boolean] Whether message content will be sent with events.
46
48
  # @param scheduled_events [Boolean] Whether events related scheduled events are enabled.
47
- #
49
+ # @param automod_configuration [Boolean] Whether automod configuration related events are enabled.
50
+ # @param automod_execution [Boolean] Whether automod execution related events are enabled.
48
51
  # @note You must enable privileged intents to use `members` and/or `presences` intents.
49
52
  # @note Message Content Intent is not required to use `message_content` intents for now,
50
53
  # this will be required in September 1, 2022. [Learn More](https://support-dev.discord.com/hc/en-us/articles/4404772028055).
51
54
  # You should specify `message_content` intent for preventing unexpected changes in the future.
52
55
  #
53
- def initialize(guilds: true,
54
- members: false,
55
- bans: true,
56
- emojis: true,
57
- integrations: true,
58
- webhooks: true,
59
- invites: true,
60
- voice_states: true,
61
- presences: false,
62
- messages: true,
63
- reactions: true,
64
- typing: true,
65
- dm_messages: true,
66
- dm_reactions: true,
67
- dm_typing: true,
68
- message_content: nil,
69
- scheduled_events: true)
56
+ def initialize(
57
+ guilds: true,
58
+ members: false,
59
+ bans: true,
60
+ emojis: true,
61
+ integrations: true,
62
+ webhooks: true,
63
+ invites: true,
64
+ voice_states: true,
65
+ presences: false,
66
+ messages: true,
67
+ reactions: true,
68
+ typing: true,
69
+ dm_messages: true,
70
+ dm_reactions: true,
71
+ dm_typing: true,
72
+ message_content: nil,
73
+ scheduled_events: true,
74
+ automod_configuration: true,
75
+ automod_execution: true
76
+ )
70
77
  @raw_value = {
71
78
  guilds: guilds,
72
79
  members: members,
@@ -85,6 +92,8 @@ module Discorb
85
92
  dm_typing: dm_typing,
86
93
  message_content: message_content,
87
94
  scheduled_events: scheduled_events,
95
+ automod_configuration: automod_configuration,
96
+ automod_execution: automod_execution,
88
97
  }
89
98
  end
90
99
 
@@ -83,21 +83,25 @@ module Discorb
83
83
  when 3, 4, 5, 10
84
84
  option[:value]
85
85
  when 6
86
- members[option[:value]] || guild.members[option[:value]] || guild.fetch_member(option[:value]).wait
86
+ members[option[:value]] || guild && (guild.members[option[:value]] ||
87
+ guild.fetch_member(option[:value]).wait)
87
88
  when 7
88
- guild.channels[option[:value]] || guild.fetch_channels.wait.find do |channel|
89
- channel.id == option[:value]
89
+ if guild
90
+ guild.channels[option[:value]] || guild.fetch_channels.wait.find do |channel|
91
+ channel.id == option[:value]
92
+ end
90
93
  end
91
94
  when 8
92
- guild.roles[option[:value]] || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
95
+ guild && (guild.roles[option[:value]] ||
96
+ guild.fetch_roles.wait.find { |role| role.id == option[:value] })
93
97
  when 9
94
98
  members[option[:value]] ||
95
- guild.members[option[:value]] ||
96
- guild.roles[option[:value]] ||
97
- guild.fetch_member(option[:value]).wait ||
98
- guild.fetch_roles.wait.find do |role|
99
- role.id == option[:value]
100
- end
99
+ guild && (guild.members[option[:value]] ||
100
+ guild.roles[option[:value]] ||
101
+ guild.fetch_member(option[:value]).wait ||
102
+ guild.fetch_roles.wait.find do |role|
103
+ role.id == option[:value]
104
+ end)
101
105
  when 11
102
106
  attachments[option[:value]]
103
107
  end
@@ -9,6 +9,8 @@ module Discorb
9
9
  # A module for response with source.
10
10
  #
11
11
  module SourceResponder
12
+ # @type instance: Discorb::Interaction
13
+
12
14
  #
13
15
  # Response with `DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE`(`5`).
14
16
  #
@@ -46,6 +48,8 @@ module Discorb
46
48
  # @param [Discorb::Embed] embed The embed to send.
47
49
  # @param [Array<Discorb::Embed>] embeds The embeds to send. (max: 10)
48
50
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
51
+ # @param [Discorb::Attachment] attachment The attachment to send.
52
+ # @param [Array<Discorb::Attachment>] attachments The attachments to send. (max: 10)
49
53
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
50
54
  # @param [Boolean] ephemeral Whether to make the response ephemeral.
51
55
  #
@@ -58,6 +62,8 @@ module Discorb
58
62
  embed: nil,
59
63
  embeds: nil,
60
64
  allowed_mentions: nil,
65
+ attachment: nil,
66
+ attachments: nil,
61
67
  components: nil,
62
68
  ephemeral: false
63
69
  )
@@ -70,23 +76,48 @@ module Discorb
70
76
  allowed_mentions&.to_hash(@client.allowed_mentions) || @client.allowed_mentions.to_hash
71
77
  payload[:components] = Component.to_payload(components) if components
72
78
  payload[:flags] = (ephemeral ? 1 << 6 : 0)
79
+ attachments ||= attachment ? [attachment] : []
80
+
81
+ payload[:attachments] = attachments.map.with_index do |a, i|
82
+ {
83
+ id: i,
84
+ filename: a.filename,
85
+ description: a.description,
86
+ }
87
+ end
73
88
 
74
89
  ret = if @responded
75
- _resp, data = @client.http.request(
76
- Route.new("/webhooks/#{@application_id}/#{@token}", "//webhooks/:webhook_id/:token", :post), payload
90
+ _resp, data = @client.http.multipart_request(
91
+ Route.new(
92
+ "/webhooks/#{@application_id}/#{@token}",
93
+ "//webhooks/:webhook_id/:token",
94
+ :post
95
+ ),
96
+ payload,
97
+ attachments
77
98
  ).wait
78
99
  webhook = Webhook::URLWebhook.new("/webhooks/#{@application_id}/#{@token}")
79
100
  Webhook::Message.new(webhook, data, @client)
80
101
  elsif @defered
81
- @client.http.request(
82
- Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original",
83
- "//webhooks/:webhook_id/:token/messages/@original", :patch), payload
102
+ @client.http.multipart_request(
103
+ Route.new(
104
+ "/webhooks/#{@application_id}/#{@token}/messages/@original",
105
+ "//webhooks/:webhook_id/:token/messages/@original",
106
+ :patch
107
+ ),
108
+ payload,
109
+ attachments
84
110
  ).wait
85
111
  CallbackMessage.new(@client, payload, @application_id, @token)
86
112
  else
87
- @client.http.request(
88
- Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback",
89
- :post), { type: 4, data: payload }
113
+ @client.http.multipart_request(
114
+ Route.new(
115
+ "/interactions/#{@id}/#{@token}/callback",
116
+ "//interactions/:interaction_id/:token/callback",
117
+ :post
118
+ ),
119
+ { type: 4, data: payload },
120
+ attachments
90
121
  ).wait
91
122
  CallbackMessage.new(@client, payload, @application_id, @token)
92
123
  end
@@ -144,8 +175,13 @@ module Discorb
144
175
  files = [file] if file != Discorb::Unset
145
176
  files = [] if files == Discorb::Unset
146
177
  @client.http.multipart_request(
147
- Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original",
148
- "//webhooks/:webhook_id/:token/messages/@original", :patch), payload, files, headers: headers,
178
+ Route.new(
179
+ "/webhooks/#{@application_id}/#{@token}/messages/@original",
180
+ "//webhooks/:webhook_id/:token/messages/@original",
181
+ :patch
182
+ ),
183
+ payload,
184
+ files,
149
185
  ).wait
150
186
  end
151
187
  end
@@ -176,6 +212,8 @@ module Discorb
176
212
  # A module for response with update.
177
213
  #
178
214
  module UpdateResponder
215
+ # @type instance: Discorb::Interaction
216
+
179
217
  #
180
218
  # Response with `DEFERRED_UPDATE_MESSAGE`(`6`).
181
219
  # @async
@@ -211,12 +249,24 @@ module Discorb
211
249
  # @param [Discorb::Embed] embed The embed to send.
212
250
  # @param [Array<Discorb::Embed>] embeds The embeds to send. (max: 10)
213
251
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
252
+ # @param [Discorb::Attachment] attachment The attachment to send.
253
+ # @param [Array<Discorb::Attachment>] attachments The attachments to send. (max: 10)
214
254
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
215
255
  # @param [Boolean] ephemeral Whether to make the response ephemeral.
216
256
  #
217
257
  # @return [Async::Task<void>] The task.
218
258
  #
219
- def edit(content, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil, ephemeral: false)
259
+ def edit(
260
+ content,
261
+ tts: false,
262
+ embed: nil,
263
+ embeds: nil,
264
+ allowed_mentions: nil,
265
+ attachment: nil,
266
+ attachments: nil,
267
+ components: nil,
268
+ ephemeral: false
269
+ )
220
270
  Async do
221
271
  payload = {}
222
272
  payload[:content] = content if content
@@ -231,9 +281,17 @@ module Discorb
231
281
  allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
232
282
  payload[:components] = Component.to_payload(components) if components
233
283
  payload[:flags] = (ephemeral ? 1 << 6 : 0)
234
- @client.http.request(
284
+ attachments ||= [attachment] if attachment
285
+ payload[:attachments] = attachments.map.with_index do |a, i|
286
+ {
287
+ id: i,
288
+ filename: a.filename,
289
+ description: a.description,
290
+ }
291
+ end
292
+ @client.http.multipart_request(
235
293
  Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback",
236
- :post), { type: 7, data: payload }
294
+ :post), { type: 7, data: payload }, attachments
237
295
  ).wait
238
296
  end
239
297
  end
@@ -243,6 +301,8 @@ module Discorb
243
301
  # A module for response with modal.
244
302
  #
245
303
  module ModalResponder
304
+ # @type instance: Discorb::Interaction
305
+
246
306
  #
247
307
  # Response with `MODAL`(`9`).
248
308
  #
@@ -263,7 +323,7 @@ module Discorb
263
323
 
264
324
  private
265
325
 
266
- def _set_data(*)
326
+ def _set_data(_)
267
327
  nil
268
328
  end
269
329
  end
@@ -52,10 +52,10 @@ module Discorb
52
52
  # @return [Discorb::Presence] The presence of the member.
53
53
  # @!attribute [r] activity
54
54
  # @macro client_cache
55
- # @return [Discorb::Activity] The activity of the member. It's from the {#presence}.
55
+ # @return [Discorb::Presence::Activity] The activity of the member. It's from the {#presence}.
56
56
  # @!attribute [r] activities
57
57
  # @macro client_cache
58
- # @return [Array<Discorb::Activity>] The activities of the member. It's from the {#presence}.
58
+ # @return [Array<Discorb::Presence::Activity>] The activities of the member. It's from the {#presence}.
59
59
  # @!attribute [r] status
60
60
  # @macro client_cache
61
61
  # @return [Symbol] The status of the member. It's from the {#presence}.
@@ -303,7 +303,7 @@ module Discorb
303
303
  @deaf = member_data[:deaf]
304
304
  @custom_avatar = member_data[:avatar] && Asset.new(self, member_data[:avatar])
305
305
  super(user_data)
306
- @display_avatar = @avatar || @custom_avatar
306
+ @display_avatar = @custom_avatar || @avatar
307
307
  @client.guilds[@guild_id].members[@id] = self unless @guild_id.nil? || @client.guilds[@guild_id].nil?
308
308
  @_member_data.update(member_data)
309
309
  end