discorb 0.12.2 → 0.13.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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_main.yml +1 -0
  3. data/.github/workflows/build_version.yml +1 -0
  4. data/.github/workflows/crowdin.yml +32 -0
  5. data/.gitignore +3 -1
  6. data/.yardopts +2 -0
  7. data/Changelog.md +399 -367
  8. data/Gemfile +5 -1
  9. data/README.md +1 -1
  10. data/Rakefile +139 -9
  11. data/crowdin.yml +2 -0
  12. data/discorb.gemspec +1 -1
  13. data/docs/Examples.md +2 -0
  14. data/docs/application_command.md +17 -12
  15. data/docs/cli/irb.md +2 -0
  16. data/docs/cli/new.md +2 -0
  17. data/docs/cli/run.md +3 -1
  18. data/docs/cli/setup.md +4 -2
  19. data/docs/cli.md +2 -0
  20. data/docs/events.md +59 -5
  21. data/docs/extension.md +2 -2
  22. data/docs/faq.md +4 -2
  23. data/docs/license.md +2 -0
  24. data/docs/tutorial.md +4 -3
  25. data/docs/voice_events.md +2 -0
  26. data/lib/discorb/app_command.rb +13 -7
  27. data/lib/discorb/application.rb +32 -2
  28. data/lib/discorb/audit_logs.rb +28 -16
  29. data/lib/discorb/channel.rb +112 -81
  30. data/lib/discorb/client.rb +17 -19
  31. data/lib/discorb/common.rb +28 -1
  32. data/lib/discorb/components.rb +12 -0
  33. data/lib/discorb/dictionary.rb +1 -1
  34. data/lib/discorb/embed.rb +4 -0
  35. data/lib/discorb/emoji.rb +9 -7
  36. data/lib/discorb/emoji_table.rb +3774 -3689
  37. data/lib/discorb/event.rb +266 -24
  38. data/lib/discorb/event_handler.rb +39 -0
  39. data/lib/discorb/exe/show.rb +2 -0
  40. data/lib/discorb/extension.rb +5 -5
  41. data/lib/discorb/file.rb +4 -0
  42. data/lib/discorb/flag.rb +5 -1
  43. data/lib/discorb/gateway.rb +65 -14
  44. data/lib/discorb/gateway_requests.rb +4 -0
  45. data/lib/discorb/guild.rb +169 -82
  46. data/lib/discorb/guild_template.rb +12 -9
  47. data/lib/discorb/http.rb +82 -37
  48. data/lib/discorb/image.rb +7 -5
  49. data/lib/discorb/integration.rb +4 -1
  50. data/lib/discorb/intents.rb +8 -3
  51. data/lib/discorb/interaction/autocomplete.rb +1 -1
  52. data/lib/discorb/interaction/command.rb +2 -2
  53. data/lib/discorb/interaction/response.rb +27 -25
  54. data/lib/discorb/interaction/root.rb +8 -0
  55. data/lib/discorb/invite.rb +3 -2
  56. data/lib/discorb/log.rb +4 -0
  57. data/lib/discorb/member.rb +42 -13
  58. data/lib/discorb/message.rb +32 -17
  59. data/lib/discorb/modules.rb +19 -26
  60. data/lib/discorb/permission.rb +4 -0
  61. data/lib/discorb/rate_limit.rb +6 -2
  62. data/lib/discorb/role.rb +15 -11
  63. data/lib/discorb/sticker.rb +17 -12
  64. data/lib/discorb/user.rb +8 -7
  65. data/lib/discorb/voice_state.rb +8 -5
  66. data/lib/discorb/webhook.rb +38 -47
  67. data/lib/discorb.rb +2 -2
  68. data/po/yard.pot +7775 -5157
  69. data/sig/discorb.rbs +3317 -3820
  70. data/template-replace/scripts/locale_ja.rb +62 -0
  71. data/template-replace/scripts/yard_replace.rb +6 -0
  72. metadata +7 -4
data/lib/discorb/http.rb CHANGED
@@ -18,14 +18,14 @@ module Discorb
18
18
 
19
19
  #
20
20
  # Execute a GET request.
21
- # @macro async
21
+ # @async
22
22
  #
23
23
  # @param [String] path The path to the resource.
24
24
  # @param [Hash] headers The headers to send with the request.
25
25
  # @param [String] audit_log_reason The audit log reason to send with the request.
