mij-discord 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aca2803ee72c1ab5229d6767b809ee5a3a1aa605
4
- data.tar.gz: 037b4495e988f6c7c70e83801920fda475b9a262
3
+ metadata.gz: 79f209e5e6420da2007626aae908544d05da9121
4
+ data.tar.gz: a3ced104cc02f533b5ba05641112685823a9f382
5
5
  SHA512:
6
- metadata.gz: 2ff78a29820234b6ff79a848ccb0fb9b77019d645ec18bb6040a3566923f3e775462f01224a8df803ac07d31f29d55d4f7eb50c7de3ae5e464eac19b05c7fb0d
7
- data.tar.gz: 641bcc97f7a0039e655eb7ad4800a1dfcf0d62c9a5ff9333243204dc2eb9fbec24e897a4b54b40bf0288bece09cff9f740bc3a5308ade781647adb8b908fd0ac
6
+ metadata.gz: ae684e032ccb55100cd23faf439039f7a2c0f8bc352b8b890307c9270e78b0c724fc0f334fcf6579c4a70b232a2ab55a79b45eeb52146fa3211c15fd71a5c19f
7
+ data.tar.gz: 933eacfede575e90b795bf7b023260f4964e9d0fb08b8d455a68635a7f2324b8f6abb3b498b1ee2748f5ab0c2ec69c44c961b0e00837f5c43760e87d0d61d744
@@ -13,17 +13,19 @@ require 'websocket-client-simple'
13
13
  require 'rest-client'
14
14
 
15
15
  require_relative 'mij-discord/version'
16
+ require_relative 'mij-discord/extensions'
16
17
  require_relative 'mij-discord/logger'
17
18
  require_relative 'mij-discord/cache'
18
19
  require_relative 'mij-discord/events'
20
+ require_relative 'mij-discord/errors'
19
21
 
20
22
  require_relative 'mij-discord/core/gateway'
21
- require_relative 'mij-discord/core/errors'
22
23
  require_relative 'mij-discord/core/api'
23
24
  require_relative 'mij-discord/core/api/channel'
24
25
  require_relative 'mij-discord/core/api/invite'
25
26
  require_relative 'mij-discord/core/api/server'
26
27
  require_relative 'mij-discord/core/api/user'
28
+ require_relative 'mij-discord/core/api/webhook'
27
29
 
28
30
  require_relative 'mij-discord/data'
29
31
  require_relative 'mij-discord/data/invite'
@@ -38,6 +40,7 @@ require_relative 'mij-discord/data/server'
38
40
  require_relative 'mij-discord/data/embed'
39
41
  require_relative 'mij-discord/data/emoji'
40
42
  require_relative 'mij-discord/data/message'
43
+ require_relative 'mij-discord/data/webhook'
41
44
 
42
45
  require_relative 'mij-discord/events/basic'
43
46
  require_relative 'mij-discord/events/server'
@@ -45,12 +48,4 @@ require_relative 'mij-discord/events/member'
45
48
  require_relative 'mij-discord/events/channel'
46
49
  require_relative 'mij-discord/events/message'
47
50
 
48
- require_relative 'mij-discord/bot'
49
-
50
- class Integer
51
- alias_method :to_id, :itself
52
- end
53
-
54
- class String
55
- alias_method :to_id, :to_i
56
- end
51
+ require_relative 'mij-discord/bot'
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MijDiscord
4
- class Bot
5
- class AuthInfo
6
- attr_reader :token
4
+ class Bot
5
+ class AuthInfo
6
+ attr_reader :id
7
+
8
+ attr_reader :token
7
9
 
8
10
  attr_reader :type
9
11
 
10
12
  attr_reader :name
11
13
 
12
- def initialize(token, type, name)
13
- @type, @name = type, name
14
+ def initialize(id, token, type, name)
15
+ @id, @type, @name = id.to_id, type, name
14
16
 
15
17
  @token = case type
16
18
  when :bot then "Bot #{token}"
@@ -28,6 +30,10 @@ module MijDiscord
28
30
  end
29
31
 
30
32
  alias_method :to_s, :token
33
+
34
+ def inspect
35
+ MijDiscord.make_inspect(self, :id, :type, :name)
36
+ end
31
37
  end
