discordrb 3.1.1 → 3.2.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.

@@ -10,6 +10,7 @@ require 'discordrb/api/channel'
10
10
  require 'discordrb/api/server'
11
11
  require 'discordrb/api/invite'
12
12
  require 'discordrb/api/user'
13
+ require 'discordrb/webhooks/embeds'
13
14
  require 'time'
14
15
  require 'base64'
15
16
 
@@ -84,6 +85,18 @@ module Discordrb
84
85
  ms = (@id >> 22) + DISCORD_EPOCH
85
86
  Time.at(ms / 1000.0)
86
87
  end
88
+
89
+ # Creates an artificial snowflake at the given point in time. Useful for comparing against.
90
+ # @param time [Time] The time the snowflake should represent.
91
+ # @return [Integer] a snowflake with the timestamp data as the given time
92
+ def self.synthesise(time)
93
+ ms = (time.to_f * 1000).to_i
94
+ (ms - DISCORD_EPOCH) << 22
95
+ end
96
+
97
+ class << self
98
+ alias_method :synthesize, :synthesise
99
+ end
87
100
  end
88
101
 
89
102
  # Mixin for the attributes users should have
@@ -104,7 +117,7 @@ module Discordrb
104
117
 
105
118
  # @return [String] the ID of this user's current avatar, can be used to generate an avatar URL.
106
119
  # @see #avatar_url
107
- attr_reader :avatar_id
120
+ attr_accessor :avatar_id
108
121
 
109
122
  # Utility function to mention users in messages
110
123
  # @return [String] the mention code in the form of <@id>
@@ -130,13 +143,18 @@ module Discordrb
130
143
  include IDObject
131
144
  include UserAttributes
132
145
 
133
- # @!attribute [r] status
134
- # @return [Symbol] the current online status of the user (`:online`, `:offline` or `:idle`)
135
- attr_accessor :status
146
+ # @return [Symbol] the current online status of the user (`:online`, `:offline` or `:idle`)
147
+ attr_reader :status
148
+
149
+ # @return [String, nil] the game the user is currently playing, or `nil` if none is being played.
150
+ attr_reader :game
151
+
152
+ # @return [String, nil] the URL to the stream, if the user is currently streaming something.
153
+ attr_reader :stream_url
136
154
 
137
- # @!attribute [r] game
138
- # @return [String, nil] the game the user is currently playing, or `nil` if none is being played.
139
- attr_accessor :game
155
+ # @return [String, Integer, nil] the type of the stream. Can technically be set to anything, most of the time it
156
+ # will be 0 for no stream or 1 for Twitch streams.
157
+ attr_reader :stream_type
140
158
 
141
159
  def initialize(data, bot)
142
160
  @bot = bot
@@ -189,6 +207,23 @@ module Discordrb
189
207
  @username = username
190
208
  end
191
209
 
210
+ # Set the user's presence data
211
+ # @note for internal use only
212
+ # @!visibility private
213
+ def update_presence(data)
214
+ @status = data['status'].to_sym
215
+
216
+ if data['game']
217
+ game = data['game']
218
+
219
+ @game = game['name']
220
+ @stream_url = game['url']
221
+ @stream_type = game['type']
222
+ else
223
+ @game = @stream_url = @stream_type = nil
224
+ end
225
+ end
226
+
192
227
  # Add an await for a message from this user. Specifically, this adds a global await for a MessageEvent with this
193
228
  # user's ID as a :from attribute.
194
229
  # @see Bot#add_await
@@ -418,6 +453,8 @@ module Discordrb
418
453
  end
419
454
  end
420
455
 
456
+ # A presence represents a
457
+
421
458
  # A member is a user on a server. It differs from regular users in that it has roles, voice statuses and things like
422
459
  # that.
423
460
  class Member < DelegateClass(User)
@@ -1031,6 +1068,7 @@ module Discordrb
1031
1068
  # `allow` and `deny` properties which are {Permissions} objects respectively.
1032
1069
  # @return [Hash<Integer => OpenStruct>] the channel's permission overwrites
1033
1070
  attr_reader :permission_overwrites
1071
+ alias_method :overwrites, :permission_overwrites
1034
1072
 
1035
1073
  # @return [true, false] whether or not this channel is a PM or group channel.
1036
1074
  def private?
@@ -1119,9 +1157,10 @@ module Discordrb
1119
1157
  # Sends a message to this channel.