26
26
  # @param [Hash] kwargs The keyword arguments.
27
27
  #
28
- # @return [Array(Net::HTTPResponse, Hash)] The response and as JSON.
28
+ # @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
29
29
  # @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
30
30
  #
31
31
  # @raise [Discorb::HTTPError] The request was failed.
@@ -42,7 +42,7 @@ module Discorb
42
42
 
43
43
  #
44
44
  # Execute a POST request.
45
- # @macro async
45
+ # @async
46
46
  #
47
47
  # @param [String] path The path to the resource.
48
48
  # @param [String, Hash] body The body of the request.
@@ -50,7 +50,7 @@ module Discorb
50
50
  # @param [String] audit_log_reason The audit log reason to send with the request.
51
51
  # @param [Hash] kwargs The keyword arguments.
52
52
  #
53
- # @return [Array(Net::HTTPResponse, Hash)] The response and as JSON.
53
+ # @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
54
54
  # @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
55
55
  #
56
56
  # @raise [Discorb::HTTPError] The request was failed.
@@ -65,9 +65,46 @@ module Discorb
65
65
  end
66
66
  end
67
67
 
68
+ #
69
+ # Execute a multipart POST request.
70
+ # @async
71
+ #
72
+ # @param [String] path The path to the resource.
73
+ # @param [String, Hash] body The body of the request.
74
+ # @param [Array<Discorb::File>] files The files to upload.
75
+ # @param [Hash] headers The headers to send with the request.
76
+ # @param [String] audit_log_reason The audit log reason to send with the request.
77
+ # @param [Hash] kwargs The keyword arguments.
78
+ #
79
+ # @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
80
+ # @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
81
+ #
82
+ # @raise [Discorb::HTTPError] The request was failed.
83
+ #
84
+ def multipart_post(path, body = "", files, headers: nil, audit_log_reason: nil, **kwargs)
85
+ Async do |task|
86
+ @ratelimit_handler.wait("POST", path)
87
+ req = Net::HTTP::Post.new(get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
88
+ data = [
89
+ ["payload_json", get_body(body)],
90
+ ]
91
+ files&.each_with_index do |file, i|
92
+ next if file.nil?
93
+ data << ["files[#{i}]", file.io, { filename: file.filename, content_type: file.content_type }]
94
+ end
95
+ req.set_form(data, "multipart/form-data")
96
+ session = Net::HTTP.new("discord.com", 443)
97
+ session.use_ssl = true
98
+ resp = session.request(req)
99
+ data = get_response_data(resp)
100
+ @ratelimit_handler.save("POST", path, resp)
101
+ handle_response(:post, resp, data, path, body, headers, audit_log_reason, kwargs)
102
+ end
103
+ end
104
+
68
105
  #
69
106
  # Execute a PATCH request.
70
- # @macro async
107
+ # @async
71
108
  #
72
109
  # @param [String] path The path to the resource.
73
110
  # @param [String, Hash] body The body of the request.
@@ -75,7 +112,7 @@ module Discorb
75
112
  # @param [String] audit_log_reason The audit log reason to send with the request.
76
113
  # @param [Hash] kwargs The keyword arguments.
77
114
  #
78
- # @return [Array(Net::HTTPResponse, Hash)] The response and as JSON.
115
+ # @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
79
116
  # @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
80
117
  #
81
118
  # @raise [Discorb::HTTPError] The request was failed.
@@ -90,9 +127,44 @@ module Discorb
90
127
  end
91
128
  end
92
129
 
130
+ #
131
+ # Execute a PATCH request.
132
+ # @async
133
+ #
134
+ # @param [String] path The path to the resource.
135
+ # @param [String, Hash] body The body of the request.
136
+ # @param [Hash] headers The headers to send with the request.
137
+ # @param [String] audit_log_reason The audit log reason to send with the request.
138
+ # @param [Hash] kwargs The keyword arguments.
139
+ #
140
+ # @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
141
+ # @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
142
+ #
143
+ # @raise [Discorb::HTTPError] The request was failed.
144
+ #
145
+ def multipart_patch(path, body = "", headers: nil, audit_log_reason: nil, **kwargs)
146
+ Async do |task|
147
+ @ratelimit_handler.wait("PATCH", path)
148
+ req = Net::HTTP::Patch.new(get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
149
+ data = [
150
+ ["payload_json", get_body(body)],
151
+ ]
152
+ files&.each_with_index do |file, i|
153
+ data << ["files[#{i}]", file.io, { filename: file.filename, content_type: file.content_type }]
154
+ end
155
+ req.set_form(data, "multipart/form-data")
156
+ session = Net::HTTP.new("discord.com", 443)
157
+ session.use_ssl = true
158
+ resp = session.request(req)
159
+ data = get_response_data(resp)
160
+ @ratelimit_handler.save("PATCH", path, resp)
161
+ handle_response(:patch, resp, data, path, body, headers, audit_log_reason, kwargs)
162
+ end
163
+ end
164
+
93
165
  #
94
166
  # Execute a PUT request.
95
- # @macro async
167
+ # @async
96
168
  #
97
169
  # @param [String] path The path to the resource.
98
170
  # @param [String, Hash] body The body of the request.
@@ -100,7 +172,7 @@ module Discorb
100
172
  # @param [String] audit_log_reason The audit log reason to send with the request.
101
173
  # @param [Hash] kwargs The keyword arguments.
102
174
  #
103
- # @return [Array(Net::HTTPResponse, Hash)] The response and as JSON.
175
+ # @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
104
176
  # @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
105
177
  #
106
178
  # @raise [Discorb::HTTPError] The request was failed.
@@ -117,14 +189,14 @@ module Discorb
117
189
 
118
190
  #
119
191
  # Execute a DELETE request.
120
- # @macro async
192
+ # @async
121
193
  #
122
194
  # @param [String] path The path to the resource.
123
195
  # @param [Hash] headers The headers to send with the request.
124
196
  # @param [String] audit_log_reason The audit log reason to send with the request.
125
197
  # @param [Hash] kwargs The keyword arguments.
126
198
  #
127
- # @return [Array(Net::HTTPResponse, Hash)] The response and as JSON.
199
+ # @return [Async::Task<Array(Net::HTTPResponse, Hash)>] The response and as JSON.
128
200
  # @return [Async::Task<Array(Net::HTTPResponse, nil)>] The response was 204.
129
201
  #
130
202
  # @raise [Discorb::HTTPError] The request was failed.
@@ -143,33 +215,6 @@ module Discorb
143
215
  "#<#{self.class} client=#{@client}>"
144
216
  end
145
217
 
146
- #
147
- # A helper method to send multipart/form-data requests.
148
- #
149
- # @param [Hash] payload The payload to send.
150
- # @param [Array<Discorb::File>] files The files to send.
151
- #
152
- # @return [Array(String, String)] The boundary and body.
153
- #
154
- def self.multipart(payload, files)
155
- boundary = "DiscorbBySevenC7CMultipartFormData#{Time.now.to_f}"
156
- str_payloads = [<<~HTTP]
157
- Content-Disposition: form-data; name="payload_json"
158
- Content-Type: application/json
159
-
160
- #{payload.to_json}
161
- HTTP
162
- files.each do |single_file|
163
- str_payloads << <<~HTTP
164
- Content-Disposition: form-data; name="file"; filename="#{single_file.filename}"
165
- Content-Type: #{single_file.content_type}
166
-
167
- #{single_file.io.read}
168
- HTTP
169
- end
170
- [boundary, "--#{boundary}\n#{str_payloads.join("\n--#{boundary}\n")}\n--#{boundary}--"]
171
- end
172
-
173
218
  private
174
219
 
175
220
  def handle_response(method, resp, data, path, body, headers, audit_log_reason, kwargs)
data/lib/discorb/image.rb CHANGED
@@ -16,12 +16,10 @@ module Discorb
16
16
  #
17
17
  def initialize(source, type = nil)
18
18
  if source.respond_to?(:read)
19
- @bytes = source.read
19
+ @io = source
20
20
  @type = type || MIME::Types.type_for(source.path).first.content_type
21
21
  elsif ::File.exist?(source)
22
- ::File.open(source, "rb") do |file|
23
- @bytes = file.read
24
- end
22
+ @io = ::File.open(source, "rb")
25
23
  @type = MIME::Types.type_for(source).first.to_s
26
24
  else
27
25
  raise ArgumentError, "Couldn't read file."
@@ -34,7 +32,11 @@ module Discorb
34
32
  # @return [String] The image as a Discord style.
35
33
  #
36
34
  def to_s
37
- "data:#{@type};base64,#{Base64.strict_encode64(@bytes)}"
35
+ "data:#{@type};base64,#{Base64.strict_encode64(@io.read)}"
36
+ end
37
+
38
+ def inspect
39
+ "#<#{self.class} #{@type}>"
38
40
  end
39
41
  end
40
42
  end
@@ -58,9 +58,12 @@ module Discorb
58
58
 
59
59
  #
60
60
  # Delete the integration.
61
+ # @async
61
62
  #
62
63
  # @param [String] reason The reason for deleting the integration.
63
64
  #
65
+ # @return [Async::Task<void>] The task.
66
+ #
64
67
  def delete!(reason: nil)
65
68
  Async do
66
69
  @client.http.delete("/guilds/#{@guild}/integrations/#{@id}", audit_log_reason: reason).wait
@@ -84,7 +87,7 @@ module Discorb
84
87
  @account = Account.new(data[:account])
85
88
  @subscriber_count = data[:subscriber_count]
86
89
  @revoked = data[:revoked]
87
- @application = Application.new(@client, data[:application])
90
+ @application = data[:application] and Application.new(@client, data[:application])
88
91
  end
89
92
 
90
93
  class << self
@@ -19,6 +19,7 @@ module Discorb
19
19
  dm_messages: 1 << 12,
20
20
  dm_reactions: 1 << 13,
21
21
  dm_typing: 1 << 14,
22
+ scheduled_events: 1 << 16,
22
23
  }.freeze
23
24
 
24
25
  #
@@ -38,6 +39,7 @@ module Discorb
38
39
  # @param dm_messages [Boolean] Whether dm messages related events are enabled.
39
40
  # @param dm_reactions [Boolean] Whether dm reactions related events are enabled.
40
41
  # @param dm_typing [Boolean] Whether dm typing related events are enabled.
42
+ # @param scheduled_events [Boolean] Whether events related scheduled events are enabled.
41
43
  #
42
44
  # @note You must enable privileged intents to use `members` and/or `presences` intents.
43
45
  #
@@ -55,7 +57,8 @@ module Discorb
55
57
  typing: true,
56
58
  dm_messages: true,
57
59
  dm_reactions: true,
58
- dm_typing: true)
60
+ dm_typing: true,
61
+ scheduled_events: true)
59
62
  @raw_value = {
60
63
  guilds: guilds,
61
64
  members: members,
@@ -72,6 +75,7 @@ module Discorb
72
75
  dm_messages: dm_messages,
73
76
  dm_reactions: dm_reactions,
74
77
  dm_typing: dm_typing,
78
+ scheduled_events: scheduled_events,
75
79
  }
