Module: Discordrb::API

Defined in:
lib/discordrb/api.rb

Overview

List of methods representing endpoints in Discord's API

Constant Summary collapse

APIBASE =

The base URL of the Discord REST API.

'https://discordapp.com/api'.freeze

Class Method Summary collapse

Class Method Details

.acknowledge_message(token, channel_id, message_id) ⇒ Object

Acknowledge that a message has been received The last acknowledged message will be sent in the ready packet, so this is an easy way to catch up on messages



421
422
423
424
425
426
427
428
429
# File 'lib/discordrb/api.rb', line 421

def acknowledge_message(token, channel_id, message_id)
  request(
    nil,
    :post,
    "#{api_base}/channels/#{channel_id}/messages/#{message_id}/ack",
    nil,
    Authorization: token
  )
end

.api_baseString

Returns the currently used API base URL.

Returns:

  • (String)

    the currently used API base URL.



16
17
18
# File 'lib/discordrb/api.rb', line 16

def api_base
  @api_base || APIBASE
end

.api_base=(value) ⇒ Object

Sets the API base URL to something.



21
22
23
# File 'lib/discordrb/api.rb', line 21

def api_base=(value)
  @api_base = value
end

.avatar_url(user_id, avatar_id) ⇒ Object

Make an avatar URL from the user and avatar IDs



97
98
99
# File 'lib/discordrb/api.rb', line 97

def avatar_url(user_id, avatar_id)
  "#{api_base}/users/#{user_id}/avatars/#{avatar_id}.jpg"
end

.ban_user(token, server_id, user_id, message_days) ⇒ Object

Ban a user from a server and delete their messages from the last message_days days



107
108
109
110
111
112
113
114
115
# File 'lib/discordrb/api.rb', line 107

def ban_user(token, server_id, user_id, message_days)
  request(
    nil,
    :put,
    "#{api_base}/guilds/#{server_id}/bans/#{user_id}?delete-message-days=#{message_days}",
    nil,
    Authorization: token
  )
end

.bans(token, server_id) ⇒ Object

Get a server's banned users



150
151
152
153
154
155
156
157
# File 'lib/discordrb/api.rb', line 150

def bans(token, server_id)
  request(
    nil,
    :get,
    "#{api_base}/guilds/#{server_id}/bans",
    Authorization: token
  )
end

.bot_nameString

Returns the bot name, previously specified using #bot_name=.

Returns:

  • (String)

    the bot name, previously specified using #bot_name=.



26
27
28
# File 'lib/discordrb/api.rb', line 26

def bot_name
  @bot_name
end

.bot_name=(value) ⇒ Object

Sets the bot name to something.



31
32
33
# File 'lib/discordrb/api.rb', line 31

def bot_name=(value)
  @bot_name = value
end

.channel(token, channel_id) ⇒ Object

Get a channel's data



262
263
264
265
266
267
268
269
# File 'lib/discordrb/api.rb', line 262

def channel(token, channel_id)
  request(
    nil,
    :get,
    "#{api_base}/channels/#{channel_id}",
    Authorization: token
  )
end

.channel_log(token, channel_id, amount, before = nil, after = nil) ⇒ Object

Get a list of messages from a channel's history



600
601
602
603
604
605
606
607
# File 'lib/discordrb/api.rb', line 600

def channel_log(token, channel_id, amount, before = nil, after = nil)
  request(
    nil,
    :get,
    "#{api_base}/channels/#{channel_id}/messages?limit=#{amount}#{"&before=#{before}" if before}#{"&after=#{after}" if after}",
    Authorization: token
  )
end

.connections(token) ⇒ Object

Get information about a user's connections



568
569
570
571
572
573
574
575
# File 'lib/discordrb/api.rb', line 568

def connections(token)
  request(
    nil,
    :get,
    "#{api_base}/users/@me/connections",
    Authorization: token
  )
end

.create_channel(token, server_id, name, type) ⇒ Object

Create a channel



292
293
294
295
296
297
298
299
300
301
# File 'lib/discordrb/api.rb', line 292