1120
1158
  # @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error.
1121
1159
  # @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
1160
+ # @param embed [Hash, Discordrb::Webhooks::Embed, nil] The rich embed to append to this message.
1122
1161
  # @return [Message] the message that was sent.
1123
- def send_message(content, tts = false)
1124
- @bot.send_message(@id, content, tts, @server && @server.id)
1162
+ def send_message(content, tts = false, embed = nil)
1163
+ @bot.send_message(@id, content, tts, embed)
1125
1164
  end
1126
1165
 
1127
1166
  alias_method :send, :send_message
@@ -1130,8 +1169,26 @@ module Discordrb
1130
1169
  # @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error.
1131
1170
  # @param timeout [Float] The amount of time in seconds after which the message sent will be deleted.
1132
1171
  # @param tts [true, false] Whether or not this message should be sent using Discord text-to-speech.
1133
- def send_temporary_message(content, timeout, tts = false)
1134
- @bot.send_temporary_message(@id, content, timeout, tts, @server && @server.id)
1172
+ # @param embed [Hash, Discordrb::Webhooks::Embed, nil] The rich embed to append to this message.
1173
+ def send_temporary_message(content, timeout, tts = false, embed = nil)
1174
+ @bot.send_temporary_message(@id, content, timeout, tts, embed)
1175
+ end
1176
+
1177
+ # Convenience method to send a message with an embed.
1178
+ # @example Send a message with an embed
1179
+ # channel.send_embed do |embed|
1180
+ # embed.title = 'The Ruby logo'
1181
+ # embed.image = Discordrb::Webhooks::EmbedImage.new(url: 'https://www.ruby-lang.org/images/header-ruby-logo.png')
1182
+ # end
1183
+ # @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.
1184
+ # @param embed [Discordrb::Webhooks::Embed, nil] The embed to start the building process with, or nil if one should be created anew.
1185
+ # @yield [embed] Yields the embed to allow for easy building inside a block.
1186
+ # @yieldparam embed [Discordrb::Webhooks::Embed] The embed from the parameters, or a new one.
1187
+ # @return [Message] The resulting message.
1188
+ def send_embed(message = '', embed = nil)
1189
+ embed ||= Discordrb::Webhooks::Embed.new
1190
+ yield(embed) if block_given?
1191
+ send_message(message, false, embed)
1135
1192
  end
1136
1193
 
1137
1194
  # Sends multiple messages to a channel
@@ -1154,6 +1211,12 @@ module Discordrb
1154
1211
  @bot.send_file(@id, file, caption: caption, tts: tts)
1155
1212
  end
1156
1213
 
1214
+ # Deletes a message on this channel. Mostly useful in case a message needs to be deleted when only the ID is known
1215
+ # @param message [Message, String, Integer, #resolve_id] The message that should be deleted.
1216
+ def delete_message(message)
1217
+ API::Channel.delete_message(@bot.token, @id, message.resolve_id)
1218
+ end
1219
+
1157
1220
  # Permanently deletes this channel
1158
1221
  def delete
1159
1222
  API::Channel.delete(@bot.token, @id)
@@ -1230,12 +1293,25 @@ module Discordrb
1230
1293
  API::Channel.update_permission(@bot.token, @id, thing.id, allow_bits, deny_bits, type)
1231
1294
  end
1232
1295
 
1296
+ # Deletes a permission overwrite for this channel
1297
+ # @param target [Member, User, Role, Profile, Recipient, #resolve_id] What permission overwrite to delete
1298
+ def delete_overwrite(target)
1299
+ 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)
1300
+
1301
+ API::Channel.delete_permission(@bot.token, @id, target.resolve_id)
1302
+ end
1303
+
1233
1304
  # Updates the cached data from another channel.
1234
1305
  # @note For internal use only
1235
1306
  # @!visibility private
1236
1307
  def update_from(other)
1237
1308
  @topic = other.topic
1238
1309
  @name = other.name
1310
+ @position = other.position
1311
+ @topic = other.topic
1312
+ @recipients = other.recipients
1313
+ @bitrate = other.bitrate
1314
+ @user_limit = other.user_limit
1239
1315
  @permission_overwrites = other.permission_overwrites
1240
1316
  end
1241
1317
 
@@ -1270,7 +1346,7 @@ module Discordrb
1270
1346
  # @!visibility private
1271
1347
  def history_ids(amount, before_id = nil, after_id = nil)
