discorb 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/build_main.yml +2 -2
  4. data/.github/workflows/build_version.yml +1 -1
  5. data/.github/workflows/codeql-analysis.yml +1 -1
  6. data/.github/workflows/lint-push.yml +3 -5
  7. data/.github/workflows/lint.yml +1 -1
  8. data/.github/workflows/spec.yml +30 -0
  9. data/.lefthook/commit-msg/validator.rb +5 -0
  10. data/.rspec +2 -0
  11. data/.rspec_parallel +2 -0
  12. data/.rubocop.yml +43 -6
  13. data/Changelog.md +14 -1
  14. data/Gemfile +14 -8
  15. data/Rakefile +41 -26
  16. data/bin/console +3 -3
  17. data/docs/Examples.md +1 -1
  18. data/docs/application_command.md +138 -46
  19. data/docs/cli/irb.md +2 -2
  20. data/docs/cli/new.md +14 -9
  21. data/docs/cli/run.md +7 -11
  22. data/docs/cli.md +17 -10
  23. data/docs/events.md +209 -211
  24. data/docs/extension.md +1 -2
  25. data/docs/faq.md +0 -1
  26. data/docs/tutorial.md +12 -12
  27. data/docs/voice_events.md +106 -106
  28. data/examples/commands/message.rb +63 -0
  29. data/examples/commands/permission.rb +18 -0
  30. data/examples/commands/slash.rb +44 -0
  31. data/examples/commands/user.rb +51 -0
  32. data/examples/components/authorization_button.rb +2 -2
  33. data/examples/components/select_menu.rb +2 -2
  34. data/examples/extension/main.rb +1 -1
  35. data/examples/extension/message_expander.rb +5 -2
  36. data/examples/simple/eval.rb +2 -2
  37. data/examples/simple/ping_pong.rb +1 -1
  38. data/examples/simple/rolepanel.rb +1 -1
  39. data/examples/simple/shard.rb +1 -1
  40. data/examples/simple/wait_for_message.rb +1 -1
  41. data/exe/discorb +31 -16
  42. data/lefthook.yml +45 -0
  43. data/lib/discorb/allowed_mentions.rb +1 -0
  44. data/lib/discorb/app_command/command.rb +127 -65
  45. data/lib/discorb/app_command/common.rb +25 -0
  46. data/lib/discorb/app_command/handler.rb +115 -33
  47. data/lib/discorb/app_command.rb +2 -1
  48. data/lib/discorb/application.rb +1 -0
  49. data/lib/discorb/asset.rb +1 -2
  50. data/lib/discorb/attachment.rb +1 -1
  51. data/lib/discorb/audit_logs.rb +11 -8
  52. data/lib/discorb/channel/base.rb +108 -0
  53. data/lib/discorb/channel/category.rb +32 -0
  54. data/lib/discorb/channel/container.rb +44 -0
  55. data/lib/discorb/channel/dm.rb +28 -0
  56. data/lib/discorb/channel/guild.rb +245 -0
  57. data/lib/discorb/channel/stage.rb +140 -0
  58. data/lib/discorb/channel/text.rb +345 -0
  59. data/lib/discorb/channel/thread.rb +321 -0
  60. data/lib/discorb/channel/voice.rb +79 -0
  61. data/lib/discorb/channel.rb +2 -1165
  62. data/lib/discorb/client.rb +38 -26
  63. data/lib/discorb/common.rb +2 -1
  64. data/lib/discorb/components/button.rb +2 -1
  65. data/lib/discorb/components/select_menu.rb +4 -2
  66. data/lib/discorb/components/text_input.rb +12 -2
  67. data/lib/discorb/components.rb +1 -1
  68. data/lib/discorb/embed.rb +22 -7
  69. data/lib/discorb/emoji.rb +30 -3
  70. data/lib/discorb/emoji_table.rb +4969 -3
  71. data/lib/discorb/event.rb +29 -4
  72. data/lib/discorb/exe/about.rb +1 -0
  73. data/lib/discorb/exe/irb.rb +2 -4
  74. data/lib/discorb/exe/new.rb +90 -23
  75. data/lib/discorb/exe/run.rb +8 -22
  76. data/lib/discorb/exe/setup.rb +25 -12
  77. data/lib/discorb/exe/show.rb +4 -3
  78. data/lib/discorb/extend.rb +1 -0
  79. data/lib/discorb/extension.rb +6 -3
  80. data/lib/discorb/flag.rb +11 -0
  81. data/lib/discorb/gateway.rb +67 -19
  82. data/lib/discorb/guild.rb +188 -56
  83. data/lib/discorb/guild_template.rb +10 -4
  84. data/lib/discorb/http.rb +16 -9
  85. data/lib/discorb/integration.rb +4 -1
  86. data/lib/discorb/intents.rb +1 -1
  87. data/lib/discorb/interaction/autocomplete.rb +28 -16
  88. data/lib/discorb/interaction/command.rb +36 -12
  89. data/lib/discorb/interaction/components.rb +5 -2
  90. data/lib/discorb/interaction/modal.rb +0 -1
  91. data/lib/discorb/interaction/response.rb +61 -22
  92. data/lib/discorb/interaction/root.rb +13 -13
  93. data/lib/discorb/interaction.rb +1 -0
  94. data/lib/discorb/invite.rb +5 -2
  95. data/lib/discorb/member.rb +25 -5
  96. data/lib/discorb/message.rb +47 -14
  97. data/lib/discorb/message_meta.rb +1 -0
  98. data/lib/discorb/modules.rb +56 -14
  99. data/lib/discorb/presence.rb +2 -2
  100. data/lib/discorb/rate_limit.rb +7 -2
  101. data/lib/discorb/reaction.rb +4 -4
  102. data/lib/discorb/role.rb +19 -4
  103. data/lib/discorb/shard.rb +1 -1
  104. data/lib/discorb/sticker.rb +8 -7
  105. data/lib/discorb/user.rb +2 -1
  106. data/lib/discorb/utils/colored_puts.rb +1 -0
  107. data/lib/discorb/voice_state.rb +10 -6
  108. data/lib/discorb/webhook.rb +36 -24
  109. data/lib/discorb.rb +5 -3
  110. data/po/yard.pot +9 -9
  111. data/sig/discorb.rbs +7232 -7235
  112. metadata +21 -5
  113. data/examples/commands/bookmarker.rb +0 -42
  114. data/examples/commands/hello.rb +0 -10
  115. data/examples/commands/inspect.rb +0 -25
