discorb 0.0.8 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +2 -1
- data/Changelog.md +51 -1
- data/Gemfile +0 -6
- data/Gemfile.lock +2 -6
- data/docs/application_command.md +251 -0
- data/docs/discord_irb.md +39 -0
- data/docs/events.md +10 -10
- data/docs/extension.md +53 -0
- data/examples/commands/bookmarker.rb +41 -0
- data/examples/commands/hello.rb +9 -0
- data/examples/commands/inspect.rb +24 -0
- data/examples/components/authorization_button.rb +1 -1
- data/examples/components/select_menu.rb +1 -1
- data/exe/discord-irb +60 -0
- data/lib/discorb/asset.rb +34 -0
- data/lib/discorb/channel.rb +4 -4
- data/lib/discorb/client.rb +55 -13
- data/lib/discorb/command.rb +393 -0
- data/lib/discorb/common.rb +7 -5
- data/lib/discorb/dictionary.rb +1 -1
- data/lib/discorb/embed.rb +7 -7
- data/lib/discorb/emoji.rb +6 -1
- data/lib/discorb/emoji_table.rb +9 -2
- data/lib/discorb/error.rb +4 -1
- data/lib/discorb/extension.rb +5 -2
- data/lib/discorb/gateway.rb +487 -478
- data/lib/discorb/http.rb +1 -1
- data/lib/discorb/interaction.rb +131 -19
- data/lib/discorb/log.rb +1 -1
- data/lib/discorb/member.rb +10 -1
- data/lib/discorb/message.rb +27 -0
- data/lib/discorb/modules.rb +76 -3
- data/lib/discorb/user.rb +8 -3
- data/lib/discorb/webhook.rb +12 -1
- data/lib/discorb.rb +7 -7
- metadata +12 -3
data/lib/discorb/http.rb
CHANGED
@@ -227,7 +227,7 @@ module Discorb
|
|
227
227
|
end
|
228
228
|
|
229
229
|
def get_headers(headers, body = "", audit_log_reason = nil)
|
230
|
-
ret = if body.nil? || body
|
230
|
+
ret = if body.nil? || body == ""
|
231
231
|
{ "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}" }
|
232
232
|
else
|
233
233
|
{ "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}",
|
data/lib/discorb/interaction.rb
CHANGED
@@ -75,11 +75,15 @@ module Discorb
|
|
75
75
|
|
76
76
|
# @!visibility private
|
77
77
|
def make_interaction(client, data)
|
78
|
+
interaction = nil
|
78
79
|
descendants.each do |klass|
|
79
|
-
|
80
|
+
interaction = klass.make_interaction(client, data) if !klass.interaction_type.nil? && klass.interaction_type == data[:type]
|
80
81
|
end
|
81
|
-
|
82
|
-
|
82
|
+
if interaction.nil?
|
83
|
+
client.log.warn("Unknown interaction type #{data[:type]}, initialized Interaction")
|
84
|
+
interaction = Interaction.new(client, data)
|
85
|
+
end
|
86
|
+
interaction
|
83
87
|
end
|
84
88
|
|
85
89
|
# @!visibility private
|
@@ -95,14 +99,14 @@ module Discorb
|
|
95
99
|
#
|
96
100
|
# Response with `DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE`(`5`).
|
97
101
|
#
|
98
|
-
# @param [Boolean]
|
102
|
+
# @param [Boolean] ephemeral Whether to make the response ephemeral.
|
99
103
|
#
|
100
|
-
def defer_source(
|
104
|
+
def defer_source(ephemeral: false)
|
101
105
|
Async do
|
102
106
|
@client.http.post("/interactions/#{@id}/#{@token}/callback", {
|
103
107
|
type: 5,
|
104
108
|
data: {
|
105
|
-
flags: (
|
109
|
+
flags: (ephemeral ? 1 << 6 : 0),
|
106
110
|
},
|
107
111
|
}).wait
|
108
112
|
@defered = true
|
@@ -118,9 +122,9 @@ module Discorb
|
|
118
122
|
# @param [Array<Discorb::Embed>] embeds The embeds to send. (max: 10)
|
119
123
|
# @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
|
120
124
|
# @param [Array<Discorb::Components>, Array<Array<Discorb::Components>>] components The components to send.
|
121
|
-
# @param [Boolean]
|
125
|
+
# @param [Boolean] ephemeral Whether to make the response ephemeral.
|
122
126
|
#
|
123
|
-
def post(content, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil,
|
127
|
+
def post(content = nil, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil, ephemeral: false)
|
124
128
|
payload = {}
|
125
129
|
payload[:content] = content if content
|
126
130
|
payload[:tts] = tts
|
@@ -151,7 +155,7 @@ module Discorb
|
|
151
155
|
tmp_components << tmp_row
|
152
156
|
payload[:components] = tmp_components.filter { |c| c.length.positive? }.map { |c| { type: 1, components: c.map(&:to_hash) } }
|
153
157
|
end
|
154
|
-
payload[:flags] = (
|
158
|
+
payload[:flags] = (ephemeral ? 1 << 6 : 0)
|
155
159
|
if @responded
|
156
160
|
@client.http.post("/webhooks/#{@id}/#{@token}", { type: 4, data: payload }).wait
|
157
161
|
elsif @defered
|
@@ -170,14 +174,14 @@ module Discorb
|
|
170
174
|
#
|
171
175
|
# Response with `DEFERRED_UPDATE_MESSAGE`(`6`).
|
172
176
|
#
|
173
|
-
# @param [Boolean]
|
177
|
+
# @param [Boolean] ephemeral Whether to make the response ephemeral.
|
174
178
|
#
|
175
|
-
def defer_update(
|
179
|
+
def defer_update(ephemeral: false)
|
176
180
|
Async do
|
177
181
|
@client.http.post("/interactions/#{@id}/#{@token}/callback", {
|
178
182
|
type: 7,
|
179
183
|
data: {
|
180
|
-
flags: (
|
184
|
+
flags: (ephemeral ? 1 << 6 : 0),
|
181
185
|
},
|
182
186
|
}).wait
|
183
187
|
end
|
@@ -192,9 +196,9 @@ module Discorb
|
|
192
196
|
# @param [Array<Discorb::Embed>] embeds The embeds to send. (max: 10)
|
193
197
|
# @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions to send.
|
194
198
|
# @param [Array<Discorb::Components>, Array<Array<Discorb::Components>>] components The components to send.
|
195
|
-
# @param [Boolean]
|
199
|
+
# @param [Boolean] ephemeral Whether to make the response ephemeral.
|
196
200
|
#
|
197
|
-
def edit(content, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil,
|
201
|
+
def edit(content, tts: false, embed: nil, embeds: nil, allowed_mentions: nil, components: nil, ephemeral: false)
|
198
202
|
payload = {}
|
199
203
|
payload[:content] = content if content
|
200
204
|
payload[:tts] = tts
|
@@ -225,7 +229,7 @@ module Discorb
|
|
225
229
|
tmp_components << tmp_row
|
226
230
|
payload[:components] = tmp_components.filter { |c| c.length.positive? }.map { |c| { type: 1, components: c.map(&:to_hash) } }
|
227
231
|
end
|
228
|
-
payload[:flags] = (
|
232
|
+
payload[:flags] = (ephemeral ? 1 << 6 : 0)
|
229
233
|
@client.http.post("/interactions/#{@id}/#{@token}/callback", { type: 6, data: payload }).wait
|
230
234
|
end
|
231
235
|
end
|
@@ -238,15 +242,123 @@ module Discorb
|
|
238
242
|
end
|
239
243
|
|
240
244
|
#
|
241
|
-
# Represents a
|
245
|
+
# Represents a command interaction.
|
242
246
|
# @todo Implement this.
|
243
247
|
#
|
244
|
-
class
|
248
|
+
class CommandInteraction < Interaction
|
245
249
|
@interaction_type = 2
|
246
|
-
@interaction_name = :
|
250
|
+
@interaction_name = :application_command
|
251
|
+
include Interaction::SourceResponse
|
252
|
+
|
253
|
+
#
|
254
|
+
# Represents a slash command interaction.
|
255
|
+
#
|
256
|
+
class SlashCommand < CommandInteraction
|
257
|
+
@command_type = 1
|
258
|
+
|
259
|
+
def _set_data(data)
|
260
|
+
super
|
261
|
+
Sync do
|
262
|
+
name = data[:name]
|
263
|
+
options = nil
|
264
|
+
if (option = data[:options]&.first)
|
265
|
+
case option[:type]
|
266
|
+
when 1
|
267
|
+
name += " #{option[:name]}"
|
268
|
+
options = option[:options]
|
269
|
+
when 2
|
270
|
+
name += " #{option[:name]}"
|
271
|
+
if (option_sub = option[:options]&.first)
|
272
|
+
if option_sub[:type] == 1
|
273
|
+
name += " #{option_sub[:name]}"
|
274
|
+
options = option_sub[:options]
|
275
|
+
else
|
276
|
+
options = option[:options]
|
277
|
+
end
|
278
|
+
end
|
279
|
+
else
|
280
|
+
options = data[:options]
|
281
|
+
end
|
282
|
+
end
|
283
|
+
options ||= []
|
284
|
+
options.map! do |option|
|
285
|
+
case option[:type]
|
286
|
+
when 3, 4, 5, 10
|
287
|
+
option[:value]
|
288
|
+
when 6
|
289
|
+
guild.members[option[:value]] || guild.fetch_member(option[:value]).wait
|
290
|
+
when 7
|
291
|
+
guild.channels[option[:value]] || guild.fetch_channels.wait.find { |channel| channel.id == option[:value] }
|
292
|
+
when 8
|
293
|
+
guild.roles[option[:value]] || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
|
294
|
+
when 9
|
295
|
+
guild.members[option[:value]] || guild.roles[option[:value]] || guild.fetch_member(option[:value]).wait || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
unless (command = @client.commands.find { |c| c.to_s == name })
|
300
|
+
@client.log.warn "Unknown command name #{name}, ignoreing"
|
301
|
+
next
|
302
|
+
end
|
303
|
+
|
304
|
+
command.block.call(self, *options)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
#
|
310
|
+
# Represents a user context menu interaction.
|
311
|
+
#
|
312
|
+
class UserMenuCommand < CommandInteraction
|
313
|
+
@command_type = 2
|
314
|
+
|
315
|
+
# @return [Discorb::Member, Discorb::User] The target user.
|
316
|
+
attr_reader :target
|
317
|
+
|
318
|
+
def _set_data(data)
|
319
|
+
@target = guild.members[data[:target_id]] || Discorb::Member.new(@client, @guild_id, data[:resolved][:users][data[:target_id].to_sym], data[:resolved][:members][data[:target_id].to_sym])
|
320
|
+
@client.commands.find { |c| c.name == data[:name] && c.type_raw == 2 }.block.call(self, @target)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
#
|
325
|
+
# Represents a message context menu interaction.
|
326
|
+
#
|
327
|
+
class MessageMenuCommand < CommandInteraction
|
328
|
+
@command_type = 3
|
329
|
+
|
330
|
+
# @return [Discorb::Message] The target message.
|
331
|
+
attr_reader :target
|
332
|
+
|
333
|
+
def _set_data(data)
|
334
|
+
@target = Message.new(@client, data[:resolved][:messages][data[:target_id].to_sym].merge({ guild_id: @guild_id.to_s }))
|
335
|
+
@client.commands.find { |c| c.name == data[:name] && c.type_raw == 3 }.block.call(self, @target)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
private
|
247
340
|
|
248
341
|
def _set_data(data)
|
249
|
-
|
342
|
+
@name = data[:name]
|
343
|
+
end
|
344
|
+
|
345
|
+
class << self
|
346
|
+
# @!visibility private
|
347
|
+
attr_reader :command_type
|
348
|
+
|
349
|
+
# @!visibility private
|
350
|
+
def make_interaction(client, data)
|
351
|
+
nested_classes.each do |klass|
|
352
|
+
return klass.new(client, data) if !klass.command_type.nil? && klass.command_type == data[:data][:type]
|
353
|
+
end
|
354
|
+
client.log.warn("Unknown command type #{data[:type]}, initialized CommandInteraction")
|
355
|
+
CommandInteraction.new(client, data)
|
356
|
+
end
|
357
|
+
|
358
|
+
# @!visibility private
|
359
|
+
def nested_classes
|
360
|
+
constants.select { |c| const_get(c).is_a? Class }.map { |c| const_get(c) }
|
361
|
+
end
|
250
362
|
end
|
251
363
|
end
|
252
364
|
|
data/lib/discorb/log.rb
CHANGED
@@ -61,7 +61,7 @@ module Discorb
|
|
61
61
|
return unless @out
|
62
62
|
|
63
63
|
if @colorize_log
|
64
|
-
@out.puts("[#{Time.now.iso8601}] #{color}#{name}\e[m -- #{message}")
|
64
|
+
@out.puts("\e[2;90m[#{Time.now.iso8601}] #{color}#{name}\e[m -- #{message}")
|
65
65
|
else
|
66
66
|
@out.puts("[#{Time.now.iso8601}] #{name} -- #{message}")
|
67
67
|
end
|
data/lib/discorb/member.rb
CHANGED
@@ -78,6 +78,15 @@ module Discorb
|
|
78
78
|
"@#{name}"
|
79
79
|
end
|
80
80
|
|
81
|
+
#
|
82
|
+
# Format the member to `Username#Discriminator` style.
|
83
|
+
#
|
84
|
+
# @return [String] The formatted member.
|
85
|
+
#
|
86
|
+
def to_s_user
|
87
|
+
"#{username}##{discriminator}"
|
88
|
+
end
|
89
|
+
|
81
90
|
def name
|
82
91
|
@nick || @username
|
83
92
|
end
|
@@ -223,8 +232,8 @@ module Discorb
|
|
223
232
|
@hoisted_role_id = member_data[:hoisted_role]
|
224
233
|
@deaf = member_data[:deaf]
|
225
234
|
@custom_avatar = member_data[:avatar] && Asset.new(member_data[:avatar])
|
226
|
-
@display_avatar = Asset.new(self, member_data[:avatar] || user_data[:avatar])
|
227
235
|
super(user_data)
|
236
|
+
@display_avatar = @avatar || @custom_avatar
|
228
237
|
@client.guilds[@guild_id].members[@id] = self unless @guild_id.nil?
|
229
238
|
@_member_data.update(member_data)
|
230
239
|
end
|
data/lib/discorb/message.rb
CHANGED
@@ -213,6 +213,33 @@ module Discorb
|
|
213
213
|
!@updated_at.nil?
|
214
214
|
end
|
215
215
|
|
216
|
+
#
|
217
|
+
# Edit the message.
|
218
|
+
#
|
219
|
+
# @param [String] content The message content.
|
220
|
+
# @param [Discorb::Embed] embed The embed to send.
|
221
|
+
# @param [Array<Discord::Embed>] embeds The embeds to send.
|
222
|
+
# @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
|
223
|
+
# @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
|
224
|
+
# @param [Boolean] supress Whether to supress embeds.
|
225
|
+
#
|
226
|
+
def edit(...)
|
227
|
+
Async do
|
228
|
+
channel.edit_message(@id, ...).wait
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
#
|
233
|
+
# Delete the message.
|
234
|
+
#
|
235
|
+
# @param [String] reason The reason for deleting the message.
|
236
|
+
#
|
237
|
+
def delete!(reason: nil)
|
238
|
+
Async do
|
239
|
+
channel.delete_message!(@id, reason: reason).wait
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
216
243
|
#
|
217
244
|
# Convert the message to reference object.
|
218
245
|
#
|
data/lib/discorb/modules.rb
CHANGED
@@ -7,6 +7,8 @@ module Discorb
|
|
7
7
|
module Messageable
|
8
8
|
#
|
9
9
|
# Post a message to the channel.
|
10
|
+
# @macro async
|
11
|
+
# @macro http
|
10
12
|
#
|
11
13
|
# @param [String] content The message content.
|
12
14
|
# @param [Boolean] tts Whether the message is tts.
|
@@ -61,13 +63,82 @@ module Discorb
|
|
61
63
|
else
|
62
64
|
headers = {}
|
63
65
|
end
|
64
|
-
_resp, data = @client.http.post("
|
66
|
+
_resp, data = @client.http.post("/channels/#{channel_id.wait}/messages", payload, headers: headers).wait
|
65
67
|
Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
71
|
+
#
|
72
|
+
# Edit a message.
|
73
|
+
# @macro async
|
74
|
+
# @macro http
|
75
|
+
#
|
76
|
+
# @param [#to_s] message_id The message id.
|
77
|
+
# @param [String] content The message content.
|
78
|
+
# @param [Discorb::Embed] embed The embed to send.
|
79
|
+
# @param [Array<Discord::Embed>] embeds The embeds to send.
|
80
|
+
# @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
|
81
|
+
# @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
|
82
|
+
# @param [Boolean] supress Whether to supress embeds.
|
83
|
+
#
|
84
|
+
def edit_message(message_id, content = nil, embed: nil, embeds: nil, allowed_mentions: nil,
|
85
|
+
components: nil, supress: nil)
|
86
|
+
Async do
|
87
|
+
payload = {}
|
88
|
+
payload[:content] = content if content
|
89
|
+
tmp_embed = if embed
|
90
|
+
[embed]
|
91
|
+
elsif embeds
|
92
|
+
embeds
|
93
|
+
end
|
94
|
+
payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
|
95
|
+
payload[:allowed_mentions] =
|
96
|
+
allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
|
97
|
+
if components
|
98
|
+
tmp_components = []
|
99
|
+
tmp_row = []
|
100
|
+
components.each do |c|
|
101
|
+
case c
|
102
|
+
when Array
|
103
|
+
tmp_components << tmp_row
|
104
|
+
tmp_row = []
|
105
|
+
tmp_components << c
|
106
|
+
when SelectMenu
|
107
|
+
tmp_components << tmp_row
|
108
|
+
tmp_row = []
|
109
|
+
tmp_components << [c]
|
110
|
+
else
|
111
|
+
tmp_row << c
|
112
|
+
end
|
113
|
+
end
|
114
|
+
tmp_components << tmp_row
|
115
|
+
payload[:flags] = (supress ? 1 << 2 : 0) unless flags.nil?
|
116
|
+
payload[:components] = tmp_components.filter { |c| c.length.positive? }.map { |c| { type: 1, components: c.map(&:to_hash) } }
|
117
|
+
end
|
118
|
+
@client.http.patch("/channels/#{channel_id.wait}/messages/#{message_id}", payload).wait
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# Delete a message.
|
124
|
+
# @macro async
|
125
|
+
# @macro http
|
126
|
+
#
|
127
|
+
# @param [#to_s] message_id The message id.
|
128
|
+
# @param [String] reason The reason for deleting the message.
|
129
|
+
#
|
130
|
+
def delete_message!(message_id, reason: nil)
|
131
|
+
Async do
|
132
|
+
@client.http.delete("/channels/#{channel_id.wait}/messages/#{message_id}", reason: reason).wait
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
alias destroy_message! delete_message!
|
137
|
+
|
69
138
|
#
|
70
139
|
# Fetch a message from ID.
|
140
|
+
# @macro async
|
141
|
+
# @macro http
|
71
142
|
#
|
72
143
|
# @param [Discorb::Snowflake] id The ID of the message.
|
73
144
|
#
|
@@ -76,13 +147,15 @@ module Discorb
|
|
76
147
|
#
|
77
148
|
def fetch_message(id)
|
78
149
|
Async do
|
79
|
-
_resp, data = @client.http.get("
|
150
|
+
_resp, data = @client.http.get("/channels/#{channel_id.wait}/messages/#{id}").wait
|
80
151
|
Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
|
81
152
|
end
|
82
153
|
end
|
83
154
|
|
84
155
|
#
|
85
156
|
# Fetch a message history.
|
157
|
+
# @macro async
|
158
|
+
# @macro http
|
86
159
|
#
|
87
160
|
# @param [Integer] limit The number of messages to fetch.
|
88
161
|
# @param [Discorb::Snowflake] before The ID of the message to fetch before.
|
@@ -99,7 +172,7 @@ module Discorb
|
|
99
172
|
after: Discorb::Utils.try(around, :id),
|
100
173
|
around: Discorb::Utils.try(before, :id),
|
101
174
|
}.filter { |_k, v| !v.nil? }.to_h
|
102
|
-
_resp, messages = @client.http.get("
|
175
|
+
_resp, messages = @client.http.get("/channels/#{channel_id.wait}/messages?#{URI.encode_www_form(params)}").wait
|
103
176
|
messages.map { |m| Message.new(@client, m.merge({ guild_id: @guild_id.to_s })) }
|
104
177
|
end
|
105
178
|
end
|
data/lib/discorb/user.rb
CHANGED
@@ -21,6 +21,8 @@ module Discorb
|
|
21
21
|
# @return [Boolean] Whether the user is a bot.
|
22
22
|
attr_reader :bot
|
23
23
|
alias bot? bot
|
24
|
+
# @return [Time] The time the user was created.
|
25
|
+
attr_reader :created_at
|
24
26
|
|
25
27
|
include Discorb::Messageable
|
26
28
|
|
@@ -41,6 +43,8 @@ module Discorb
|
|
41
43
|
"#{@username}##{@discriminator}"
|
42
44
|
end
|
43
45
|
|
46
|
+
alias to_s_user to_s
|
47
|
+
|
44
48
|
def inspect
|
45
49
|
"#<#{self.class} #{self}>"
|
46
50
|
end
|
@@ -70,13 +74,13 @@ module Discorb
|
|
70
74
|
alias app_owner? bot_owner?
|
71
75
|
|
72
76
|
# @!visibility private
|
73
|
-
def
|
77
|
+
def channel_id
|
74
78
|
Async do
|
75
79
|
next @dm_channel_id if @dm_channel_id
|
76
80
|
|
77
81
|
dm_channel = @client.http.post("/users/#{@id}/channels", { recipient_id: @client.user.id }).wait
|
78
82
|
@dm_channel_id = dm_channel[:id]
|
79
|
-
|
83
|
+
@dm_channel_id
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
@@ -123,10 +127,11 @@ module Discorb
|
|
123
127
|
@id = Snowflake.new(data[:id])
|
124
128
|
@flag = User::Flag.new(data[:public_flags] | (data[:flags] || 0))
|
125
129
|
@discriminator = data[:discriminator]
|
126
|
-
@avatar = Asset.new(self, data[:avatar])
|
130
|
+
@avatar = data[:avatar] ? Asset.new(self, data[:avatar]) : DefaultAvatar.new(data[:discriminator])
|
127
131
|
@bot = data[:bot]
|
128
132
|
@raw_data = data
|
129
133
|
@client.users[@id] = self if !data[:no_cache] && data.is_a?(User)
|
134
|
+
@created_at = @id.timestamp
|
130
135
|
@data.update(data)
|
131
136
|
end
|
132
137
|
end
|