1272
1348
  logs = API::Channel.messages(@bot.token, @id, amount, before_id, after_id)
1273
- JSON.parse(logs).map { |message| message['id'] }
1349
+ JSON.parse(logs).map { |message| message['id'].to_i }
1274
1350
  end
1275
1351
 
1276
1352
  # Returns a single message from this channel's history by ID.
@@ -1294,22 +1370,26 @@ module Discordrb
1294
1370
 
1295
1371
  # Delete the last N messages on this channel.
1296
1372
  # @param amount [Integer] How many messages to delete. Must be a value between 2 and 100 (Discord limitation)
1373
+ # @param strict [true, false] Whether an error should be raised when a message is reached that is too old to be bulk
1374
+ # deleted. If this is false only a warning message will be output to the console.
1297
1375
  # @raise [ArgumentError] if the amount of messages is not a value between 2 and 100
1298
- def prune(amount)
1376
+ def prune(amount, strict = false)
1299
1377
  raise ArgumentError, 'Can only prune between 2 and 100 messages!' unless amount.between?(2, 100)
1300
1378
 
1301
1379
  messages = history_ids(amount)
1302
- API::Channel.bulk_delete_messages(@bot.token, @id, messages)
1380
+ bulk_delete(messages, strict)
1303
1381
  end
1304
1382
 
1305
1383
  # Deletes a collection of messages
1306
1384
  # @param messages [Array<Message, Integer>] the messages (or message IDs) to delete. Total must be an amount between 2 and 100 (Discord limitation)
1385
+ # @param strict [true, false] Whether an error should be raised when a message is reached that is too old to be bulk
1386
+ # deleted. If this is false only a warning message will be output to the console.
1307
1387
  # @raise [ArgumentError] if the amount of messages is not a value between 2 and 100
1308
- def delete_messages(messages)
1388
+ def delete_messages(messages, strict = false)
1309
1389
  raise ArgumentError, 'Can only delete between 2 and 100 messages!' unless messages.count.between?(2, 100)
1310
1390
 
1311
1391
  messages.map!(&:resolve_id)
1312
- API::Channel.bulk_delete_messages(@bot.token, @id, messages)
1392
+ bulk_delete(messages, strict)
1313
1393
  end
1314
1394
 
1315
1395
  # Updates the cached permission overwrites
@@ -1414,13 +1494,32 @@ module Discordrb
1414
1494
  # @note For internal use only
1415
1495
  # @!visibility private
1416
1496
  def remove_recipient(recipient)
1417
- raise 'Tried to add recipient to a non-group channel' unless group?
1497
+ raise 'Tried to remove recipient from a non-group channel' unless group?
1418
1498
  raise ArgumentError, 'Tried to remove a non-recipient from a group' unless recipient.is_a?(Recipient)
1419
1499
  @recipients.delete(recipient)
1420
1500
  end
1421
1501
 
1422
1502
  private
1423
1503
 
1504
+ # For bulk_delete checking
1505
+ TWO_WEEKS = 86_400 * 14
1506
+
1507
+ # Deletes a list of messages on this channel using bulk delete
1508
+ def bulk_delete(ids, strict = false)
1509
+ min_snowflake = IDObject.synthesise(Time.now - TWO_WEEKS)
1510
+
1511
+ ids.reject! do |e|
1512
+ next unless e < min_snowflake
1513
+
1514
+ message = "Attempted to bulk_delete message #{e} which is too old (min = #{min_snowflake})"
1515
+ raise ArgumentError, message if strict
1516
+ Discordrb::LOGGER.warn(message)
1517
+ false
1518
+ end
1519
+
1520
+ API::Channel.bulk_delete_messages(@bot.token, @id, ids)
1521
+ end
1522
+
1424
1523
  def update_channel_data
1425
1524
  API::Channel.update(@bot.token, @id, @name, @topic, @position, @bitrate, @user_limit)
1426
1525
  end
@@ -1597,7 +1696,8 @@ module Discordrb
1597
1696
  alias_method :text, :content
1598
1697
  alias_method :to_s, :content
1599
1698
 
1600
- # @return [Member] the user that sent this message.
1699
+ # @return [Member, User] the user that sent this message. (Will be a {Member} most of the time, it should only be a
1700
+ # {User} for old messages when the author has left the server since then)
1601
1701
  attr_reader :author
1602
1702
  alias_method :user, :author
1603
1703
  alias_method :writer, :author