data/lib/discorb/http.rb CHANGED
@@ -40,7 +40,8 @@ module Discorb
40
40
  Async do |_task|
41
41
  @ratelimit_handler.wait(path)
42
42
  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), **kwargs)
43
+ http.send(path.method, get_path(path), get_body(body), get_headers(headers, body, audit_log_reason),
44
+ **kwargs)
44
45
  else
45
46
  http.send(path.method, get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
46
47
  end
@@ -69,18 +70,23 @@ module Discorb
69
70
  def multipart_request(path, body, files, headers: nil, audit_log_reason: nil, **kwargs)
70
71
  Async do |_task|
71
72
  @ratelimit_handler.wait(path)
72
- req = Net::HTTP.const_get(path.method.to_s.capitalize).new(get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
73
+ req = Net::HTTP.const_get(path.method.to_s.capitalize).new(
74
+ get_path(path),
75
+ get_headers(headers, body, audit_log_reason),
76
+ **kwargs,
77
+ )
73
78
  data = [
74
79
  ["payload_json", get_body(body)],
75
80
  ]
76
81
  files&.each_with_index do |file, i|
77
82
  next if file.nil?
83
+
78
84
  if file.created_by == :discord
79
85
  request_io = StringIO.new(
80
86
  cdn_http.get(URI.parse(file.url).path, {
81
- "Content-Type" => nil,
82
- "User-Agent" => Discorb::USER_AGENT,
83
- }).body
87
+ "Content-Type" => nil,
88
+ "User-Agent" => Discorb::USER_AGENT,
89
+ }).body
84
90
  )
