discordrb 3.1.1 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of discordrb might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.circleci/config.yml +126 -0
- data/.codeclimate.yml +16 -0
- data/.github/CONTRIBUTING.md +13 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
- data/.github/pull_request_template.md +37 -0
- data/.gitignore +5 -0
- data/.rubocop.yml +39 -33
- data/.travis.yml +27 -2
- data/.yardopts +1 -1
- data/CHANGELOG.md +808 -208
- data/Gemfile +4 -1
- data/LICENSE.txt +1 -1
- data/README.md +108 -53
- data/Rakefile +14 -1
- data/bin/console +1 -0
- data/bin/travis_build_docs.sh +17 -0
- data/discordrb-webhooks.gemspec +26 -0
- data/discordrb.gemspec +24 -15
- data/lib/discordrb.rb +75 -2
- data/lib/discordrb/allowed_mentions.rb +36 -0
- data/lib/discordrb/api.rb +126 -27
- data/lib/discordrb/api/channel.rb +165 -43
- data/lib/discordrb/api/invite.rb +10 -7
- data/lib/discordrb/api/server.rb +240 -61
- data/lib/discordrb/api/user.rb +26 -24
- data/lib/discordrb/api/webhook.rb +83 -0
- data/lib/discordrb/await.rb +1 -2
- data/lib/discordrb/bot.rb +417 -149
- data/lib/discordrb/cache.rb +42 -10
- data/lib/discordrb/colour_rgb.rb +43 -0
- data/lib/discordrb/commands/command_bot.rb +186 -31
- data/lib/discordrb/commands/container.rb +30 -16
- data/lib/discordrb/commands/parser.rb +102 -47
- data/lib/discordrb/commands/rate_limiter.rb +18 -17
- data/lib/discordrb/container.rb +245 -41
- data/lib/discordrb/data.rb +27 -2511
- data/lib/discordrb/data/activity.rb +264 -0
- data/lib/discordrb/data/application.rb +50 -0
- data/lib/discordrb/data/attachment.rb +56 -0
- data/lib/discordrb/data/audit_logs.rb +345 -0
- data/lib/discordrb/data/channel.rb +849 -0
- data/lib/discordrb/data/embed.rb +251 -0
- data/lib/discordrb/data/emoji.rb +82 -0
- data/lib/discordrb/data/integration.rb +83 -0
- data/lib/discordrb/data/invite.rb +137 -0
- data/lib/discordrb/data/member.rb +297 -0
- data/lib/discordrb/data/message.rb +334 -0
- data/lib/discordrb/data/overwrite.rb +102 -0
- data/lib/discordrb/data/profile.rb +91 -0
- data/lib/discordrb/data/reaction.rb +33 -0
- data/lib/discordrb/data/recipient.rb +34 -0
- data/lib/discordrb/data/role.rb +191 -0
- data/lib/discordrb/data/server.rb +1002 -0
- data/lib/discordrb/data/user.rb +204 -0
- data/lib/discordrb/data/voice_region.rb +45 -0
- data/lib/discordrb/data/voice_state.rb +41 -0
- data/lib/discordrb/data/webhook.rb +145 -0
- data/lib/discordrb/errors.rb +36 -2
- data/lib/discordrb/events/bans.rb +7 -5
- data/lib/discordrb/events/channels.rb +2 -0
- data/lib/discordrb/events/generic.rb +19 -3
- data/lib/discordrb/events/guilds.rb +129 -6
- data/lib/discordrb/events/invites.rb +125 -0
- data/lib/discordrb/events/members.rb +6 -2
- data/lib/discordrb/events/message.rb +86 -36
- data/lib/discordrb/events/presence.rb +23 -16
- data/lib/discordrb/events/raw.rb +47 -0
- data/lib/discordrb/events/reactions.rb +159 -0
- data/lib/discordrb/events/roles.rb +7 -6
- data/lib/discordrb/events/typing.rb +9 -5
- data/lib/discordrb/events/voice_server_update.rb +47 -0
- data/lib/discordrb/events/voice_state_update.rb +29 -9
- data/lib/discordrb/events/webhooks.rb +64 -0
- data/lib/discordrb/gateway.rb +219 -88
- data/lib/discordrb/id_object.rb +39 -0
- data/lib/discordrb/light.rb +1 -1
- data/lib/discordrb/light/integrations.rb +1 -1
- data/lib/discordrb/light/light_bot.rb +1 -1
- data/lib/discordrb/logger.rb +12 -11
- data/lib/discordrb/paginator.rb +57 -0
- data/lib/discordrb/permissions.rb +148 -14
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +14 -15
- data/lib/discordrb/voice/network.rb +86 -45
- data/lib/discordrb/voice/sodium.rb +96 -0
- data/lib/discordrb/voice/voice_bot.rb +52 -40
- data/lib/discordrb/webhooks.rb +12 -0
- data/lib/discordrb/websocket.rb +2 -2
- metadata +137 -34
@@ -0,0 +1,849 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discordrb
|
4
|
+
# A Discord channel, including data like the topic
|
5
|
+
class Channel
|
6
|
+
include IDObject
|
7
|
+
|
8
|
+
# Map of channel types
|
9
|
+
TYPES = {
|
10
|
+
text: 0,
|
11
|
+
dm: 1,
|
12
|
+
voice: 2,
|
13
|
+
group: 3,
|
14
|
+
category: 4,
|
15
|
+
news: 5,
|
16
|
+
store: 6
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
# @return [String] this channel's name.
|
20
|
+
attr_reader :name
|
21
|
+
|
22
|
+
# @return [Server, nil] the server this channel is on. If this channel is a PM channel, it will be nil.
|
23
|
+
attr_reader :server
|
24
|
+
|
25
|
+
# @return [Integer, nil] the ID of the parent channel, if this channel is inside a category
|
26
|
+
attr_reader :parent_id
|
27
|
+
|
28
|
+
# @return [Integer] the type of this channel
|
29
|
+
# @see TYPES
|
30
|
+
attr_reader :type
|
31
|
+
|
32
|
+
# @return [Integer, nil] the ID of the owner of the group channel or nil if this is not a group channel.
|
33
|
+
attr_reader :owner_id
|
34
|
+
|
35
|
+
# @return [Array<Recipient>, nil] the array of recipients of the private messages, or nil if this is not a Private channel
|
36
|
+
attr_reader :recipients
|
37
|
+
|
38
|
+
# @return [String] the channel's topic
|
39
|
+
attr_reader :topic
|
40
|
+
|
41
|
+
# @return [Integer] the bitrate (in bps) of the channel
|
42
|
+
attr_reader :bitrate
|
43
|
+
|
44
|
+
# @return [Integer] the amount of users that can be in the channel. `0` means it is unlimited.
|
45
|
+
attr_reader :user_limit
|
46
|
+
alias_method :limit, :user_limit
|
47
|
+
|
48
|
+
# @return [Integer] the channel's position on the channel list
|
49
|
+
attr_reader :position
|
50
|
+
|
51
|
+
# @return [true, false] if this channel is marked as nsfw
|
52
|
+
attr_reader :nsfw
|
53
|
+
alias_method :nsfw?, :nsfw
|
54
|
+
|
55
|
+
# @return [Integer] the amount of time (in seconds) users need to wait to send in between messages.
|
56
|
+
attr_reader :rate_limit_per_user
|
57
|
+
alias_method :slowmode_rate, :rate_limit_per_user
|
58
|
+
|
59
|
+
# @return [true, false] whether or not this channel is a PM or group channel.
|
60
|
+
def private?
|
61
|
+
pm? || group?
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [String] a string that will mention the channel as a clickable link on Discord.
|
65
|
+
def mention
|
66
|
+
"<##{@id}>"
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [Recipient, nil] the recipient of the private messages, or nil if this is not a PM channel
|
70
|
+
def recipient
|
71
|
+
@recipients.first if pm?
|
72
|
+
end
|
73
|
+
|
74
|
+
# @!visibility private
|
75
|
+
def initialize(data, bot, server = nil)
|
76
|
+
@bot = bot
|
77
|
+
# data is sometimes a Hash and other times an array of Hashes, you only want the last one if it's an array
|
78
|
+
data = data[-1] if data.is_a?(Array)
|
79
|
+
|
80
|
+
@id = data['id'].to_i
|
81
|
+
@type = data['type'] || 0
|
82
|
+
@topic = data['topic']
|
83
|
+
@bitrate = data['bitrate']
|
84
|
+
@user_limit = data['user_limit']
|
85
|
+
@position = data['position']
|
86
|
+
@parent_id = data['parent_id'].to_i if data['parent_id']
|
87
|
+
|
88
|
+
if private?
|
89
|
+
@recipients = []
|
90
|
+
data['recipients']&.each do |recipient|
|
91
|
+
recipient_user = bot.ensure_user(recipient)
|
92
|
+
@recipients << Recipient.new(recipient_user, self, bot)
|
93
|
+
end
|
94
|
+
if pm?
|
95
|
+
@name = @recipients.first.username
|
96
|
+
else
|
97
|
+
@name = data['name']
|
98
|
+
@owner_id = data['owner_id']
|
99
|
+
end
|
100
|
+
else
|
101
|
+
@name = data['name']
|
102
|
+
@server = server || bot.server(data['guild_id'].to_i)
|
103
|
+
end
|
104
|
+
|
105
|
+
@nsfw = data['nsfw'] || false
|
106
|
+
@rate_limit_per_user = data['rate_limit_per_user'] || 0
|
107
|
+
|
108
|
+
process_permission_overwrites(data['permission_overwrites'])
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [true, false] whether or not this channel is a text channel
|
112
|
+
def text?
|
113
|
+
@type.zero?
|
114
|
+
end
|
115
|
+
|
116
|
+
# @return [true, false] whether or not this channel is a PM channel.
|
117
|
+
def pm?
|
118
|
+
@type == 1
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [true, false] whether or not this channel is a voice channel.
|
122
|
+
def voice?
|
123
|
+
@type == 2
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return [true, false] whether or not this channel is a group channel.
|
127
|
+
def group?
|
128
|
+
@type == 3
|
129
|
+
end
|
130
|
+
|
131
|
+
# @return [true, false] whether or not this channel is a category channel.
|
132
|
+
def category?
|
133
|
+
@type == 4
|
134
|
+
end
|
135
|
+
|
136
|
+
# @return [true, false] whether or not this channel is a news channel.
|
137
|
+
def news?
|
138
|
+
@type == 5
|
139
|
+
end
|
140
|
+
|
141
|
+
# @return [true, false] whether or not this channel is a store channel.
|
142
|
+
def store?
|
143
|
+
@type == 6
|
144
|
+
end
|
145
|
+
|
146
|
+
# @return [Channel, nil] the category channel, if this channel is in a category
|
147
|
+
def category
|
148
|
+
@bot.channel(@parent_id) if @parent_id
|
149
|
+
end
|
150
|
+
|
151
|
+
alias_method :parent, :category
|
152
|
+
|
153
|
+
# Sets this channels parent category
|
154
|
+
# @param channel [Channel, String, Integer] the target category channel, or its ID
|
155
|
+
# @raise [ArgumentError] if the target channel isn't a category
|
156
|
+
def category=(channel)
|
157
|
+
channel = @bot.channel(channel)
|
158
|
+
raise ArgumentError, 'Cannot set parent category to a channel that isn\'t a category' unless channel.category?
|
159
|
+
|
160
|
+
update_channel_data(parent_id: channel.id)
|
161
|
+
end
|
162
|
+
|
163
|
+
alias_method :parent=, :category=
|
164
|
+
|
165
|
+
# Sorts this channel's position to follow another channel.
|
166
|
+
# @param other [Channel, String, Integer, nil] The channel, or its ID, below which this channel should be sorted. If the given
|
167
|
+
# channel is a category, this channel will be sorted at the top of that category. If it is `nil`, the channel will
|
168
|
+
# be sorted at the top of the channel list.
|
169
|
+
# @param lock_permissions [true, false] Whether the channel's permissions should be synced to the category's
|
170
|
+
def sort_after(other = nil, lock_permissions = false)
|
171
|
+
raise TypeError, 'other must be one of Channel, NilClass, String, or Integer' unless other.is_a?(Channel) || other.nil? || other.respond_to?(:resolve_id)
|
172
|
+
|
173
|
+
other = @bot.channel(other.resolve_id) if other
|
174
|
+
|
175
|
+
# Container for the API request payload
|
176
|
+
move_argument = []
|
177
|
+
|
178
|
+
if other
|
179
|
+
raise ArgumentError, 'Can only sort a channel after a channel of the same type!' unless other.category? || (@type == other.type)
|
180
|
+
|
181
|
+
raise ArgumentError, 'Can only sort a channel after a channel in the same server!' unless other.server == server
|
182
|
+
|
183
|
+
# Store `others` parent (or if `other` is a category itself)
|
184
|
+
parent = if category? && other.category?
|
185
|
+
# If we're sorting two categories, there is no new parent
|
186
|
+
nil
|
187
|
+
elsif other.category?
|
188
|
+
# `other` is the category this channel will be moved into
|
189
|
+
other
|
190
|
+
else
|
191
|
+
# `other`'s parent is the category this channel will be
|
192
|
+
# moved into (if it exists)
|
193
|
+
other.parent
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Collect and sort the IDs within the context (category or not) that we
|
198
|
+
# need to form our payload with
|
199
|
+
ids = if parent
|
200
|
+
parent.children
|
201
|
+
else
|
202
|
+
@server.channels.reject(&:parent_id).select { |c| c.type == @type }
|
203
|
+
end.sort_by(&:position).map(&:id)
|
204
|
+
|
205
|
+
# Move our channel ID after the target ID by deleting it,
|
206
|
+
# getting the index of `other`, and inserting it after.
|
207
|
+
ids.delete(@id) if ids.include?(@id)
|
208
|
+
index = other ? (ids.index { |c| c == other.id } || -1) + 1 : 0
|
209
|
+
ids.insert(index, @id)
|
210
|
+
|
211
|
+
# Generate `move_argument`, making the positions in order from how
|
212
|
+
# we have sorted them in the above logic
|
213
|
+
ids.each_with_index do |id, pos|
|
214
|
+
# These keys are present in each element
|
215
|
+
hash = { id: id, position: pos }
|
216
|
+
|
217
|
+
# Conditionally add `lock_permissions` and `parent_id` if we're
|
218
|
+
# iterating past ourselves
|
219
|
+
if id == @id
|
220
|
+
hash[:lock_permissions] = true if lock_permissions
|
221
|
+
hash[:parent_id] = parent.nil? ? nil : parent.id
|
222
|
+
end
|
223
|
+
|
224
|
+
# Add it to the stack
|
225
|
+
move_argument << hash
|
226
|
+
end
|
227
|
+
|
228
|
+
API::Server.update_channel_positions(@bot.token, @server.id, move_argument)
|
229
|
+
end
|
230
|
+
|
231
|
+
# Sets whether this channel is NSFW
|
232
|
+
# @param nsfw [true, false]
|
233
|
+
# @raise [ArgumentError] if value isn't one of true, false
|
234
|
+
def nsfw=(nsfw)
|
235
|
+
raise ArgumentError, 'nsfw value must be true or false' unless nsfw.is_a?(TrueClass) || nsfw.is_a?(FalseClass)
|
236
|
+
|
237
|
+
update_channel_data(nsfw: nsfw)
|
238
|
+
end
|
239
|
+
|
240
|
+
# This channel's permission overwrites
|
241
|
+
# @overload permission_overwrites
|
242
|
+
# The overwrites represented as a hash of role/user ID
|
243
|
+
# to an Overwrite object
|
244
|
+
# @return [Hash<Integer => Overwrite>] the channel's permission overwrites
|
245
|
+
# @overload permission_overwrites(type)
|
246
|
+
# Return an array of a certain type of overwrite
|
247
|
+
# @param type [Symbol] the kind of overwrite to return
|
248
|
+
# @return [Array<Overwrite>]
|
249
|
+
def permission_overwrites(type = nil)
|
250
|
+
return @permission_overwrites unless type
|
251
|
+
|
252
|
+
@permission_overwrites.values.select { |e| e.type == type }
|
253
|
+
end
|
254
|
+
|
255
|
+
alias_method :overwrites, :permission_overwrites
|
256
|
+
|
257
|
+
# Bulk sets this channels permission overwrites
|
258
|
+
# @param overwrites [Array<Overwrite>]
|
259
|
+
def permission_overwrites=(overwrites)
|
260
|
+
update_channel_data(permission_overwrites: overwrites)
|
261
|
+
end
|
262
|
+
|
263
|
+
# Sets the amount of time (in seconds) users have to wait in between sending messages.
|
264
|
+
# @param rate [Integer]
|
265
|
+
# @raise [ArgumentError] if value isn't between 0 and 120
|
266
|
+
def rate_limit_per_user=(rate)
|
267
|
+
raise ArgumentError, 'rate_limit_per_user must be between 0 and 120' unless rate.between?(0, 120)
|
268
|
+
|
269
|
+
update_channel_data(rate_limit_per_user: rate)
|
270
|
+
end
|
271
|
+
|
272
|
+
alias_method :slowmode_rate=, :rate_limit_per_user=
|
273
|
+
|
274
|
+
# Syncs this channels overwrites with its parent category
|
275
|
+
# @raise [RuntimeError] if this channel is not in a category
|
276
|
+
def sync_overwrites
|
277
|
+
raise 'Cannot sync overwrites on a channel with no parent category' unless parent
|
278
|
+
|
279
|
+
self.permission_overwrites = parent.permission_overwrites
|
280
|
+
end
|
281
|
+
|
282
|
+
alias_method :sync, :sync_overwrites
|
283
|
+
|
284
|
+
# @return [true, false, nil] whether this channels permissions match the permission overwrites of the category that it's in, or nil if it is not in a category
|
285
|
+
def synchronized?
|
286
|
+
return unless parent
|
287
|
+
|
288
|
+
permission_overwrites == parent.permission_overwrites
|
289
|
+
end
|
290
|
+
|
291
|
+
alias_method :synced?, :synchronized?
|
292
|
+
|
293
|
+
# Returns the children of this channel, if it is a category. Otherwise returns an empty array.
|
294
|
+
# @return [Array<Channel>]
|
295
|
+
def children
|
296
|
+
return [] unless category?
|
297
|
+
|
298
|
+
server.channels.select { |c| c.parent_id == id }
|
299
|
+
end
|
300
|
+
|
301
|
+
alias_method :channels, :children
|
302
|
+
|
303
|
+
# Returns the text channels in this category, if it is a category channel. Otherwise returns an empty array.
|
304
|
+
# @return [Array<Channel>]
|
305
|
+
def text_channels
|
306
|
+
children.select(&:text?)
|
307
|
+
end
|
308
|
+
|
309
|
+
# Returns the voice channels in this category, if it is a category channel. Otherwise returns an empty array.
|
310
|
+
# @return [Array<Channel>]
|
311
|
+
def voice_channels
|
312
|
+
children.select(&:voice?)
|
313
|
+
end
|
314
|
+
|
315
|
+
# @return [Overwrite] any member-type permission overwrites on this channel
|
316
|
+
def member_overwrites
|
317
|
+
permission_overwrites :member
|
318
|
+
end
|
319
|
+
|
320
|
+
# @return [Overwrite] any role-type permission overwrites on this channel
|
321
|
+
def role_overwrites
|
322
|
+
permission_overwrites :role
|
323
|
+
end
|
324
|
+
|
325
|
+
# @return [true, false] whether or not this channel is the default channel
|
326
|
+
def default_channel?
|
327
|
+
server.default_channel == self
|
328
|
+
end
|
329
|
+
|
330
|
+
alias_method :default?, :default_channel?
|
331
|
+
|
332
|
+
# @return [true, false] whether or not this channel has slowmode enabled
|
333
|
+
def slowmode?
|
334
|
+
@rate_limit_per_user != 0
|
335
|
+
end
|
336
|
+
|
337
|
+
# Sends a message to this channel.
|
338
|
+
# @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error.
|
339
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
340
|
+
# @param embed [Hash, Discordrb::Webhooks::Embed, nil] The rich embed to append to this message.
|
341
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
342
|
+
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
343
|
+
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
344
|
+
# @return [Message] the message that was sent.
|
345
|
+
def send_message(content, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil)
|
346
|
+
@bot.send_message(@id, content, tts, embed, attachments, allowed_mentions, message_reference)
|
347
|
+
end
|
348
|
+
|
349
|
+
alias_method :send, :send_message
|
350
|
+
|
351
|
+
# Sends a temporary message to this channel.
|
352
|
+
# @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error.
|
353
|
+
# @param timeout [Float] The amount of time in seconds after which the message sent will be deleted.
|
354
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
355
|
+
# @param embed [Hash, Discordrb::Webhooks::Embed, nil] The rich embed to append to this message.
|
356
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
357
|
+
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
358
|
+
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
359
|
+
def send_temporary_message(content, timeout, tts = false, embed = nil, attachments = nil, allowed_mentions = nil, message_reference = nil)
|
360
|
+
@bot.send_temporary_message(@id, content, timeout, tts, embed, attachments, allowed_mentions, message_reference)
|
361
|
+
end
|
362
|
+
|
363
|
+
# Convenience method to send a message with an embed.
|
364
|
+
# @example Send a message with an embed
|
365
|
+
# channel.send_embed do |embed|
|
366
|
+
# embed.title = 'The Ruby logo'
|
367
|
+
# embed.image = Discordrb::Webhooks::EmbedImage.new(url: 'https://www.ruby-lang.org/images/header-ruby-logo.png')
|
368
|
+
# end
|
369
|
+
# @param message [String] The message that should be sent along with the embed. If this is the empty string, only the embed will be shown.
|
370
|
+
# @param embed [Discordrb::Webhooks::Embed, nil] The embed to start the building process with, or nil if one should be created anew.
|
371
|
+
# @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`
|
372
|
+
# @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
|
373
|
+
# @param allowed_mentions [Hash, Discordrb::AllowedMentions, false, nil] Mentions that are allowed to ping on this message. `false` disables all pings
|
374
|
+
# @param message_reference [Message, String, Integer, nil] The message, or message ID, to reply to if any.
|
375
|
+
# @yield [embed] Yields the embed to allow for easy building inside a block.
|
376
|
+
# @yieldparam embed [Discordrb::Webhooks::Embed] The embed from the parameters, or a new one.
|
377
|
+
# @return [Message] The resulting message.
|
378
|
+
def send_embed(message = '', embed = nil, attachments = nil, tts = false, allowed_mentions = nil, message_reference = nil)
|
379
|
+
embed ||= Discordrb::Webhooks::Embed.new
|
380
|
+
yield(embed) if block_given?
|
381
|
+
send_message(message, tts, embed, attachments, allowed_mentions, message_reference)
|
382
|
+
end
|
383
|
+
|
384
|
+
# Sends multiple messages to a channel
|
385
|
+
# @param content [Array<String>] The messages to send.
|
386
|
+
def send_multiple(content)
|
387
|
+
content.each { |e| send_message(e) }
|
388
|
+
end
|
389
|
+
|
390
|
+
# Splits a message into chunks whose length is at most the Discord character limit, then sends them individually.
|
391
|
+
# Useful for sending long messages, but be wary of rate limits!
|
392
|
+
def split_send(content)
|
393
|
+
send_multiple(Discordrb.split_message(content))
|
394
|
+
nil
|
395
|
+
end
|
396
|
+
|
397
|
+
# Sends a file to this channel. If it is an image, it will be embedded.
|
398
|
+
# @param file [File] The file to send. There's no clear size limit for this, you'll have to attempt it for yourself (most non-image files are fine, large images may fail to embed)
|
399
|
+
# @param caption [string] The caption for the file.
|
400
|
+
# @param tts [true, false] Whether or not this file's caption should be sent using Discord text-to-speech.
|
401
|
+
# @param filename [String] Overrides the filename of the uploaded file
|
402
|
+
# @param spoiler [true, false] Whether or not this file should appear as a spoiler.
|
403
|
+
# @example Send a file from disk
|
404
|
+
# channel.send_file(File.open('rubytaco.png', 'r'))
|
405
|
+
def send_file(file, caption: nil, tts: false, filename: nil, spoiler: nil)
|
406
|
+
@bot.send_file(@id, file, caption: caption, tts: tts, filename: filename, spoiler: spoiler)
|
407
|
+
end
|
408
|
+
|
409
|
+
# Deletes a message on this channel. Mostly useful in case a message needs to be deleted when only the ID is known
|
410
|
+
# @param message [Message, String, Integer, String, Integer] The message, or its ID, that should be deleted.
|
411
|
+
def delete_message(message)
|
412
|
+
API::Channel.delete_message(@bot.token, @id, message.resolve_id)
|
413
|
+
end
|
414
|
+
|
415
|
+
# Permanently deletes this channel
|
416
|
+
# @param reason [String] The reason the for the channel deletion.
|
417
|
+
def delete(reason = nil)
|
418
|
+
API::Channel.delete(@bot.token, @id, reason)
|
419
|
+
end
|
420
|
+
|
421
|
+
# Sets this channel's name. The name must be alphanumeric with dashes, unless this is a voice channel (then there are no limitations)
|
422
|
+
# @param name [String] The new name.
|
423
|
+
def name=(name)
|
424
|
+
update_channel_data(name: name)
|
425
|
+
end
|
426
|
+
|
427
|
+
# Sets this channel's topic.
|
428
|
+
# @param topic [String] The new topic.
|
429
|
+
def topic=(topic)
|
430
|
+
raise 'Tried to set topic on voice channel' if voice?
|
431
|
+
|
432
|
+
update_channel_data(topic: topic)
|
433
|
+
end
|
434
|
+
|
435
|
+
# Sets this channel's bitrate.
|
436
|
+
# @param bitrate [Integer] The new bitrate (in bps). Number has to be between 8000-96000 (128000 for VIP servers)
|
437
|
+
def bitrate=(bitrate)
|
438
|
+
raise 'Tried to set bitrate on text channel' if text?
|
439
|
+
|
440
|
+
update_channel_data(bitrate: bitrate)
|
441
|
+
end
|
442
|
+
|
443
|
+
# Sets this channel's user limit.
|
444
|
+
# @param limit [Integer] The new user limit. `0` for unlimited, has to be a number between 0-99
|
445
|
+
def user_limit=(limit)
|
446
|
+
raise 'Tried to set user_limit on text channel' if text?
|
447
|
+
|
448
|
+
update_channel_data(user_limit: limit)
|
449
|
+
end
|
450
|
+
|
451
|
+
alias_method :limit=, :user_limit=
|
452
|
+
|
453
|
+
# Sets this channel's position in the list.
|
454
|
+
# @param position [Integer] The new position.
|
455
|
+
def position=(position)
|
456
|
+
update_channel_data(position: position)
|
457
|
+
end
|
458
|
+
|
459
|
+
# Defines a permission overwrite for this channel that sets the specified thing to the specified allow and deny
|
460
|
+
# permission sets, or change an existing one.
|
461
|
+
# @overload define_overwrite(overwrite)
|
462
|
+
# @param thing [Overwrite] an Overwrite object to apply to this channel
|
463
|
+
# @param reason [String] The reason the for defining the overwrite.
|
464
|
+
# @overload define_overwrite(thing, allow, deny)
|
465
|
+
# @param thing [User, Role] What to define an overwrite for.
|
466
|
+
# @param allow [#bits, Permissions, Integer] The permission sets that should receive an `allow` override (i.e. a
|
467
|
+
# green checkmark on Discord)
|
468
|
+
# @param deny [#bits, Permissions, Integer] The permission sets that should receive a `deny` override (i.e. a red
|
469
|
+
# cross on Discord)
|
470
|
+
# @param reason [String] The reason the for defining the overwrite.
|
471
|
+
# @example Define a permission overwrite for a user that can then mention everyone and use TTS, but not create any invites
|
472
|
+
# allow = Discordrb::Permissions.new
|
473
|
+
# allow.can_mention_everyone = true
|
474
|
+
# allow.can_send_tts_messages = true
|
475
|
+
#
|
476
|
+
# deny = Discordrb::Permissions.new
|
477
|
+
# deny.can_create_instant_invite = true
|
478
|
+
#
|
479
|
+
# channel.define_overwrite(user, allow, deny)
|
480
|
+
def define_overwrite(thing, allow = 0, deny = 0, reason: nil)
|
481
|
+
unless thing.is_a? Overwrite
|
482
|
+
allow_bits = allow.respond_to?(:bits) ? allow.bits : allow
|
483
|
+
deny_bits = deny.respond_to?(:bits) ? deny.bits : deny
|
484
|
+
|
485
|
+
thing = Overwrite.new thing, allow: allow_bits, deny: deny_bits
|
486
|
+
end
|
487
|
+
|
488
|
+
API::Channel.update_permission(@bot.token, @id, thing.id, thing.allow.bits, thing.deny.bits, thing.type, reason)
|
489
|
+
end
|
490
|
+
|
491
|
+
# Deletes a permission overwrite for this channel
|
492
|
+
# @param target [Member, User, Role, Profile, Recipient, String, Integer] What permission overwrite to delete
|
493
|
+
# @param reason [String] The reason the for the overwrite deletion.
|
494
|
+
def delete_overwrite(target, reason = nil)
|
495
|
+
raise 'Tried deleting a overwrite for an invalid target' unless target.is_a?(Member) || target.is_a?(User) || target.is_a?(Role) || target.is_a?(Profile) || target.is_a?(Recipient) || target.respond_to?(:resolve_id)
|
496
|
+
|
497
|
+
API::Channel.delete_permission(@bot.token, @id, target.resolve_id, reason)
|
498
|
+
end
|
499
|
+
|
500
|
+
# Updates the cached data from another channel.
|
501
|
+
# @note For internal use only
|
502
|
+
# @!visibility private
|
503
|
+
def update_from(other)
|
504
|
+
@name = other.name
|
505
|
+
@position = other.position
|
506
|
+
@topic = other.topic
|
507
|
+
@recipients = other.recipients
|
508
|
+
@bitrate = other.bitrate
|
509
|
+
@user_limit = other.user_limit
|
510
|
+
@permission_overwrites = other.permission_overwrites
|
511
|
+
@nsfw = other.nsfw
|
512
|
+
@parent_id = other.parent_id
|
513
|
+
@rate_limit_per_user = other.rate_limit_per_user
|
514
|
+
end
|
515
|
+
|
516
|
+
# The list of users currently in this channel. For a voice channel, it will return all the members currently
|
517
|
+
# in that channel. For a text channel, it will return all online members that have permission to read it.
|
518
|
+
# @return [Array<Member>] the users in this channel
|
519
|
+
def users
|
520
|
+
if text?
|
521
|
+
@server.online_members(include_idle: true).select { |u| u.can_read_messages? self }
|
522
|
+
elsif voice?
|
523
|
+
@server.voice_states.map { |id, voice_state| @server.member(id) if !voice_state.voice_channel.nil? && voice_state.voice_channel.id == @id }.compact
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
# Retrieves some of this channel's message history.
|
528
|
+
# @param amount [Integer] How many messages to retrieve. This must be less than or equal to 100, if it is higher
|
529
|
+
# than 100 it will be treated as 100 on Discord's side.
|
530
|
+
# @param before_id [Integer] The ID of the most recent message the retrieval should start at, or nil if it should
|
531
|
+
# start at the current message.
|
532
|
+
# @param after_id [Integer] The ID of the oldest message the retrieval should start at, or nil if it should start
|
533
|
+
# as soon as possible with the specified amount.
|
534
|
+
# @param around_id [Integer] The ID of the message retrieval should start from, reading in both directions
|
535
|
+
# @example Count the number of messages in the last 50 messages that contain the letter 'e'.
|
536
|
+
# message_count = channel.history(50).count {|message| message.content.include? "e"}
|
537
|
+
# @example Get the last 10 messages before the provided message.
|
538
|
+
# last_ten_messages = channel.history(10, message.id)
|
539
|
+
# @return [Array<Message>] the retrieved messages.
|
540
|
+
def history(amount, before_id = nil, after_id = nil, around_id = nil)
|
541
|
+
logs = API::Channel.messages(@bot.token, @id, amount, before_id, after_id, around_id)
|
542
|
+
JSON.parse(logs).map { |message| Message.new(message, @bot) }
|
543
|
+
end
|
544
|
+
|
545
|
+
# Retrieves message history, but only message IDs for use with prune.
|
546
|
+
# @note For internal use only
|
547
|
+
# @!visibility private
|
548
|
+
def history_ids(amount, before_id = nil, after_id = nil, around_id = nil)
|
549
|
+
logs = API::Channel.messages(@bot.token, @id, amount, before_id, after_id, around_id)
|
550
|
+
JSON.parse(logs).map { |message| message['id'].to_i }
|
551
|
+
end
|
552
|
+
|
553
|
+
# Returns a single message from this channel's history by ID.
|
554
|
+
# @param message_id [Integer] The ID of the message to retrieve.
|
555
|
+
# @return [Message, nil] the retrieved message, or `nil` if it couldn't be found.
|
556
|
+
def load_message(message_id)
|
557
|
+
response = API::Channel.message(@bot.token, @id, message_id)
|
558
|
+
Message.new(JSON.parse(response), @bot)
|
559
|
+
rescue RestClient::ResourceNotFound
|
560
|
+
nil
|
561
|
+
end
|
562
|
+
|
563
|
+
alias_method :message, :load_message
|
564
|
+
|
565
|
+
# Requests all pinned messages in a channel.
|
566
|
+
# @return [Array<Message>] the received messages.
|
567
|
+
def pins
|
568
|
+
msgs = API::Channel.pinned_messages(@bot.token, @id)
|
569
|
+
JSON.parse(msgs).map { |msg| Message.new(msg, @bot) }
|
570
|
+
end
|
571
|
+
|
572
|
+
# Delete the last N messages on this channel.
|
573
|
+
# @param amount [Integer] The amount of message history to consider for pruning. Must be a value between 2 and 100 (Discord limitation)
|
574
|
+
# @param strict [true, false] Whether an error should be raised when a message is reached that is too old to be bulk
|
575
|
+
# deleted. If this is false only a warning message will be output to the console.
|
576
|
+
# @param reason [String, nil] The reason for pruning
|
577
|
+
# @raise [ArgumentError] if the amount of messages is not a value between 2 and 100
|
578
|
+
# @yield [message] Yields each message in this channels history for filtering the messages to delete
|
579
|
+
# @example Pruning messages from a specific user ID
|
580
|
+
# channel.prune(100) { |m| m.author.id == 83283213010599936 }
|
581
|
+
# @return [Integer] The amount of messages that were successfully deleted
|
582
|
+
def prune(amount, strict = false, reason = nil, &block)
|
583
|
+
raise ArgumentError, 'Can only delete between 1 and 100 messages!' unless amount.between?(1, 100)
|
584
|
+
|
585
|
+
messages =
|
586
|
+
if block
|
587
|
+
history(amount).select(&block).map(&:id)
|
588
|
+
else
|
589
|
+
history_ids(amount)
|
590
|
+
end
|
591
|
+
|
592
|
+
case messages.size
|
593
|
+
when 0
|
594
|
+
0
|
595
|
+
when 1
|
596
|
+
API::Channel.delete_message(@bot.token, @id, messages.first, reason)
|
597
|
+
1
|
598
|
+
else
|
599
|
+
bulk_delete(messages, strict, reason)
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
# Deletes a collection of messages
|
604
|
+
# @param messages [Array<Message, String, Integer>] the messages (or message IDs) to delete. Total must be an amount between 2 and 100 (Discord limitation)
|
605
|
+
# @param strict [true, false] Whether an error should be raised when a message is reached that is too old to be bulk
|
606
|
+
# deleted. If this is false only a warning message will be output to the console.
|
607
|
+
# @param reason [String, nil] The reason for deleting the messages
|
608
|
+
# @raise [ArgumentError] if the amount of messages is not a value between 2 and 100
|
609
|
+
# @return [Integer] The amount of messages that were successfully deleted
|
610
|
+
def delete_messages(messages, strict = false, reason = nil)
|
611
|
+
raise ArgumentError, 'Can only delete between 2 and 100 messages!' unless messages.count.between?(2, 100)
|
612
|
+
|
613
|
+
messages.map!(&:resolve_id)
|
614
|
+
bulk_delete(messages, strict, reason)
|
615
|
+
end
|
616
|
+
|
617
|
+
# Updates the cached permission overwrites
|
618
|
+
# @note For internal use only
|
619
|
+
# @!visibility private
|
620
|
+
def update_overwrites(overwrites)
|
621
|
+
@permission_overwrites = overwrites
|
622
|
+
end
|
623
|
+
|
624
|
+
# Add an {Await} for a message in this channel. This is identical in functionality to adding a
|
625
|
+
# {Discordrb::Events::MessageEvent} await with the `in` attribute as this channel.
|
626
|
+
# @see Bot#add_await
|
627
|
+
# @deprecated Will be changed to blocking behavior in v4.0. Use {#await!} instead.
|
628
|
+
def await(key, attributes = {}, &block)
|
629
|
+
@bot.add_await(key, Discordrb::Events::MessageEvent, { in: @id }.merge(attributes), &block)
|
630
|
+
end
|
631
|
+
|
632
|
+
# Add a blocking {Await} for a message in this channel. This is identical in functionality to adding a
|
633
|
+
# {Discordrb::Events::MessageEvent} await with the `in` attribute as this channel.
|
634
|
+
# @see Bot#add_await!
|
635
|
+
def await!(attributes = {}, &block)
|
636
|
+
@bot.add_await!(Discordrb::Events::MessageEvent, { in: @id }.merge(attributes), &block)
|
637
|
+
end
|
638
|
+
|
639
|
+
# Creates a new invite to this channel.
|
640
|
+
# @param max_age [Integer] How many seconds this invite should last.
|
641
|
+
# @param max_uses [Integer] How many times this invite should be able to be used.
|
642
|
+
# @param temporary [true, false] Whether membership should be temporary (kicked after going offline).
|
643
|
+
# @param unique [true, false] If true, Discord will always send a unique invite instead of possibly re-using a similar one
|
644
|
+
# @param reason [String] The reason the for the creation of this invite.
|
645
|
+
# @return [Invite] the created invite.
|
646
|
+
def make_invite(max_age = 0, max_uses = 0, temporary = false, unique = false, reason = nil)
|
647
|
+
response = API::Channel.create_invite(@bot.token, @id, max_age, max_uses, temporary, unique, reason)
|
648
|
+
Invite.new(JSON.parse(response), @bot)
|
649
|
+
end
|
650
|
+
|
651
|
+
alias_method :invite, :make_invite
|
652
|
+
|
653
|
+
# Starts typing, which displays the typing indicator on the client for five seconds.
|
654
|
+
# If you want to keep typing you'll have to resend this every five seconds. (An abstraction
|
655
|
+
# for this will eventually be coming)
|
656
|
+
# @example Send a typing indicator for the bot in a given channel.
|
657
|
+
# channel.start_typing()
|
658
|
+
def start_typing
|
659
|
+
API::Channel.start_typing(@bot.token, @id)
|
660
|
+
end
|
661
|
+
|
662
|
+
# Creates a Group channel
|
663
|
+
# @param user_ids [Array<Integer>] Array of user IDs to add to the new group channel (Excluding
|
664
|
+
# the recipient of the PM channel).
|
665
|
+
# @return [Channel] the created channel.
|
666
|
+
def create_group(user_ids)
|
667
|
+
raise 'Attempted to create group channel on a non-pm channel!' unless pm?
|
668
|
+
|
669
|
+
response = API::Channel.create_group(@bot.token, @id, user_ids.shift)
|
670
|
+
channel = Channel.new(JSON.parse(response), @bot)
|
671
|
+
channel.add_group_users(user_ids)
|
672
|
+
end
|
673
|
+
|
674
|
+
# Adds a user to a group channel.
|
675
|
+
# @param user_ids [Array<String, Integer>, String, Integer] User ID or array of user IDs to add to the group channel.
|
676
|
+
# @return [Channel] the group channel.
|
677
|
+
def add_group_users(user_ids)
|
678
|
+
raise 'Attempted to add a user to a non-group channel!' unless group?
|
679
|
+
|
680
|
+
user_ids = [user_ids] unless user_ids.is_a? Array
|
681
|
+
user_ids.each do |user_id|
|
682
|
+
API::Channel.add_group_user(@bot.token, @id, user_id.resolve_id)
|
683
|
+
end
|
684
|
+
self
|
685
|
+
end
|
686
|
+
|
687
|
+
alias_method :add_group_user, :add_group_users
|
688
|
+
|
689
|
+
# Removes a user from a group channel.
|
690
|
+
# @param user_ids [Array<String, Integer>, String, Integer] User ID or array of user IDs to remove from the group channel.
|
691
|
+
# @return [Channel] the group channel.
|
692
|
+
def remove_group_users(user_ids)
|
693
|
+
raise 'Attempted to remove a user from a non-group channel!' unless group?
|
694
|
+
|
695
|
+
user_ids = [user_ids] unless user_ids.is_a? Array
|
696
|
+
user_ids.each do |user_id|
|
697
|
+
API::Channel.remove_group_user(@bot.token, @id, user_id.resolve_id)
|
698
|
+
end
|
699
|
+
self
|
700
|
+
end
|
701
|
+
|
702
|
+
alias_method :remove_group_user, :remove_group_users
|
703
|
+
|
704
|
+
# Leaves the group.
|
705
|
+
def leave_group
|
706
|
+
raise 'Attempted to leave a non-group channel!' unless group?
|
707
|
+
|
708
|
+
API::Channel.leave_group(@bot.token, @id)
|
709
|
+
end
|
710
|
+
|
711
|
+
alias_method :leave, :leave_group
|
712
|
+
|
713
|
+
# Creates a webhook in this channel
|
714
|
+
# @param name [String] the default name of this webhook.
|
715
|
+
# @param avatar [String] the default avatar URL to give this webhook.
|
716
|
+
# @param reason [String] the reason for the webhook creation.
|
717
|
+
# @raise [ArgumentError] if the channel isn't a text channel in a server.
|
718
|
+
# @return [Webhook] the created webhook.
|
719
|
+
def create_webhook(name, avatar = nil, reason = nil)
|
720
|
+
raise ArgumentError, 'Tried to create a webhook in a non-server channel' unless server
|
721
|
+
raise ArgumentError, 'Tried to create a webhook in a non-text channel' unless text?
|
722
|
+
|
723
|
+
response = API::Channel.create_webhook(@bot.token, @id, name, avatar, reason)
|
724
|
+
Webhook.new(JSON.parse(response), @bot)
|
725
|
+
end
|
726
|
+
|
727
|
+
# Requests a list of Webhooks on the channel.
|
728
|
+
# @return [Array<Webhook>] webhooks on the channel.
|
729
|
+
def webhooks
|
730
|
+
raise 'Tried to request webhooks from a non-server channel' unless server
|
731
|
+
|
732
|
+
webhooks = JSON.parse(API::Channel.webhooks(@bot.token, @id))
|
733
|
+
webhooks.map { |webhook_data| Webhook.new(webhook_data, @bot) }
|
734
|
+
end
|
735
|
+
|
736
|
+
# Requests a list of Invites to the channel.
|
737
|
+
# @return [Array<Invite>] invites to the channel.
|
738
|
+
def invites
|
739
|
+
raise 'Tried to request invites from a non-server channel' unless server
|
740
|
+
|
741
|
+
invites = JSON.parse(API::Channel.invites(@bot.token, @id))
|
742
|
+
invites.map { |invite_data| Invite.new(invite_data, @bot) }
|
743
|
+
end
|
744
|
+
|
745
|
+
# The default `inspect` method is overwritten to give more useful output.
|
746
|
+
def inspect
|
747
|
+
"<Channel name=#{@name} id=#{@id} topic=\"#{@topic}\" type=#{@type} position=#{@position} server=#{@server}>"
|
748
|
+
end
|
749
|
+
|
750
|
+
# Adds a recipient to a group channel.
|
751
|
+
# @param recipient [Recipient] the recipient to add to the group
|
752
|
+
# @raise [ArgumentError] if tried to add a non-recipient
|
753
|
+
# @note For internal use only
|
754
|
+
# @!visibility private
|
755
|
+
def add_recipient(recipient)
|
756
|
+
raise 'Tried to add recipient to a non-group channel' unless group?
|
757
|
+
raise ArgumentError, 'Tried to add a non-recipient to a group' unless recipient.is_a?(Recipient)
|
758
|
+
|
759
|
+
@recipients << recipient
|
760
|
+
end
|
761
|
+
|
762
|
+
# Removes a recipient from a group channel.
|
763
|
+
# @param recipient [Recipient] the recipient to remove from the group
|
764
|
+
# @raise [ArgumentError] if tried to remove a non-recipient
|
765
|
+
# @note For internal use only
|
766
|
+
# @!visibility private
|
767
|
+
def remove_recipient(recipient)
|
768
|
+
raise 'Tried to remove recipient from a non-group channel' unless group?
|
769
|
+
raise ArgumentError, 'Tried to remove a non-recipient from a group' unless recipient.is_a?(Recipient)
|
770
|
+
|
771
|
+
@recipients.delete(recipient)
|
772
|
+
end
|
773
|
+
|
774
|
+
# Updates the cached data with new data
|
775
|
+
# @note For internal use only
|
776
|
+
# @!visibility private
|
777
|
+
def update_data(new_data = nil)
|
778
|
+
new_data ||= JSON.parse(API::Channel.resolve(@bot.token, @id))
|
779
|
+
@name = new_data[:name] || new_data['name'] || @name
|
780
|
+
@topic = new_data[:topic] || new_data['topic'] || @topic
|
781
|
+
@position = new_data[:position] || new_data['position'] || @position
|
782
|
+
@bitrate = new_data[:bitrate] || new_data['bitrate'] || @bitrate
|
783
|
+
@user_limit = new_data[:user_limit] || new_data['user_limit'] || @user_limit
|
784
|
+
new_nsfw = new_data.key?(:nsfw) ? new_data[:nsfw] : new_data['nsfw']
|
785
|
+
@nsfw = new_nsfw.nil? ? @nsfw : new_nsfw
|
786
|
+
@parent_id = new_data[:parent_id] || new_data['parent_id'] || @parent_id
|
787
|
+
process_permission_overwrites(new_data[:permission_overwrites] || new_data['permission_overwrites'])
|
788
|
+
@rate_limit_per_user = new_data[:rate_limit_per_user] || new_data['rate_limit_per_user'] || @rate_limit_per_user
|
789
|
+
end
|
790
|
+
|
791
|
+
# @return [String] a URL that a user can use to navigate to this channel in the client
|
792
|
+
def link
|
793
|
+
"https://discord.com/channels/#{@server&.id || '@me'}/#{@channel.id}"
|
794
|
+
end
|
795
|
+
|
796
|
+
alias_method :jump_link, :link
|
797
|
+
|
798
|
+
private
|
799
|
+
|
800
|
+
# For bulk_delete checking
|
801
|
+
TWO_WEEKS = 86_400 * 14
|
802
|
+
|
803
|
+
# Deletes a list of messages on this channel using bulk delete.
|
804
|
+
def bulk_delete(ids, strict = false, reason = nil)
|
805
|
+
min_snowflake = IDObject.synthesise(Time.now - TWO_WEEKS)
|
806
|
+
|
807
|
+
ids.reject! do |e|
|
808
|
+
next unless e < min_snowflake
|
809
|
+
|
810
|
+
message = "Attempted to bulk_delete message #{e} which is too old (min = #{min_snowflake})"
|
811
|
+
raise ArgumentError, message if strict
|
812
|
+
|
813
|
+
Discordrb::LOGGER.warn(message)
|
814
|
+
true
|
815
|
+
end
|
816
|
+
|
817
|
+
API::Channel.bulk_delete_messages(@bot.token, @id, ids, reason)
|
818
|
+
ids.size
|
819
|
+
end
|
820
|
+
|
821
|
+
def update_channel_data(new_data)
|
822
|
+
new_nsfw = new_data[:nsfw].is_a?(TrueClass) || new_data[:nsfw].is_a?(FalseClass) ? new_data[:nsfw] : @nsfw
|
823
|
+
# send permission_overwrite only when explicitly set
|
824
|
+
overwrites = new_data[:permission_overwrites] ? new_data[:permission_overwrites].map { |_, v| v.to_hash } : nil
|
825
|
+
response = JSON.parse(API::Channel.update(@bot.token, @id,
|
826
|
+
new_data[:name] || @name,
|
827
|
+
new_data[:topic] || @topic,
|
828
|
+
new_data[:position] || @position,
|
829
|
+
new_data[:bitrate] || @bitrate,
|
830
|
+
new_data[:user_limit] || @user_limit,
|
831
|
+
new_nsfw,
|
832
|
+
overwrites,
|
833
|
+
new_data[:parent_id] || @parent_id,
|
834
|
+
new_data[:rate_limit_per_user] || @rate_limit_per_user))
|
835
|
+
update_data(response)
|
836
|
+
end
|
837
|
+
|
838
|
+
def process_permission_overwrites(overwrites)
|
839
|
+
# Populate permission overwrites
|
840
|
+
@permission_overwrites = {}
|
841
|
+
return unless overwrites
|
842
|
+
|
843
|
+
overwrites.each do |element|
|
844
|
+
id = element['id'].to_i
|
845
|
+
@permission_overwrites[id] = Overwrite.from_hash(element)
|
846
|
+
end
|
847
|
+
end
|
848
|
+
end
|
849
|
+
end
|