@@ -1624,6 +1724,9 @@ module Discordrb
1624
1724
  # @return [Array<Embed>] the embed objects contained in this message.
1625
1725
  attr_reader :embeds
1626
1726
 
1727
+ # @return [Hash<String, Reaction>] the reaction objects attached to this message keyed by the name of the reaction
1728
+ attr_reader :reactions
1729
+
1627
1730
  # @return [true, false] whether the message used Text-To-Speech (TTS) or not.
1628
1731
  attr_reader :tts
1629
1732
  alias_method :tts?, :tts
@@ -1672,7 +1775,12 @@ module Discordrb
1672
1775
  Recipient.new(bot.user(data['author']['id'].to_i), @channel, bot)
1673
1776
  else
1674
1777
  member = @channel.server.member(data['author']['id'].to_i)
1675
- Discordrb::LOGGER.warn("Member with ID #{data['author']['id']} not cached even though it should be.") unless member
1778
+
1779
+ unless member
1780
+ Discordrb::LOGGER.debug("Member with ID #{data['author']['id']} not cached (possibly left the server).")
1781
+ member = @bot.user(data['author']['id'].to_i)
1782
+ end
1783
+
1676
1784
  member
1677
1785
  end
1678
1786
  end
@@ -1686,19 +1794,31 @@ module Discordrb
1686
1794
 
1687
1795
  @emoji = []
1688
1796
 
1797
+ @reactions = {}
1798
+
1799
+ if data['reactions']
1800
+ data['reactions'].each do |element|
1801
+ @reactions[element['emoji']['name']] = Reaction.new(element)
1802
+ end
1803
+ end
1804
+
1689
1805
  @mentions = []
1690
1806
 
1691
- data['mentions'].each do |element|
1692
- @mentions << bot.ensure_user(element)
1693
- end if data['mentions']
1807
+ if data['mentions']
1808
+ data['mentions'].each do |element|
1809
+ @mentions << bot.ensure_user(element)
1810
+ end
1811
+ end
1694
1812
 
1695
1813
  @role_mentions = []
1696
1814
 
1697
1815
  # Role mentions can only happen on public servers so make sure we only parse them there
1698
1816
  if @channel.text?
1699
- data['mention_roles'].each do |element|
1700
- @role_mentions << @channel.server.role(element.to_i)
1701
- end if data['mention_roles']
1817
+ if data['mention_roles']
1818
+ data['mention_roles'].each do |element|
1819
+ @role_mentions << @channel.server.role(element.to_i)
1820
+ end
1821
+ end
1702
1822
  end
1703
1823
 
1704
1824
  @attachments = []
@@ -1717,9 +1837,10 @@ module Discordrb
1717
1837
  # Edits this message to have the specified content instead.
1718
1838
  # You can only edit your own messages.
1719
1839
  # @param new_content [String] the new content the message should have.
1840
+ # @param new_embed [Hash, Discordrb::Webhooks::Embed, nil] The new embed the message should have. If nil the message will be changed to have no embed.
1720
1841
  # @return [Message] the resulting message.
1721
- def edit(new_content)
1722
- response = API::Channel.edit_message(@bot.token, @channel.id, @id, new_content)
1842
+ def edit(new_content, new_embed = nil)
1843
+ response = API::Channel.edit_message(@bot.token, @channel.id, @id, new_content, [], new_embed ? new_embed.to_hash : nil)
1723
1844
  Message.new(JSON.parse(response), @bot)
1724
1845
  end
1725
1846
 
@@ -1785,12 +1906,86 @@ module Discordrb
1785
1906
  return true unless emoji.empty?
1786
1907
  end
1787
1908
 