76
80
  end
77
81
 
@@ -124,13 +128,14 @@ module Discorb
124
128
  end
125
129
 
126
130
  # Create new intent object with default values.
131
+ # This will return intents without members and presence.
127
132
  def default
128
- from_value(32509)
133
+ from_value(@intent_bits.values.reduce(:+) - @intent_bits[:members] - @intent_bits[:presences])
129
134
  end
130
135
 
131
136
  # Create new intent object with all intents.
132
137
  def all
133
- from_value(32767)
138
+ from_value(@intent_bits.values.reduce(:+))
134
139
  end
135
140
 
136
141
  # Create new intent object with no intents.
@@ -18,7 +18,7 @@ module Discorb
18
18
  end
19
19
 
20
20
  option_map = command.options.map { |k, v| [k.to_s, v[:default]] }.to_h
21
- Discorb::CommandInteraction::SlashCommand.modify_option_map(option_map, options)
21
+ Discorb::CommandInteraction::SlashCommand.modify_option_map(option_map, options, guild)
22
22
  focused_index = options.find_index { |o| o[:focused] }
23
23
  val = command.options.values[focused_index][:autocomplete]&.call(self, *command.options.map { |k, v| option_map[k.to_s] })
24
24
  send_complete_result(val)
@@ -26,7 +26,7 @@ module Discorb
26
26
  end