32
38
 
33
39
  EVENTS = {
@@ -55,6 +61,7 @@ module MijDiscord
55
61
  create_channel: MijDiscord::Events::CreateChannel,
56
62
  update_channel: MijDiscord::Events::UpdateChannel,
57
63
  delete_channel: MijDiscord::Events::DeleteChannel,
64
+ update_webhooks: MijDiscord::Events::UpdateWebhooks,
58
65
  add_recipient: MijDiscord::Events::AddRecipient,
59
66
  remove_recipient: MijDiscord::Events::RemoveRecipient,
60
67
 
@@ -76,10 +83,6 @@ module MijDiscord
76
83
 
77
84
  UNAVAILABLE_SERVER_TIMEOUT = 10
78
85
 
79
- attr_reader :name
80
-
81
- attr_reader :client_id
82
-
83
86
  attr_reader :auth
84
87
 
85
88
  attr_reader :shard_key
@@ -92,8 +95,7 @@ module MijDiscord
92
95
 
93
96
  def initialize(client_id:, token:, type: :bot, name: nil,
94
97
  shard_id: nil, num_shards: nil, ignore_bots: false, ignore_self: true)
95
- @client_id = client_id.to_id
96
- @auth = AuthInfo.new(token, type, name)
98
+ @auth = AuthInfo.new(client_id, token, type, name)
97
99
 
98
100
  @cache = MijDiscord::Cache::BotCache.new(self)
99
101
 
@@ -197,7 +199,7 @@ module MijDiscord
197
199
  end
198
200
 
199
201
  def application
200
- raise 'Cannot get OAuth application for non-bot user' if @type != :bot
202
+ raise 'Cannot get OAuth application for non-bot user' unless @auth.bot?
201
203
 
202
204
  response = MijDiscord::Core::API.oauth_application(@auth)
203
205
  MijDiscord::Data::Application.new(JSON.parse(response), self)
@@ -205,7 +207,7 @@ module MijDiscord
205
207
 
206
208
  def invite(invite)
207
209
  code = parse_invite_code(invite)
208
- response = MijDiscord::Core::API::Invite.resolve(@auth, code)
210
+ response = MijDiscord::Core::API::Invite.resolve(@auth, code, true)
209
211
  MijDiscord::Data::Invite.new(JSON.parse(response), self)
210
212
  end
211
213
 
@@ -216,7 +218,7 @@ module MijDiscord
216
218
  end
217
219
 
218
220
  def make_invite_url(server: nil, permissions: nil)
219
- url = "https://discordapp.com/oauth2/authorize?scope=bot&client_id=#{@client_id}".dup
221
+ url = "https://discordapp.com/oauth2/authorize?scope=bot&client_id=#{@auth.id}".dup
220
222
  url << "&permissions=#{permissions.to_i}" if permissions.respond_to?(:to_i)
221
223
  url << "&guild_id=#{server.to_id}" if server.respond_to?(:to_id)
222
224
  url
@@ -258,14 +260,17 @@ module MijDiscord
258
260
  role = sv.role($1)
259
261
  return role if role
260
262
  end
261
- when /^<:\w+:(\d+)>$/
262
- emoji = emoji(server_id, $1)
263
+ when /^<(a?):(\w+):(\d+)>$/
264
+ emoji = emoji(server_id, $3)
263
265
  return emoji if emoji
264
266
 
265
267
  servers.each do |sv|
266
- emoji = sv.emoji($1)
268
+ emoji = sv.emoji($3)
267
269
  return emoji if emoji
268
270
  end
271
+
272
+ em_data = { 'id' => $3.to_i, 'name' => $2, 'animated' => !$1.empty? }
273
+ MijDiscord::Data::Emoji.new(em_data, self, nil)
269
274
  end
270
275
  end
271
276
 
@@ -300,7 +305,7 @@ module MijDiscord
300
305
  end
301
306
 
302
307
  def ignored_user?(user)
303
- @ignore_self && user.to_id == @client_id || @ignored_ids.include?(user.to_id)
308
+ @ignore_self && user.to_id == @auth.id || @ignored_ids.include?(user.to_id)
304
309
  end
305
310
 
306
311
  def update_presence(status: nil, game: nil)
@@ -379,7 +384,6 @@ module MijDiscord
379
384
  when :GUILD_MEMBERS_CHUNK
380
385
  server = @cache.get_server(data['guild_id'])
381
386
  server.update_members_chunk(data['members'])
382
- puts "Chunk(#{server.id}+#{data['members'].length})"
383
387
 
384
388
  when :GUILD_CREATE
385
389
  server = @cache.put_server(data)
@@ -424,6 +428,10 @@ module MijDiscord
424
428
  channel = @cache.remove_channel(data['id'])
425
429
  trigger_event(:delete_channel, self, channel)
426
430
 
431
+ when :WEBHOOKS_UPDATE
432
+ channel = @cache.get_channel(data['channel_id'], nil)
433
+ trigger_event(:update_webhooks, self, channel)
434
+
427
435
  when :CHANNEL_RECIPIENT_ADD
428
436
  channel = @cache.get_channel(data['channel_id'], nil)
429
437
  recipient = channel.update_recipient(add: data['user'])
@@ -538,7 +546,7 @@ module MijDiscord
538
546
  when :TYPING_START
539
547
  begin
540
548
  trigger_event(:start_typing, self, data)
541
- rescue MijDiscord::Core::Errors::NoPermission
549
+ rescue MijDiscord::Errors::Forbidden
542
550
  # Ignoring the channel we can't access
543
551
  # Why is this even sent? :S
544
552
  end
@@ -575,6 +583,10 @@ module MijDiscord
575
583
  MijDiscord::LOGGER.error('Dispatch') { exc }
576
584
  end
577
585
 
586
+ def inspect
587
+ MijDiscord.make_inspect(self, :auth)
588
+ end
589
+
578
590
  private
579
591
 
580
592
  def gateway_check
@@ -32,7 +32,7 @@ module MijDiscord::Cache
32
32
 
33
33
  begin
34
34
  response = MijDiscord::Core::API::Server.resolve(@bot.auth, id)
35
- rescue RestClient::ResourceNotFound
35
+ rescue MijDiscord::Errors::NotFound
36
36
  return nil
37
37
  end
38
38
 
@@ -42,14 +42,14 @@ module MijDiscord::Cache
42
42
  def get_channel(key, server, local: false)
43
43
  id = key&.to_id
44
44
  return @channels[id] if @channels.has_key?(id)
45
- raise MijDiscord::Errors::NoPermission if @restricted_channels[id]
45
+ raise MijDiscord::Errors::Forbidden if @restricted_channels[id]
46
46
  return nil if local
47
47
 
48
48
  begin
49
49
  response = MijDiscord::Core::API::Channel.resolve(@bot.auth, id)
50
- rescue RestClient::ResourceNotFound
50
+ rescue MijDiscord::Errors::NotFound
51
51
  return nil
52
- rescue MijDiscord::Errors::NoPermission
52
+ rescue MijDiscord::Errors::Forbidden
53
53
  @restricted_channels[id] = true
54
54
  raise
55
55
  end
@@ -85,7 +85,7 @@ module MijDiscord::Cache
85
85
  when :bot then MijDiscord::Core::API::User.resolve(@bot.auth, id)
86
86
  when :user then MijDiscord::Core::API::User.resolve2(@bot.auth, id)
87
87
  end
88
- rescue RestClient::ResourceNotFound
88
+ rescue MijDiscord::Errors::NotFound
89
89
  return nil
90
90
  end
91
91
 
@@ -147,6 +147,10 @@ module MijDiscord::Cache
147
147
  def remove_user(key)
148
148
  @users.delete(key&.to_id)
149
149
  end
150
+
151
+ def inspect
152
+ MijDiscord.make_inspect(self)
153
+ end
150
154
  end
151
155
 
152
156
  class ServerCache
@@ -179,7 +183,7 @@ module MijDiscord::Cache
179
183
 
180
184
  begin
181
185
  response = MijDiscord::Core::API::Server.resolve_member(@bot.auth, @server.id, id)
182
- rescue RestClient::ResourceNotFound
186
+ rescue MijDiscord::Errors::NotFound
183
187
  return nil
184
188
  end
185
189
 
@@ -248,6 +252,10 @@ module MijDiscord::Cache
248
252
 
249
253
  channel
250
254
  end
255
+
256
+ def inspect
257
+ MijDiscord.make_inspect(self)
258
+ end
251
259
  end
252
260
 
253
261
  class ChannelCache
@@ -270,8 +278,11 @@ module MijDiscord::Cache
270
278
  return nil if local
271
279
 
272
280
  begin
273
- response = MijDiscord::Core::API::Channel.message(@bot.auth, @channel.id, key)
274
- rescue RestClient::ResourceNotFound
281
+ response = case @bot.auth.type
282
+ when :bot then MijDiscord::Core::API::Channel.message(@bot.auth, @channel.id, key)
283
+ when :user then MijDiscord::Core::API::Channel.messages(@bot.auth, @channel.id, 1, nil, nil, key)
284
+ end
285
+ rescue MijDiscord::Errors::NotFound
275
286
  return nil
276
287
  end
277
288
 
@@ -297,5 +308,9 @@ module MijDiscord::Cache
297
308
  def remove_message(key)
298
309
  @messages.delete(key&.to_id)
299
310
  end
311
+
312
+ def inspect
313
+ MijDiscord.make_inspect(self)
314
+ end
300
315
  end
301
316
  end
@@ -154,10 +154,21 @@ module MijDiscord::Core::API
154
154
  )