def create_channel(token, server_id, name, type)
  request(
    nil,
    :post,
    "#{api_base}/guilds/#{server_id}/channels",
    { name: name, type: type }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.create_invite(token, channel_id, max_age = 0, max_uses = 0, temporary = false, xkcd = false) ⇒ Object

Create an instant invite from a server or a channel id



361
362
363
364
365
366
367
368
369
370
# File 'lib/discordrb/api.rb', line 361

def create_invite(token, channel_id, max_age = 0, max_uses = 0, temporary = false, xkcd = false)
  request(
    nil,
    :post,
    "#{api_base}/channels/#{channel_id}/invites",
    { max_age: max_age, max_uses: max_uses, temporary: temporary, xkcdpass: xkcd }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.create_oauth_application(token, name, redirect_uris) ⇒ Object

Create an OAuth application



182
183
184
185
186
187
188
189
190
191
# File 'lib/discordrb/api.rb', line 182

def create_oauth_application(token, name, redirect_uris)
  request(
    nil,
    :post,
    "#{api_base}/oauth2/applications",
    { name: name, redirect_uris: redirect_uris }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.create_private(token, bot_user_id, user_id) ⇒ Object

Create a private channel



347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/discordrb/api.rb', line 347

def create_private(token, bot_user_id, user_id)
  request(
    nil,
    :post,
    "#{api_base}/users/#{bot_user_id}/channels",
    { recipient_id: user_id }.to_json,
    Authorization: token,
    content_type: :json
  )
rescue RestClient::BadRequest
  raise 'Attempted to PM the bot itself!'
end

.create_role(token, server_id) ⇒ Object

Create a role (parameters such as name and colour will have to be set by update_role afterwards)



443
444
445
446
447
448
449
450
451
# File 'lib/discordrb/api.rb', line 443

def create_role(token, server_id)
  request(
    nil,
    :post,
    "#{api_base}/guilds/#{server_id}/roles",
    nil,
    Authorization: token
  )
end

.create_server(token, name, region = :london) ⇒ Object

Create a server



206
207
208
209
210
211
212
213
214
215
# File 'lib/discordrb/api.rb', line 206

def create_server(token, name, region = :london)
  request(
    nil,
    :post,
    "#{api_base}/guilds",
    { name: name, region: region.to_s }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.delete_channel(token, channel_id) ⇒ Object

Delete a channel



316
317
318
319
320
321
322
323
# File 'lib/discordrb/api.rb', line 316

def delete_channel(token, channel_id)
  request(
    nil,
    :delete,
    "#{api_base}/channels/#{channel_id}",
    Authorization: token
  )
end

.delete_invite(token, code) ⇒ Object

Delete an invite by code



373
374
375
376
377
378
379
380
# File 'lib/discordrb/api.rb', line 373

def delete_invite(token, code)
  request(
    nil,
    :delete,
    "#{api_base}/invites/#{code}",
    Authorization: token
  )
end

.delete_message(token, channel_id, message_id) ⇒ Object

Delete a message



397
398
399
400
401
402
403
404
# File 'lib/discordrb/api.rb', line 397

def delete_message(token, channel_id, message_id)
  request(
    nil,
    :delete,
    "#{api_base}/channels/#{channel_id}/messages/#{message_id}",
    Authorization: token
  )
end

.delete_role(token, server_id, role_id) ⇒ Object

Delete a role



469
470
471
472
473
474
475
476
# File 'lib/discordrb/api.rb', line 469

def delete_role(token, server_id, role_id)
  request(
    nil,
    :delete,
    "#{api_base}/guilds/#{server_id}/roles/#{role_id}",
    Authorization: token
  )
end

.delete_server(token, server_id) ⇒ Object

Delete a server



242
243
244
245
246
247
248
249
# File 'lib/discordrb/api.rb', line 242

def delete_server(token, server_id)
  request(
    nil,
    :delete,
    "#{api_base}/guilds/#{server_id}",
    Authorization: token
  )
end

.edit_message(token, channel_id, message_id, message, mentions = []) ⇒ Object

Edit a message



407
408
409
410
411
412
413
414
415
416
# File 'lib/discordrb/api.rb', line 407

def edit_message(token, channel_id, message_id, message, mentions = [])
  request(
    :message,
    :patch,
    "#{api_base}/channels/#{channel_id}/messages/#{message_id}",
    { content: message, mentions: mentions }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.gateway(token) ⇒ Object

Get the gateway to be used



515
516
517
518
519
520
521
522
# File 'lib/discordrb/api.rb', line 515

def gateway(token)
  request(
    nil,
    :get,
    "#{api_base}/gateway",
    Authorization: token
  )
end

.icon_url(server_id, icon_id) ⇒ Object

Make an icon URL from server and icon IDs



102
103
104
# File 'lib/discordrb/api.rb', line 102

def icon_url(server_id, icon_id)
  "#{api_base}/guilds/#{server_id}/icons/#{icon_id}.jpg"
end

.join_server(token, invite_code) ⇒ Object

Join a server using an invite



326
327
328
329
330
331
332
333
334
# File 'lib/discordrb/api.rb', line 326

def join_server(token, invite_code)
  request(
    nil,
    :post,
    "#{api_base}/invite/#{invite_code}",
    nil,
    Authorization: token
  )
end

.kick_user(token, server_id, user_id) ⇒ Object

Kick a user from a server



128
129
130
131
132
133
134
135
# File 'lib/discordrb/api.rb', line 128

def kick_user(token, server_id, user_id)
  request(
    nil,
    :delete,
    "#{api_base}/guilds/#{server_id}/members/#{user_id}",
    Authorization: token
  )
end

.leave_server(token, server_id) ⇒ Object

Leave a server



252
253
254
255
256
257
258
259
# File 'lib/discordrb/api.rb', line 252

def leave_server(token, server_id)
  request(
    nil,
    :delete,
    "#{api_base}/users/@me/guilds/#{server_id}",
    Authorization: token
  )
end

.login(email, password) ⇒ Object

Login to the server



160
161
162
163
164
165
166
167
168
# File 'lib/discordrb/api.rb', line 160

def (email, password)
  request(
    nil,
    :post,
    "#{api_base}/auth/login",
    email: email,
    password: password
  )
end

.logout(token) ⇒ Object

Logout from the server



171
172
173
174
175
176
177
178
179
# File 'lib/discordrb/api.rb', line 171

def logout(token)
  request(
    nil,
    :post,
    "#{api_base}/auth/logout",
    nil,
    Authorization: token
  )
end

.member(token, server_id, user_id) ⇒ Object

Get a member's data



282
283
284
285
286
287
288
289
# File 'lib/discordrb/api.rb', line 282

def member(token, server_id, user_id)
  request(
    nil,
    :get,
    "#{api_base}/guilds/#{server_id}/members/#{user_id}",
    Authorization: token
  )
end

.move_user(token, server_id, user_id, channel_id) ⇒ Object

Move a user to a different voice channel



138
139
140
141
142
143
144
145
146
147
# File 'lib/discordrb/api.rb', line 138

def move_user(token, server_id, user_id, channel_id)
  request(
    nil,
    :patch,
    "#{api_base}/guilds/#{server_id}/members/#{user_id}",
    { channel_id: channel_id }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.profile(token) ⇒ Object

Get profile data



558
559
560
561
562
563
564
565
# File 'lib/discordrb/api.rb', line 558

def profile(token)
  request(
    nil,
    :get,
    "#{api_base}/users/@me",
    Authorization: token
  )
end

.raw_request(type, attributes) ⇒ Object

Performs a RestClient request.

Parameters:

  • type (Symbol)

    The type of HTTP request to use.

  • attributes (Array)

    The attributes for the request.



54
55
56
57
58
59
60
61
# File 'lib/discordrb/api.rb', line 54

def raw_request(type, attributes)
  RestClient.send(type, *attributes)
rescue RestClient::Forbidden
  raise Discordrb::Errors::NoPermission, "The bot doesn't have the required permission to do this!"
rescue RestClient::BadGateway
  Discordrb::LOGGER.warn('Got a 502 while sending a request! Not a big deal, retrying the request')
  retry
end

.request(key, type, *attributes) ⇒ Object

Make an API request. Utility function to implement message queueing in the future



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/discordrb/api.rb', line 65

def request(key, type, *attributes)
  # Add a custom user agent
  attributes.last[:user_agent] = user_agent if attributes.last.is_a? Hash

  begin
    if key
      # Lock and unlock, i. e. wait for the mutex to unlock and don't do anything with it afterwards
      @mutexes[key].lock
      @mutexes[key].unlock
    end

    response = raw_request(type, attributes)
  rescue RestClient::TooManyRequests => e
    raise "Got an HTTP 429 for an untracked API call! Please report this bug together with the following information: #{type} #{attributes}" unless key

    unless @mutexes[key].locked?
      response = JSON.parse(e.response)
      wait_seconds = response['retry_after'].to_i / 1000.0
      Discordrb::LOGGER.warn("Locking RL mutex (key: #{key}) for #{wait_seconds} seconds due to Discord rate limiting")

      # Wait the required time synchronized by the mutex (so other incoming requests have to wait) but only do it if
      # the mutex isn't locked already so it will only ever wait once
      @mutexes[key].synchronize { sleep wait_seconds }
    end

    retry
  end

  response
end

.reset_mutexesObject

Resets all rate limit mutexes



45
46
47
48
49
# File 'lib/discordrb/api.rb', line 45

def reset_mutexes
  @mutexes = {
    message: Mutex.new
  }
end

.resolve_invite(token, invite_code) ⇒ Object

Resolve an invite



337
338
339
340
341
342
343
344
# File 'lib/discordrb/api.rb', line 337

def resolve_invite(token, invite_code)
  request(
    nil,
    :get,
    "#{api_base}/invite/#{invite_code}",
    Authorization: token
  )
end

.send_file(token, channel_id, file) ⇒ Object

Send a file as a message to a channel



432
433
434
435
436
437
438
439
440
# File 'lib/discordrb/api.rb', line 432

def send_file(token, channel_id, file)
  request(
    nil,
    :post,
    "#{api_base}/channels/#{channel_id}/messages",
    { file: file },
    Authorization: token
  )
end

.send_message(token, channel_id, message, mentions = [], tts = false) ⇒ Object

Send a message to a channel



383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/discordrb/api.rb', line 383

def send_message(token, channel_id, message, mentions = [], tts = false)
  request(
    :message,
    :post,
    "#{api_base}/channels/#{channel_id}/messages",
    { content: message, mentions: mentions, tts: tts }.to_json,
    Authorization: token,
    content_type: :json
  )
rescue RestClient::InternalServerError
  raise Discordrb::Errors::MessageTooLong, "Message over the character limit (#{message.length} > 2000)"
end

.server(token, server_id) ⇒ Object

Get a server's data



272
273
274
275
276
277
278
279
# File 'lib/discordrb/api.rb', line 272

def server(token, server_id)
  request(
    nil,
    :get,
    "#{api_base}/guilds/#{server_id}",
    Authorization: token
  )
end

.servers(token) ⇒ Object

Get the servers a user is connected to



590
591
592
593
594
595
596
597
# File 'lib/discordrb/api.rb', line 590

def servers(token)
  request(
    nil,
    :get,
    "#{api_base}/users/@me/guilds",
    Authorization: token
  )
end

.start_typing(token, channel_id) ⇒ Object

Start typing (needs to be resent every 5 seconds to keep up the typing)



537
538
539
540
541
542
543
544
545
# File 'lib/discordrb/api.rb', line 537

def start_typing(token, channel_id)
  request(
    nil,
    :post,
    "#{api_base}/channels/#{channel_id}/typing",
    nil,
    Authorization: token
  )
end

.transfer_ownership(token, server_id, user_id) ⇒ Object

Transfer server ownership



230
231
232
233
234
235
236
237
238
239
# File 'lib/discordrb/api.rb', line 230

def transfer_ownership(token, server_id, user_id)
  request(
    nil,
    :patch,
    "#{api_base}/guilds/#{server_id}",
    { owner_id: user_id }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.unban_user(token, server_id, user_id) ⇒ Object

Unban a user from a server



118
119
120
121
122
123
124
125
# File 'lib/discordrb/api.rb', line 118

def unban_user(token, server_id, user_id)
  request(
    nil,
    :delete,
    "#{api_base}/guilds/#{server_id}/bans/#{user_id}",
    Authorization: token
  )
end

.update_channel(token, channel_id, name, topic, position = 0) ⇒ Object

Update a channel's data



304
305
306
307
308
309
310
311
312
313
# File 'lib/discordrb/api.rb', line 304

def update_channel(token, channel_id, name, topic, position = 0)
  request(
    nil,
    :patch,
    "#{api_base}/channels/#{channel_id}",
    { name: name, position: position, topic: topic }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.update_oauth_application(token, name, redirect_uris, description = '', icon = nil) ⇒ Object

Change an OAuth application's properties



194
195
196
197
198
199
200
201
202
203
# File 'lib/discordrb/api.rb', line 194

def update_oauth_application(token, name, redirect_uris, description = '', icon = nil)
  request(
    nil,
    :put,
    "#{api_base}/oauth2/applications",
    { name: name, redirect_uris: redirect_uris, description: description, icon: icon }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.update_role(token, server_id, role_id, name, colour, hoist = false, packed_permissions = 36_953_089) ⇒ Object

Update a role Permissions are the Discord defaults; allowed: invite creation, reading/sending messages, sending TTS messages, embedding links, sending files, reading the history, mentioning everybody, connecting to voice, speaking and voice activity (push-to-talk isn't mandatory)



457
458
459
460
461
462
463
464
465
466
# File 'lib/discordrb/api.rb', line 457

def update_role(token, server_id, role_id, name, colour, hoist = false, packed_permissions = 36_953_089)
  request(
    nil,
    :patch,
    "#{api_base}/guilds/#{server_id}/roles/#{role_id}",
    { color: colour, name: name, hoist: hoist, permissions: packed_permissions }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.update_role_overrides(token, channel_id, role_id, allow, deny) ⇒ Object

Update a role's permission overrides in a channel



503
504
505
506
507
508
509
510
511
512
# File 'lib/discordrb/api.rb', line 503

def update_role_overrides(token, channel_id, role_id, allow, deny)
  request(
    nil,
    :put,
    "#{api_base}/channels/#{channel_id}/permissions/#{role_id}",
    { type: 'role', id: role_id, allow: allow, deny: deny }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.update_server(token, server_id, name, region, icon, afk_channel_id, afk_timeout) ⇒ Object

Update a server



218
219
220
221
222
223
224
225
226
227
# File 'lib/discordrb/api.rb', line 218

def update_server(token, server_id, name, region, icon, afk_channel_id, afk_timeout)
  request(
    nil,
    :patch,
    "#{api_base}/guilds/#{server_id}",
    { name: name, region: region, icon: icon, afk_channel_id: afk_channel_id, afk_timeout: afk_timeout }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.update_user(token, email, password, new_username, avatar, new_password = nil) ⇒ Object

Update user data



578
579
580
581
582
583
584
585
586
587
# File 'lib/discordrb/api.rb', line 578

def update_user(token, email, password, new_username, avatar, new_password = nil)
  request(
    nil,
    :patch,
    "#{api_base}/users/@me",
    { avatar: avatar, email: email, new_password: new_password, password: password, username: new_username }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.update_user_overrides(token, channel_id, user_id, allow, deny) ⇒ Object

Update a user's permission overrides in a channel



491
492
493
494
495
496
497
498
499
500
# File 'lib/discordrb/api.rb', line 491

def update_user_overrides(token, channel_id, user_id, allow, deny)
  request(
    nil,
    :put,
    "#{api_base}/channels/#{channel_id}/permissions/#{user_id}",
    { type: 'member', id: user_id, allow: allow, deny: deny }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.update_user_roles(token, server_id, user_id, roles) ⇒ Object

Update a user's roles



479
480
481
482
483
484
485
486
487
488
# File 'lib/discordrb/api.rb', line 479

def update_user_roles(token, server_id, user_id, roles)
  request(
    nil,
    :patch,
    "#{api_base}/guilds/#{server_id}/members/#{user_id}",
    { roles: roles }.to_json,
    Authorization: token,
    content_type: :json
  )
end

.user(token, user_id) ⇒ Object

Get user data



548
549
550
551
552
553
554
555
# File 'lib/discordrb/api.rb', line 548

def user(token, user_id)
  request(
    nil,
    :get,
    "#{api_base}/users/#{user_id}",
    Authorization: token
  )
end

.user_agentObject

Generate a user agent identifying this requester as discordrb.



36
37
38
39
40
41
42
# File 'lib/discordrb/api.rb', line 36

def user_agent
  # This particular string is required by the Discord devs.
  required = "DiscordBot (https://github.com/meew0/discordrb, v#{Discordrb::VERSION})"
  @bot_name ||= ''

  "rest-client/#{RestClient::VERSION} #{RUBY_ENGINE}/#{RUBY_VERSION}p#{RUBY_PATCHLEVEL} discordrb/#{Discordrb::VERSION} #{required} #{@bot_name}"
end

.validate_token(token) ⇒ Object

Validate a token (this request will fail if the token is invalid)



525
526
527
528
529
530
531
532
533
534
# File 'lib/discordrb/api.rb', line 525

def validate_token(token)
  request(
    nil,
    :post,
    "#{api_base}/auth/login",
    {}.to_json,
    Authorization: token,
    content_type: :json
  )
end