85
91
  data << ["files[#{i}]", request_io, { filename: file.filename, content_type: file.content_type }]
86
92
  else
@@ -125,10 +131,10 @@ module Discorb
125
131
 
126
132
  def get_headers(headers, body = "", audit_log_reason = nil)
127
133
  ret = if body.nil? || body == ""
128
- { "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}" }
134
+ { "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}" }
129
135
  else
130
136
  { "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}",
131
- "content-type" => "application/json" }
137
+ "content-type" => "application/json", }
132
138
  end
133
139
  ret.merge!(headers) if !headers.nil? && headers.length.positive?
134
140
  ret["X-Audit-Log-Reason"] = audit_log_reason unless audit_log_reason.nil?
@@ -147,7 +153,7 @@ module Discorb
147
153
 
148
154
  def get_path(path)
149
155
  full_path = if path.url.start_with?("https://")
150
- path.url
156
+ path.url
151
157
  else
152
158
  API_BASE_URL + path.url
153
159
  end
@@ -160,12 +166,13 @@ module Discorb
160
166
  data = JSON.parse(resp.body, symbolize_names: true)
161
167
  rescue JSON::ParserError, TypeError
162
168
  data = if resp.body.nil? || resp.body.empty?
163
- nil
169
+ nil
164
170
  else
165
171
  resp.body
166
172
  end
167
173
  end
168
174
  raise CloudFlareBanError.new(resp, @client) if resp["Via"].nil? && resp.code == "429" && data.is_a?(String)
175
+
169
176
  data
170
177
  end
171
178
 
@@ -74,7 +74,10 @@ module Discorb
74
74
  #
75
75
  def delete!(reason: nil)
76
76
  Async do
77
- @client.http.request(Route.new("/guilds/#{@guild}/integrations/#{@id}", "//guilds/:guild_id/integrations/:integration_id", :delete), audit_log_reason: reason).wait
77
+ @client.http.request(
78
+ Route.new("/guilds/#{@guild}/integrations/#{@id}", "//guilds/:guild_id/integrations/:integration_id",
79
+ :delete), {}, audit_log_reason: reason
80
+ ).wait
78
81
  end
79
82
  end
80
83
 
@@ -47,7 +47,7 @@ module Discorb
47
47
  #
48
48
  # @note You must enable privileged intents to use `members` and/or `presences` intents.
49
49
  # @note Message Content Intent is not required to use `message_content` intents for now,
50
- # this will be required in April 30, 2022. [Learn More](https://support-dev.discord.com/hc/en-us/articles/4404772028055).
50
+ # this will be required in September 1, 2022. [Learn More](https://support-dev.discord.com/hc/en-us/articles/4404772028055).
51
51
  # You should specify `message_content` intent for preventing unexpected changes in the future.
52
52
  #
53
53
  def initialize(guilds: true,
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Discorb
3
4
  #
4
5
  # Represents auto complete interaction.
@@ -12,35 +13,46 @@ module Discorb
12
13
  def _set_data(data)
13
14
  super
14
15
  Sync do
15
- name, options = Discorb::CommandInteraction::SlashCommand.get_command_data(data)
16
+ name, options = Discorb::CommandInteraction::ChatInputCommand.get_command_data(data)
16
17
 
17
- unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
18
+ unless (command = @client.callable_commands.find { |c| c.to_s == name && c.type_raw == 1 })
18
19
  @client.logger.warn "Unknown command name #{name}, ignoring"
19
20
  next
20
21
  end
21
22
 
22
23
  option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
23
- Discorb::CommandInteraction::SlashCommand.modify_option_map(option_map, options, guild, {}, {})
24
+ Discorb::CommandInteraction::ChatInputCommand.modify_option_map(option_map, options, guild, {}, {})
24
25
  focused_index = options.find_index { |o| o[:focused] }
25
- val = command.options.values.filter { |option| option[:type] != :attachment }[focused_index][:autocomplete]&.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
26
+ val = command.options.values.filter do |option|
27
+ option[:type] != :attachment
28
+ end[focused_index][:autocomplete]&.call(self, *command.options.map do |k, _v|
29
+ option_map[k.to_s]
30
+ end)
26
31
  send_complete_result(val)
27
32
  end
28
33
  end
29
34
 
30
35
  def send_complete_result(val)
31
- @client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), {
32
- type: 8,
33
- data: {
34
- choices: val.map do |vk, vv|
35
- {
36
- name: vk,
37
- value: vv,
38
- }
39
- end,
40
- },
41
- }).wait
36
+ @client.http.request(
37
+ Route.new(
38
+ "/interactions/#{@id}/#{@token}/callback",
39
+ "//interactions/:interaction_id/:token/callback",
40
+ :post
41
+ ), {
42
+ type: 8,
43
+ data: {
44
+ choices: val.map do |vk, vv|
45
+ {
46
+ name: vk,
47
+ value: vv,
48
+ }
49
+ end,
50
+ },
51
+ }
52
+ ).wait
42
53
  rescue Discorb::NotFoundError