155
155
  end
156
156
 
157
- def raw_request(type, attributes)
157
+ def raw_request(type, *attributes)
158
158
  RestClient.send(type, *attributes)
159
- rescue RestClient::Forbidden
160
- raise MijDiscord::Core::Errors::NoPermission
159
+ rescue RestClient::RequestFailed => e
160
+ # Holy fuck, Discord…
161
+ if (klazz = MijDiscord::Errors::HTTP_ERRORS[e.http_code])
162
+ data = JSON.parse(e.response)
163
+ if data['message'] || data['code']
164
+ raise klazz.new(data['code'], data['message'], e.response)
165
+ elsif (error = (data['content'] || data['embed']).join)
166
+ if MijDiscord::Errors::MessageTooLong.match_pattern?(error)
167
+ raise MijDiscord::Errors::MessageTooLong.new(error, e.response)
168
+ end
169
+ end
170
+ end
171
+ raise
161
172
  rescue RestClient::BadGateway
162
173
  MijDiscord::LOGGER.warn('HTTP') { 'Received 502 Bad Gateway during API request' }
163
174
  retry
@@ -179,7 +190,7 @@ module MijDiscord::Core::API
179
190
  mutex_wait(key_mutex)
180
191
  mutex_wait(global_mutex) if global_mutex.locked?
