discordrb 1.8.1 → 2.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/.overcommit.yml +7 -0
- data/.rubocop.yml +5 -4
- data/CHANGELOG.md +77 -0
- data/README.md +25 -15
- data/discordrb.gemspec +2 -3
- data/examples/commands.rb +14 -2
- data/examples/ping.rb +1 -1
- data/examples/pm_send.rb +1 -1
- data/lib/discordrb.rb +9 -0
- data/lib/discordrb/api.rb +176 -50
- data/lib/discordrb/await.rb +3 -0
- data/lib/discordrb/bot.rb +607 -372
- data/lib/discordrb/cache.rb +208 -0
- data/lib/discordrb/commands/command_bot.rb +50 -18
- data/lib/discordrb/commands/container.rb +11 -2
- data/lib/discordrb/commands/events.rb +2 -0
- data/lib/discordrb/commands/parser.rb +10 -8
- data/lib/discordrb/commands/rate_limiter.rb +2 -0
- data/lib/discordrb/container.rb +24 -25
- data/lib/discordrb/data.rb +521 -219
- data/lib/discordrb/errors.rb +6 -7
- data/lib/discordrb/events/await.rb +2 -0
- data/lib/discordrb/events/bans.rb +3 -1
- data/lib/discordrb/events/channels.rb +124 -0
- data/lib/discordrb/events/generic.rb +2 -0
- data/lib/discordrb/events/guilds.rb +16 -13
- data/lib/discordrb/events/lifetime.rb +12 -2
- data/lib/discordrb/events/members.rb +26 -15
- data/lib/discordrb/events/message.rb +20 -7
- data/lib/discordrb/events/presence.rb +18 -2
- data/lib/discordrb/events/roles.rb +83 -0
- data/lib/discordrb/events/typing.rb +15 -2
- data/lib/discordrb/events/voice_state_update.rb +2 -0
- data/lib/discordrb/light.rb +8 -0
- data/lib/discordrb/light/data.rb +62 -0
- data/lib/discordrb/light/integrations.rb +73 -0
- data/lib/discordrb/light/light_bot.rb +56 -0
- data/lib/discordrb/logger.rb +4 -0
- data/lib/discordrb/permissions.rb +16 -12
- data/lib/discordrb/token_cache.rb +3 -0
- data/lib/discordrb/version.rb +3 -1
- data/lib/discordrb/voice/encoder.rb +2 -0
- data/lib/discordrb/voice/network.rb +21 -14
- data/lib/discordrb/voice/voice_bot.rb +26 -3
- data/lib/discordrb/websocket.rb +69 -0
- metadata +15 -26
- data/lib/discordrb/events/channel_create.rb +0 -44
- data/lib/discordrb/events/channel_delete.rb +0 -44
- data/lib/discordrb/events/channel_update.rb +0 -46
- data/lib/discordrb/events/guild_role_create.rb +0 -35
- data/lib/discordrb/events/guild_role_delete.rb +0 -36
- data/lib/discordrb/events/guild_role_update.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca5ae97de9345328dac0b9f9e8c14f38e2d70bc9
|
4
|
+
data.tar.gz: fe60d3642cecec76594a3356d93c923be5f27997
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa6c978e90c0f5338a9f6b67f0cf1fafd6d2c847c76b1fb6aadacfb820c95248ecdb8962ab84d63c2811b0bd28dd6913b72ae1463b671822f8716d526d04e9dc
|
7
|
+
data.tar.gz: b0eab7396be2942e2c7f9370c49fa1b45e70c2836d1281bf31e9fc98bc44919ac276c6a453000758b90a502cbde65ced78782a5b5b82c5472a20f429dc710bb7
|
data/.overcommit.yml
ADDED
data/.rubocop.yml
CHANGED
@@ -41,10 +41,11 @@ Lint/RescueException:
|
|
41
41
|
AllCops:
|
42
42
|
TargetRubyVersion: 2.1
|
43
43
|
|
44
|
-
# Apparently setting the target version to 2.1 is not enough to prevent this cop...
|
45
|
-
Style/FrozenStringLiteralComment:
|
46
|
-
Enabled: false
|
47
|
-
|
48
44
|
# http://stackoverflow.com/questions/4763121/should-i-use-alias-or-alias-method
|
49
45
|
Style/Alias:
|
50
46
|
Enabled: false
|
47
|
+
|
48
|
+
# So RuboCop doesn't complain about application IDs
|
49
|
+
Style/NumericLiterals:
|
50
|
+
Exclude:
|
51
|
+
- examples/*
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,82 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.0.0
|
4
|
+
|
5
|
+
This is the first major update with some breaking changes! Those are highlighted in bold with migration advice after them. Ask in the Discord channel (see the README) if you have questions.
|
6
|
+
|
7
|
+
- **Bot initializers now only use named parameters.** This shouldn't be a hard change to adjust to, but everyone will have to do it. Here's some examples:
|
8
|
+
```rb
|
9
|
+
# Previously
|
10
|
+
bot = Discordrb::Bot.new 'email@example.com', 'hunter2', true
|
11
|
+
|
12
|
+
# Now
|
13
|
+
bot = Discordrb::Bot.new email: 'email@example.com', password: 'hunter2', log_mode: :debug
|
14
|
+
```
|
15
|
+
```rb
|
16
|
+
# Previously
|
17
|
+
bot = Discordrb::Bot.new :token, 'TOKEN HERE'
|
18
|
+
|
19
|
+
# Now
|
20
|
+
bot = Discordrb::Bot.new token: 'TOKEN HERE', application_id: 163456789123456789
|
21
|
+
```
|
22
|
+
```rb
|
23
|
+
# Previously
|
24
|
+
bot = Discordrb::Commands::CommandBot.new :token, 'TOKEN HERE', '!', nil, {advanced_functionality: false}
|
25
|
+
|
26
|
+
# Now
|
27
|
+
bot = Discordrb::Commands::CommandBot.new token: 'TOKEN HERE', application_id: 163456789123456789, prefix: '!', advanced_functionality: false
|
28
|
+
```
|
29
|
+
- Connecting to multiple voice channels at once (only available with bot accounts) is now supported. **This means `bot.voice` now takes the server ID as the parameter**. For a seamless switch, the utility method `MessageEvent#voice` was added - simply replace `bot.voice` with `event.voice` in all instances.
|
30
|
+
- **The `Member` and `Recipient` classes were split off from `User`**. Members are users on servers and recipients are partners in private messages. Since both are delegates to `User`, most things will work as before, but most notably roles were changed to no longer be by ID (for example, instead of `event.author.roles(event.server.id)`, you'd just use `event.author.roles` instead).
|
31
|
+
- **All previously deprecated methods were removed.** This includes:
|
32
|
+
- `Server#afk_channel_id=` (use `afk_channel=`, it works with the ID too)
|
33
|
+
- `Channel#is_private` (use `private?` instead, it's more reliable with edge cases like Twitch subscriber-only channels)
|
34
|
+
- `Bot#find` (use `find_channel` instead, it does the exact same thing without confusion with `find_user`)
|
35
|
+
- **`Server` is now used instead of `Guild` in all external methods and classes.** Previously, all the events regarding roles and such were called `GuildRoleXYZEvent`, now they're all called `ServerRoleXYZEvent` for consistency with other attributes and methods.
|
36
|
+
- **`advanced_functionality` is now disabled by default.** If you absolutely need it, you can easily re-enable it by just setting that parameter in the CommandBot initializer, but for most people that didn't need it this will fix some bugs with mentions in commands and such.
|
37
|
+
- **`User#bot?` was renamed to `User#current_bot?`** with the addition of the `User#bot_account?` reader to check for bot account-ness (the "BOT" tag visible on Discord)
|
38
|
+
- Member chunks will no longer automatically be requested on startup, but rather once they're actually needed (`event.server.members`). This is both a performance change (much faster startup for large bots especially) and an important API compliance one - this is what the Discord devs have requested.
|
39
|
+
- Initial support for bots that have no WebSocket connection was started. This is useful for web apps that need to get information on something without having to run something in the background all the time. A tutorial on these will be coming soon, in the meantime, use this short example:
|
40
|
+
```rb
|
41
|
+
require 'discordrb'
|
42
|
+
require 'discordrb/light'
|
43
|
+
|
44
|
+
bot = Discordrb::Light::LightBot.new 'token here'
|
45
|
+
puts bot.profile.username
|
46
|
+
```
|
47
|
+
- OAuth bot accounts are now better supported using a method `Bot#invite_url` to get a bot's invite URL and sending tokens using the new `Bot` prefix.
|
48
|
+
- discordrb now fully uses [websocket-client-simple](https://github.com/shokai/websocket-client-simple) (a.k.a. WSCS) instead of Faye::WebSocket, this means that the annoying OpenSSL library thing won't have to be done anymore.
|
49
|
+
- The new version of the Discord gateway (v4) is supported and used by default. This should bring more stability and possibly slight performance improvements.
|
50
|
+
- Some older v3 features that weren't supported before are now:
|
51
|
+
- Compressed ready packets (should decrease network overhead for very large bots)
|
52
|
+
- Discord rate limits are now supported better - the client will never send a message if it knows it's going to be rate limited, instead it's going to wait for the correct time.
|
53
|
+
- Requests will now automatically be retried if a 502 (cloudflare error) is received.
|
54
|
+
- `MessageEditEvent`s now have a whole message instead of just the ID to allow for checking the content of edited messages.
|
55
|
+
- `Message`s now have an `attachments` array with files attached to the message.
|
56
|
+
- `ReadyEvent` and `DisconnectEvent` now have the bot as a readable attribute - useful for container-based bots that don't have a way to get them otherwise.
|
57
|
+
- `Bot#find_channel` can now parse channel mentions and search for specific types of channels (text or voice).
|
58
|
+
- `Server#create_channel` can now create voice channels.
|
59
|
+
- A utility function `User#distinct` was added to get the distinct representation of a user (i.e. name + discrim, for example "meew0#9811")
|
60
|
+
- The `User#discriminator` attribute now has more aliases (`#tag`, `#discord_tag`, `#discrim`)
|
61
|
+
- `Permission` objects can now be created or set even without a role writer, useful to quickly get byte representations of permissions
|
62
|
+
- Permission overwrites can now be defined more easily using the utility method `Channel#define_overwrite`
|
63
|
+
- `Message`s returned at the end of commands (for example using `User#pm` or `Message#edit`) will now no longer be sent ([#66](https://github.com/meew0/discordrb/issues/66))
|
64
|
+
- The `:with_text` event attribute is now aliased to `:exact_text` ([#65](https://github.com/meew0/discordrb/issues/65))
|
65
|
+
- Server icons (`Server#icon=`) can now be set just like avatars (`Profile#avatar=`)
|
66
|
+
- Lots of comments were added to the examples and some bugs fixed
|
67
|
+
- The overall performance and memory usage was improved, especially on Ruby 2.3 (using the new frozen string literal comment)
|
68
|
+
- The documentation was slightly improved.
|
69
|
+
|
70
|
+
**Bugfixes**:
|
71
|
+
- A *lot* of latent bugs with caching were fixed. This doesn't really have a noticeable effect, it just means better stability and reliability as a whole.
|
72
|
+
- **Command bots no longer respond when there are spaces between the prefix and the command.** Because this behaviour may be desirable, a `spaces_allowed` attribute was added to the CommandBot initializer that can be set to true to re-enable this behaviour.
|
73
|
+
- Permission calculation (`User#permission?`) has been thoroughly rewritten and should now account for edge cases like server owners and Manage Permissions.
|
74
|
+
- The gateway reconnect logic now uses a correct falloff system - before it would start at 1 second between attempts and immediately jump to 120. Now the transition is more smooth.
|
75
|
+
- Commands with aliases now show up correctly in the auto-generated help command ([#72](https://github.com/meew0/discordrb/issues/72))
|
76
|
+
- The auto-generated help command can now actually be disabled by setting the corresponding attribute to nil ([#73](https://github.com/meew0/discordrb/issues/73))
|
77
|
+
- Including empty containers now does nothing instead of raising an error
|
78
|
+
- Command bots now obey `should_parse_self`
|
79
|
+
|
3
80
|
## 1.8.1
|
4
81
|
|
5
82
|
### Bugfixes
|
data/README.md
CHANGED
@@ -1,18 +1,36 @@
|
|
1
|
+
[![Gem](https://img.shields.io/gem/v/discordrb.svg)](https://rubygems.org/gems/discordrb)
|
2
|
+
[![Gem](https://img.shields.io/gem/dt/discordrb.svg)](https://rubygems.org/gems/discordrb)
|
1
3
|
[![Build Status](https://travis-ci.org/meew0/discordrb.svg?branch=master)](https://travis-ci.org/meew0/discordrb)
|
2
|
-
|
4
|
+
[![Inline docs](http://inch-ci.org/github/meew0/discordrb.svg?branch=master&style=shields)](http://inch-ci.org/github/meew0/discordrb)
|
5
|
+
[![Join Discord](https://img.shields.io/badge/discord-join-7289DA.svg)](https://discord.gg/0SBTUU1wZTWfFQL2)
|
3
6
|
# discordrb
|
4
7
|
|
5
8
|
An implementation of the [Discord](https://discordapp.com/) API using Ruby.
|
6
9
|
|
10
|
+
**News**: Please help test version 2 of discordrb with a lot of changes! A preliminary changelog can be found [here](https://gist.github.com/meew0/ea120051da52604e7873b7cfaed4c40b). The code can be found on the `v2` branch; if you're using bundler you can change the gem reference to `gem 'discordrb', git: 'git://github.com/meew0/discordrb.git', branch: 'v2'`. A downloadable gem file for everybody else will follow here shortly.
|
11
|
+
|
7
12
|
## Quick links to sections
|
8
13
|
|
14
|
+
* [Dependencies](https://github.com/meew0/discordrb#dependencies)
|
9
15
|
* [Installation](https://github.com/meew0/discordrb#installation)
|
10
16
|
* [Usage](https://github.com/meew0/discordrb#usage)
|
11
17
|
* [Support](https://github.com/meew0/discordrb#support)
|
12
18
|
* [Development](https://github.com/meew0/discordrb#development), [Contributing](https://github.com/meew0/discordrb#contributing)
|
13
19
|
* [License](https://github.com/meew0/discordrb#license)
|
14
20
|
|
15
|
-
See also: [Documentation](
|
21
|
+
See also: [Documentation](http://www.rubydoc.info/gems/discordrb), [Tutorials](https://github.com/meew0/discordrb/wiki)
|
22
|
+
|
23
|
+
## Dependencies
|
24
|
+
|
25
|
+
* Ruby 2.1+
|
26
|
+
* An installed build system for native extensions (on Windows, try the [DevKit](http://rubyinstaller.org/downloads/); installation instructions [here](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit#quick-start))
|
27
|
+
|
28
|
+
### Voice dependencies
|
29
|
+
|
30
|
+
This section only applies to you if you want to use voice functionality.
|
31
|
+
* [libsodium](https://github.com/meew0/discordrb/wiki/Installing-libsodium)
|
32
|
+
* A compiled libopus distribution for your system, anywhere the script can find it (on Windows, make sure it's named `opus.dll`)
|
33
|
+
* [FFmpeg](https://www.ffmpeg.org/download.html) installed and in your PATH
|
16
34
|
|
17
35
|
## Installation
|
18
36
|
|
@@ -49,16 +67,6 @@ Then reinstall discordrb:
|
|
49
67
|
gem uninstall discordrb
|
50
68
|
gem install discordrb
|
51
69
|
|
52
|
-
**If you get an error like this when running the example**:
|
53
|
-
|
54
|
-
terminate called after throwing an instance of 'std::runtime_error'
|
55
|
-
what(): Encryption not available on this event-machine
|
56
|
-
|
57
|
-
You're missing the OpenSSL libraries that EventMachine, a dependency of discordrb, needs to be built with to use encrypted connections (which Discord requires). Download the OpenSSL libraries from [here](https://slproweb.com/download/Win32OpenSSL-1_0_2f.exe), install them to their default location and reinstall EventMachine using these libraries:
|
58
|
-
|
59
|
-
gem uninstall eventmachine
|
60
|
-
gem install eventmachine -- --with-ssl-dir=C:/OpenSSL-Win32
|
61
|
-
|
62
70
|
**If you're having trouble getting voice playback to work**:
|
63
71
|
|
64
72
|
Look here: https://github.com/meew0/discordrb/wiki/Voice-sending#troubleshooting
|
@@ -70,10 +78,10 @@ You can make a simple bot like this:
|
|
70
78
|
```ruby
|
71
79
|
require 'discordrb'
|
72
80
|
|
73
|
-
bot = Discordrb::Bot.new
|
81
|
+
bot = Discordrb::Bot.new token: '<token here>'
|
74
82
|
|
75
|
-
bot.message(with_text:
|
76
|
-
event.respond
|
83
|
+
bot.message(with_text: 'Ping!') do |event|
|
84
|
+
event.respond 'Pong!'
|
77
85
|
end
|
78
86
|
|
79
87
|
bot.run
|
@@ -87,6 +95,8 @@ You can find me (@meew0, ID 66237334693085184) on the unofficial Discord API ser
|
|
87
95
|
|
88
96
|
## Development
|
89
97
|
|
98
|
+
**This section is for developing discordrb itself! If you just want to make a bot, see the [Installation](https://github.com/meew0/discordrb#installation) section.**
|
99
|
+
|
90
100
|
After checking out the repo, run `bin/setup` to install dependencies. You can then run tests via `bundle exec rspec spec`. Make sure to run rubocop also: `bundle exec rubocop`. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
91
101
|
|
92
102
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
data/discordrb.gemspec
CHANGED
@@ -19,11 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
|
-
spec.add_dependency 'faye-websocket'
|
23
22
|
spec.add_dependency 'rest-client'
|
24
23
|
spec.add_dependency 'activesupport'
|
25
24
|
spec.add_dependency 'opus-ruby'
|
26
|
-
spec.add_dependency 'websocket-client-simple'
|
25
|
+
spec.add_dependency 'websocket-client-simple', '>= 0.3.0'
|
27
26
|
spec.add_dependency 'rbnacl'
|
28
27
|
|
29
28
|
spec.required_ruby_version = '>= 2.1.0'
|
@@ -32,5 +31,5 @@ Gem::Specification.new do |spec|
|
|
32
31
|
spec.add_development_dependency 'rake', '~> 10.0'
|
33
32
|
spec.add_development_dependency 'yard', '~> 0.8.7.6'
|
34
33
|
spec.add_development_dependency 'rspec', '~> 3.4.0'
|
35
|
-
spec.add_development_dependency 'rubocop', '0.
|
34
|
+
spec.add_development_dependency 'rubocop', '0.39.0'
|
36
35
|
end
|
data/examples/commands.rb
CHANGED
@@ -2,25 +2,35 @@
|
|
2
2
|
|
3
3
|
require 'discordrb'
|
4
4
|
|
5
|
-
bot = Discordrb::Commands::CommandBot.new '
|
5
|
+
bot = Discordrb::Commands::CommandBot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543, prefix: '!'
|
6
6
|
|
7
7
|
bot.command :user do |event|
|
8
|
+
# Commands send whatever is returned from the block to the channel. This allows for compact commands like this,
|
9
|
+
# but you have to be aware of this so you don't accidentally return something you didn't intend to.
|
10
|
+
# To prevent the return value to be sent to the channel, you can just return `nil`.
|
8
11
|
event.user.name
|
9
12
|
end
|
10
13
|
|
11
14
|
bot.command :bold do |_event, *args|
|
15
|
+
# Again, the return value of the block is sent to the channel
|
12
16
|
"**#{args.join(' ')}**"
|
13
17
|
end
|
14
18
|
|
15
19
|
bot.command :italic do |_event, *args|
|
16
|
-
"
|
20
|
+
"*#{args.join(' ')}*"
|
17
21
|
end
|
18
22
|
|
19
23
|
bot.command(:join, permission_level: 1, chain_usable: false) do |event, invite|
|
20
24
|
event.bot.join invite
|
25
|
+
|
26
|
+
# The `join` call above returns the data Discord sends as a response to joining the server. We don't want that
|
27
|
+
# in the channel so here we're just returning `nil` afterwards
|
28
|
+
nil
|
21
29
|
end
|
22
30
|
|
23
31
|
bot.command(:random, min_args: 0, max_args: 2, description: 'Generates a random number between 0 and 1, 0 and max or min and max.', usage: 'random [min/max] [max]') do |_event, min, max|
|
32
|
+
# The `if` statement returns one of multiple different things based on the condition. Its return value
|
33
|
+
# is then returned from the block and sent to the channel
|
24
34
|
if max
|
25
35
|
rand(min.to_i..max.to_i)
|
26
36
|
elsif min
|
@@ -35,6 +45,8 @@ bot.command :long do |event|
|
|
35
45
|
event << 'It has multiple lines that are each sent by doing `event << line`.'
|
36
46
|
event << 'This is an easy way to do such long messages, or to create lines that should only be sent conditionally.'
|
37
47
|
event << 'Anyway, have a nice day.'
|
48
|
+
|
49
|
+
# Here we don't have to worry about the return value because the `event << line` statement automatically returns nil.
|
38
50
|
end
|
39
51
|
|
40
52
|
bot.run
|
data/examples/ping.rb
CHANGED
data/examples/pm_send.rb
CHANGED
data/lib/discordrb.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
unless ENV['DISCORDRB_V2_MESSAGE']
|
4
|
+
puts "You're using version 2 of discordrb which has some breaking changes!"
|
5
|
+
puts "Don't worry if your bot crashes, you can find a list and migration advice here:"
|
6
|
+
puts ' https://github.com/meew0/discordrb/blob/master/CHANGELOG.md#200'
|
7
|
+
puts 'This message will go away in version 2.1 or can be disabled by setting the DISCORDRB_V2_MESSAGE environment variable.'
|
8
|
+
end
|
9
|
+
|
1
10
|
require 'discordrb/version'
|
2
11
|
require 'discordrb/bot'
|
3
12
|
require 'discordrb/commands/command_bot'
|
data/lib/discordrb/api.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rest-client'
|
2
4
|
require 'json'
|
3
5
|
|
@@ -10,6 +12,16 @@ module Discordrb::API
|
|
10
12
|
|
11
13
|
module_function
|
12
14
|
|
15
|
+
# @return [String] the currently used API base URL.
|
16
|
+
def api_base
|
17
|
+
@api_base || APIBASE
|
18
|
+
end
|
19
|
+
|
20
|
+
# Sets the API base URL to something.
|
21
|
+
def api_base=(value)
|
22
|
+
@api_base = value
|
23
|
+
end
|
24
|
+
|
13
25
|
# @return [String] the bot name, previously specified using #bot_name=.
|
14
26
|
def bot_name
|
15
27
|
@bot_name
|
@@ -29,6 +41,13 @@ module Discordrb::API
|
|
29
41
|
"rest-client/#{RestClient::VERSION} #{RUBY_ENGINE}/#{RUBY_VERSION}p#{RUBY_PATCHLEVEL} discordrb/#{Discordrb::VERSION} #{required} #{@bot_name}"
|
30
42
|
end
|
31
43
|
|
44
|
+
# Resets all rate limit mutexes
|
45
|
+
def reset_mutexes
|
46
|
+
@mutexes = {
|
47
|
+
message: Mutex.new
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
32
51
|
# Performs a RestClient request.
|
33
52
|
# @param type [Symbol] The type of HTTP request to use.
|
34
53
|
# @param attributes [Array] The attributes for the request.
|
@@ -36,20 +55,39 @@ module Discordrb::API
|
|
36
55
|
RestClient.send(type, *attributes)
|
37
56
|
rescue RestClient::Forbidden
|
38
57
|
raise Discordrb::Errors::NoPermission, "The bot doesn't have the required permission to do this!"
|
58
|
+
rescue RestClient::BadGateway
|
59
|
+
Discordrb::LOGGER.warn('Got a 502 while sending a request! Not a big deal, retrying the request')
|
60
|
+
retry
|
39
61
|
end
|
40
62
|
|
41
63
|
# Make an API request. Utility function to implement message queueing
|
42
64
|
# in the future
|
43
|
-
def request(type, *attributes)
|
65
|
+
def request(key, type, *attributes)
|
44
66
|
# Add a custom user agent
|
45
67
|
attributes.last[:user_agent] = user_agent if attributes.last.is_a? Hash
|
46
|
-
response = raw_request(type, attributes)
|
47
68
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
69
|
+
begin
|
70
|
+
if key
|
71
|
+
# Lock and unlock, i. e. wait for the mutex to unlock and don't do anything with it afterwards
|
72
|
+
@mutexes[key].lock
|
73
|
+
@mutexes[key].unlock
|
74
|
+
end
|
75
|
+
|
52
76
|
response = raw_request(type, attributes)
|
77
|
+
rescue RestClient::TooManyRequests => e
|
78
|
+
raise "Got an HTTP 429 for an untracked API call! Please report this bug together with the following information: #{type} #{attributes}" unless key
|
79
|
+
|
80
|
+
unless @mutexes[key].locked?
|
81
|
+
response = JSON.parse(e.response)
|
82
|
+
wait_seconds = response['retry_after'].to_i / 1000.0
|
83
|
+
Discordrb::LOGGER.warn("Locking RL mutex (key: #{key}) for #{wait_seconds} seconds due to Discord rate limiting")
|
84
|
+
|
85
|
+
# Wait the required time synchronized by the mutex (so other incoming requests have to wait) but only do it if
|
86
|
+
# the mutex isn't locked already so it will only ever wait once
|
87
|
+
@mutexes[key].synchronize { sleep wait_seconds }
|
88
|
+
end
|
89
|
+
|
90
|
+
retry
|
53
91
|
end
|
54
92
|
|
55
93
|
response
|
@@ -57,14 +95,20 @@ module Discordrb::API
|
|
57
95
|
|
58
96
|
# Make an avatar URL from the user and avatar IDs
|
59
97
|
def avatar_url(user_id, avatar_id)
|
60
|
-
"#{
|
98
|
+
"#{api_base}/users/#{user_id}/avatars/#{avatar_id}.jpg"
|
99
|
+
end
|
100
|
+
|
101
|
+
# Make an icon URL from server and icon IDs
|
102
|
+
def icon_url(server_id, icon_id)
|
103
|
+
"#{api_base}/guilds/#{server_id}/icons/#{icon_id}.jpg"
|
61
104
|
end
|
62
105
|
|
63
106
|
# Ban a user from a server and delete their messages from the last message_days days
|
64
107
|
def ban_user(token, server_id, user_id, message_days)
|
65
108
|
request(
|
109
|
+
nil,
|
66
110
|
:put,
|
67
|
-
"#{
|
111
|
+
"#{api_base}/guilds/#{server_id}/bans/#{user_id}?delete-message-days=#{message_days}",
|
68
112
|
nil,
|
69
113
|
Authorization: token
|
70
114
|
)
|
@@ -73,8 +117,9 @@ module Discordrb::API
|
|
73
117
|
# Unban a user from a server
|
74
118
|
def unban_user(token, server_id, user_id)
|
75
119
|
request(
|
120
|
+
nil,
|
76
121
|
:delete,
|
77
|
-
"#{
|
122
|
+
"#{api_base}/guilds/#{server_id}/bans/#{user_id}",
|
78
123
|
Authorization: token
|
79
124
|
)
|
80
125
|
end
|
@@ -82,8 +127,9 @@ module Discordrb::API
|
|
82
127
|
# Kick a user from a server
|
83
128
|
def kick_user(token, server_id, user_id)
|
84
129
|
request(
|
130
|
+
nil,
|
85
131
|
:delete,
|
86
|
-
"#{
|
132
|
+
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
87
133
|
Authorization: token
|
88
134
|
)
|
89
135
|
end
|
@@ -91,8 +137,9 @@ module Discordrb::API
|
|
91
137
|
# Move a user to a different voice channel
|
92
138
|
def move_user(token, server_id, user_id, channel_id)
|
93
139
|
request(
|
140
|
+
nil,
|
94
141
|
:patch,
|
95
|
-
"#{
|
142
|
+
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
96
143
|
{ channel_id: channel_id }.to_json,
|
97
144
|
Authorization: token,
|
98
145
|
content_type: :json
|
@@ -102,8 +149,9 @@ module Discordrb::API
|
|
102
149
|
# Get a server's banned users
|
103
150
|
def bans(token, server_id)
|
104
151
|
request(
|
152
|
+
nil,
|
105
153
|
:get,
|
106
|
-
"#{
|
154
|
+
"#{api_base}/guilds/#{server_id}/bans",
|
107
155
|
Authorization: token
|
108
156
|
)
|
109
157
|
end
|
@@ -111,8 +159,9 @@ module Discordrb::API
|
|
111
159
|
# Login to the server
|
112
160
|
def login(email, password)
|
113
161
|
request(
|
162
|
+
nil,
|
114
163
|
:post,
|
115
|
-
"#{
|
164
|
+
"#{api_base}/auth/login",
|
116
165
|
email: email,
|
117
166
|
password: password
|
118
167
|
)
|
@@ -121,8 +170,9 @@ module Discordrb::API
|
|
121
170
|
# Logout from the server
|
122
171
|
def logout(token)
|
123
172
|
request(
|
173
|
+
nil,
|
124
174
|
:post,
|
125
|
-
"#{
|
175
|
+
"#{api_base}/auth/logout",
|
126
176
|
nil,
|
127
177
|
Authorization: token
|
128
178
|
)
|
@@ -131,8 +181,9 @@ module Discordrb::API
|
|
131
181
|
# Create an OAuth application
|
132
182
|
def create_oauth_application(token, name, redirect_uris)
|
133
183
|
request(
|
184
|
+
nil,
|
134
185
|
:post,
|
135
|
-
"#{
|
186
|
+
"#{api_base}/oauth2/applications",
|
136
187
|
{ name: name, redirect_uris: redirect_uris }.to_json,
|
137
188
|
Authorization: token,
|
138
189
|
content_type: :json
|
@@ -142,8 +193,9 @@ module Discordrb::API
|
|
142
193
|
# Change an OAuth application's properties
|
143
194
|
def update_oauth_application(token, name, redirect_uris, description = '', icon = nil)
|
144
195
|
request(
|
196
|
+
nil,
|
145
197
|
:put,
|
146
|
-
"#{
|
198
|
+
"#{api_base}/oauth2/applications",
|
147
199
|
{ name: name, redirect_uris: redirect_uris, description: description, icon: icon }.to_json,
|
148
200
|
Authorization: token,
|
149
201
|
content_type: :json
|
@@ -153,8 +205,9 @@ module Discordrb::API
|
|
153
205
|
# Create a server
|
154
206
|
def create_server(token, name, region = :london)
|
155
207
|
request(
|
208
|
+
nil,
|
156
209
|
:post,
|
157
|
-
"#{
|
210
|
+
"#{api_base}/guilds",
|
158
211
|
{ name: name, region: region.to_s }.to_json,
|
159
212
|
Authorization: token,
|
160
213
|
content_type: :json
|
@@ -164,8 +217,9 @@ module Discordrb::API
|
|
164
217
|
# Update a server
|
165
218
|
def update_server(token, server_id, name, region, icon, afk_channel_id, afk_timeout)
|
166
219
|
request(
|
220
|
+
nil,
|
167
221
|
:patch,
|
168
|
-
"#{
|
222
|
+
"#{api_base}/guilds/#{server_id}",
|
169
223
|
{ name: name, region: region, icon: icon, afk_channel_id: afk_channel_id, afk_timeout: afk_timeout }.to_json,
|
170
224
|
Authorization: token,
|
171
225
|
content_type: :json
|
@@ -175,8 +229,9 @@ module Discordrb::API
|
|
175
229
|
# Transfer server ownership
|
176
230
|
def transfer_ownership(token, server_id, user_id)
|
177
231
|
request(
|
232
|
+
nil,
|
178
233
|
:patch,
|
179
|
-
"#{
|
234
|
+
"#{api_base}/guilds/#{server_id}",
|
180
235
|
{ owner_id: user_id }.to_json,
|
181
236
|
Authorization: token,
|
182
237
|
content_type: :json
|
@@ -186,8 +241,9 @@ module Discordrb::API
|
|
186
241
|
# Delete a server
|
187
242
|
def delete_server(token, server_id)
|
188
243
|
request(
|
244
|
+
nil,
|
189
245
|
:delete,
|
190
|
-
"#{
|
246
|
+
"#{api_base}/guilds/#{server_id}",
|
191
247
|
Authorization: token
|
192
248
|
)
|
193
249
|
end
|
@@ -195,8 +251,9 @@ module Discordrb::API
|
|
195
251
|
# Leave a server
|
196
252
|
def leave_server(token, server_id)
|
197
253
|
request(
|
254
|
+
nil,
|
198
255
|
:delete,
|
199
|
-
"#{
|
256
|
+
"#{api_base}/users/@me/guilds/#{server_id}",
|
200
257
|
Authorization: token
|
201
258
|
)
|
202
259
|
end
|
@@ -204,8 +261,19 @@ module Discordrb::API
|
|
204
261
|
# Get a channel's data
|
205
262
|
def channel(token, channel_id)
|
206
263
|
request(
|
264
|
+
nil,
|
207
265
|
:get,
|
208
|
-
"#{
|
266
|
+
"#{api_base}/channels/#{channel_id}",
|
267
|
+
Authorization: token
|
268
|
+
)
|
269
|
+
end
|
270
|
+
|
271
|
+
# Get a server's data
|
272
|
+
def server(token, server_id)
|
273
|
+
request(
|
274
|
+
nil,
|
275
|
+
:get,
|
276
|
+
"#{api_base}/guilds/#{server_id}",
|
209
277
|
Authorization: token
|
210
278
|
)
|
211
279
|
end
|
@@ -213,8 +281,9 @@ module Discordrb::API
|
|
213
281
|
# Get a member's data
|
214
282
|
def member(token, server_id, user_id)
|
215
283
|
request(
|
284
|
+
nil,
|
216
285
|
:get,
|
217
|
-
"#{
|
286
|
+
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
218
287
|
Authorization: token
|
219
288
|
)
|
220
289
|
end
|
@@ -222,8 +291,9 @@ module Discordrb::API
|
|
222
291
|
# Create a channel
|
223
292
|
def create_channel(token, server_id, name, type)
|
224
293
|
request(
|
294
|
+
nil,
|
225
295
|
:post,
|
226
|
-
"#{
|
296
|
+
"#{api_base}/guilds/#{server_id}/channels",
|
227
297
|
{ name: name, type: type }.to_json,
|
228
298
|
Authorization: token,
|
229
299
|
content_type: :json
|
@@ -233,8 +303,9 @@ module Discordrb::API
|
|
233
303
|
# Update a channel's data
|
234
304
|
def update_channel(token, channel_id, name, topic, position = 0)
|
235
305
|
request(
|
306
|
+
nil,
|
236
307
|
:patch,
|
237
|
-
"#{
|
308
|
+
"#{api_base}/channels/#{channel_id}",
|
238
309
|
{ name: name, position: position, topic: topic }.to_json,
|
239
310
|
Authorization: token,
|
240
311
|
content_type: :json
|
@@ -244,8 +315,9 @@ module Discordrb::API
|
|
244
315
|
# Delete a channel
|
245
316
|
def delete_channel(token, channel_id)
|
246
317
|
request(
|
318
|
+
nil,
|
247
319
|
:delete,
|
248
|
-
"#{
|
320
|
+
"#{api_base}/channels/#{channel_id}",
|
249
321
|
Authorization: token
|
250
322
|
)
|
251
323
|
end
|
@@ -253,8 +325,9 @@ module Discordrb::API
|
|
253
325
|
# Join a server using an invite
|
254
326
|
def join_server(token, invite_code)
|
255
327
|
request(
|
328
|
+
nil,
|
256
329
|
:post,
|
257
|
-
"#{
|
330
|
+
"#{api_base}/invite/#{invite_code}",
|
258
331
|
nil,
|
259
332
|
Authorization: token
|
260
333
|
)
|
@@ -263,8 +336,9 @@ module Discordrb::API
|
|
263
336
|
# Resolve an invite
|
264
337
|
def resolve_invite(token, invite_code)
|
265
338
|
request(
|
339
|
+
nil,
|
266
340
|
:get,
|
267
|
-
"#{
|
341
|
+
"#{api_base}/invite/#{invite_code}",
|
268
342
|
Authorization: token
|
269
343
|
)
|
270
344
|
end
|
@@ -272,19 +346,23 @@ module Discordrb::API
|
|
272
346
|
# Create a private channel
|
273
347
|
def create_private(token, bot_user_id, user_id)
|
274
348
|
request(
|
349
|
+
nil,
|
275
350
|
:post,
|
276
|
-
"#{
|
351
|
+
"#{api_base}/users/#{bot_user_id}/channels",
|
277
352
|
{ recipient_id: user_id }.to_json,
|
278
353
|
Authorization: token,
|
279
354
|
content_type: :json
|
280
355
|
)
|
356
|
+
rescue RestClient::BadRequest
|
357
|
+
raise 'Attempted to PM the bot itself!'
|
281
358
|
end
|
282
359
|
|
283
360
|
# Create an instant invite from a server or a channel id
|
284
361
|
def create_invite(token, channel_id, max_age = 0, max_uses = 0, temporary = false, xkcd = false)
|
285
362
|
request(
|
363
|
+
nil,
|
286
364
|
:post,
|
287
|
-
"#{
|
365
|
+
"#{api_base}/channels/#{channel_id}/invites",
|
288
366
|
{ max_age: max_age, max_uses: max_uses, temporary: temporary, xkcdpass: xkcd }.to_json,
|
289
367
|
Authorization: token,
|
290
368
|
content_type: :json
|
@@ -294,8 +372,9 @@ module Discordrb::API
|
|
294
372
|
# Delete an invite by code
|
295
373
|
def delete_invite(token, code)
|
296
374
|
request(
|
375
|
+
nil,
|
297
376
|
:delete,
|
298
|
-
"#{
|
377
|
+
"#{api_base}/invites/#{code}",
|
299
378
|
Authorization: token
|
300
379
|
)
|
301
380
|
end
|
@@ -303,23 +382,23 @@ module Discordrb::API
|
|
303
382
|
# Send a message to a channel
|
304
383
|
def send_message(token, channel_id, message, mentions = [], tts = false)
|
305
384
|
request(
|
385
|
+
:message,
|
306
386
|
:post,
|
307
|
-
"#{
|
387
|
+
"#{api_base}/channels/#{channel_id}/messages",
|
308
388
|
{ content: message, mentions: mentions, tts: tts }.to_json,
|
309
389
|
Authorization: token,
|
310
390
|
content_type: :json
|
311
391
|
)
|
312
392
|
rescue RestClient::InternalServerError
|
313
393
|
raise Discordrb::Errors::MessageTooLong, "Message over the character limit (#{message.length} > 2000)"
|
314
|
-
rescue RestClient::BadGateway
|
315
|
-
raise Discordrb::Errors::CloudflareError, "Discord's Cloudflare system encountered an error! Usually you can ignore this error and retry the request."
|
316
394
|
end
|
317
395
|
|
318
396
|
# Delete a message
|
319
397
|
def delete_message(token, channel_id, message_id)
|
320
398
|
request(
|
399
|
+
nil,
|
321
400
|
:delete,
|
322
|
-
"#{
|
401
|
+
"#{api_base}/channels/#{channel_id}/messages/#{message_id}",
|
323
402
|
Authorization: token
|
324
403
|
)
|
325
404
|
end
|
@@ -327,8 +406,9 @@ module Discordrb::API
|
|
327
406
|
# Edit a message
|
328
407
|
def edit_message(token, channel_id, message_id, message, mentions = [])
|
329
408
|
request(
|
409
|
+
:message,
|
330
410
|
:patch,
|
331
|
-
"#{
|
411
|
+
"#{api_base}/channels/#{channel_id}/messages/#{message_id}",
|
332
412
|
{ content: message, mentions: mentions }.to_json,
|
333
413
|
Authorization: token,
|
334
414
|
content_type: :json
|
@@ -340,8 +420,9 @@ module Discordrb::API
|
|
340
420
|
# so this is an easy way to catch up on messages
|
341
421
|
def acknowledge_message(token, channel_id, message_id)
|
342
422
|
request(
|
423
|
+
nil,
|
343
424
|
:post,
|
344
|
-
"#{
|
425
|
+
"#{api_base}/channels/#{channel_id}/messages/#{message_id}/ack",
|
345
426
|
nil,
|
346
427
|
Authorization: token
|
347
428
|
)
|
@@ -350,8 +431,9 @@ module Discordrb::API
|
|
350
431
|
# Send a file as a message to a channel
|
351
432
|
def send_file(token, channel_id, file)
|
352
433
|
request(
|
434
|
+
nil,
|
353
435
|
:post,
|
354
|
-
"#{
|
436
|
+
"#{api_base}/channels/#{channel_id}/messages",
|
355
437
|
{ file: file },
|
356
438
|
Authorization: token
|
357
439
|
)
|
@@ -360,8 +442,9 @@ module Discordrb::API
|
|
360
442
|
# Create a role (parameters such as name and colour will have to be set by update_role afterwards)
|
361
443
|
def create_role(token, server_id)
|
362
444
|
request(
|
445
|
+
nil,
|
363
446
|
:post,
|
364
|
-
"#{
|
447
|
+
"#{api_base}/guilds/#{server_id}/roles",
|
365
448
|
nil,
|
366
449
|
Authorization: token
|
367
450
|
)
|
@@ -373,8 +456,9 @@ module Discordrb::API
|
|
373
456
|
# connecting to voice, speaking and voice activity (push-to-talk isn't mandatory)
|
374
457
|
def update_role(token, server_id, role_id, name, colour, hoist = false, packed_permissions = 36_953_089)
|
375
458
|
request(
|
459
|
+
nil,
|
376
460
|
:patch,
|
377
|
-
"#{
|
461
|
+
"#{api_base}/guilds/#{server_id}/roles/#{role_id}",
|
378
462
|
{ color: colour, name: name, hoist: hoist, permissions: packed_permissions }.to_json,
|
379
463
|
Authorization: token,
|
380
464
|
content_type: :json
|
@@ -384,8 +468,9 @@ module Discordrb::API
|
|
384
468
|
# Delete a role
|
385
469
|
def delete_role(token, server_id, role_id)
|
386
470
|
request(
|
471
|
+
nil,
|
387
472
|
:delete,
|
388
|
-
"#{
|
473
|
+
"#{api_base}/guilds/#{server_id}/roles/#{role_id}",
|
389
474
|
Authorization: token
|
390
475
|
)
|
391
476
|
end
|
@@ -393,8 +478,9 @@ module Discordrb::API
|
|
393
478
|
# Update a user's roles
|
394
479
|
def update_user_roles(token, server_id, user_id, roles)
|
395
480
|
request(
|
481
|
+
nil,
|
396
482
|
:patch,
|
397
|
-
"#{
|
483
|
+
"#{api_base}/guilds/#{server_id}/members/#{user_id}",
|
398
484
|
{ roles: roles }.to_json,
|
399
485
|
Authorization: token,
|
400
486
|
content_type: :json
|
@@ -404,8 +490,9 @@ module Discordrb::API
|
|
404
490
|
# Update a user's permission overrides in a channel
|
405
491
|
def update_user_overrides(token, channel_id, user_id, allow, deny)
|
406
492
|
request(
|
493
|
+
nil,
|
407
494
|
:put,
|
408
|
-
"#{
|
495
|
+
"#{api_base}/channels/#{channel_id}/permissions/#{user_id}",
|
409
496
|
{ type: 'member', id: user_id, allow: allow, deny: deny }.to_json,
|
410
497
|
Authorization: token,
|
411
498
|
content_type: :json
|
@@ -415,8 +502,9 @@ module Discordrb::API
|
|
415
502
|
# Update a role's permission overrides in a channel
|
416
503
|
def update_role_overrides(token, channel_id, role_id, allow, deny)
|
417
504
|
request(
|
505
|
+
nil,
|
418
506
|
:put,
|
419
|
-
"#{
|
507
|
+
"#{api_base}/channels/#{channel_id}/permissions/#{role_id}",
|
420
508
|
{ type: 'role', id: role_id, allow: allow, deny: deny }.to_json,
|
421
509
|
Authorization: token,
|
422
510
|
content_type: :json
|
@@ -426,8 +514,9 @@ module Discordrb::API
|
|
426
514
|
# Get the gateway to be used
|
427
515
|
def gateway(token)
|
428
516
|
request(
|
517
|
+
nil,
|
429
518
|
:get,
|
430
|
-
"#{
|
519
|
+
"#{api_base}/gateway",
|
431
520
|
Authorization: token
|
432
521
|
)
|
433
522
|
end
|
@@ -435,8 +524,9 @@ module Discordrb::API
|
|
435
524
|
# Validate a token (this request will fail if the token is invalid)
|
436
525
|
def validate_token(token)
|
437
526
|
request(
|
527
|
+
nil,
|
438
528
|
:post,
|
439
|
-
"#{
|
529
|
+
"#{api_base}/auth/login",
|
440
530
|
{}.to_json,
|
441
531
|
Authorization: token,
|
442
532
|
content_type: :json
|
@@ -446,8 +536,9 @@ module Discordrb::API
|
|
446
536
|
# Start typing (needs to be resent every 5 seconds to keep up the typing)
|
447
537
|
def start_typing(token, channel_id)
|
448
538
|
request(
|
539
|
+
nil,
|
449
540
|
:post,
|
450
|
-
"#{
|
541
|
+
"#{api_base}/channels/#{channel_id}/typing",
|
451
542
|
nil,
|
452
543
|
Authorization: token
|
453
544
|
)
|
@@ -456,8 +547,29 @@ module Discordrb::API
|
|
456
547
|
# Get user data
|
457
548
|
def user(token, user_id)
|
458
549
|
request(
|
550
|
+
nil,
|
459
551
|
:get,
|
460
|
-
"#{
|
552
|
+
"#{api_base}/users/#{user_id}",
|
553
|
+
Authorization: token
|
554
|
+
)
|
555
|
+
end
|
556
|
+
|
557
|
+
# Get profile data
|
558
|
+
def profile(token)
|
559
|
+
request(
|
560
|
+
nil,
|
561
|
+
:get,
|
562
|
+
"#{api_base}/users/@me",
|
563
|
+
Authorization: token
|
564
|
+
)
|
565
|
+
end
|
566
|
+
|
567
|
+
# Get information about a user's connections
|
568
|
+
def connections(token)
|
569
|
+
request(
|
570
|
+
nil,
|
571
|
+
:get,
|
572
|
+
"#{api_base}/users/@me/connections",
|
461
573
|
Authorization: token
|
462
574
|
)
|
463
575
|
end
|
@@ -465,20 +577,34 @@ module Discordrb::API
|
|
465
577
|
# Update user data
|
466
578
|
def update_user(token, email, password, new_username, avatar, new_password = nil)
|
467
579
|
request(
|
580
|
+
nil,
|
468
581
|
:patch,
|
469
|
-
"#{
|
582
|
+
"#{api_base}/users/@me",
|
470
583
|
{ avatar: avatar, email: email, new_password: new_password, password: password, username: new_username }.to_json,
|
471
584
|
Authorization: token,
|
472
585
|
content_type: :json
|
473
586
|
)
|
474
587
|
end
|
475
588
|
|
589
|
+
# Get the servers a user is connected to
|
590
|
+
def servers(token)
|
591
|
+
request(
|
592
|
+
nil,
|
593
|
+
:get,
|
594
|
+
"#{api_base}/users/@me/guilds",
|
595
|
+
Authorization: token
|
596
|
+
)
|
597
|
+
end
|
598
|
+
|
476
599
|
# Get a list of messages from a channel's history
|
477
600
|
def channel_log(token, channel_id, amount, before = nil, after = nil)
|
478
601
|
request(
|
602
|
+
nil,
|
479
603
|
:get,
|
480
|
-
"#{
|
604
|
+
"#{api_base}/channels/#{channel_id}/messages?limit=#{amount}#{"&before=#{before}" if before}#{"&after=#{after}" if after}",
|
481
605
|
Authorization: token
|
482
606
|
)
|
483
607
|
end
|
484
608
|
end
|
609
|
+
|
610
|
+
Discordrb::API.reset_mutexes
|