1909
+ # Check if any reactions got used in this message
1910
+ # @return [true, false] whether or not this message has reactions
1911
+ def reactions?
1912
+ @reactions.any?
1913
+ end
1914
+
1915
+ # Returns the reactions made by the current bot or user
1916
+ # @return [Array<Reaction>] the reactions
1917
+ def my_reactions
1918
+ @reactions.select(&:me)
1919
+ end
1920
+
1921
+ # Reacts to a message
1922
+ # @param [String, #to_reaction] the unicode emoji, Emoji, or GlobalEmoji
1923
+ def create_reaction(reaction)
1924
+ reaction = reaction.to_reaction if reaction.respond_to?(:to_reaction)
1925
+ API::Channel.create_reaction(@bot.token, @channel.id, @id, reaction)
1926
+ nil
1927
+ end
1928
+
1929
+ alias_method :react, :create_reaction
1930
+
1931
+ # Returns the list of users who reacted with a certain reaction
1932
+ # @param [String, #to_reaction] the unicode emoji, Emoji, or GlobalEmoji
1933
+ # @return [Array<User>] the users who used this reaction
1934
+ def reacted_with(reaction)
1935
+ reaction = reaction.to_reaction if reaction.respond_to?(:to_reaction)
1936
+ response = JSON.parse(API::Channel.get_reactions(@bot.token, @channel.id, @id, reaction))
1937
+ response.map { |d| User.new(d, @bot) }
1938
+ end
1939
+
1940
+ # Deletes a reaction made by a user on this message
1941
+ # @param [User, #resolve_id] the user who used this reaction
1942
+ # @param [String, #to_reaction] the reaction to remove
1943
+ def delete_reaction(user, reaction)
1944
+ reaction = reaction.to_reaction if reaction.respond_to?(:to_reaction)
1945
+ API::Channel.delete_user_reaction(@bot.token, @channel.id, @id, reaction, user.resolve_id)
1946
+ end
1947
+
1948
+ # Delete's this clients reaction on this message
1949
+ # @param [String, #to_reaction] the reaction to remove
1950
+ def delete_own_reaction(reaction)
1951
+ reaction = reaction.to_reaction if reaction.respond_to?(:to_reaction)
1952
+ API::Channel.delete_own_reaction(@bot.token, @channel.id, @id, reaction)
1953
+ end
1954
+
1955
+ # Removes all reactions from this message
1956
+ def delete_all_reactions
1957
+ API::Channel.delete_all_reactions(@bot.token, @channel.id, @id)
1958
+ end
1959
+
1788
1960
  # The inspect method is overwritten to give more useful output
1789
1961
  def inspect
1790
1962
  "<Message content=\"#{@content}\" id=#{@id} timestamp=#{@timestamp} author=#{@author} channel=#{@channel}>"
1791
1963
  end
1792
1964
  end
1793
1965
 
1966
+ # A reaction to a message
1967
+ class Reaction
1968
+ # @return [Integer] the amount of users who have reacted with this reaction
1969
+ attr_reader :count
1970
+
1971
+ # @return [true, false] whether the current bot or user used this reaction
1972
+ attr_reader :me
1973
+ alias_method :me?, :me
1974
+
1975
+ # @return [Integer] the ID of the emoji, if it was custom
1976
+ attr_reader :id
1977
+
1978
+ # @return [String] the name or unicode representation of the emoji
1979
+ attr_reader :name
1980
+
1981
+ def initialize(data)
1982
+ @count = data['count']
1983
+ @me = data['me']
1984
+ @id = data['emoji']['id'].nil? ? nil : data['emoji']['id'].to_i
1985
+ @name = data['emoji']['name']
1986
+ end
1987
+ end
1988
+
1794
1989
  # Server emoji
1795
1990
  class Emoji
1796
1991
  include IDObject
@@ -1810,7 +2005,7 @@ module Discordrb
1810
2005
 
1811
2006
  @name = data['name']
1812
2007
  @server = server
1813
- @id = data['id'].to_i
2008
+ @id = data['id'].nil? ? nil : data['id'].to_i
1814
2009
 
1815
2010
  process_roles(data['roles']) if server
1816
2011
  end
@@ -1823,6 +2018,11 @@ module Discordrb
1823
2018
  alias_method :use, :mention
1824
2019
  alias_method :to_s, :mention
1825
2020
 
2021
+ # @return [String] the layout to use this emoji in a reaction
2022
+ def to_reaction
2023
+ "#{@name}:#{@id}"
2024
+ end
2025
+
1826
2026
  # @return [String] the icon URL of the emoji
1827
2027
  def icon_url
1828
2028
  API.emoji_icon_url(@id)
@@ -1872,6 +2072,11 @@ module Discordrb
1872
2072
  alias_method :use, :mention
1873
2073
  alias_method :to_s, :mention
1874
2074
 
2075
+ # @return [String] the layout to use this emoji in a reaction
2076
+ def to_reaction
2077
+ "#{@name}:#{@id}"
2078
+ end
2079
+
1875
2080
  # @return [String] the icon URL of the emoji
1876
2081
  def icon_url
1877
2082
  API.emoji_icon_url(@id)
