discorb 0.19.0 → 0.20.0

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +2 -2
  3. data/.rubocop.yml +12 -75
  4. data/Changelog.md +10 -0
  5. data/Rakefile +482 -454
  6. data/lib/discorb/allowed_mentions.rb +68 -72
  7. data/lib/discorb/app_command/command.rb +466 -398
  8. data/lib/discorb/app_command/common.rb +65 -25
  9. data/lib/discorb/app_command/handler.rb +304 -266
  10. data/lib/discorb/app_command.rb +5 -5
  11. data/lib/discorb/application.rb +198 -197
  12. data/lib/discorb/asset.rb +101 -101
  13. data/lib/discorb/attachment.rb +134 -119
  14. data/lib/discorb/audit_logs.rb +412 -385
  15. data/lib/discorb/automod.rb +279 -269
  16. data/lib/discorb/channel/base.rb +107 -108
  17. data/lib/discorb/channel/category.rb +32 -32
  18. data/lib/discorb/channel/container.rb +44 -44
  19. data/lib/discorb/channel/dm.rb +26 -28
  20. data/lib/discorb/channel/guild.rb +311 -246
  21. data/lib/discorb/channel/stage.rb +156 -140
  22. data/lib/discorb/channel/text.rb +430 -336
  23. data/lib/discorb/channel/thread.rb +374 -325
  24. data/lib/discorb/channel/voice.rb +85 -79
  25. data/lib/discorb/channel.rb +5 -5
  26. data/lib/discorb/client.rb +635 -621
  27. data/lib/discorb/color.rb +178 -182
  28. data/lib/discorb/common.rb +168 -164
  29. data/lib/discorb/components/button.rb +107 -106
  30. data/lib/discorb/components/select_menu.rb +157 -145
  31. data/lib/discorb/components/text_input.rb +103 -106
  32. data/lib/discorb/components.rb +68 -66
  33. data/lib/discorb/dictionary.rb +135 -135
  34. data/lib/discorb/embed.rb +404 -398
  35. data/lib/discorb/emoji.rb +309 -302
  36. data/lib/discorb/emoji_table.rb +16099 -8857
  37. data/lib/discorb/error.rb +131 -131
  38. data/lib/discorb/event.rb +360 -314
  39. data/lib/discorb/event_handler.rb +39 -39
  40. data/lib/discorb/exe/about.rb +17 -17
  41. data/lib/discorb/exe/irb.rb +72 -67
  42. data/lib/discorb/exe/new.rb +323 -315
  43. data/lib/discorb/exe/run.rb +69 -68
  44. data/lib/discorb/exe/setup.rb +57 -55
  45. data/lib/discorb/exe/show.rb +12 -12
  46. data/lib/discorb/extend.rb +25 -45
  47. data/lib/discorb/extension.rb +89 -83
  48. data/lib/discorb/flag.rb +126 -128
  49. data/lib/discorb/gateway.rb +984 -804
  50. data/lib/discorb/gateway_events.rb +670 -638
  51. data/lib/discorb/gateway_requests.rb +45 -48
  52. data/lib/discorb/guild.rb +2115 -1626
  53. data/lib/discorb/guild_template.rb +280 -241
  54. data/lib/discorb/http.rb +247 -232
  55. data/lib/discorb/image.rb +42 -42
  56. data/lib/discorb/integration.rb +169 -161
  57. data/lib/discorb/intents.rb +161 -163
  58. data/lib/discorb/interaction/autocomplete.rb +76 -62
  59. data/lib/discorb/interaction/command.rb +279 -224
  60. data/lib/discorb/interaction/components.rb +114 -104
  61. data/lib/discorb/interaction/modal.rb +36 -32
  62. data/lib/discorb/interaction/response.rb +379 -336
  63. data/lib/discorb/interaction/root.rb +271 -257
  64. data/lib/discorb/interaction.rb +5 -5
  65. data/lib/discorb/invite.rb +154 -153
  66. data/lib/discorb/member.rb +344 -311
  67. data/lib/discorb/message.rb +615 -544
  68. data/lib/discorb/message_meta.rb +197 -186
  69. data/lib/discorb/modules.rb +371 -290
  70. data/lib/discorb/permission.rb +305 -291
  71. data/lib/discorb/presence.rb +352 -346
  72. data/lib/discorb/rate_limit.rb +81 -76
  73. data/lib/discorb/reaction.rb +55 -54
  74. data/lib/discorb/role.rb +272 -240
  75. data/lib/discorb/shard.rb +76 -74
  76. data/lib/discorb/sticker.rb +193 -171
  77. data/lib/discorb/user.rb +205 -188
  78. data/lib/discorb/utils/colored_puts.rb +16 -16
  79. data/lib/discorb/utils.rb +12 -16
  80. data/lib/discorb/voice_state.rb +305 -281
  81. data/lib/discorb/webhook.rb +537 -507
  82. data/lib/discorb.rb +62 -56
  83. data/sig/discorb/application.rbs +2 -0
  84. data/sig/discorb/automod.rbs +10 -1
  85. data/sig/discorb/guild.rbs +2 -0
  86. data/sig/discorb/message.rbs +2 -0
  87. data/sig/discorb/user.rbs +22 -20
  88. metadata +2 -2