43
- @client.logger.warn "Failed to send auto complete result, This may be caused by the suggestion is taking too long (over 3 seconds) to respond", fallback: $stderr
54
+ @client.logger.warn "Failed to send auto complete result, " \
55
+ "This may be caused by the suggestion is taking too long (over 3 seconds) to respond"
44
56
  end
45
57
 
46
58
  class << self
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Discorb
3
4
  #
4
5
  # Represents a command interaction.
@@ -12,7 +13,7 @@ module Discorb
12
13
  #
13
14
  # Represents a slash command interaction.
14
15
  #
15
- class SlashCommand < CommandInteraction
16
+ class ChatInputCommand < CommandInteraction
16
17
  @command_type = 1
17
18
  @event_name = :slash_command
18
19
 
@@ -21,15 +22,15 @@ module Discorb
21
22
  def _set_data(data)
22
23
  super
23
24
 
24
- name, options = SlashCommand.get_command_data(data)
25
+ name, options = ChatInputCommand.get_command_data(data)
25
26
 
26
- unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
27
+ unless (command = @client.callable_commands.find { |c| c.to_s == name && c.type_raw == 1 })
27
28
  @client.logger.warn "Unknown command name #{name}, ignoring"
28
29
  return
29
30
  end
30
31
 
31
32
  option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
32
- SlashCommand.modify_option_map(option_map, options, guild, @members, @attachments)
33
+ ChatInputCommand.modify_option_map(option_map, options, guild, @members, @attachments)
33
34
 
34
35
  command.block.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
35
36
  end
@@ -84,11 +85,19 @@ module Discorb
84
85
  when 6
85
86
  members[option[:value]] || guild.members[option[:value]] || guild.fetch_member(option[:value]).wait
86
87
  when 7
87
- guild.channels[option[:value]] || guild.fetch_channels.wait.find { |channel| channel.id == option[:value] }
88
+ guild.channels[option[:value]] || guild.fetch_channels.wait.find do |channel|
89
+ channel.id == option[:value]
90
+ end
88
91
  when 8
89
92
  guild.roles[option[:value]] || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
90
93
  when 9
91
- members[option[:value]] || guild.members[option[:value]] || guild.roles[option[:value]] || guild.fetch_member(option[:value]).wait || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
94
+ 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
92
101
  when 11
93
102
  attachments[option[:value]]
94
103
  end
@@ -112,8 +121,17 @@ module Discorb
112
121
 
113
122
  def _set_data(data)
114
123
  super
115
- @target = guild.members[data[:target_id]] || Discorb::Member.new(@client, @guild_id, data[:resolved][:users][data[:target_id].to_sym], data[:resolved][:members][data[:target_id].to_sym])
116
- @client.commands.find { |c| c.name == data[:name] && c.type_raw == 2 }.block.call(self, @target)
124
+ @target = guild.members[data[:target_id]] || Discorb::Member.new(
125
+ @client, @guild_id,
126
+ data[:resolved][:users][data[:target_id].to_sym],
127
+ data[:resolved][:members][data[:target_id].to_sym]
128
+ )
129
+ command = @client.commands.find { |c| c.name["default"] == data[:name] && c.type_raw == 2 }
130
+ if command
131
+ command.block.call(self, @target)
132
+ else
133
+ @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
134
+ end
117
135
  end