@@ -2007,7 +2212,7 @@ module Discordrb
2007
2212
  # @return [Array<Role>] an array of all the roles created on this server.
2008
2213
  attr_reader :roles
2009
2214
 
2010
- # @return [Array<Emoji>] an array of all the emoji available on this server.
2215
+ # @return [Hash<Integer, Emoji>] a hash of all the emoji available on this server.
2011
2216
  attr_reader :emoji
2012
2217
  alias_method :emojis, :emoji
2013
2218
 
@@ -2074,8 +2279,9 @@ module Discordrb
2074
2279
  alias_method :general_channel, :default_channel
2075
2280
 
2076
2281
  # Gets a role on this server based on its ID.
2077
- # @param id [Integer] The role ID to look for.
2282
+ # @param id [Integer, String, #resolve_id] The role ID to look for.
2078
2283
  def role(id)
2284
+ id = id.resolve_id
2079
2285
  @roles.find { |e| e.id == id }
2080
2286
  end
2081
2287
 
@@ -2107,7 +2313,7 @@ module Discordrb
2107
2313
 
2108
2314
  # @return [Array<Integration>] an array of all the integrations connected to this server.
2109
2315
  def integrations
2110
- integration = JSON.parse(API.server_integrations(@bot.token, @id))
2316
+ integration = JSON.parse(API::Server.integrations(@bot.token, @id))
2111
2317
  integration.map { |element| Integration.new(element, @bot, self) }
2112
2318
  end
2113
2319
 
@@ -2115,7 +2321,7 @@ module Discordrb
2115
2321
  # @note For internal use only
2116
2322
  # @!visibility private
2117
2323
  def cache_embed
2118
- @embed = JSON.parse(API.server(@bot.token, @id))['embed_enabled'] if @embed.nil?
2324
+ @embed ||= JSON.parse(API::Server.resolve(@bot.token, @id))['embed_enabled']
2119
2325
  end
2120
2326
 
2121
2327
  # @return [true, false] whether or not the server has widget enabled
@@ -2169,8 +2375,7 @@ module Discordrb
2169
2375
 
2170
2376
  # @return [String] the hexadecimal ID used to identify this server's splash image for their VIP invite page.
2171
2377
  def splash_id
2172
- @splash_id = JSON.parse(API.server(@bot.token, @id))['splash'] if @splash_id.nil?
2173
- @splash_id
2378
+ @splash_id ||= JSON.parse(API::Server.resolve(@bot.token, @id))['splash']
2174
2379
  end
2175
2380
 
2176
2381
  # @return [String, nil] the splash image URL for the server's VIP invite page.
@@ -2411,6 +2616,30 @@ module Discordrb
2411
2616
  end
2412
2617
  end
2413
2618
 
2619
+ # Adds a channel to this server's cache
2620
+ # @note For internal use only
2621
+ # @!visibility private
2622
+ def add_channel(channel)
2623
+ @channels << channel
2624
+ @channels_by_id[channel.id] = channel
2625
+ end
2626
+
2627
+ # Deletes a channel from this server's cache
2628
+ # @note For internal use only
2629
+ # @!visibility private
2630
+ def delete_channel(id)
2631
+ @channels.reject! { |e| e.id == id }
2632
+ @channels_by_id.delete(id)
2633
+ end
2634
+
2635
+ # Updates the cached emoji data with new data
2636
+ # @note For internal use only
2637
+ # @!visibility private
2638
+ def update_emoji_data(new_data)
2639
+ @emoji = {}
2640
+ process_emoji(new_data['emojis'])
2641
+ end
2642
+
2414
2643
  # The inspect method is overwritten to give more useful output
2415
2644
  def inspect
2416
2645
  "<Server name=#{@name} id=#{@id} large=#{@large} region=#{@region} owner=#{@owner} afk_channel_id=#{@afk_channel_id} afk_timeout=#{@afk_timeout}>"
@@ -2465,8 +2694,7 @@ module Discordrb
2465
2694
  user_id = element['user']['id'].to_i
2466
2695
  user = @members[user_id]
2467
2696
  if user
2468
- user.status = element['status'].to_sym
2469
- user.game = element['game'] ? element['game']['name'] : nil
2697
+ user.update_presence(element)
2470
2698
  else
2471
2699
  LOGGER.warn "Rogue presence update! #{element['user']['id']} on #{@id}"
2472
2700
  end