181
192
 
182
- response = raw_request(type, attributes)
193
+ response = raw_request(type, *attributes)
183
194
  rescue RestClient::TooManyRequests => e
184
195
  response = e.response
185
196
 
@@ -83,12 +83,6 @@ module MijDiscord::Core::API::Channel
83
83
  Authorization: auth,
84
84
  content_type: :json
85
85
  )
86
- rescue RestClient::BadRequest => e
87
- parsed = JSON.parse(e.response.body)
88
- if (content = parsed['content']).is_a?(Array) && content.first == 'Must be 2000 or fewer characters long.'
89
- raise MijDiscord::Core::Errors::MessageTooLong, "Message over the character limit (#{message.length} > 2000)"
90
- end
91
- raise
92
86
  end
93
87
 
94
88
  # Send a file as a message to a channel
@@ -4,12 +4,13 @@ module MijDiscord::Core::API::Invite
4
4
  class << self
5
5
  # Resolve an invite
6
6
  # https://discordapp.com/developers/docs/resources/invite#get-invite
7
- def resolve(auth, invite_code)
7
+ def resolve(auth, invite_code, with_counts = false)
8
+ counts = with_counts ? '?with_counts=true' : ''
8
9
  MijDiscord::Core::API.request(
9
10
  :invite_code,
10
11
  nil,
11
12
  :get,
12
- "#{MijDiscord::Core::API::APIBASE_URL}/invites/#{invite_code}",
13
+ "#{MijDiscord::Core::API::APIBASE_URL}/invites/#{invite_code}#{counts}",
13
14
  Authorization: auth
14
15
  )