118
136
  end
119
137
 
@@ -132,7 +150,12 @@ module Discorb
132
150
  def _set_data(data)
133
151
  super
134
152
  @target = @messages[data[:target_id]]
135
- @client.commands.find { |c| c.name == data[:name] && c.type_raw == 3 }.block.call(self, @target)
153
+ command = @client.commands.find { |c| c.name["default"] == data[:name] && c.type_raw == 3 }
154
+ if command
155
+ command.block.call(self, @target)
156
+ else
157
+ @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
158
+ end
136
159
  end
137
160
  end
138
161
 
@@ -152,10 +175,11 @@ module Discorb
152
175
  @client, @guild_id, data[:resolved][:users][id], member
153
176
  )
154
177
  end
155
- data[:resolved][:messages]&.to_h do |id, _message|
156
- @messages[id.to_i] = Message.new(@client, data[:resolved][:messages][data[:target_id].to_sym].merge(guild_id: @guild_id.to_s)).merge(guild_id: @guild_id.to_s)
178
+
179
+ data[:resolved][:messages]&.each do |id, message|
180
+ @messages[id.to_s] = Message.new(@client, message.merge(guild_id: @guild_id.to_s))
157
181
  end
158
- data[:resolved][:attachments]&.to_h do |id, attachment|
182
+ data[:resolved][:attachments]&.each do |id, attachment|
159
183
  @attachments[id.to_s] = Attachment.new(attachment)
160
184
  end
161
185
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
- module Discorb
3
2
 
3
+ module Discorb
4
4
  #
5
5
  # Represents a message component interaction.
6
6
  # @abstract
@@ -41,7 +41,10 @@ module Discorb
41
41
  #
42
42
  def make_interaction(client, data)
43
43
  nested_classes.each do |klass|
44
- return klass.new(client, data) if !klass.component_type.nil? && klass.component_type == data[:data][:component_type]
44
+ if !klass.component_type.nil? && klass.component_type == data[:data][:component_type]
45
+ return klass.new(client,
46
+ data)
47
+ end
45
48
  end
46
49
  client.logger.warn("Unknown component type #{data[:component_type]}, initialized Interaction")
47
50
  MessageComponentInteraction.new(client, data)
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Discorb
4
-
5
4
  #
6
5
  # Represents a modal interaction.
7
6
  #
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Discorb
3
4
  #
4
5
  # Represents an interaction of Discord.
@@ -19,12 +20,18 @@ module Discorb
19
20
  #
20
21
  def defer_source(ephemeral: false)
21
22
  Async do
22
- @client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), {
23
- type: 5,
24
- data: {
25
- flags: (ephemeral ? 1 << 6 : 0),
26
- },
27
- }).wait
23
+ @client.http.request(
24
+ Route.new(
25
+ "/interactions/#{@id}/#{@token}/callback",
26
+ "//interactions/:interaction_id/:token/callback",
27
+ :post
28
+ ), {
29
+ type: 5,
30
+ data: {
31
+ flags: (ephemeral ? 1 << 6 : 0),
32
+ },
33
+ }
34
+ ).wait
28
35
  @defered = true
29
36
  end
30
37
  end
@@ -42,27 +49,45 @@ module Discorb
42
49
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
43
50
  # @param [Boolean] ephemeral Whether to make the response ephemeral.
44
51
  #
45
- # @return [Discorb::Interaction::SourceResponder::CallbackMessage, Discorb::Webhook::Message] The callback message.
52
+ # @return [Discorb::Interaction::SourceResponder::CallbackMessage, Discorb::Webhook::Message]
53
+ # The callback message.
46
54
  #
47
- def post(content = nil, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil, ephemeral: false)
55
+ def post(
56
+ content = nil,
57
+ tts: false,
58
+ embed: nil,
59
+ embeds: nil,
60
+ allowed_mentions: nil,
61
+ components: nil,
62
+ ephemeral: false
63
+ )
48
64
  Async do
