discordrb 2.1.3 → 3.0.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +76 -0
- data/README.md +4 -2
- data/discordrb.gemspec +1 -1
- data/examples/commands.rb +2 -0
- data/examples/data/music.dca +0 -0
- data/examples/data/music.mp3 +0 -0
- data/examples/eval.rb +6 -3
- data/examples/ping.rb +14 -1
- data/examples/ping_with_respond_time.rb +6 -4
- data/examples/pm_send.rb +3 -0
- data/examples/shutdown.rb +7 -2
- data/examples/voice_send.rb +51 -0
- data/lib/discordrb/api.rb +66 -460
- data/lib/discordrb/api/channel.rb +306 -0
- data/lib/discordrb/api/invite.rb +41 -0
- data/lib/discordrb/api/server.rb +357 -0
- data/lib/discordrb/api/user.rb +134 -0
- data/lib/discordrb/bot.rb +266 -576
- data/lib/discordrb/cache.rb +27 -28
- data/lib/discordrb/commands/command_bot.rb +44 -15
- data/lib/discordrb/commands/container.rb +3 -2
- data/lib/discordrb/commands/parser.rb +14 -6
- data/lib/discordrb/container.rb +30 -3
- data/lib/discordrb/data.rb +823 -189
- data/lib/discordrb/errors.rb +145 -0
- data/lib/discordrb/events/channels.rb +63 -3
- data/lib/discordrb/events/members.rb +1 -2
- data/lib/discordrb/events/message.rb +96 -17
- data/lib/discordrb/events/presence.rb +15 -0
- data/lib/discordrb/events/typing.rb +7 -1
- data/lib/discordrb/gateway.rb +724 -0
- data/lib/discordrb/light/light_bot.rb +6 -4
- data/lib/discordrb/logger.rb +26 -9
- data/lib/discordrb/permissions.rb +6 -3
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/voice_bot.rb +29 -6
- metadata +12 -5
- data/lib/discordrb/token_cache.rb +0 -181
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eae3c0ee1c9f49e7e8c498ce1db7361a9e812053
|
4
|
+
data.tar.gz: ed4937a0c6c8a4c1c084fa684c78e5b8f11ace7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b1fddaa771f734968bc3d0172b8fe87a95a442d9d6ee3ace91ad8e9a182a94c8b1829d333272d01dcad6a8a0cfad676d0c7f1018b34ba9afa66acdca58cf32e
|
7
|
+
data.tar.gz: d1fe90193e8abd77d749a5982bb8ba4bb23b88625acd80f80fbdb0a37ab99127af5574cd3284c187258b254dbb863e235d9d85c313ec8ff5e71253a12bca0923
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,81 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.0.0
|
4
|
+
|
5
|
+
I didn't think there could possibly be a release larger than 2.0.0 was, but here it is! Including the respective release commit, there were 540 commits from 1.8.1 to 2.0.0, but a whopping 734 commits from 2.1.3 to 3.0.0.
|
6
|
+
|
7
|
+
As with 2.0.0, there are some breaking changes! They are, as always, highlighted in bold.
|
8
|
+
|
9
|
+
- **The `application_id` parameter has been renamed to `client_id`**. With the changes to how bot applications work, it would just be confusing to have it be called `application_id` any longer. If you try to use `application_id` now, it will raise a descriptive exception; with 3.1.0 that will be removed too (you'll get a less descriptive exception).
|
10
|
+
- The gateway implementation has been completely rewritten, for more performance, stability and maintainability. This means that **to call some internal methods like `inject_reconnect`, a `Gateway` instance (available as `Bot#gateway`) now needs to be used.**
|
11
|
+
- **User login using email and password has been removed**. Use a user token instead, see also [here](https://github.com/hammerandchisel/discord-api-docs/issues/69#issuecomment-223886862).
|
12
|
+
- In addition to the rewrite, the gateway version has also been upgraded to protocol version 6 (the rewrite was for v5). **With this, the way channel types are handled has been changed a bit!** If you've been using the abstraction methods like `Channel#voice?`, you should be fine though. This also includes support for group chats on user accounts, as that was the only real functionality change on v6. ([#211](https://github.com/meew0/discordrb/pull/211), thanks @Daniel-Worrall)
|
13
|
+
- **Custom prefix handlers for `CommandBot`s now get the full message object as their parameter rather than only the content**, for even more flexibility.
|
14
|
+
- For internal consistency, **the `UnknownGuild` error was renamed to `UnknownServer`**. I doubt this change affects anyone, but if you handle that error specifically in your bot, make sure to change it.
|
15
|
+
- **The API module has undergone a refactor**, if you were using any manual API calls you will have to update them to the new format. Specifically, endpoints dealing with channels have been moved to `API::Channel`, ones dealing with users to `API::User` and so on. ([#203](https://github.com/meew0/discordrb/pull/203), thanks @depl0y)
|
16
|
+
- **Calling `users` on a text channel will now only return users who have permission to read it** ([#186](https://github.com/meew0/discordrb/issues/186))
|
17
|
+
- A variety of new fields have been added to `Message` objects, specifically embeds (`Message#embeds`), when it was last edited (`#edited_timestamp`), whether it uses TTS (`#tts?`), its nonce (`#nonce`), whether it was ever edited (`#edited?`), and whether it mentions everyone (`mention_everyone?`) ([#206](https://github.com/meew0/discordrb/pull/206), thanks @SnazzyPine25)
|
18
|
+
- A variety of new functionality has been added to `Server` and `Channel` objects ([#181](https://github.com/meew0/discordrb/pull/181), thanks @SnazzyPine25):
|
19
|
+
- Bitrate and user limit can now be read and set for voice channels
|
20
|
+
- Server integrations can now be read
|
21
|
+
- Server features and verification level can now be read
|
22
|
+
- Utility functions to generate widget, widget banner and splash URLs
|
23
|
+
- Message pinning is now supported, both reading pin status and pinning existing messages ([#145](https://github.com/meew0/discordrb/issues/145) / [#146](https://github.com/meew0/discordrb/pull/146), thanks @hlaaftana)
|
24
|
+
- Support for the new available statuses:
|
25
|
+
- `Bot#dnd` to make the bot show up as DnD (red dot)
|
26
|
+
- `Bot#invisible` to make the bot show up as offline
|
27
|
+
- Setting the bot's status to streaming is now supported ([#128](https://github.com/meew0/discordrb/pull/128) and [#143](https://github.com/meew0/discordrb/pull/143), thanks @SnazzyPine25 and @barkerja)
|
28
|
+
- You can now set a message to be sent when a `CommandBot`'s command fails with a `NoPermission` error ([#200](https://github.com/meew0/discordrb/pull/200), thanks @PoVa)
|
29
|
+
- There is now an optional field to list the parameters a command can accept ([#201](https://github.com/meew0/discordrb/pull/201), thanks @FormalHellhound)
|
30
|
+
- Commands can now have an array of roles set that are required to be able to use it ([#178](https://github.com/meew0/discordrb/pull/178), thanks @PoVa)
|
31
|
+
- Methods like `CommandEvent#<<` for quickly responding to an event are now available in `MessageEvent` too ([#154](https://github.com/meew0/discordrb/pull/154), thanks @hlaaftana)
|
32
|
+
- Temporary messages, that automatically delete after some time, can now be sent to channels ([#136](https://github.com/meew0/discordrb/issues/136) / [#139](https://github.com/meew0/discordrb/pull/139), thanks @unleashy)
|
33
|
+
- Captions can now be sent together with files, and files can be attached to events to be sent on completion ([#130](https://github.com/meew0/discordrb/pull/130), thanks @SnazzyPine25)
|
34
|
+
- There is now a `Channel#load_message` method to get a single message by its ID ([#174](https://github.com/meew0/discordrb/pull/174), thanks @z64)
|
35
|
+
- `Channel#define_overwrite` can now be used with a `Profile` object, together with some internal changes ([#232](https://github.com/meew0/discordrb/issues/232))
|
36
|
+
- There are now endpoint methods to list a server's channels and channel invites ([#197](https://github.com/meew0/discordrb/pull/197))
|
37
|
+
- Two methods, `Member#roles=` and `Member#modify_roles` to manipulate a member's roles in a more advanced way have been added ([#223](https://github.com/meew0/discordrb/pull/223), thanks @z64)
|
38
|
+
- Role mentionability can now be set using `Role#mentionable=`
|
39
|
+
- The current bot's OAuth application can now be read ([#175](https://github.com/meew0/discordrb/pull/175), thanks @SnazzyPine25)
|
40
|
+
- You can now mute and deafen other members ([#157](https://github.com/meew0/discordrb/pull/157), thanks @SnazzyPine25)
|
41
|
+
- The internal `Logger` now supports writing to a file instead of STDOUT ([#171](https://github.com/meew0/discordrb/issues/171))
|
42
|
+
- Building on top of that, you can also write to multiple streams at the same time now, in case you want to have input on both a file and STDOUT, or even more advanced setups. ([#217](https://github.com/meew0/discordrb/pull/217), thanks @PoVa)
|
43
|
+
- Roles can now have their permissions bitfield set directly ([#177](https://github.com/meew0/discordrb/issues/177))
|
44
|
+
- The `Bot#invite_url` method now supports adding permission bits into the generated URL ([#218](https://github.com/meew0/discordrb/pull/218), thanks @PoVa)
|
45
|
+
- A utility method `User#send_file` has been added to directly send a file to a user in PM ([#168](https://github.com/meew0/discordrb/issues/168) / [#172](https://github.com/meew0/discordrb/pull/172), thanks @SnazzyPine25)
|
46
|
+
- You can now get the list of members that have a particular role assigned using `Role#members` ([#147](https://github.com/meew0/discordrb/pull/147), thanks @hlaaftana)
|
47
|
+
- You can now check whether a `VoiceBot` is playing right now using `#playing?` ([#137](https://github.com/meew0/discordrb/pull/137), thanks @SnazzyPine25)
|
48
|
+
- You can now get the channel a `VoiceBot` is playing on ([#138](https://github.com/meew0/discordrb/pull/138), thanks @snapcase)
|
49
|
+
- The permissions bit map has been updated for emoji, "Administrator" and nickname changes ([#180](https://github.com/meew0/discordrb/pull/180), thanks @megumisonoda)
|
50
|
+
- A method `Bot#connected?` has been added to check whether the bot is currently connected to the gateway.
|
51
|
+
- The indescriptive error message that was previously sent when calling methods like `Bot#game=` without an active gateway connection has been replaced with a more descriptive one.
|
52
|
+
- The bot's token is now, by default, redacted from any logging output; this can be turned off if desired using the `redact_token` initialization parameter. ([#225](https://github.com/meew0/discordrb/issues/225) / [#231](https://github.com/meew0/discordrb/pull/231), thanks @Daniel-Worrall)
|
53
|
+
- The new rate limit headers are now supported. This will have no real impact on any code using discordrb, but it means discordrb is now considered compliant again. See also [here](https://github.com/hammerandchisel/discord-api-docs/issues/108).
|
54
|
+
- Rogue presences, i.e. presences without an associated cached member, now print a log message instead of being completely ignored
|
55
|
+
- A variety of aliases have been added to existing methods.
|
56
|
+
- An example to show off voice sending has been added to the repo, and existing examples have been improved.
|
57
|
+
- A large amount of fixes and clarifications have been made to the docs.
|
58
|
+
|
59
|
+
### Bugfixes
|
60
|
+
|
61
|
+
- The almost a year old bug where changing the own user's username would reset its avatar has finally been fixed.
|
62
|
+
- The issue where resolving a large server with the owner offline would sometimes cause a stack overflow has been fixed ([#169](https://github.com/meew0/discordrb/issues/169) / [#170](https://github.com/meew0/discordrb/issues/170) / [#191](https://github.com/meew0/discordrb/pull/191), thanks @stoodfarback)
|
63
|
+
- Fixed an issue where if a server had an AFK channel set, but that AFK channel couldn't be connected to, resolving the server (and in turn all objects depending on it) would fail. This likely fixes any random `NoPermission` errors you've ever encountered in your log.
|
64
|
+
- A message's author will be resolved over the REST API like other objects in case it's not cached yet. This should fix all instances of "Member not cached even thought it should be". ([#210](https://github.com/meew0/discordrb/pull/210), thanks @megumisonoda)
|
65
|
+
- Voice state handling has been completely redone, fixing a variety of caching issues. ([#159](https://github.com/meew0/discordrb/issues/159))
|
66
|
+
- Getting a voice channel's users no longer does a chunk request ([#142](https://github.com/meew0/discordrb/issues/142))
|
67
|
+
- `Channel#define_overwrite` can now be used to define user overwrites, apparently that didn't work at all before
|
68
|
+
- Nested command chains where an inner command doesn't exist now no longer crash the command chain handler ([#215](https://github.com/meew0/discordrb/issues/215))
|
69
|
+
- Gateway errors should no longer spam the console ([#141](https://github.com/meew0/discordrb/issues/141) / [#148](https://github.com/meew0/discordrb/pull/148), thanks @meew0)
|
70
|
+
- Role hoisting (both setting and reading it) should now work properly
|
71
|
+
- The `VoiceBot#stop_playing` method should now work more predictably
|
72
|
+
- Voice states with a nil channel should no longer crash when accessed ([#183](https://github.com/meew0/discordrb/pull/183), thanks @Apexal)
|
73
|
+
- A latent bug in how PM channels were cached is fixed, previously they were cached twice - once by channel ID and once by recipient ID. Now they're only cached by recipient ID.
|
74
|
+
- Two problems in how Discord outages are handled are now fixed; the bot should now no longer break when one happens. Specifically, the fixed problems are:
|
75
|
+
- `GUILD_DELETE` events for unavailable servers are now ignored
|
76
|
+
- Opcode 9 packets which are received while no session currently exists are handled correctly
|
77
|
+
- A possible regression in PM channel creation was fixed. ([#227](https://github.com/meew0/discordrb/issues/227) / [#228](https://github.com/meew0/discordrb/pull/228), thanks @heimidal)
|
78
|
+
|
3
79
|
## 2.1.3
|
4
80
|
|
5
81
|
*Bugfix-only release.*
|
data/README.md
CHANGED
@@ -30,6 +30,8 @@ This section only applies to you if you want to use voice functionality.
|
|
30
30
|
* A compiled libopus distribution for your system, anywhere the script can find it (on Windows, make sure it's named `opus.dll`)
|
31
31
|
* [FFmpeg](https://www.ffmpeg.org/download.html) installed and in your PATH
|
32
32
|
|
33
|
+
In addition to this, if you're on Windows and want to use voice functionality, your installed Ruby version **needs to be 32 bit**, as otherwise Opus won't work.
|
34
|
+
|
33
35
|
## Installation
|
34
36
|
|
35
37
|
### Linux
|
@@ -40,9 +42,9 @@ On Linux, it should be as simple as running:
|
|
40
42
|
|
41
43
|
### Windows
|
42
44
|
|
43
|
-
On Windows, to install discordrb, run this in a shell
|
45
|
+
On Windows, to install discordrb, run this in a shell **(make sure you have the DevKit installed! See the [Dependencies](https://github.com/meew0/discordrb#dependencies) section)**:
|
44
46
|
|
45
|
-
gem install discordrb
|
47
|
+
gem install discordrb --platform=ruby
|
46
48
|
|
47
49
|
Run the [ping example](https://github.com/meew0/discordrb/blob/master/examples/ping.rb) to verify that the installation works (make sure to replace the username and password in there with your own or your bots'!):
|
48
50
|
|
data/discordrb.gemspec
CHANGED
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency 'rake', '~> 10.0'
|
32
32
|
spec.add_development_dependency 'yard', '~> 0.8.7.6'
|
33
33
|
spec.add_development_dependency 'rspec', '~> 3.4.0'
|
34
|
-
spec.add_development_dependency 'rubocop', '0.
|
34
|
+
spec.add_development_dependency 'rubocop', '0.42.0'
|
35
35
|
end
|
data/examples/commands.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'discordrb'
|
4
4
|
|
5
|
+
# Here we instantiate a `CommandBot` instead of a regular `Bot`, which has the functionality to add commands using the
|
6
|
+
# `command` method. We have to set a `prefix` here, which will be the character that triggers command execution.
|
5
7
|
bot = Discordrb::Commands::CommandBot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543, prefix: '!'
|
6
8
|
|
7
9
|
bot.command :user do |event|
|
Binary file
|
Binary file
|
data/examples/eval.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
|
-
#
|
1
|
+
# Eval bots are useful for developers because they give you a way to execute code directly from your Discord channel,
|
2
|
+
# e.g. to quickly check something, demonstrate something to other, or something else entirely. Special care must be
|
3
|
+
# taken since anyone with access to the command can execute arbitrary code on your system which may potentially be
|
4
|
+
# malicious.
|
2
5
|
|
3
6
|
require 'discordrb'
|
4
7
|
|
5
8
|
bot = Discordrb::Commands::CommandBot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543, prefix: '!'
|
6
9
|
|
7
10
|
bot.command(:eval, help_available: false) do |event, *code|
|
8
|
-
break unless event.user.id ==
|
11
|
+
break unless event.user.id == 66237334693085184 # Replace number with your ID
|
9
12
|
|
10
13
|
begin
|
11
14
|
eval code.join(' ')
|
12
15
|
rescue
|
13
|
-
|
16
|
+
'An error occured 😞'
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
data/examples/ping.rb
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'discordrb'
|
4
4
|
|
5
|
+
# This statement creates a bot with the specified token and application ID. After this line, you can add events to the
|
6
|
+
# created bot, and eventually run it.
|
7
|
+
#
|
8
|
+
# If you don't yet have a token and application ID to put in here, you will need to create a bot account here:
|
9
|
+
# https://discordapp.com/developers/applications/me
|
10
|
+
# If you're wondering about what redirect URIs and RPC origins, you can ignore those for now. If that doesn't satisfy
|
11
|
+
# you, look here: https://github.com/meew0/discordrb/wiki/Redirect-URIs-and-RPC-origins
|
12
|
+
# After creating the bot, simply copy the token (*not* the OAuth2 secret) and the client ID and put it into the
|
13
|
+
# respective places.
|
5
14
|
bot = Discordrb::Bot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543
|
6
15
|
|
7
16
|
# Here we output the invite URL to the console so the bot account can be invited to the channel. This only has to be
|
@@ -9,8 +18,12 @@ bot = Discordrb::Bot.new token: 'B0T.T0KEN.here', application_id: 16012345678987
|
|
9
18
|
puts "This bot's invite URL is #{bot.invite_url}."
|
10
19
|
puts 'Click on it to invite it to your server.'
|
11
20
|
|
12
|
-
|
21
|
+
# This method call adds an event handler that will be called on any message that exactly contains the string "Ping!".
|
22
|
+
# The code inside it will be executed, and a "Pong!" response will be sent to the channel.
|
23
|
+
bot.message(content: 'Ping!') do |event|
|
13
24
|
event.respond 'Pong!'
|
14
25
|
end
|
15
26
|
|
27
|
+
# This method call has to be put at the end of your script, it is what makes the bot actually connect to Discord. If you
|
28
|
+
# leave it out (try it!) the script will simply stop and the bot will not appear online.
|
16
29
|
bot.run
|
@@ -1,13 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# This example is nearly the same as the normal ping example, but rather than simply responding with "Pong!", it also
|
2
|
+
# responds with the time it took to send the message.
|
2
3
|
|
3
4
|
require 'discordrb'
|
4
5
|
|
5
|
-
bot = Discordrb::
|
6
|
+
bot = Discordrb::Bot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543
|
6
7
|
|
7
|
-
bot.
|
8
|
+
bot.message(content: 'Ping!') do |event|
|
9
|
+
# The `respond` method returns a `Message` object, which is stored in a variable `m`. The `edit` method is then called
|
10
|
+
# to edit the message with the time difference between when the event was received and after the message was sent.
|
8
11
|
m = event.respond('Pong!')
|
9
12
|
m.edit "Pong! Time taken: #{Time.now - event.timestamp} seconds."
|
10
|
-
nil
|
11
13
|
end
|
12
14
|
|
13
15
|
bot.run
|
data/examples/pm_send.rb
CHANGED
@@ -4,7 +4,10 @@ require 'discordrb'
|
|
4
4
|
|
5
5
|
bot = Discordrb::Bot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543
|
6
6
|
|
7
|
+
# The `mention` event is called if the bot is *directly mentioned*, i.e. not using a role mention or @everyone/@here.
|
7
8
|
bot.mention do |event|
|
9
|
+
# The `pm` method is used to send a private message (also called a DM or direct message) to the user who sent the
|
10
|
+
# initial message.
|
8
11
|
event.user.pm('You have mentioned me!')
|
9
12
|
end
|
10
13
|
|
data/examples/shutdown.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
|
-
# This
|
1
|
+
# This bot doesn't do anything except for letting a specifically authorised user shutdown the bot on command.
|
2
2
|
|
3
3
|
require 'discordrb'
|
4
4
|
|
5
5
|
bot = Discordrb::Commands::CommandBot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543, prefix: '!'
|
6
6
|
|
7
|
+
# Here we can see the `help_available` property used, which can determine whether a command shows up in the default
|
8
|
+
# generated `help` command. It is true by default but it can be set to false to hide internal commands that only
|
9
|
+
# specific people can use.
|
7
10
|
bot.command(:exit, help_available: false) do |event|
|
8
|
-
|
11
|
+
# This is a check that only allows a user with a specific ID to execute this command. Otherwise, everyone would be
|
12
|
+
# able to shut your bot down whenever they wanted.
|
13
|
+
break unless event.user.id == 66237334693085184 # Replace number with your ID
|
9
14
|
|
10
15
|
bot.send_message(event.channel.id, 'Bot is shutting down')
|
11
16
|
exit
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# discordrb can send music or other audio data to voice channels. This example exists to show that off.
|
2
|
+
#
|
3
|
+
# To avoid copyright infringement, the example music I will be using is a self-composed piece of highly debatable
|
4
|
+
# quality. If you want something better you can replace the files in the data/ directory. Make sure to execute this
|
5
|
+
# example from the appropriate place, so that it has access to the files in that directory.
|
6
|
+
|
7
|
+
require 'discordrb'
|
8
|
+
|
9
|
+
bot = Discordrb::Commands::CommandBot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543, prefix: '!'
|
10
|
+
|
11
|
+
bot.command(:connect) do |event|
|
12
|
+
# The `voice_channel` method returns the voice channel the user is currently in, or `nil` if the user is not in a
|
13
|
+
# voice channel.
|
14
|
+
channel = event.user.voice_channel
|
15
|
+
|
16
|
+
# Here we return from the command unless the channel is not nil (i. e. the user is in a voice channel). The `next`
|
17
|
+
# construct can be used to exit a command prematurely, and even send a message while we're at it.
|
18
|
+
next "You're not in any voice channel!" unless channel
|
19
|
+
|
20
|
+
# The `voice_connect` method does everything necessary for the bot to connect to a voice channel. Afterwards the bot
|
21
|
+
# will be connected and ready to play stuff back.
|
22
|
+
bot.voice_connect(channel)
|
23
|
+
"Connected to voice channel: #{channel.name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
# A simple command that plays back an mp3 file.
|
27
|
+
bot.command(:play_mp3) do |event|
|
28
|
+
# `event.voice` is a helper method that gets the correct voice bot on the server the bot is currently in. Since a
|
29
|
+
# bot may be connected to more than one voice channel (never more than one on the same server, though), this is
|
30
|
+
# necessary to allow the differentiation of servers.
|
31
|
+
#
|
32
|
+
# It returns a `VoiceBot` object that methods such as `play_file` can be called on.
|
33
|
+
voice_bot = event.voice
|
34
|
+
voice_bot.play_file('data/music.mp3')
|
35
|
+
end
|
36
|
+
|
37
|
+
# DCA is a custom audio format developed by a couple people from the Discord API community (including myself, meew0).
|
38
|
+
# It represents the audio data exactly as Discord wants it in a format that is very simple to parse, so libraries can
|
39
|
+
# very easily add support for it. It has the advantage that absolutely no transcoding has to be done, so it is very
|
40
|
+
# light on CPU in comparison to `play_file`.
|
41
|
+
#
|
42
|
+
# A conversion utility that converts existing audio files to DCA can be found here: https://github.com/nstafie/dca-rs
|
43
|
+
bot.command(:play_dca) do |event|
|
44
|
+
voice_bot = event.voice
|
45
|
+
|
46
|
+
# Since the DCA format is non-standard (i.e. ffmpeg doesn't support it), a separate method other than `play_file` has
|
47
|
+
# to be used to play DCA files back. `play_dca` fulfills that role.
|
48
|
+
voice_bot.play_dca('data/music.dca')
|
49
|
+
end
|
50
|
+
|
51
|
+
bot.run
|
data/lib/discordrb/api.rb
CHANGED
@@ -2,13 +2,14 @@
|
|
2
2
|
|
3
3
|
require 'rest-client'
|
4
4
|
require 'json'
|
5
|
+
require 'time'
|
5
6
|
|
6
7
|
require 'discordrb/errors'
|
7
8
|
|
8
9
|
# List of methods representing endpoints in Discord's API
|
9
10
|
module Discordrb::API
|
10
11
|
# The base URL of the Discord REST API.
|
11
|
-
APIBASE = 'https://discordapp.com/api'.freeze
|
12
|
+
APIBASE = 'https://discordapp.com/api/v6'.freeze
|
12
13
|
|
13
14
|
module_function
|
14
15
|
|
@@ -44,6 +45,18 @@ module Discordrb::API
|
|
44
45
|
# Resets all rate limit mutexes
|
45
46
|
def reset_mutexes
|
46
47
|
@mutexes = {}
|
48
|
+
@global_mutex = Mutex.new
|
49
|
+
end
|
50
|
+
|
51
|
+
# Wait a specified amount of time synchronised with the specified mutex.
|
52
|
+
def sync_wait(time, mutex)
|
53
|
+
mutex.synchronize { sleep time }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Wait for a specified mutex to unlock and do nothing with it afterwards.
|
57
|
+
def mutex_wait(mutex)
|
58
|
+
mutex.lock
|
59
|
+
mutex.unlock
|
47
60
|
end
|
48
61
|
|
49
62
|
# Performs a RestClient request.
|
@@ -58,33 +71,49 @@ module Discordrb::API
|
|
58
71
|
retry
|
59
72
|
end
|
60
73
|
|
61
|
-
# Make an API request
|
62
|
-
|
63
|
-
def request(key, type, *attributes)
|
74
|
+
# Make an API request, including rate limit handling.
|
75
|
+
def request(key, major_parameter, type, *attributes)
|
64
76
|
# Add a custom user agent
|
65
77
|
attributes.last[:user_agent] = user_agent if attributes.last.is_a? Hash
|
66
78
|
|
79
|
+
# The most recent Discord rate limit requirements require the support of major parameters, where a particular route
|
80
|
+
# and major parameter combination (*not* the HTTP method) uniquely identifies a RL bucket.
|
81
|
+
key = [key, major_parameter].freeze
|
82
|
+
|
67
83
|
begin
|
68
|
-
|
69
|
-
@mutexes[key] = Mutex.new unless @mutexes[key]
|
84
|
+
mutex = @mutexes[key] ||= Mutex.new
|
70
85
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
86
|
+
# Lock and unlock, i. e. wait for the mutex to unlock and don't do anything with it afterwards
|
87
|
+
mutex_wait(mutex)
|
88
|
+
|
89
|
+
# If the global mutex happens to be locked right now, wait for that as well.
|
90
|
+
mutex_wait(@global_mutex) if @global_mutex.locked?
|
75
91
|
|
76
92
|
response = raw_request(type, attributes)
|
93
|
+
|
94
|
+
if response.headers[:x_ratelimit_remaining] == '0' && !mutex.locked?
|
95
|
+
Discordrb::LOGGER.debug "RL bucket depletion detected! Date: #{response.headers[:date]} Reset: #{response.headers[:x_ratelimit_reset]}"
|
96
|
+
|
97
|
+
now = Time.rfc2822(response.headers[:date])
|
98
|
+
reset = Time.at(response.headers[:x_ratelimit_reset].to_i)
|
99
|
+
|
100
|
+
delta = reset - now
|
101
|
+
|
102
|
+
Discordrb::LOGGER.warn("Locking RL mutex (key: #{key}) for #{delta} seconds preemptively")
|
103
|
+
sync_wait(delta, mutex)
|
104
|
+
end
|
77
105
|
rescue RestClient::TooManyRequests => e
|
78
|
-
|
106
|
+
# If the 429 is from the global RL, then we have to use the global mutex instead.
|
107
|
+
mutex = @global_mutex if e.response.headers[:x_ratelimit_global] == 'true'
|
79
108
|
|
80
|
-
unless
|
109
|
+
unless mutex.locked?
|
81
110
|
response = JSON.parse(e.response)
|
82
111
|
wait_seconds = response['retry_after'].to_i / 1000.0
|
83
112
|
Discordrb::LOGGER.warn("Locking RL mutex (key: #{key}) for #{wait_seconds} seconds due to Discord rate limiting")
|
84
113
|
|
85
114
|
# Wait the required time synchronized by the mutex (so other incoming requests have to wait) but only do it if
|
86
115
|
# the mutex isn't locked already so it will only ever wait once
|
87
|
-
|
116
|
+
sync_wait(wait_seconds, mutex)
|
88
117
|
end
|
89
118
|
|
90
119
|
retry
|
@@ -93,85 +122,26 @@ module Discordrb::API
|
|
93
122
|
response
|
94
123
|
end
|
95
124
|
|
96
|
-
# Make an avatar URL from the user and avatar IDs
|
97
|
-
def avatar_url(user_id, avatar_id)
|
98
|
-
"#{api_base}/users/#{user_id}/avatars/#{avatar_id}.jpg"
|
99
|
-
end
|
100
|
-
|
101
125
|
# Make an icon URL from server and icon IDs
|
102
126
|
def icon_url(server_id, icon_id)
|
103
127
|
"#{api_base}/guilds/#{server_id}/icons/#{icon_id}.jpg"
|
104
128
|
end
|
105
129
|
|
106
|
-
#
|
107
|
-
def
|
108
|
-
|
109
|
-
__method__,
|
110
|
-
:put,
|
111
|
-
"#{api_base}/guilds/#{server_id}/bans/#{user_id}?delete-message-days=#{message_days}",
|
112
|
-
nil,
|
113
|
-
Authorization: token
|
114
|
-
)
|
115
|
-
end
|
116
|
-
|
117
|
-
# Unban a user from a server
|
118
|
-
def unban_user(token, server_id, user_id)
|
119
|
-
request(
|
120
|
-
__method__,
|
121
|
-
:delete,
|
122
|
-
"#{api_base}/guilds/#{server_id}/bans/#{user_id}",
|
123
|
-
Authorization: token
|
124
|
-
)
|
125
|
-
end
|
126
|
-
|
127
|
-
# Kick a user from a server
|
128
|
-
def kick_user(token, server_id, user_id)
|
129
|
-
request(
|
130
|
-
__method__,
|
131
|
-
:delete,
|
132
|
-
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
133
|
-
Authorization: token
|
134
|
-
)
|
135
|
-
end
|
136
|
-
|
137
|
-
# Move a user to a different voice channel
|
138
|
-
def move_user(token, server_id, user_id, channel_id)
|
139
|
-
request(
|
140
|
-
__method__,
|
141
|
-
:patch,
|
142
|
-
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
143
|
-
{ channel_id: channel_id }.to_json,
|
144
|
-
Authorization: token,
|
145
|
-
content_type: :json
|
146
|
-
)
|
147
|
-
end
|
148
|
-
|
149
|
-
# Change a user's nickname on a server
|
150
|
-
def change_nickname(token, server_id, user_id, nick)
|
151
|
-
request(
|
152
|
-
__method__,
|
153
|
-
:patch,
|
154
|
-
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
155
|
-
{ nick: nick }.to_json,
|
156
|
-
Authorization: token,
|
157
|
-
content_type: :json
|
158
|
-
)
|
130
|
+
# Make an icon URL from application and icon IDs
|
131
|
+
def app_icon_url(app_id, icon_id)
|
132
|
+
"https://cdn.discordapp.com/app-icons/#{app_id}/#{icon_id}.jpg"
|
159
133
|
end
|
160
134
|
|
161
|
-
#
|
162
|
-
def
|
163
|
-
|
164
|
-
__method__,
|
165
|
-
:get,
|
166
|
-
"#{api_base}/guilds/#{server_id}/bans",
|
167
|
-
Authorization: token
|
168
|
-
)
|
135
|
+
# Make a widget picture URL from server ID
|
136
|
+
def widget_url(server_id, style = 'shield')
|
137
|
+
"#{api_base}/guilds/#{server_id}/widget.png?style=#{style}"
|
169
138
|
end
|
170
139
|
|
171
140
|
# Login to the server
|
172
141
|
def login(email, password)
|
173
142
|
request(
|
174
|
-
|
143
|
+
:auth_login,
|
144
|
+
nil,
|
175
145
|
:post,
|
176
146
|
"#{api_base}/auth/login",
|
177
147
|
email: email,
|
@@ -182,7 +152,8 @@ module Discordrb::API
|
|
182
152
|
# Logout from the server
|
183
153
|
def logout(token)
|
184
154
|
request(
|
185
|
-
|
155
|
+
:auth_logout,
|
156
|
+
nil,
|
186
157
|
:post,
|
187
158
|
"#{api_base}/auth/logout",
|
188
159
|
nil,
|
@@ -193,7 +164,8 @@ module Discordrb::API
|
|
193
164
|
# Create an OAuth application
|
194
165
|
def create_oauth_application(token, name, redirect_uris)
|
195
166
|
request(
|
196
|
-
|
167
|
+
:oauth2_applications,
|
168
|
+
nil,
|
197
169
|
:post,
|
198
170
|
"#{api_base}/oauth2/applications",
|
199
171
|
{ name: name, redirect_uris: redirect_uris }.to_json,
|
@@ -205,7 +177,8 @@ module Discordrb::API
|
|
205
177
|
# Change an OAuth application's properties
|
206
178
|
def update_oauth_application(token, name, redirect_uris, description = '', icon = nil)
|
207
179
|
request(
|
208
|
-
|
180
|
+
:oauth2_applications,
|
181
|
+
nil,
|
209
182
|
:put,
|
210
183
|
"#{api_base}/oauth2/applications",
|
211
184
|
{ name: name, redirect_uris: redirect_uris, description: description, icon: icon }.to_json,
|
@@ -214,237 +187,24 @@ module Discordrb::API
|
|
214
187
|
)
|
215
188
|
end
|
216
189
|
|
217
|
-
#
|
218
|
-
def
|
219
|
-
request(
|
220
|
-
__method__,
|
221
|
-
:post,
|
222
|
-
"#{api_base}/guilds",
|
223
|
-
{ name: name, region: region.to_s }.to_json,
|
224
|
-
Authorization: token,
|
225
|
-
content_type: :json
|
226
|
-
)
|
227
|
-
end
|
228
|
-
|
229
|
-
# Update a server
|
230
|
-
def update_server(token, server_id, name, region, icon, afk_channel_id, afk_timeout)
|
190
|
+
# Get the bot's OAuth application's information
|
191
|
+
def oauth_application(token)
|
231
192
|
request(
|
232
|
-
|
233
|
-
:patch,
|
234
|
-
"#{api_base}/guilds/#{server_id}",
|
235
|
-
{ name: name, region: region, icon: icon, afk_channel_id: afk_channel_id, afk_timeout: afk_timeout }.to_json,
|
236
|
-
Authorization: token,
|
237
|
-
content_type: :json
|
238
|
-
)
|
239
|
-
end
|
240
|
-
|
241
|
-
# Transfer server ownership
|
242
|
-
def transfer_ownership(token, server_id, user_id)
|
243
|
-
request(
|
244
|
-
__method__,
|
245
|
-
:patch,
|
246
|
-
"#{api_base}/guilds/#{server_id}",
|
247
|
-
{ owner_id: user_id }.to_json,
|
248
|
-
Authorization: token,
|
249
|
-
content_type: :json
|
250
|
-
)
|
251
|
-
end
|
252
|
-
|
253
|
-
# Delete a server
|
254
|
-
def delete_server(token, server_id)
|
255
|
-
request(
|
256
|
-
__method__,
|
257
|
-
:delete,
|
258
|
-
"#{api_base}/guilds/#{server_id}",
|
259
|
-
Authorization: token
|
260
|
-
)
|
261
|
-
end
|
262
|
-
|
263
|
-
# Leave a server
|
264
|
-
def leave_server(token, server_id)
|
265
|
-
request(
|
266
|
-
__method__,
|
267
|
-
:delete,
|
268
|
-
"#{api_base}/users/@me/guilds/#{server_id}",
|
269
|
-
Authorization: token
|
270
|
-
)
|
271
|
-
end
|
272
|
-
|
273
|
-
# Get a channel's data
|
274
|
-
def channel(token, channel_id)
|
275
|
-
request(
|
276
|
-
__method__,
|
277
|
-
:get,
|
278
|
-
"#{api_base}/channels/#{channel_id}",
|
279
|
-
Authorization: token
|
280
|
-
)
|
281
|
-
end
|
282
|
-
|
283
|
-
# Get a server's data
|
284
|
-
def server(token, server_id)
|
285
|
-
request(
|
286
|
-
__method__,
|
287
|
-
:get,
|
288
|
-
"#{api_base}/guilds/#{server_id}",
|
289
|
-
Authorization: token
|
290
|
-
)
|
291
|
-
end
|
292
|
-
|
293
|
-
# Get a member's data
|
294
|
-
def member(token, server_id, user_id)
|
295
|
-
request(
|
296
|
-
__method__,
|
297
|
-
:get,
|
298
|
-
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
299
|
-
Authorization: token
|
300
|
-
)
|
301
|
-
end
|
302
|
-
|
303
|
-
# Create a channel
|
304
|
-
def create_channel(token, server_id, name, type)
|
305
|
-
request(
|
306
|
-
__method__,
|
307
|
-
:post,
|
308
|
-
"#{api_base}/guilds/#{server_id}/channels",
|
309
|
-
{ name: name, type: type }.to_json,
|
310
|
-
Authorization: token,
|
311
|
-
content_type: :json
|
312
|
-
)
|
313
|
-
end
|
314
|
-
|
315
|
-
# Update a channel's data
|
316
|
-
def update_channel(token, channel_id, name, topic, position = 0)
|
317
|
-
request(
|
318
|
-
__method__,
|
319
|
-
:patch,
|
320
|
-
"#{api_base}/channels/#{channel_id}",
|
321
|
-
{ name: name, position: position, topic: topic }.to_json,
|
322
|
-
Authorization: token,
|
323
|
-
content_type: :json
|
324
|
-
)
|
325
|
-
end
|
326
|
-
|
327
|
-
# Delete a channel
|
328
|
-
def delete_channel(token, channel_id)
|
329
|
-
request(
|
330
|
-
__method__,
|
331
|
-
:delete,
|
332
|
-
"#{api_base}/channels/#{channel_id}",
|
333
|
-
Authorization: token
|
334
|
-
)
|
335
|
-
end
|
336
|
-
|
337
|
-
# Join a server using an invite
|
338
|
-
def join_server(token, invite_code)
|
339
|
-
request(
|
340
|
-
__method__,
|
341
|
-
:post,
|
342
|
-
"#{api_base}/invite/#{invite_code}",
|
193
|
+
:oauth2_applications_me,
|
343
194
|
nil,
|
344
|
-
Authorization: token
|
345
|
-
)
|
346
|
-
end
|
347
|
-
|
348
|
-
# Resolve an invite
|
349
|
-
def resolve_invite(token, invite_code)
|
350
|
-
request(
|
351
|
-
__method__,
|
352
195
|
:get,
|
353
|
-
"#{api_base}/
|
196
|
+
"#{api_base}/oauth2/applications/@me",
|
354
197
|
Authorization: token
|
355
198
|
)
|
356
199
|
end
|
357
200
|
|
358
|
-
# Create a private channel
|
359
|
-
def create_private(token, bot_user_id, user_id)
|
360
|
-
request(
|
361
|
-
__method__,
|
362
|
-
:post,
|
363
|
-
"#{api_base}/users/#{bot_user_id}/channels",
|
364
|
-
{ recipient_id: user_id }.to_json,
|
365
|
-
Authorization: token,
|
366
|
-
content_type: :json
|
367
|
-
)
|
368
|
-
rescue RestClient::BadRequest
|
369
|
-
raise 'Attempted to PM the bot itself!'
|
370
|
-
end
|
371
|
-
|
372
|
-
# Create an instant invite from a server or a channel id
|
373
|
-
def create_invite(token, channel_id, max_age = 0, max_uses = 0, temporary = false, xkcd = false)
|
374
|
-
request(
|
375
|
-
__method__,
|
376
|
-
:post,
|
377
|
-
"#{api_base}/channels/#{channel_id}/invites",
|
378
|
-
{ max_age: max_age, max_uses: max_uses, temporary: temporary, xkcdpass: xkcd }.to_json,
|
379
|
-
Authorization: token,
|
380
|
-
content_type: :json
|
381
|
-
)
|
382
|
-
end
|
383
|
-
|
384
|
-
# Delete an invite by code
|
385
|
-
def delete_invite(token, code)
|
386
|
-
request(
|
387
|
-
__method__,
|
388
|
-
:delete,
|
389
|
-
"#{api_base}/invites/#{code}",
|
390
|
-
Authorization: token
|
391
|
-
)
|
392
|
-
end
|
393
|
-
|
394
|
-
# Send a message to a channel
|
395
|
-
def send_message(token, channel_id, message, mentions = [], tts = false, guild_id = nil)
|
396
|
-
request(
|
397
|
-
"message-#{guild_id}".to_sym,
|
398
|
-
:post,
|
399
|
-
"#{api_base}/channels/#{channel_id}/messages",
|
400
|
-
{ content: message, mentions: mentions, tts: tts }.to_json,
|
401
|
-
Authorization: token,
|
402
|
-
content_type: :json
|
403
|
-
)
|
404
|
-
rescue RestClient::InternalServerError
|
405
|
-
raise Discordrb::Errors::MessageTooLong, "Message over the character limit (#{message.length} > 2000)"
|
406
|
-
end
|
407
|
-
|
408
|
-
# Delete a message
|
409
|
-
def delete_message(token, channel_id, message_id)
|
410
|
-
request(
|
411
|
-
__method__,
|
412
|
-
:delete,
|
413
|
-
"#{api_base}/channels/#{channel_id}/messages/#{message_id}",
|
414
|
-
Authorization: token
|
415
|
-
)
|
416
|
-
end
|
417
|
-
|
418
|
-
# Delete messages in bulk
|
419
|
-
def bulk_delete(token, channel_id, messages = [])
|
420
|
-
request(
|
421
|
-
__method__,
|
422
|
-
:post,
|
423
|
-
"#{api_base}/channels/#{channel_id}/messages/bulk_delete",
|
424
|
-
{ messages: messages }.to_json,
|
425
|
-
Authorization: token,
|
426
|
-
content_type: :json
|
427
|
-
)
|
428
|
-
end
|
429
|
-
|
430
|
-
# Edit a message
|
431
|
-
def edit_message(token, channel_id, message_id, message, mentions = [])
|
432
|
-
request(
|
433
|
-
:message,
|
434
|
-
:patch,
|
435
|
-
"#{api_base}/channels/#{channel_id}/messages/#{message_id}",
|
436
|
-
{ content: message, mentions: mentions }.to_json,
|
437
|
-
Authorization: token,
|
438
|
-
content_type: :json
|
439
|
-
)
|
440
|
-
end
|
441
|
-
|
442
201
|
# Acknowledge that a message has been received
|
443
202
|
# The last acknowledged message will be sent in the ready packet,
|
444
203
|
# so this is an easy way to catch up on messages
|
445
204
|
def acknowledge_message(token, channel_id, message_id)
|
446
205
|
request(
|
447
|
-
|
206
|
+
:channels_cid_messages_mid_ack,
|
207
|
+
nil, # This endpoint is unavailable for bot accounts and thus isn't subject to its rate limit requirements.
|
448
208
|
:post,
|
449
209
|
"#{api_base}/channels/#{channel_id}/messages/#{message_id}/ack",
|
450
210
|
nil,
|
@@ -452,93 +212,11 @@ module Discordrb::API
|
|
452
212
|
)
|
453
213
|
end
|
454
214
|
|
455
|
-
# Send a file as a message to a channel
|
456
|
-
def send_file(token, channel_id, file)
|
457
|
-
request(
|
458
|
-
__method__,
|
459
|
-
:post,
|
460
|
-
"#{api_base}/channels/#{channel_id}/messages",
|
461
|
-
{ file: file },
|
462
|
-
Authorization: token
|
463
|
-
)
|
464
|
-
end
|
465
|
-
|
466
|
-
# Create a role (parameters such as name and colour will have to be set by update_role afterwards)
|
467
|
-
def create_role(token, server_id)
|
468
|
-
request(
|
469
|
-
__method__,
|
470
|
-
:post,
|
471
|
-
"#{api_base}/guilds/#{server_id}/roles",
|
472
|
-
nil,
|
473
|
-
Authorization: token
|
474
|
-
)
|
475
|
-
end
|
476
|
-
|
477
|
-
# Update a role
|
478
|
-
# Permissions are the Discord defaults; allowed: invite creation, reading/sending messages,
|
479
|
-
# sending TTS messages, embedding links, sending files, reading the history, mentioning everybody,
|
480
|
-
# connecting to voice, speaking and voice activity (push-to-talk isn't mandatory)
|
481
|
-
def update_role(token, server_id, role_id, name, colour, hoist = false, packed_permissions = 36_953_089)
|
482
|
-
request(
|
483
|
-
__method__,
|
484
|
-
:patch,
|
485
|
-
"#{api_base}/guilds/#{server_id}/roles/#{role_id}",
|
486
|
-
{ color: colour, name: name, hoist: hoist, permissions: packed_permissions }.to_json,
|
487
|
-
Authorization: token,
|
488
|
-
content_type: :json
|
489
|
-
)
|
490
|
-
end
|
491
|
-
|
492
|
-
# Delete a role
|
493
|
-
def delete_role(token, server_id, role_id)
|
494
|
-
request(
|
495
|
-
__method__,
|
496
|
-
:delete,
|
497
|
-
"#{api_base}/guilds/#{server_id}/roles/#{role_id}",
|
498
|
-
Authorization: token
|
499
|
-
)
|
500
|
-
end
|
501
|
-
|
502
|
-
# Update a user's roles
|
503
|
-
def update_user_roles(token, server_id, user_id, roles)
|
504
|
-
request(
|
505
|
-
__method__,
|
506
|
-
:patch,
|
507
|
-
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
508
|
-
{ roles: roles }.to_json,
|
509
|
-
Authorization: token,
|
510
|
-
content_type: :json
|
511
|
-
)
|
512
|
-
end
|
513
|
-
|
514
|
-
# Update a user's permission overrides in a channel
|
515
|
-
def update_user_overrides(token, channel_id, user_id, allow, deny)
|
516
|
-
request(
|
517
|
-
__method__,
|
518
|
-
:put,
|
519
|
-
"#{api_base}/channels/#{channel_id}/permissions/#{user_id}",
|
520
|
-
{ type: 'member', id: user_id, allow: allow, deny: deny }.to_json,
|
521
|
-
Authorization: token,
|
522
|
-
content_type: :json
|
523
|
-
)
|
524
|
-
end
|
525
|
-
|
526
|
-
# Update a role's permission overrides in a channel
|
527
|
-
def update_role_overrides(token, channel_id, role_id, allow, deny)
|
528
|
-
request(
|
529
|
-
__method__,
|
530
|
-
:put,
|
531
|
-
"#{api_base}/channels/#{channel_id}/permissions/#{role_id}",
|
532
|
-
{ type: 'role', id: role_id, allow: allow, deny: deny }.to_json,
|
533
|
-
Authorization: token,
|
534
|
-
content_type: :json
|
535
|
-
)
|
536
|
-
end
|
537
|
-
|
538
215
|
# Get the gateway to be used
|
539
216
|
def gateway(token)
|
540
217
|
request(
|
541
|
-
|
218
|
+
:gateway,
|
219
|
+
nil,
|
542
220
|
:get,
|
543
221
|
"#{api_base}/gateway",
|
544
222
|
Authorization: token
|
@@ -548,7 +226,8 @@ module Discordrb::API
|
|
548
226
|
# Validate a token (this request will fail if the token is invalid)
|
549
227
|
def validate_token(token)
|
550
228
|
request(
|
551
|
-
|
229
|
+
:auth_login,
|
230
|
+
nil,
|
552
231
|
:post,
|
553
232
|
"#{api_base}/auth/login",
|
554
233
|
{}.to_json,
|
@@ -556,79 +235,6 @@ module Discordrb::API
|
|
556
235
|
content_type: :json
|
557
236
|
)
|
558
237
|
end
|
559
|
-
|
560
|
-
# Start typing (needs to be resent every 5 seconds to keep up the typing)
|
561
|
-
def start_typing(token, channel_id)
|
562
|
-
request(
|
563
|
-
__method__,
|
564
|
-
:post,
|
565
|
-
"#{api_base}/channels/#{channel_id}/typing",
|
566
|
-
nil,
|
567
|
-
Authorization: token
|
568
|
-
)
|
569
|
-
end
|
570
|
-
|
571
|
-
# Get user data
|
572
|
-
def user(token, user_id)
|
573
|
-
request(
|
574
|
-
__method__,
|
575
|
-
:get,
|
576
|
-
"#{api_base}/users/#{user_id}",
|
577
|
-
Authorization: token
|
578
|
-
)
|
579
|
-
end
|
580
|
-
|
581
|
-
# Get profile data
|
582
|
-
def profile(token)
|
583
|
-
request(
|
584
|
-
__method__,
|
585
|
-
:get,
|
586
|
-
"#{api_base}/users/@me",
|
587
|
-
Authorization: token
|
588
|
-
)
|
589
|
-
end
|
590
|
-
|
591
|
-
# Get information about a user's connections
|
592
|
-
def connections(token)
|
593
|
-
request(
|
594
|
-
__method__,
|
595
|
-
:get,
|
596
|
-
"#{api_base}/users/@me/connections",
|
597
|
-
Authorization: token
|
598
|
-
)
|
599
|
-
end
|
600
|
-
|
601
|
-
# Update user data
|
602
|
-
def update_user(token, email, password, new_username, avatar, new_password = nil)
|
603
|
-
request(
|
604
|
-
__method__,
|
605
|
-
:patch,
|
606
|
-
"#{api_base}/users/@me",
|
607
|
-
{ avatar: avatar, email: email, new_password: new_password, password: password, username: new_username }.to_json,
|
608
|
-
Authorization: token,
|
609
|
-
content_type: :json
|
610
|
-
)
|
611
|
-
end
|
612
|
-
|
613
|
-
# Get the servers a user is connected to
|
614
|
-
def servers(token)
|
615
|
-
request(
|
616
|
-
__method__,
|
617
|
-
:get,
|
618
|
-
"#{api_base}/users/@me/guilds",
|
619
|
-
Authorization: token
|
620
|
-
)
|
621
|
-
end
|
622
|
-
|
623
|
-
# Get a list of messages from a channel's history
|
624
|
-
def channel_log(token, channel_id, amount, before = nil, after = nil)
|
625
|
-
request(
|
626
|
-
__method__,
|
627
|
-
:get,
|
628
|
-
"#{api_base}/channels/#{channel_id}/messages?limit=#{amount}#{"&before=#{before}" if before}#{"&after=#{after}" if after}",
|
629
|
-
Authorization: token
|
630
|
-
)
|
631
|
-
end
|
632
238
|
end
|
633
239
|
|
634
240
|
Discordrb::API.reset_mutexes
|