15
16
  end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MijDiscord::Core::API::Webhook
4
+ class << self
5
+ # Get a webhook
6
+ # https://discordapp.com/developers/docs/resources/webhook#get-webhook
7
+ def webhook(auth, webhook_id)
8
+ MijDiscord::Core::API.request(
9
+ :webhooks_wid,
10
+ nil,
11
+ :get,
12
+ "#{MijDiscord::Core::API::APIBASE_URL}/webhooks/#{webhook_id}",
13
+ Authorization: auth
14
+ )
15
+ end
16
+
17
+ # Get a webhook via webhook token
18
+ # https://discordapp.com/developers/docs/resources/webhook#get-webhook-with-token
19
+ def token_webhook(webhook_token, webhook_id)
20
+ MijDiscord::Core::API.request(
21
+ :webhooks_wid,
22
+ nil,
23
+ :get,
24
+ "#{MijDiscord::Core::API::APIBASE_URL}/webhooks/#{webhook_id}/#{webhook_token}",
25
+ )
26
+ end
27
+
28
+ # Update a webhook
29
+ # https://discordapp.com/developers/docs/resources/webhook#modify-webhook
30
+ def update_webhook(auth, webhook_id, data, reason = nil)
31
+ MijDiscord::Core::API.request(
32
+ :webhooks_wid,
33
+ webhook_id,
34
+ :patch,
35
+ "#{MijDiscord::Core::API::APIBASE_URL}/webhooks/#{webhook_id}",
36
+ data.to_json,
37
+ Authorization: auth,
38
+ content_type: :json,
39
+ 'X-Audit-Log-Reason': reason,
40
+ )
41
+ end
42
+
43
+ # Update a webhook via webhook token
44
+ # https://discordapp.com/developers/docs/resources/webhook#modify-webhook-with-token
45
+ def token_update_webhook(webhook_token, webhook_id, data, reason = nil)
46
+ MijDiscord::Core::API.request(
47
+ :webhooks_wid,
48
+ webhook_id,
49
+ :patch,
50
+ "#{MijDiscord::Core::API::APIBASE_URL}/webhooks/#{webhook_id}/#{webhook_token}",
51
+ data.to_json,
52
+ content_type: :json,
53
+ 'X-Audit-Log-Reason': reason,
54
+ )
55
+ end
56
+
57
+ # Deletes a webhook
58
+ # https://discordapp.com/developers/docs/resources/webhook#delete-webhook
59
+ def delete_webhook(auth, webhook_id, reason = nil)
60
+ MijDiscord::Core::API.request(
61
+ :webhooks_wid,
62
+ webhook_id,
63
+ :delete,
64
+ "#{MijDiscord::Core::API::APIBASE_URL}/webhooks/#{webhook_id}",
65
+ Authorization: auth,
66
+ 'X-Audit-Log-Reason': reason,
67
+ )
68
+ end
69
+
70
+ # Deletes a webhook via webhook token
71
+ # https://discordapp.com/developers/docs/resources/webhook#delete-webhook-with-token
72
+ def token_delete_webhook(webhook_token, webhook_id, reason = nil)
73
+ MijDiscord::Core::API.request(
74
+ :webhooks_wid,
75
+ webhook_id,
76
+ :delete,
77
+ "#{MijDiscord::Core::API::APIBASE_URL}/webhooks/#{webhook_id}/#{webhook_token}",
78
+ 'X-Audit-Log-Reason': reason,
79
+ )
80
+ end
81
+
82
+ # Executes a webhook with JSON body
83
+ # https://discordapp.com/developers/docs/resources/webhook#execute-webhook
84
+ def execute_json(webhook_token, webhook_id, data, wait)
85
+ wait = wait ? '?wait=true' : ''
86
+ MijDiscord::Core::API.raw_request(
87
+ :post,
88
+ "#{MijDiscord::Core::API::APIBASE_URL}/webhooks/#{webhook_id}/#{webhook_token}#{wait}",
89
+ data.to_json,
90
+ content_type: :json,
91
+ )
92
+ end
93
+ end
94
+ end