49
65
  payload = {}
50
66
  payload[:content] = content if content
51
67
  payload[:tts] = tts
52
68
  payload[:embeds] = (embeds || [embed]).map { |e| e&.to_hash }.filter { _1 }
53
- payload[:allowed_mentions] = allowed_mentions&.to_hash(@client.allowed_mentions) || @client.allowed_mentions.to_hash
69
+ payload[:allowed_mentions] =
70
+ allowed_mentions&.to_hash(@client.allowed_mentions) || @client.allowed_mentions.to_hash
54
71
  payload[:components] = Component.to_payload(components) if components
55
72
  payload[:flags] = (ephemeral ? 1 << 6 : 0)
56
73
 
57
74
  ret = if @responded
58
- _resp, data = @client.http.request(Route.new("/webhooks/#{@application_id}/#{@token}", "//webhooks/:webhook_id/:token", :post), payload).wait
75
+ _resp, data = @client.http.request(
76
+ Route.new("/webhooks/#{@application_id}/#{@token}", "//webhooks/:webhook_id/:token", :post), payload
77
+ ).wait
59
78
  webhook = Webhook::URLWebhook.new("/webhooks/#{@application_id}/#{@token}")
60
79
  Webhook::Message.new(webhook, data, @client)
61
80
  elsif @defered
62
- @client.http.request(Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :patch), payload).wait
81
+ @client.http.request(
82
+ Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original",
83
+ "//webhooks/:webhook_id/:token/messages/@original", :patch), payload
84
+ ).wait
63
85
  CallbackMessage.new(@client, payload, @application_id, @token)
64
86
  else
65
- @client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), { type: 4, data: payload }).wait
87
+ @client.http.request(
88
+ Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback",
89
+ :post), { type: 4, data: payload }
90
+ ).wait
66
91
  CallbackMessage.new(@client, payload, @application_id, @token)
67
92
  end
68
93
  @responded = true
@@ -118,7 +143,10 @@ module Discorb
118
143
  payload[:attachments] = attachments.map(&:to_hash) if attachments != Discorb::Unset
119
144
  files = [file] if file != Discorb::Unset
120
145
  files = [] if files == Discorb::Unset
121
- @client.http.multipart_request(Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :patch), payload, files, headers: headers).wait
146
+ @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,
149
+ ).wait
122
150
  end
123
151
  end
124
152
 
@@ -133,7 +161,8 @@ module Discorb
133
161
  #
134
162
  def delete!
135
163
  Async do
136
- @client.http.request(Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :delete)).wait
164
+ @client.http.request(Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original",
165
+ "//webhooks/:webhook_id/:token/messages/@original", :delete)).wait
137
166
  end
138
167
  end
139
168
 
@@ -157,12 +186,18 @@ module Discorb
157
186
  #
158
187
  def defer_update(ephemeral: false)
159
188
  Async do
160
- @client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), {
161
- type: 6,
162
- data: {
163
- flags: (ephemeral ? 1 << 6 : 0),
164
- },
165
- }).wait
189
+ @client.http.request(
190
+ Route.new(
191
+ "/interactions/#{@id}/#{@token}/callback",
192
+ "//interactions/:interaction_id/:token/callback",
193
+ :post
194
+ ), {
195
+ type: 6,
196
+ data: {
197
+ flags: (ephemeral ? 1 << 6 : 0),
198
+ },
199
+ }
200
+ ).wait
166
201
  end
167
202
  end
168
203
 
@@ -192,10 +227,14 @@ module Discorb
192
227
  embeds
193
228
  end
194
229
  payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
195
- payload[:allowed_mentions] = allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
230
+ payload[:allowed_mentions] =
231
+ allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
196
232
  payload[:components] = Component.to_payload(components) if components
197
233
  payload[:flags] = (ephemeral ? 1 << 6 : 0)
198
- @client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), { type: 7, data: payload }).wait
234
+ @client.http.request(
235
+ Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback",
236
+ :post), { type: 7, data: payload }
237
+ ).wait
199
238
  end
