discordrb 3.3.0 → 3.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +126 -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/.rubocop.yml +34 -37
- data/.travis.yml +5 -6
- data/CHANGELOG.md +504 -347
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +61 -79
- data/Rakefile +2 -0
- data/bin/console +1 -0
- data/discordrb-webhooks.gemspec +6 -6
- data/discordrb.gemspec +18 -18
- data/lib/discordrb/allowed_mentions.rb +36 -0
- data/lib/discordrb/api/channel.rb +62 -39
- data/lib/discordrb/api/invite.rb +3 -3
- data/lib/discordrb/api/server.rb +57 -50
- data/lib/discordrb/api/user.rb +9 -8
- data/lib/discordrb/api/webhook.rb +6 -6
- data/lib/discordrb/api.rb +40 -15
- data/lib/discordrb/await.rb +0 -1
- data/lib/discordrb/bot.rb +175 -73
- data/lib/discordrb/cache.rb +4 -2
- data/lib/discordrb/colour_rgb.rb +43 -0
- data/lib/discordrb/commands/command_bot.rb +30 -9
- data/lib/discordrb/commands/container.rb +20 -23
- data/lib/discordrb/commands/parser.rb +18 -18
- data/lib/discordrb/commands/rate_limiter.rb +3 -2
- data/lib/discordrb/container.rb +77 -17
- data/lib/discordrb/data/activity.rb +271 -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/data.rb +25 -4180
- data/lib/discordrb/errors.rb +2 -1
- data/lib/discordrb/events/bans.rb +7 -5
- data/lib/discordrb/events/channels.rb +2 -0
- data/lib/discordrb/events/guilds.rb +16 -9
- data/lib/discordrb/events/invites.rb +125 -0
- data/lib/discordrb/events/members.rb +6 -2
- data/lib/discordrb/events/message.rb +69 -27
- data/lib/discordrb/events/presence.rb +14 -4
- data/lib/discordrb/events/raw.rb +1 -3
- data/lib/discordrb/events/reactions.rb +49 -3
- data/lib/discordrb/events/typing.rb +6 -4
- data/lib/discordrb/events/voice_server_update.rb +47 -0
- data/lib/discordrb/events/voice_state_update.rb +15 -10
- data/lib/discordrb/events/webhooks.rb +9 -6
- data/lib/discordrb/gateway.rb +72 -57
- data/lib/discordrb/id_object.rb +39 -0
- data/lib/discordrb/light/integrations.rb +1 -1
- data/lib/discordrb/light/light_bot.rb +1 -1
- data/lib/discordrb/logger.rb +4 -4
- data/lib/discordrb/paginator.rb +57 -0
- data/lib/discordrb/permissions.rb +103 -8
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +16 -7
- data/lib/discordrb/voice/network.rb +84 -43
- data/lib/discordrb/voice/sodium.rb +96 -0
- data/lib/discordrb/voice/voice_bot.rb +34 -26
- data/lib/discordrb.rb +73 -0
- metadata +98 -60
- /data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +0 -0
@@ -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
|