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



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

def acknowledge_message(token, channel_id, message_id)
  request(
    __method__,
    :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(
    __method__,
    :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



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

def bans(token, server_id)
  request(
    __method__,
    :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

.change_nickname(token, server_id, user_id, nick) ⇒ Object

Change a user's nickname on a server



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

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

.channel(token, channel_id) ⇒ Object

Get a channel's data



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

def channel(token, channel_id)
  request(
    __method__,
    :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



612
613
614
615
616
617
618
619
# File 'lib/discordrb/api.rb', line 612

def channel_log(token, channel_id, amount, before = nil, after = nil)
  request(
    __method__,
    :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



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

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

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

Create a channel



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

def create_channel(token, server_id, name, type)
  request(
    __method__,
    :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



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

def create_invite(token, channel_id, max_age = 0, max_uses = 0, temporary = false, xkcd = false)
  request(
    __method__,
    :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



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

def create_oauth_application(token, name, redirect_uris)
  request(
    __method__,
    :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



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

def create_private(token, bot_user_id, user_id)
  request(
    __method__,
    :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)



455
456
457
458
459
460
461
462
463
# File 'lib/discordrb/api.rb', line 455

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

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

Create a server



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

def create_server(token, name, region = :london)
  request(
    __method__,
    :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



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

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

.delete_invite(token, code) ⇒ Object

Delete an invite by code



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

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

.delete_message(token, channel_id, message_id) ⇒ Object

Delete a message



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

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

.delete_role(token, server_id, role_id) ⇒ Object

Delete a role



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

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

.delete_server(token, server_id) ⇒ Object

Delete a server



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

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

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

Edit a message



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

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



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

def gateway(token)
  request(
    __method__,
    :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



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

def join_server(token, invite_code)
  request(
    __method__,
    :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(
    __method__,
    :delete,
    "#{api_base}/guilds/#{server_id}/members/#{user_id}",
    Authorization: token
  )
end

.leave_server(token, server_id) ⇒ Object

Leave a server



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

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

.login(email, password) ⇒ Object

Login to the server



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

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

.logout(token) ⇒ Object

Logout from the server



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

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

.member(token, server_id, user_id) ⇒ Object

Get a member's data



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

def member(token, server_id, user_id)
  request(
    __method__,
    :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(
    __method__,
    :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



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

def profile(token)
  request(
    __method__,
    :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.



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

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



63
64
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 63

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
      @mutexes[key] = Mutex.new unless @mutexes[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
# File 'lib/discordrb/api.rb', line 45

def reset_mutexes
  @mutexes = {}
end

.resolve_invite(token, invite_code) ⇒ Object

Resolve an invite



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

def resolve_invite(token, invite_code)
  request(
    __method__,
    :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



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

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

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

Send a message to a channel



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

def send_message(token, channel_id, message, mentions = [], tts = false, guild_id = nil)
  request(
    "message-#{guild_id}".to_sym,
    :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



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

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

.servers(token) ⇒ Object

Get the servers a user is connected to



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

def servers(token)
  request(
    __method__,
    :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)



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

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

.transfer_ownership(token, server_id, user_id) ⇒ Object

Transfer server ownership



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

def transfer_ownership(token, server_id, user_id)
  request(
    __method__,
    :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(
    __method__,
    :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



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

def update_channel(token, channel_id, name, topic, position = 0)
  request(
    __method__,
    :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



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

def update_oauth_application(token, name, redirect_uris, description = '', icon = nil)
  request(
    __method__,
    :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)



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

def update_role(token, server_id, role_id, name, colour, hoist = false, packed_permissions = 36_953_089)
  request(
    __method__,
    :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



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

def update_role_overrides(token, channel_id, role_id, allow, deny)
  request(
    __method__,
    :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



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

def update_server(token, server_id, name, region, icon, afk_channel_id, afk_timeout)
  request(
    __method__,
    :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



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

def update_user(token, email, password, new_username, avatar, new_password = nil)
  request(
    __method__,
    :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



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

def update_user_overrides(token, channel_id, user_id, allow, deny)
  request(
    __method__,
    :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



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

def update_user_roles(token, server_id, user_id, roles)
  request(
    __method__,
    :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



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

def user(token, user_id)
  request(
    __method__,
    :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)



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

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