200
239
  end
201
240
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Discorb
3
4
  #
4
5
  # Represents a user interaction with the bot.
@@ -10,10 +11,9 @@ module Discorb
10
11
  attr_reader :application_id
11
12
  # @return [Symbol] The type of interaction.
12
13
  attr_reader :type
13
- # @return [Discorb::Member] The member that created the interaction.
14
- attr_reader :member
15
- # @return [Discorb::User] The user that created the interaction.
14
+ # @return [Discorb::User, Discorb::Member] The user or member that created the interaction.
16
15
  attr_reader :user
16
+ alias member user
17
17
  # @return [Integer] The type of interaction.
18
18
  # @note This is always `1` for now.
19
19
  attr_reader :version
@@ -53,8 +53,12 @@ module Discorb
53
53
  @type_id = self.class.interaction_type
54
54
  @guild_id = data[:guild_id] && Snowflake.new(data[:guild_id])
55
55
  @channel_id = data[:channel_id] && Snowflake.new(data[:channel_id])
56
- @member = guild.members[data[:member][:id]] || Member.new(@client, @guild_id, data[:member][:user], data[:member]) if data[:member]
57
- @user = @client.users[data[:user][:id]] || User.new(@client, data[:user]) if data[:user]
56
+ if data[:member]
57
+ @user = guild.members[data[:member][:id]] || Member.new(@client, @guild_id, data[:member][:user],
58
+ data[:member])
59
+ elsif data[:user]
60
+ @user = @client.users[data[:user][:id]] || User.new(@client, data[:user])
61
+ end
58
62
  @token = data[:token]
59
63
  @locale = data[:locale].to_s.gsub("-", "_").to_sym
60
64
  @guild_locale = data[:guild_locale].to_s.gsub("-", "_").to_sym
@@ -72,13 +76,6 @@ module Discorb
72
76
  @client.channels[@channel_id]
73
77
  end
74
78
 
75
- def target
76
- @member || @user
77
- end
78
-
79
- alias fired_by target
80
- alias from target
81
-
82
79
  def inspect
83
80
  "#<#{self.class} id=#{@id}>"
84
81
  end
@@ -97,7 +94,10 @@ module Discorb
97
94
  def make_interaction(client, data)
98
95
  interaction = nil
99
96
  descendants.each do |klass|
100
- interaction = klass.make_interaction(client, data) if !klass.interaction_type.nil? && klass.interaction_type == data[:type]
97
+ if !klass.interaction_type.nil? && klass.interaction_type == data[:type]
98
+ interaction = klass.make_interaction(client,
99
+ data)
100
+ end
101
101
  end
102
102
  if interaction.nil?
103
103
  client.logger.warn("Unknown interaction type #{data[:type]}, initialized Interaction")
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  %w[root response command components autocomplete modal].each do |file|
3
4
  require_relative "interaction/#{file}.rb"
4
5
  end
@@ -114,7 +114,7 @@ module Discorb
114
114
  #
115
115
  def delete!(reason: nil)
116
116
  Async do
117
- @client.http.request(Route.new("/invites/#{@code}", "//invites/:code", :delete), audit_log_reason: reason)
117
+ @client.http.request(Route.new("/invites/#{@code}", "//invites/:code", :delete), {}, audit_log_reason: reason)
118
118
  end
119
119
  end
120
120
 
@@ -134,7 +134,10 @@ module Discorb
134
134
  end
135
135
  @inviter_data = data[:inviter]
136
136
  @target_type = TARGET_TYPES[data[:target_type]]
137
- @target_user = @client.users[data[:target_user][:id]] || User.new(@client, data[:target_user]) if data[:target_user]
137
+ if data[:target_user]
138
+ @target_user = @client.users[data[:target_user][:id]] || User.new(@client,
139
+ data[:target_user])
140
+ end
138
141
  # @target_application = nil
139
142
 
140
143
  # @stage_instance = data[:stage_instance] && Invite::StageInstance.new(self, data[:stage_instance])