@@ -1,290 +1,371 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Module for sending and reading messages.
6
- #
7
- module Messageable
8
- #
9
- # Post a message to the channel.
10
- # @async
11
- #
12
- # @param [String] content The message content.
13
- # @param [Boolean] tts Whether the message is tts.
14
- # @param [Discorb::Embed] embed The embed to send.
15
- # @param [Array<Discorb::Embed>] embeds The embeds to send.
16
- # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
17
- # @param [Discorb::Message, Discorb::Message::Reference] reference The message to reply to.
18
- # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
19
- # @param [Discorb::Attachment] attachment The attachment to send.
20
- # @param [Array<Discorb::Attachment>] attachments The attachments to send.
21
- #
22
- # @return [Async::Task<Discorb::Message>] The message sent.
23
- #
24
- def post(
25
- content = nil,
26
- tts: false,
27
- embed: nil,
28
- embeds: nil,
29
- allowed_mentions: nil,
30
- reference: nil,
31
- components: nil,
32
- attachment: nil,
33
- attachments: nil
34
- )
35
- Async do
36
- payload = {}
37
- payload[:content] = content if content
38
- payload[:tts] = tts
39
- tmp_embed = if embed
40
- [embed]
41
- elsif embeds
42
- embeds
43
- end
44
- payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
45
- payload[:allowed_mentions] =
46
- allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
47
- payload[:message_reference] = reference.to_reference.to_hash if reference
48
- payload[:components] = Component.to_payload(components) if components
49
- attachments ||= attachment ? [attachment] : []
50
-
51
- payload[:attachments] = attachments.map.with_index do |a, i|
52
- {
53
- id: i,
54
- filename: a.filename,
55
- description: a.description,
56
- }
57
- end
58
-
59
- _resp, data = @client.http.multipart_request(
60
- Route.new("/channels/#{channel_id.wait}/messages", "//channels/:channel_id/messages",
61
- :post), payload, attachments
62
- ).wait
63
- Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
64
- end
65
- end
66
-
67
- alias send_message post
68
-
69
- #
70
- # Edit a message.
71
- # @async
72
- # @!macro edit
73
- #
74
- # @param [#to_s] message_id The message id.
75
- # @param [String] content The message content.
76
- # @param [Discorb::Embed] embed The embed to send.
77
- # @param [Array<Discorb::Embed>] embeds The embeds to send.
78
- # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
79
- # @param [Array<Discorb::Attachment>] attachments The new attachments.
80
- # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
81
- # @param [Boolean] supress Whether to supress embeds.
82
- #
83
- # @return [Async::Task<void>] The task.
84
- #
85
- def edit_message(
86
- message_id,
87
- content = Discorb::Unset,
88
- embed: Discorb::Unset,
89
- embeds: Discorb::Unset,
90
- allowed_mentions: Discorb::Unset,
91
- attachments: Discorb::Unset,
92
- components: Discorb::Unset,
93
- supress: Discorb::Unset
94
- )
95
- Async do
96
- payload = {}
97
- payload[:content] = content if content != Discorb::Unset
98
- tmp_embed = if embed != Discorb::Unset
99
- [embed]
100
- elsif embeds != Discorb::Unset
101
- embeds
102
- end
103
- payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
104
- payload[:allowed_mentions] = if allowed_mentions == Discorb::Unset
105
- @client.allowed_mentions.to_hash
106
- else
107
- allowed_mentions.to_hash(@client.allowed_mentions)
108
- end
109
- payload[:components] = Component.to_payload(components) if components != Discorb::Unset
110
- payload[:flags] = (supress ? 1 << 2 : 0) if supress != Discorb::Unset
111
- if attachments != Discorb::Unset
112
- payload[:attachments] = attachments.map.with_index do |a, i|
113
- {
114
- id: i,
115
- filename: a.filename,
116
- description: a.description,
117
- }
118
- end
119
- end
120
- @client.http.multipart_request(
121
- Route.new("/channels/#{channel_id.wait}/messages/#{message_id}",
122
- "//channels/:channel_id/messages/:message_id", :patch),
123
- payload,
124
- attachments == Discorb::Unset ? [] : attachments
125
- ).wait
126
- end
127
- end
128
-
129
- #
130
- # Delete a message.
131
- # @async
132
- #
133
- # @param [#to_s] message_id The message id.
134
- # @param [String] reason The reason for deleting the message.
135
- #
136
- # @return [Async::Task<void>] The task.
137
- #
138
- def delete_message(message_id, reason: nil)
139
- Async do
140
- @client.http.request(
141
- Route.new(
142
- "/channels/#{channel_id.wait}/messages/#{message_id}", "//channels/:channel_id/messages/:message_id",
143
- :delete
144
- ), {}, audit_log_reason: reason,
145
- ).wait
146
- end
147
- end
148
-
149
- alias destroy_message delete_message
150
-
151
- #
152
- # Fetch a message from ID.
153
- # @async
154
- #
155
- # @param [Discorb::Snowflake] id The ID of the message.
156
- #
157
- # @return [Async::Task<Discorb::Message>] The message.
158
- # @raise [Discorb::NotFoundError] If the message is not found.
159
- #
160
- def fetch_message(id)
161
- Async do
162
- _resp, data = @client.http.request(Route.new("/channels/#{channel_id.wait}/messages/#{id}",
163
- "//channels/:channel_id/messages/:message_id", :get)).wait
164
- Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
165
- end
166
- end
167
-
168
- #
169
- # Fetch a message history.
170
- # @async
171
- #
172
- # @param [Integer] limit The number of messages to fetch.
173
- # @param [Discorb::Snowflake] before The ID of the message to fetch before.
174
- # @param [Discorb::Snowflake] after The ID of the message to fetch after.
175
- # @param [Discorb::Snowflake] around The ID of the message to fetch around.
176
- #
177
- # @return [Async::Task<Array<Discorb::Message>>] The messages.
178
- #
179
- def fetch_messages(limit = 50, before: nil, after: nil, around: nil)
180
- Async do
181
- params = {
182
- limit: limit,
183
- before: Discorb::Utils.try(after, :id),
184
- after: Discorb::Utils.try(around, :id),
185
- around: Discorb::Utils.try(before, :id),
186
- }.filter { |_k, v| !v.nil? }.to_h
187
- _resp, messages = @client.http.request(
188
- Route.new(
189
- "/channels/#{channel_id.wait}/messages?#{URI.encode_www_form(params)}", "//channels/:channel_id/messages",
190
- :get
191
- )
192
- ).wait
193
- messages.map { |m| Message.new(@client, m.merge({ guild_id: @guild_id.to_s })) }
194
- end
195
- end
196
-
197
- #
198
- # Fetch the pinned messages in the channel.
199
- # @async
200
- #
201
- # @return [Async::Task<Array<Discorb::Message>>] The pinned messages in the channel.
202
- #
203
- def fetch_pins
204
- Async do
205
- _resp, data = @client.http.request(Route.new("/channels/#{channel_id.wait}/pins",
206
- "//channels/:channel_id/pins", :get)).wait
207
- data.map { |pin| Message.new(@client, pin) }
208
- end
209
- end
210
-
211
- #
212
- # Pin a message in the channel.
213
- # @async
214
- #
215
- # @param [Discorb::Message] message The message to pin.
216
- # @param [String] reason The reason of pinning the message.
217
- #
218
- # @return [Async::Task<void>] The task.
219
- #
220
- def pin_message(message, reason: nil)
221
- Async do
222
- @client.http.request(
223
- Route.new("/channels/#{channel_id.wait}/pins/#{message.id}", "//channels/:channel_id/pins/:message_id",
224
- :put), {}, audit_log_reason: reason,
225
- ).wait
226
- end
227
- end
228
-
229
- #
230
- # Unpin a message in the channel.
231
- # @async
232
- #
233
- # @param [Discorb::Message] message The message to unpin.
234
- # @param [String] reason The reason of unpinning the message.
235
- #
236
- # @return [Async::Task<void>] The task.
237
- #
238
- def unpin_message(message, reason: nil)
239
- Async do
240
- @client.http.request(
241
- Route.new("/channels/#{channel_id.wait}/pins/#{message.id}", "//channels/:channel_id/pins/:message_id",
242
- :delete), {}, audit_log_reason: reason,
243
- ).wait
244
- end
245
- end
246
-
247
- #
248
- # Trigger the typing indicator in the channel.
249
- # @async
250
- #
251
- # If block is given, trigger typing indicator during executing block.
252
- # @example
253
- # channel.typing do
254
- # channel.post("Waiting for 60 seconds...")
255
- # sleep 60
256
- # channel.post("Done!")
257
- # end
258
- #
259
- def typing
260
- if block_given?
261
- begin
262
- post_task = Async do
263
- loop do
264
- @client.http.request(Route.new("/channels/#{@id}/typing", "//channels/:channel_id/typing", :post), {})
265
- sleep(5)
266
- end
267
- end
268
- ret = yield
269
- ensure
270
- post_task.stop
271
- end
272
- ret
273
- else
274
- Async do |_task|
275
- @client.http.request(Route.new("/channels/#{@id}/typing", "//channels/:channel_id/typing", :post), {})
276
- end
277
- end
278
- end
279
- end
280
-
281
- #
282
- # Module for connecting to a voice channel.
283
- # This will be discord-voice gem.
284
- #
285
- module Connectable
286
- def connect
287
- raise NotImplementedError, "This method is implemented by discord-voice gem."
288
- end
289
- end
290
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Module for sending and reading messages.
6
+ #
7
+ module Messageable
8
+ #
9
+ # Post a message to the channel.
10
+ # @async
11
+ #
12
+ # @param [String] content The message content.
13
+ # @param [Boolean] tts Whether the message is tts.
14
+ # @param [Discorb::Embed] embed The embed to send.
15
+ # @param [Array<Discorb::Embed>] embeds The embeds to send.
16
+ # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
17
+ # @param [Discorb::Message, Discorb::Message::Reference] reference The message to reply to.
18
+ # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
19
+ # @param [Discorb::Attachment] attachment The attachment to send.
20
+ # @param [Array<Discorb::Attachment>] attachments The attachments to send.
21
+ #
22
+ # @return [Async::Task<Discorb::Message>] The message sent.
23
+ #
24
+ def post(
25
+ content = nil,
26
+ tts: false,
27
+ embed: nil,
28
+ embeds: nil,
29
+ allowed_mentions: nil,
30
+ reference: nil,
31
+ components: nil,
32
+ attachment: nil,
33
+ attachments: nil
34
+ )
35
+ Async do
36
+ payload = {}
37
+ payload[:content] = content if content
38
+ payload[:tts] = tts
39
+ tmp_embed =
40
+ if embed
41
+ [embed]
42
+ elsif embeds
43
+ embeds
44
+ end
45
+ payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
46
+ payload[:allowed_mentions] = (
47
+ if allowed_mentions
48
+ allowed_mentions.to_hash(@client.allowed_mentions)
49
+ else
50
+ @client.allowed_mentions.to_hash
51
+ end
52
+ )
53
+ payload[
54
+ :message_reference
55
+ ] = reference.to_reference.to_hash if reference
56
+ payload[:components] = Component.to_payload(components) if components
57
+ attachments ||= attachment ? [attachment] : []
58
+
59
+ payload[:attachments] = attachments.map.with_index do |a, i|
60
+ { id: i, filename: a.filename, description: a.description }
61
+ end
62
+
63
+ _resp, data =
64
+ @client
65
+ .http
66
+ .multipart_request(
67
+ Route.new(
68
+ "/channels/#{channel_id.wait}/messages",
69
+ "//channels/:channel_id/messages",
70
+ :post
71
+ ),
72
+ payload,
73
+ attachments
74
+ )
75
+ .wait
76
+ Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
77
+ end
78
+ end
79
+
80
+ alias send_message post
81
+
82
+ #
83
+ # Edit a message.
84
+ # @async
85
+ # @!macro edit
86
+ #
87
+ # @param [#to_s] message_id The message id.
88
+ # @param [String] content The message content.
89
+ # @param [Discorb::Embed] embed The embed to send.
90
+ # @param [Array<Discorb::Embed>] embeds The embeds to send.
91
+ # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
92
+ # @param [Array<Discorb::Attachment>] attachments The new attachments.
93
+ # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
94
+ # @param [Boolean] supress Whether to supress embeds.
95
+ #
96
+ # @return [Async::Task<void>] The task.
97
+ #
98
+ def edit_message(
99
+ message_id,
100
+ content = Discorb::Unset,
101
+ embed: Discorb::Unset,
102
+ embeds: Discorb::Unset,
103
+ allowed_mentions: Discorb::Unset,
104
+ attachments: Discorb::Unset,
105
+ components: Discorb::Unset,
106
+ supress: Discorb::Unset
107
+ )
108
+ Async do
109
+ payload = {}
110
+ payload[:content] = content if content != Discorb::Unset
111
+ tmp_embed =
112
+ if embed != Discorb::Unset
113
+ [embed]
114
+ elsif embeds != Discorb::Unset
115
+ embeds
116
+ end
117
+ payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
118
+ payload[:allowed_mentions] = if allowed_mentions == Discorb::Unset
119
+ @client.allowed_mentions.to_hash
120
+ else
121
+ allowed_mentions.to_hash(@client.allowed_mentions)
122
+ end
123
+ payload[:components] = Component.to_payload(components) if components !=
124
+ Discorb::Unset
125
+ payload[:flags] = (supress ? 1 << 2 : 0) if supress != Discorb::Unset
126
+ if attachments != Discorb::Unset
127
+ payload[:attachments] = attachments.map.with_index do |a, i|
128
+ { id: i, filename: a.filename, description: a.description }
129
+ end
130
+ end
131
+ @client
132
+ .http
133
+ .multipart_request(
134
+ Route.new(
135
+ "/channels/#{channel_id.wait}/messages/#{message_id}",
136
+ "//channels/:channel_id/messages/:message_id",
137
+ :patch
138
+ ),
139
+ payload,
140
+ attachments == Discorb::Unset ? [] : attachments
141
+ )
142
+ .wait
143
+ end
144
+ end
145
+
146
+ #
147
+ # Delete a message.
148
+ # @async
149
+ #
150
+ # @param [#to_s] message_id The message id.
151
+ # @param [String] reason The reason for deleting the message.
152
+ #
153
+ # @return [Async::Task<void>] The task.
154
+ #
155
+ def delete_message(message_id, reason: nil)
156
+ Async do
157
+ @client
158
+ .http
159
+ .request(
160
+ Route.new(
161
+ "/channels/#{channel_id.wait}/messages/#{message_id}",
162
+ "//channels/:channel_id/messages/:message_id",
163
+ :delete
164
+ ),
165
+ {},
166
+ audit_log_reason: reason
167
+ )
168
+ .wait
169
+ end
170
+ end
171
+
172
+ alias destroy_message delete_message
173
+
174
+ #
175
+ # Fetch a message from ID.
176
+ # @async
177
+ #
178
+ # @param [Discorb::Snowflake] id The ID of the message.
179
+ #
180
+ # @return [Async::Task<Discorb::Message>] The message.
181
+ # @raise [Discorb::NotFoundError] If the message is not found.
182
+ #
183
+ def fetch_message(id)
184
+ Async do
185
+ _resp, data =
186
+ @client
187
+ .http
188
+ .request(
189
+ Route.new(
190
+ "/channels/#{channel_id.wait}/messages/#{id}",
191
+ "//channels/:channel_id/messages/:message_id",
192
+ :get
193
+ )
194
+ )
195
+ .wait
196
+ Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
197
+ end
198
+ end
199
+
200
+ #
201
+ # Fetch a message history.
202
+ # @async
203
+ #
204
+ # @param [Integer] limit The number of messages to fetch.
205
+ # @param [Discorb::Snowflake] before The ID of the message to fetch before.
206
+ # @param [Discorb::Snowflake] after The ID of the message to fetch after.
207
+ # @param [Discorb::Snowflake] around The ID of the message to fetch around.
208
+ #
209
+ # @return [Async::Task<Array<Discorb::Message>>] The messages.
210
+ #
211
+ def fetch_messages(limit = 50, before: nil, after: nil, around: nil)
212
+ Async do
213
+ params =
214
+ {
215
+ limit: limit,
216
+ before: Discorb::Utils.try(after, :id),
217
+ after: Discorb::Utils.try(around, :id),
218
+ around: Discorb::Utils.try(before, :id)
219
+ }.filter { |_k, v| !v.nil? }.to_h
220
+ _resp, messages =
221
+ @client
222
+ .http
223
+ .request(
224
+ Route.new(
225
+ "/channels/#{channel_id.wait}/messages?#{URI.encode_www_form(params)}",
226
+ "//channels/:channel_id/messages",
227
+ :get
228
+ )
229
+ )
230
+ .wait
231
+ messages.map do |m|
232
+ Message.new(@client, m.merge({ guild_id: @guild_id.to_s }))
233
+ end
234
+ end
235
+ end
236
+
237
+ #
238
+ # Fetch the pinned messages in the channel.
239
+ # @async
240
+ #
241
+ # @return [Async::Task<Array<Discorb::Message>>] The pinned messages in the channel.
242
+ #
243
+ def fetch_pins
244
+ Async do
245
+ _resp, data =
246
+ @client
247
+ .http
248
+ .request(
249
+ Route.new(
250
+ "/channels/#{channel_id.wait}/pins",
251
+ "//channels/:channel_id/pins",
252
+ :get
253
+ )
254
+ )
255
+ .wait
256
+ data.map { |pin| Message.new(@client, pin) }
257
+ end
258
+ end
259
+
260
+ #
261
+ # Pin a message in the channel.
262
+ # @async
263
+ #
264
+ # @param [Discorb::Message] message The message to pin.
265
+ # @param [String] reason The reason of pinning the message.
266
+ #
267
+ # @return [Async::Task<void>] The task.
268
+ #
269
+ def pin_message(message, reason: nil)
270
+ Async do
271
+ @client
272
+ .http
273
+ .request(
274
+ Route.new(
275
+ "/channels/#{channel_id.wait}/pins/#{message.id}",
276
+ "//channels/:channel_id/pins/:message_id",
277
+ :put
278
+ ),
279
+ {},
280
+ audit_log_reason: reason
281
+ )
282
+ .wait
283
+ end
284
+ end
285
+
286
+ #
287
+ # Unpin a message in the channel.
288
+ # @async
289
+ #
290
+ # @param [Discorb::Message] message The message to unpin.
291
+ # @param [String] reason The reason of unpinning the message.
292
+ #
293
+ # @return [Async::Task<void>] The task.
294
+ #
295
+ def unpin_message(message, reason: nil)
296
+ Async do
297
+ @client
298
+ .http
299
+ .request(
300
+ Route.new(
301
+ "/channels/#{channel_id.wait}/pins/#{message.id}",
302
+ "//channels/:channel_id/pins/:message_id",
303
+ :delete
304
+ ),
305
+ {},
306
+ audit_log_reason: reason
307
+ )
308
+ .wait
309
+ end
310
+ end
311
+
312
+ #
313
+ # Trigger the typing indicator in the channel.
314
+ # @async
315
+ #
316
+ # If block is given, trigger typing indicator during executing block.
317
+ # @example
318
+ # channel.typing do
319
+ # channel.post("Waiting for 60 seconds...")
320
+ # sleep 60
321
+ # channel.post("Done!")
322
+ # end
323
+ #
324
+ def typing
325
+ if block_given?
326
+ begin
327
+ post_task =
328
+ Async do
329
+ loop do
330
+ @client.http.request(
331
+ Route.new(
332
+ "/channels/#{@id}/typing",
333
+ "//channels/:channel_id/typing",
334
+ :post
335
+ ),
336
+ {}
337
+ )
338
+ sleep(5)
339
+ end
340
+ end
341
+ ret = yield
342
+ ensure
343
+ post_task.stop
344
+ end
345
+ ret
346
+ else
347
+ Async do |_task|
348
+ @client.http.request(
349
+ Route.new(
350
+ "/channels/#{@id}/typing",
351
+ "//channels/:channel_id/typing",
352
+ :post
353
+ ),
354
+ {}
355
+ )
356
+ end
357
+ end
358
+ end
359
+ end
360
+
361
+ #
362
+ # Module for connecting to a voice channel.
363
+ # This will be discord-voice gem.
364
+ #
365
+ module Connectable
366
+ def connect
367
+ raise NotImplementedError,
368
+ "This method is implemented by discord-voice gem."
369
+ end
370
+ end
371
+ end