27
27
 
28
28
  option_map = command.options.map { |k, v| [k.to_s, v[:default]] }.to_h
29
- SlashCommand.modify_option_map(option_map, options)
29
+ SlashCommand.modify_option_map(option_map, options, guild)
30
30
 
31
31
  command.block.call(self, *command.options.map { |k, v| option_map[k.to_s] })
32
32
  end
@@ -59,7 +59,7 @@ module Discorb
59
59
  end
60
60
 
61
61
  # @private
62
- def modify_option_map(option_map, options)
62
+ def modify_option_map(option_map, options, guild)
63
63
  options ||= []
64
64
  options.each_with_index do |option|
65
65
  val = case option[:type]
@@ -7,11 +7,12 @@ module Discorb
7
7
  #
8
8
  # Response with `DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE`(`5`).
9
9
  #
10
- # @macro async
11
- # @macro http
10
+ # @async
12
11
  #
13
12
  # @param [Boolean] ephemeral Whether to make the response ephemeral.
14
13
  #
14
+ # @return [Async::Task<void>] The task.
15
+ #
15
16
  def defer_source(ephemeral: false)
16
17
  Async do
17
18
  @client.http.post("/interactions/#{@id}/#{@token}/callback", {
@@ -27,8 +28,7 @@ module Discorb
27
28
  #
28
29
  # Response with `CHANNEL_MESSAGE_WITH_SOURCE`(`4`).
29
30
  #
30
- # @macro async
31
- # @macro http
31
+ # @async
32
32
  #
33
33
  # @param [String] content The content of the response.
34
34
  # @param [Boolean] tts Whether to send the message as text-to-speech.
@@ -77,8 +77,7 @@ module Discorb
77
77
 
78
78
  #
79
79
  # Edits the callback message.
80
- # @macro async
81
- # @macro http
80
+ # @async
82
81
  # @macro edit
83
82
  #
84
83
  # @param [String] content The new content of the message.
@@ -88,27 +87,23 @@ module Discorb
88
87
  # @param [Discorb::File] file The file to send.
89
88
  # @param [Array<Discorb::File>] files The files to send.
90
89
  #
90
+ # @return [Async::Task<void>] The task.
91
+ #
91
92
  def edit(
92
- content = :unset,
93
- embed: :unset, embeds: :unset,
94
- file: :unset, files: :unset,
95
- attachments: :unset
93
+ content = Discorb::Unset,
94
+ embed: Discorb::Unset, embeds: Discorb::Unset,
95
+ file: Discorb::Unset, files: Discorb::Unset,
96
+ attachments: Discorb::Unset
96
97
  )
97
98
  Async do
98
99
  payload = {}
99
- payload[:content] = content if content != :unset
100
- payload[:embeds] = embed ? [embed.to_hash] : [] if embed != :unset
101
- payload[:embeds] = embeds.map(&:to_hash) if embeds != :unset
102
- payload[:attachments] = attachments.map(&:to_hash) if attachments != :unset
103
- files = [file] if file != :unset
104
- if files == :unset
105
- headers = {
106
- "Content-Type" => "application/json",
107
- }
108
- else
109
- headers, payload = HTTP.multipart(payload, files)
110
- end
111
- @client.http.patch("/webhooks/#{@application_id}/#{@token}/messages/@original", payload, headers: headers).wait
100
+ payload[:content] = content if content != Discorb::Unset
101
+ payload[:embeds] = embed ? [embed.to_hash] : [] if embed != Discorb::Unset
102
+ payload[:embeds] = embeds.map(&:to_hash) if embeds != Discorb::Unset
103
+ payload[:attachments] = attachments.map(&:to_hash) if attachments != Discorb::Unset
104
+ files = [file] if file != Discorb::Unset
105
+ files = [] if files == Discorb::Unset
106
+ @client.http.multipart_patch("/webhooks/#{@application_id}/#{@token}/messages/@original", payload, files, headers: headers).wait
112
107
  end
113
108
  end
114
109
 
@@ -116,8 +111,11 @@ module Discorb
116
111
 
117
112
  #
118
113
  # Deletes the callback message.
114
+ # @async
119
115
  # @note This will fail if the message is ephemeral.
120
116
  #
117
+ # @return [Async::Task<void>] The task.
118
+ #
121
119
  def delete!
122
120
  Async do
123
121
  @client.http.delete("/webhooks/#{@application_id}/#{@token}/messages/@original").wait
@@ -132,9 +130,12 @@ module Discorb
132
130
  module UpdateResponse
133
131
  #
134
132
  # Response with `DEFERRED_UPDATE_MESSAGE`(`6`).
133
+ # @async
135
134
  #
136
135
  # @param [Boolean] ephemeral Whether to make the response ephemeral.
137
136
  #
137
+ # @return [Async::Task<void>] The task.
138
+ #
138
139
  def defer_update(ephemeral: false)
139
140
  Async do
140
141
  @client.http.post("/interactions/#{@id}/#{@token}/callback", {
@@ -149,8 +150,7 @@ module Discorb
149
150
  #
150
151
  # Response with `UPDATE_MESSAGE`(`7`).
151
152
  #
152
- # @macro async
153
- # @macro http
153
+ # @async
154
154
  #
155
155
  # @param [String] content The content of the response.
156
156
  # @param [Boolean] tts Whether to send the message as text-to-speech.
@@ -160,6 +160,8 @@ module Discorb
160
160
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
161
161
  # @param [Boolean] ephemeral Whether to make the response ephemeral.
162
162
  #
163
+ # @return [Async::Task<void>] The task.
164
+ #
163
165
  def edit(content, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil, ephemeral: false)
164
166
  Async do
165
167
  payload = {}
@@ -18,6 +18,12 @@ module Discorb
18
18
  attr_reader :version
19
19
  # @return [String] The token for the interaction.
20
20
  attr_reader :token
21
+ # @return [Symbol] The locale of the user that created the interaction.
22
+ # @note This modifies the language code, `-` will be replaced with `_`.
23
+ attr_reader :locale
24
+ # @return [Symbol] The locale of the guild that created the interaction.
25
+ # @note This modifies the language code, `-` will be replaced with `_`.
26
+ attr_reader :guild_locale
21
27
 
22
28
  # @!attribute [r] guild
23
29
  # @macro client_cache
@@ -43,6 +49,8 @@ module Discorb
43
49
  @member = guild.members[data[:member][:id]] || Member.new(@client, @guild_id, data[:member][:user], data[:member]) if data[:member]
44
50
  @user = @client.users[data[:user][:id]] || User.new(@client, data[:user]) if data[:user]
45
51
  @token = data[:token]
52
+ @locale = data[:locale].to_s.gsub("-", "_").to_sym
53
+ @guild_locale = data[:guild_locale].to_s.gsub("-", "_").to_sym
46
54
  @version = data[:version]
47
55
  @defered = false
48
56
  @responded = false
@@ -100,8 +100,9 @@ module Discorb
100
100
  end
101
101
 
102
102
  # Delete the invite.
103
- # @macro async
104
- # @macro http
103
+ # @async
104
+ # @return [Async::Task<void>] The task.
105
+ #
105
106
  def delete!(reason: nil)
106
107
  Async do
107
108
  @client.http.delete("/invites/#{@code}", audit_log_reason: reason)
data/lib/discorb/log.rb CHANGED
@@ -13,6 +13,10 @@ module Discorb
13
13
  @colorize_log = colorize_log
14
14
  end
15
15
 
16
+ def inspect
17
+ "#<#{self.class} level=#{level}>"
18
+ end
19
+
16
20
  def level
17
21
  self.class.levels[@level]
18
22
  end
@@ -143,12 +143,13 @@ module Discorb
143
143
 
144
144
  #
145
145
  # Add a role to the member.
146
- # @macro http
147
- # @macro async
146
+ # @async
148
147
  #
149
148
  # @param [Discorb::Role] role The role to add.
150
149
  # @param [String] reason The reason for the action.
151
150
  #
151
+ # @return [Async::Task<void>] The task.
152
+ #
152
153
  def add_role(role, reason: nil)
153
154
  Async do
154
155
  @client.http.put("/guilds/#{@guild_id}/members/#{@id}/roles/#{role.is_a?(Role) ? role.id : role}", nil, audit_log_reason: reason).wait
@@ -157,12 +158,13 @@ module Discorb
157
158
 
158
159
  #
159
160
  # Remove a role to the member.
160
- # @macro http
161
- # @macro async
161
+ # @async
162
162
  #
163
163
  # @param [Discorb::Role] role The role to add.
164
164
  # @param [String] reason The reason for the action.
165
165
  #
166
+ # @return [Async::Task<void>] The task.
167
+ #
166
168
  def remove_role(role, reason: nil)
167
169
  Async do
168
170
  @client.http.delete("/guilds/#{@guild_id}/members/#{@id}/roles/#{role.is_a?(Role) ? role.id : role}", audit_log_reason: reason).wait
@@ -171,8 +173,7 @@ module Discorb
171
173
 
172
174
  #
173
175
  # Edit the member.
174
- # @macro http
175
- # @macro async
176
+ # @async
176
177
  # @macro edit
177
178
  #
178
179
  # @param [String] nick The nickname of the member.
@@ -180,27 +181,54 @@ module Discorb
180
181
  # @param [Boolean] mute Whether the member is muted.
181
182
  # @param [Boolean] deaf Whether the member is deafened.
182
183
  # @param [Discorb::StageChannel] channel The channel the member is moved to.
184
+ # @param [Time, nil] communication_disabled_until The time the member is timed out. Set to `nil` to end the timeout.
185
+ # @param [Time, nil] timeout_until Alias of `communication_disabled_until`.
183
186
  # @param [String] reason The reason for the action.
184
187
  #
185
- def edit(nick: :unset, role: :unset, mute: :unset, deaf: :unset, channel: :unset, reason: nil)
188
+ # @return [Async::Task<void>] The task.
189
+ #
190
+ def edit(
191
+ nick: Discorb::Unset, role: Discorb::Unset, mute: Discorb::Unset, deaf: Discorb::Unset, channel: Discorb::Unset, communication_disabled_until: Discorb::Unset, timeout_until: Discorb::Unset,
192
+ reason: nil
193
+ )
186
194
  Async do
187
195
  payload = {}
188
- payload[:nick] = nick if nick != :unset
189
- payload[:roles] = role if role != :unset
190
- payload[:mute] = mute if mute != :unset
191
- payload[:deaf] = deaf if deaf != :unset
192
- payload[:channel_id] = channel&.id if channel != :unset
196
+ payload[:nick] = nick if nick != Discorb::Unset
197
+ payload[:roles] = role if role != Discorb::Unset
198
+ payload[:mute] = mute if mute != Discorb::Unset
199
+ payload[:deaf] = deaf if deaf != Discorb::Unset
200
+ communication_disabled_until = timeout_until if timeout_until != Discorb::Unset
201
+ payload[:communication_disabled_until] = communication_disabled_until&.iso8601 if communication_disabled_until != Discorb::Unset
202
+ payload[:channel_id] = channel&.id if channel != Discorb::Unset
193
203
  @client.http.patch("/guilds/#{@guild_id}/members/#{@id}", payload, audit_log_reason: reason).wait
194
204
  end
195
205
  end
196
206
 
197
207
  alias modify edit
198
208
 
209
+ #
210
+ # Timeout the member.
211
+ # @async
212
+ #
213
+ # @param [Time] time The time until the member is timeout.
214
+ # @param [String] reason The reason for the action.
215
+ #
216
+ # @return [Async::Task<void>] The task.
217
+ #
218
+ def timeout(time, reason: nil)
219
+ edit(communication_disabled_until: time, reason: reason)
220
+ end
221
+
222
+ alias disable_communication timeout
223
+
199
224
  #
200
225
  # Kick the member.
226
+ # @async
201
227
  #
202
228
  # @param [String] reason The reason for the action.
203
229
  #
230
+ # @return [Async::Task<void>] The task.
231
+ #
204
232
  def kick(reason: nil)
205
233
  Async do
206
234
  guild.kick_member(self, reason: reason).wait
@@ -209,6 +237,7 @@ module Discorb
209
237
 
210
238
  #
211
239
  # Ban the member.
240
+ # @async
212
241
  #
213
242
  # @param [Integer] delete_message_days The number of days to delete messages.
214
243
  # @param [String] reason The reason for the action.
@@ -233,7 +262,7 @@ module Discorb
233
262
  @joined_at = member_data[:joined_at] && Time.iso8601(member_data[:joined_at])
234
263
  @hoisted_role_id = member_data[:hoisted_role]
235
264
  @deaf = member_data[:deaf]
236
- @custom_avatar = member_data[:avatar] && Asset.new(member_data[:avatar])
265
+ @custom_avatar = member_data[:avatar] && Asset.new(self, member_data[:avatar])
237
266
  super(user_data)
238
267
  @display_avatar = @avatar || @custom_avatar
239
268
  @client.guilds[@guild_id].members[@id] = self unless @guild_id.nil? || @client.guilds[@guild_id].nil?