@@ -114,6 +114,7 @@ module Discorb
114
114
 
115
115
  def permissions
116
116
  return Permission.new((1 << 38) - 1) if owner?
117
+
117
118
  roles.map(&:permissions).sum(Permission.new(0))
118
119
  end
119
120
 
@@ -158,7 +159,10 @@ module Discorb
158
159
  #
159
160
  def add_role(role, reason: nil)
160
161
  Async do
161
- @client.http.request(Route.new("/guilds/#{@guild_id}/members/#{@id}/roles/#{role.is_a?(Role) ? role.id : role}", "//guilds/:guild_id/members/:user_id/roles/:role_id", :put), nil, audit_log_reason: reason).wait
162
+ @client.http.request(
163
+ Route.new("/guilds/#{@guild_id}/members/#{@id}/roles/#{role.is_a?(Role) ? role.id : role}",
164
+ "//guilds/:guild_id/members/:user_id/roles/:role_id", :put), nil, audit_log_reason: reason,
165
+ ).wait
162
166
  end
163
167
  end
164
168
 
@@ -173,7 +177,10 @@ module Discorb
173
177
  #
174
178
  def remove_role(role, reason: nil)
175
179
  Async do
176
- @client.http.request(Route.new("/guilds/#{@guild_id}/members/#{@id}/roles/#{role.is_a?(Role) ? role.id : role}", "//guilds/:guild_id/members/:user_id/roles/:role_id", :delete), audit_log_reason: reason).wait
180
+ @client.http.request(
181
+ Route.new("/guilds/#{@guild_id}/members/#{@id}/roles/#{role.is_a?(Role) ? role.id : role}",
182
+ "//guilds/:guild_id/members/:user_id/roles/:role_id", :delete), {}, audit_log_reason: reason,
183
+ ).wait
177
184
  end
178
185
  end
179
186
 
@@ -194,7 +201,13 @@ module Discorb
194
201
  # @return [Async::Task<void>] The task.
195
202
  #
196
203
  def edit(
197
- nick: Discorb::Unset, role: Discorb::Unset, mute: Discorb::Unset, deaf: Discorb::Unset, channel: Discorb::Unset, communication_disabled_until: Discorb::Unset, timeout_until: Discorb::Unset,
204
+ nick: Discorb::Unset,
205
+ role: Discorb::Unset,
206
+ mute: Discorb::Unset,
207
+ deaf: Discorb::Unset,
208
+ channel: Discorb::Unset,
209
+ communication_disabled_until: Discorb::Unset,
210
+ timeout_until: Discorb::Unset,
198
211
  reason: nil
199
212
  )
200
213
  Async do
@@ -204,9 +217,15 @@ module Discorb
204
217
  payload[:mute] = mute if mute != Discorb::Unset
205
218
  payload[:deaf] = deaf if deaf != Discorb::Unset
206
219
  communication_disabled_until = timeout_until if timeout_until != Discorb::Unset
207
- payload[:communication_disabled_until] = communication_disabled_until&.iso8601 if communication_disabled_until != Discorb::Unset
220
+ if communication_disabled_until != Discorb::Unset
221
+ payload[:communication_disabled_until] =
222
+ communication_disabled_until&.iso8601
223
+ end
208
224
  payload[:channel_id] = channel&.id if channel != Discorb::Unset
209
- @client.http.request(Route.new("/guilds/#{@guild_id}/members/#{@id}", "//guilds/:guild_id/members/:user_id", :patch), payload, audit_log_reason: reason).wait
225
+ @client.http.request(
226
+ Route.new("/guilds/#{@guild_id}/members/#{@id}", "//guilds/:guild_id/members/:user_id",
227
+ :patch), payload, audit_log_reason: reason,
228
+ ).wait
210
229
  end
211
230
  end
212
231
 
@@ -265,6 +284,7 @@ module Discorb
265
284
  #
266
285
  def can_manage?(role)
267
286
  return true if owner?
287
+
268
288
  top_role = roles.max_by(&:position)
269
289
  top_role.position > role.position
270
290
  end