discordrb 3.0.2 → 3.1.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/CHANGELOG.md +18 -0
- data/README.md +1 -1
- data/discordrb.gemspec +1 -1
- data/lib/discordrb/api.rb +5 -0
- data/lib/discordrb/api/user.rb +13 -0
- data/lib/discordrb/await.rb +0 -2
- data/lib/discordrb/bot.rb +50 -7
- data/lib/discordrb/commands/command_bot.rb +31 -5
- data/lib/discordrb/commands/container.rb +2 -0
- data/lib/discordrb/commands/parser.rb +13 -6
- data/lib/discordrb/data.rb +215 -5
- data/lib/discordrb/events/message.rb +1 -1
- data/lib/discordrb/gateway.rb +1 -1
- data/lib/discordrb/logger.rb +8 -4
- data/lib/discordrb/version.rb +1 -1
- metadata +2 -11
- data/examples/commands.rb +0 -54
- data/examples/data/music.dca +0 -0
- data/examples/data/music.mp3 +0 -0
- data/examples/eval.rb +0 -20
- data/examples/ping.rb +0 -29
- data/examples/ping_with_respond_time.rb +0 -15
- data/examples/pm_send.rb +0 -14
- data/examples/shutdown.rb +0 -19
- data/examples/voice_send.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63b47e7d0728741bab426ae48763d83324c2096d
|
4
|
+
data.tar.gz: bc0bb96095c0f670d172c054673f78641dadc061
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64aa1b967a77ab2b0dc0d2ce1679436d2da83f2b332c803b2564c08eabef65ab65fb6499ea861cf9514f19cf77c76120f2b7b2f3eb5289b484e7031dc2c0f83e
|
7
|
+
data.tar.gz: 928cebe04848e4aa4db8427c1e821f6a03dbade08bca3d7d7da0e13498f896bef996024e978826a2242c0cbf3c63115072e674ed808e5c1f81abf3dff44568ec
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.1.0
|
4
|
+
|
5
|
+
- Emoji handling support ([#226](https://github.com/meew0/discordrb/pull/226), thanks @greenbigfrog)
|
6
|
+
- A `channels` attribute has been added to `CommandBot` as well as `Command` to restrict the channels in which either of the two works ([#249](https://github.com/meew0/discordrb/pull/249), thanks @Xzanth)
|
7
|
+
- The bulk deletion endpoint is now exposed directly using the `Channel#delete_messages` method ([#235](https://github.com/meew0/discordrb/pull/235), thanks @z64)
|
8
|
+
- The internal settings fields for user statuses that cause statuses to persist across restarts can now be modified ([#233](https://github.com/meew0/discordrb/pull/233), thanks @Daniel-Worrall)
|
9
|
+
- A few examples have been added to the docs ([#250](https://github.com/meew0/discordrb/pull/250), thanks @SunDwarf)
|
10
|
+
- The specs have been improved; they're still not exhaustive by far but there are at least slightly more now.
|
11
|
+
|
12
|
+
### Bugfixes
|
13
|
+
|
14
|
+
- Fixed an important bug that caused the logger not to work in some cases. ([#243](https://github.com/meew0/discordrb/pull/243), thanks @Daniel-Worrall)
|
15
|
+
- Fixed logger token redaction.
|
16
|
+
- `unavailable_servers` should no longer crash the bot due to being nil in some cases ([#244](https://github.com/meew0/discordrb/pull/244), thanks @Daniel-Worrall)
|
17
|
+
- `Profile#on` for member resolution is now no longer overwritten by an alias for `#online` ([#247](https://github.com/meew0/discordrb/pull/247), thanks @Daniel-Worrall)
|
18
|
+
- A `CommandBot` without any commands should no longer crash when receiving a message that triggers it ([#242](https://github.com/meew0/discordrb/issues/242))
|
19
|
+
- Changing nicknames works again, it has apparently been broken in 3.0.0.
|
20
|
+
|
3
21
|
## 3.0.2
|
4
22
|
|
5
23
|
- A small change to how CommandBot parameter lists are formatted ([#240](https://github.com/meew0/discordrb/pull/240), thanks @FormalHellhound)
|
data/README.md
CHANGED
@@ -86,7 +86,7 @@ You can make a simple bot like this:
|
|
86
86
|
```ruby
|
87
87
|
require 'discordrb'
|
88
88
|
|
89
|
-
bot = Discordrb::Bot.new token: '<token here>',
|
89
|
+
bot = Discordrb::Bot.new token: '<token here>', client_id: 168123456789123456
|
90
90
|
|
91
91
|
bot.message(with_text: 'Ping!') do |event|
|
92
92
|
event.respond 'Pong!'
|
data/discordrb.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = 'https://github.com/meew0/discordrb'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
17
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|examples)/}) }
|
18
18
|
spec.bindir = 'exe'
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ['lib']
|
data/lib/discordrb/api.rb
CHANGED
@@ -137,6 +137,11 @@ module Discordrb::API
|
|
137
137
|
"#{api_base}/guilds/#{server_id}/widget.png?style=#{style}"
|
138
138
|
end
|
139
139
|
|
140
|
+
# Make an emoji icon URL from emoji ID
|
141
|
+
def emoji_icon_url(emoji_id)
|
142
|
+
"https://cdn.discordapp.com/emojis/#{emoji_id}.png"
|
143
|
+
end
|
144
|
+
|
140
145
|
# Login to the server
|
141
146
|
def login(email, password)
|
142
147
|
request(
|
data/lib/discordrb/api/user.rb
CHANGED
@@ -127,6 +127,19 @@ module Discordrb::API::User
|
|
127
127
|
)
|
128
128
|
end
|
129
129
|
|
130
|
+
# Change user status setting
|
131
|
+
def change_status_setting(token, status)
|
132
|
+
Discordrb::API.request(
|
133
|
+
:users_me_settings,
|
134
|
+
nil,
|
135
|
+
:patch,
|
136
|
+
"#{Discordrb::API.api_base}/users/@me/settings",
|
137
|
+
{ status: status }.to_json,
|
138
|
+
Authorization: token,
|
139
|
+
content_type: :json
|
140
|
+
)
|
141
|
+
end
|
142
|
+
|
130
143
|
# Make an avatar URL from the user and avatar IDs
|
131
144
|
def avatar_url(user_id, avatar_id)
|
132
145
|
"#{Discordrb::API.api_base}/users/#{user_id}/avatars/#{avatar_id}.jpg"
|
data/lib/discordrb/await.rb
CHANGED
data/lib/discordrb/bot.rb
CHANGED
@@ -152,6 +152,39 @@ module Discordrb
|
|
152
152
|
@servers
|
153
153
|
end
|
154
154
|
|
155
|
+
# @overload emoji(id)
|
156
|
+
# Return an emoji by its ID
|
157
|
+
# @param id [Integer] The emoji's ID.
|
158
|
+
# @return emoji [GlobalEmoji, nil] the emoji object. `nil` if the emoji was not found.
|
159
|
+
# @overload emoji
|
160
|
+
# The list of emoji the bot can use.
|
161
|
+
# @return [Array<GlobalEmoji>] the emoji available.
|
162
|
+
def emoji(id = nil)
|
163
|
+
gateway_check
|
164
|
+
if id
|
165
|
+
emoji = @emoji.find { |sth| sth.id == id }
|
166
|
+
else
|
167
|
+
emoji = {}
|
168
|
+
@servers.each do |_, server|
|
169
|
+
server.emoji.values.each do |element|
|
170
|
+
emoji[element.name] = GlobalEmoji.new(element, self)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
emoji.values
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
alias_method :emojis, :emoji
|
178
|
+
alias_method :all_emoji, :emoji
|
179
|
+
|
180
|
+
# Finds an emoji by its name.
|
181
|
+
# @param name [String] The emoji name that should be resolved.
|
182
|
+
# @return [GlobalEmoji, nil] the emoji identified by the name, or `nil` if it couldn't be found.
|
183
|
+
def find_emoji(name)
|
184
|
+
LOGGER.out("Resolving emoji #{name}")
|
185
|
+
emoji.find { |element| element.name == name }
|
186
|
+
end
|
187
|
+
|
155
188
|
# The bot's user profile. This special user object can be used
|
156
189
|
# to edit user data like the current username (see {Profile#username=}).
|
157
190
|
# @return [Profile] The bot's profile that can be used to edit data.
|
@@ -398,13 +431,23 @@ module Discordrb
|
|
398
431
|
API.update_oauth_application(@token, name, redirect_uris, description, icon)
|
399
432
|
end
|
400
433
|
|
401
|
-
# Gets the user from a mention of the user.
|
402
|
-
# @param mention [String] The mention, which should look like
|
403
|
-
# @
|
404
|
-
|
434
|
+
# Gets the user, role or emoji from a mention of the user, role or emoji.
|
435
|
+
# @param mention [String] The mention, which should look like `<@12314873129>`, `<@&123456789>` or `<:Name:126328:>`.
|
436
|
+
# @param server [Server, nil] The server of the associated mention. (recommended for role parsing, to speed things up)
|
437
|
+
# @return [User, Role, Emoji] The user, role or emoji identified by the mention, or `nil` if none exists.
|
438
|
+
def parse_mention(mention, server = nil)
|
405
439
|
# Mention format: <@id>
|
406
|
-
|
407
|
-
|
440
|
+
if /<@!?(?<id>\d+)>?/ =~ mention
|
441
|
+
user(id.to_i)
|
442
|
+
elsif /<@&(?<id>\d+)>?/ =~ mention
|
443
|
+
return server.role(id) if server
|
444
|
+
servers.each do |element|
|
445
|
+
role = element.role(id)
|
446
|
+
return role unless role.nil?
|
447
|
+
end
|
448
|
+
elsif /<:(\w+):(?<id>\d+)>?/ =~ mention
|
449
|
+
emoji.find { |element| element.id.to_i == id.to_i }
|
450
|
+
end
|
408
451
|
end
|
409
452
|
|
410
453
|
# Updates presence status.
|
@@ -812,7 +855,7 @@ module Discordrb
|
|
812
855
|
LOGGER.warn("This means some servers are unavailable due to an outage. Notifying ready now, we'll have to live without these servers")
|
813
856
|
|
814
857
|
# Unset the unavailable server count so this doesn't get triggered again
|
815
|
-
@unavailable_servers =
|
858
|
+
@unavailable_servers = 0
|
816
859
|
|
817
860
|
notify_ready
|
818
861
|
end
|
@@ -50,6 +50,8 @@ module Discordrb::Commands
|
|
50
50
|
# command. Default is false.
|
51
51
|
# @option attributes [true, false] :webhook_commands Whether messages sent by webhooks are allowed to trigger
|
52
52
|
# commands. Default is true.
|
53
|
+
# @option attributes [Array<String, Integer, Channel>] :channels The channels this command bot accepts commands on.
|
54
|
+
# Superseded if a command has a 'channels' attribute.
|
53
55
|
# @option attributes [String] :previous Character that should designate the result of the previous command in
|
54
56
|
# a command chain (see :advanced_functionality). Default is '~'.
|
55
57
|
# @option attributes [String] :chain_delimiter Character that should designate that a new command begins in the
|
@@ -77,7 +79,7 @@ module Discordrb::Commands
|
|
77
79
|
parse_self: attributes[:parse_self],
|
78
80
|
shard_id: attributes[:shard_id],
|
79
81
|
num_shards: attributes[:num_shards],
|
80
|
-
redact_token: attributes[:redact_token])
|
82
|
+
redact_token: attributes.key?(:redact_token) ? attributes[:redact_token] : true)
|
81
83
|
|
82
84
|
@prefix = attributes[:prefix]
|
83
85
|
@attributes = {
|
@@ -100,6 +102,8 @@ module Discordrb::Commands
|
|
100
102
|
# Webhooks allowed to trigger commands
|
101
103
|
webhook_commands: attributes[:webhook_commands].nil? ? true : attributes[:webhook_commands],
|
102
104
|
|
105
|
+
channels: attributes[:channels] || [],
|
106
|
+
|
103
107
|
# All of the following need to be one character
|
104
108
|
# String to designate previous result in command chain
|
105
109
|
previous: attributes[:previous] || '~',
|
@@ -169,19 +173,27 @@ module Discordrb::Commands
|
|
169
173
|
# @param arguments [Array<String>] The arguments to pass to the command.
|
170
174
|
# @param chained [true, false] Whether or not it should be executed as part of a command chain. If this is false,
|
171
175
|
# commands that have chain_usable set to false will not work.
|
176
|
+
# @param check_permissions [true, false] Whether permission parameters such as `required_permission` or
|
177
|
+
# `permission_level` should be checked.
|
172
178
|
# @return [String, nil] the command's result, if there is any.
|
173
|
-
def execute_command(name, event, arguments, chained = false)
|
179
|
+
def execute_command(name, event, arguments, chained = false, check_permissions = true)
|
174
180
|
debug("Executing command #{name} with arguments #{arguments}")
|
181
|
+
return unless @commands
|
175
182
|
command = @commands[name]
|
183
|
+
return unless !check_permissions || channels?(event.channel, @attributes[:channels]) ||
|
184
|
+
(command && !command.attributes[:channels].nil?)
|
176
185
|
unless command
|
177
186
|
event.respond @attributes[:command_doesnt_exist_message].gsub('%command%', name.to_s) if @attributes[:command_doesnt_exist_message]
|
178
187
|
return
|
179
188
|
end
|
180
|
-
|
189
|
+
return unless !check_permissions || channels?(event.channel, command.attributes[:channels])
|
190
|
+
if (check_permissions &&
|
191
|
+
permission?(event.author, command.attributes[:permission_level], event.server) &&
|
181
192
|
required_permissions?(event.author, command.attributes[:required_permissions], event.channel) &&
|
182
|
-
required_roles?(event.author, command.attributes[:required_roles])
|
193
|
+
required_roles?(event.author, command.attributes[:required_roles])) ||
|
194
|
+
!check_permissions
|
183
195
|
event.command = command
|
184
|
-
result = command.call(event, arguments, chained)
|
196
|
+
result = command.call(event, arguments, chained, check_permissions)
|
185
197
|
stringify(result)
|
186
198
|
else
|
187
199
|
event.respond command.attributes[:permission_message].gsub('%name%', name.to_s) if command.attributes[:permission_message]
|
@@ -301,6 +313,20 @@ module Discordrb::Commands
|
|
301
313
|
end
|
302
314
|
end
|
303
315
|
|
316
|
+
def channels?(channel, channels)
|
317
|
+
return true if channels.nil? || channels.empty?
|
318
|
+
channels.any? do |c|
|
319
|
+
if c.is_a? String
|
320
|
+
# Make sure to remove the "#" from channel names in case it was specified
|
321
|
+
c.delete('#') == channel.name
|
322
|
+
elsif c.is_a? Fixnum
|
323
|
+
c == channel.id
|
324
|
+
else
|
325
|
+
c == channel
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
304
330
|
def execute_chain(chain, event)
|
305
331
|
t = Thread.new do
|
306
332
|
@event_threads << t
|
@@ -23,6 +23,8 @@ module Discordrb::Commands
|
|
23
23
|
# @option attributes [Array<Symbol>] :required_permissions Discord action permissions (e.g. `:kick_members`) that
|
24
24
|
# should be required to use this command. See {Discordrb::Permissions::Flags} for a list.
|
25
25
|
# @option attributes [Array<Role>, Array<#resolve_id>] :required_roles Roles that user should have to use this command.
|
26
|
+
# @option attributes [Array<String, Integer, Channel>] :channels The channels that this command can be used on. An
|
27
|
+
# empty array indicates it can be used on any channel. Supersedes the command bot attribute.
|
26
28
|
# @option attributes [true, false] :chain_usable Whether this command is able to be used inside of a command chain
|
27
29
|
# or sub-chain. Typically used for administrative commands that shouldn't be done carelessly.
|
28
30
|
# @option attributes [true, false] :help_available Whether this command is visible in the help command. See the
|
@@ -25,6 +25,9 @@ module Discordrb::Commands
|
|
25
25
|
# Roles required to use this command
|
26
26
|
required_roles: attributes[:required_roles] || [],
|
27
27
|
|
28
|
+
# Channels this command can be used on
|
29
|
+
channels: attributes[:channels] || nil,
|
30
|
+
|
28
31
|
# Whether this command is usable in a command chain
|
29
32
|
chain_usable: attributes[:chain_usable].nil? ? true : attributes[:chain_usable],
|
30
33
|
|
@@ -61,8 +64,10 @@ module Discordrb::Commands
|
|
61
64
|
# @param event [CommandEvent] The event to call the command with.
|
62
65
|
# @param arguments [Array<String>] The attributes for the command.
|
63
66
|
# @param chained [true, false] Whether or not this command is part of a command chain.
|
67
|
+
# @param check_permissions [true, false] Whether the user's permission to execute the command (i.e. rate limits)
|
68
|
+
# should be checked.
|
64
69
|
# @return [String] the result of the execution.
|
65
|
-
def call(event, arguments, chained = false)
|
70
|
+
def call(event, arguments, chained = false, check_permissions = true)
|
66
71
|
if arguments.length < @attributes[:min_args]
|
67
72
|
event.respond "Too few arguments for command `#{name}`!"
|
68
73
|
event.respond "Usage: `#{@attributes[:usage]}`" if @attributes[:usage]
|
@@ -80,12 +85,14 @@ module Discordrb::Commands
|
|
80
85
|
end
|
81
86
|
end
|
82
87
|
|
83
|
-
|
84
|
-
|
85
|
-
if @attributes[:
|
86
|
-
|
88
|
+
if check_permissions
|
89
|
+
rate_limited = event.bot.rate_limited?(@attributes[:bucket], event.author)
|
90
|
+
if @attributes[:bucket] && rate_limited
|
91
|
+
if @attributes[:rate_limit_message]
|
92
|
+
event.respond @attributes[:rate_limit_message].gsub('%time%', rate_limited.round(2).to_s)
|
93
|
+
end
|
94
|
+
return
|
87
95
|
end
|
88
|
-
return
|
89
96
|
end
|
90
97
|
|
91
98
|
result = @block.call(event, *arguments)
|
data/lib/discordrb/data.rb
CHANGED
@@ -10,7 +10,6 @@ require 'discordrb/api/channel'
|
|
10
10
|
require 'discordrb/api/server'
|
11
11
|
require 'discordrb/api/invite'
|
12
12
|
require 'discordrb/api/user'
|
13
|
-
require 'discordrb/events/message'
|
14
13
|
require 'time'
|
15
14
|
require 'base64'
|
16
15
|
|
@@ -262,7 +261,7 @@ module Discordrb
|
|
262
261
|
end
|
263
262
|
|
264
263
|
# Utility function to get a application's icon URL.
|
265
|
-
# @return [String, nil] the URL to the icon image (nil if no
|
264
|
+
# @return [String, nil] the URL to the icon image (nil if no image is set).
|
266
265
|
def icon_url
|
267
266
|
return nil if @icon_id.nil?
|
268
267
|
API.app_icon_url(@id, @icon_id)
|
@@ -296,6 +295,9 @@ module Discordrb
|
|
296
295
|
# through for example being the server owner or having the Manage Roles permission
|
297
296
|
# @param action [Symbol] The permission that should be checked. See also {Permissions::Flags} for a list.
|
298
297
|
# @param channel [Channel, nil] If channel overrides should be checked too, this channel specifies where the overrides should be checked.
|
298
|
+
# @example Check if the bot can send messages to a specific channel in a server.
|
299
|
+
# bot_profile = bot.profile.on(event.server)
|
300
|
+
# can_send_messages = bot_profile.permission?(:send_messages, channel)
|
299
301
|
# @return [true, false] whether or not this user has the permission.
|
300
302
|
def permission?(action, channel = nil)
|
301
303
|
# If the member is the server owner, it irrevocably has all permissions.
|
@@ -315,6 +317,8 @@ module Discordrb
|
|
315
317
|
# Manage Roles)
|
316
318
|
# @param action [Symbol] The permission that should be checked. See also {Permissions::Flags} for a list.
|
317
319
|
# @param channel [Channel, nil] If channel overrides should be checked too, this channel specifies where the overrides should be checked.
|
320
|
+
# @example Check if a member has the Manage Channels permission defined in the server.
|
321
|
+
# has_manage_channels = member.defined_permission?(:manage_channels)
|
318
322
|
# @return [true, false] whether or not this user has the permission defined.
|
319
323
|
def defined_permission?(action, channel = nil)
|
320
324
|
# Get the permission the user's roles have
|
@@ -489,6 +493,10 @@ module Discordrb
|
|
489
493
|
# Adds and removes roles from a member.
|
490
494
|
# @param add [Role, Array<Role>] The role(s) to add.
|
491
495
|
# @param remove [Role, Array<Role>] The role(s) to remove.
|
496
|
+
# @example Remove the 'Member' role from a user, and add the 'Muted' role to them.
|
497
|
+
# to_add = server.roles.find {|role| role.name == 'Muted'}
|
498
|
+
# to_remove = server.roles.find {|role| role.name == 'Member'}
|
499
|
+
# member.modify_roles(to_add, to_remove)
|
492
500
|
def modify_roles(add, remove)
|
493
501
|
add_role_ids = role_id_array(add)
|
494
502
|
remove_role_ids = role_id_array(remove)
|
@@ -548,7 +556,7 @@ module Discordrb
|
|
548
556
|
if @user.current_bot?
|
549
557
|
API::User.change_own_nickname(@bot.token, @server.id, nick)
|
550
558
|
else
|
551
|
-
API.
|
559
|
+
API::Server.update_member(@bot.token, @server.id, @user.id, nick: nick)
|
552
560
|
end
|
553
561
|
end
|
554
562
|
|
@@ -676,6 +684,32 @@ module Discordrb
|
|
676
684
|
@avatar_id = new_data[:avatar_id] || @avatar_id
|
677
685
|
end
|
678
686
|
|
687
|
+
# Sets the user status setting to Online.
|
688
|
+
# @note Only usable on User accounts.
|
689
|
+
def online
|
690
|
+
update_profile_status_setting('online')
|
691
|
+
end
|
692
|
+
|
693
|
+
# Sets the user status setting to Idle.
|
694
|
+
# @note Only usable on User accounts.
|
695
|
+
def idle
|
696
|
+
update_profile_status_setting('idle')
|
697
|
+
end
|
698
|
+
|
699
|
+
# Sets the user status setting to Do Not Disturb.
|
700
|
+
# @note Only usable on User accounts.
|
701
|
+
def dnd
|
702
|
+
update_profile_status_setting('dnd')
|
703
|
+
end
|
704
|
+
|
705
|
+
alias_method(:busy, :dnd)
|
706
|
+
|
707
|
+
# Sets the user status setting to Invisible.
|
708
|
+
# @note Only usable on User accounts.
|
709
|
+
def invisible
|
710
|
+
update_profile_status_setting('invisible')
|
711
|
+
end
|
712
|
+
|
679
713
|
# The inspect method is overwritten to give more useful output
|
680
714
|
def inspect
|
681
715
|
"<Profile user=#{super}>"
|
@@ -683,6 +717,11 @@ module Discordrb
|
|
683
717
|
|
684
718
|
private
|
685
719
|
|
720
|
+
# Internal handler for updating the user's status setting
|
721
|
+
def update_profile_status_setting(status)
|
722
|
+
API::User.change_status_setting(@bot.token, status)
|
723
|
+
end
|
724
|
+
|
686
725
|
def update_profile_data(new_data)
|
687
726
|
API::User.update_profile(@bot.token,
|
688
727
|
nil, nil,
|
@@ -729,6 +768,11 @@ module Discordrb
|
|
729
768
|
def write(bits)
|
730
769
|
@role.send(:packed=, bits, false)
|
731
770
|
end
|
771
|
+
|
772
|
+
# The inspect method is overridden, in this case to prevent the token being leaked
|
773
|
+
def inspect
|
774
|
+
"<RoleWriter role=#{@role} token=...>"
|
775
|
+
end
|
732
776
|
end
|
733
777
|
|
734
778
|
# @!visibility private
|
@@ -822,7 +866,7 @@ module Discordrb
|
|
822
866
|
@permissions.bits = packed if update_perms
|
823
867
|
end
|
824
868
|
|
825
|
-
#
|
869
|
+
# Deletes this role. This cannot be undone without recreating the role!
|
826
870
|
def delete
|
827
871
|
API::Server.delete_role(@bot.token, @server.id, @id)
|
828
872
|
@server.delete_role(@id)
|
@@ -1213,6 +1257,8 @@ module Discordrb
|
|
1213
1257
|
# start at the current message.
|
1214
1258
|
# @param after_id [Integer] The ID of the oldest message the retrieval should start at, or nil if it should start
|
1215
1259
|
# as soon as possible with the specified amount.
|
1260
|
+
# @example Count the number of messages in the last 50 messages that contain the letter 'e'.
|
1261
|
+
# message_count = channel.history(50).count {|message| message.content.include? "e"}
|
1216
1262
|
# @return [Array<Message>] the retrieved messages.
|
1217
1263
|
def history(amount, before_id = nil, after_id = nil)
|
1218
1264
|
logs = API::Channel.messages(@bot.token, @id, amount, before_id, after_id)
|
@@ -1256,6 +1302,16 @@ module Discordrb
|
|
1256
1302
|
API::Channel.bulk_delete_messages(@bot.token, @id, messages)
|
1257
1303
|
end
|
1258
1304
|
|
1305
|
+
# Deletes a collection of messages
|
1306
|
+
# @param messages [Array<Message, Integer>] the messages (or message IDs) to delete. Total must be an amount between 2 and 100 (Discord limitation)
|
1307
|
+
# @raise [ArgumentError] if the amount of messages is not a value between 2 and 100
|
1308
|
+
def delete_messages(messages)
|
1309
|
+
raise ArgumentError, 'Can only delete between 2 and 100 messages!' unless messages.count.between?(2, 100)
|
1310
|
+
|
1311
|
+
messages.map!(&:resolve_id)
|
1312
|
+
API::Channel.bulk_delete_messages(@bot.token, @id, messages)
|
1313
|
+
end
|
1314
|
+
|
1259
1315
|
# Updates the cached permission overwrites
|
1260
1316
|
# @note For internal use only
|
1261
1317
|
# @!visibility private
|
@@ -1628,6 +1684,8 @@ module Discordrb
|
|
1628
1684
|
@edited = !@edited_timestamp.nil?
|
1629
1685
|
@id = data['id'].to_i
|
1630
1686
|
|
1687
|
+
@emoji = []
|
1688
|
+
|
1631
1689
|
@mentions = []
|
1632
1690
|
|
1633
1691
|
data['mentions'].each do |element|
|
@@ -1657,6 +1715,7 @@ module Discordrb
|
|
1657
1715
|
end
|
1658
1716
|
|
1659
1717
|
# Edits this message to have the specified content instead.
|
1718
|
+
# You can only edit your own messages.
|
1660
1719
|
# @param new_content [String] the new content the message should have.
|
1661
1720
|
# @return [Message] the resulting message.
|
1662
1721
|
def edit(new_content)
|
@@ -1700,12 +1759,141 @@ module Discordrb
|
|
1700
1759
|
!@webhook_id.nil?
|
1701
1760
|
end
|
1702
1761
|
|
1762
|
+
# @!visibility private
|
1763
|
+
# @return [Array<String>] the emoji mentions found in the message
|
1764
|
+
def scan_for_emoji
|
1765
|
+
emoji = @content.split
|
1766
|
+
emoji = emoji.grep(/<:(?<name>\w+):(?<id>\d+)>?/)
|
1767
|
+
emoji
|
1768
|
+
end
|
1769
|
+
|
1770
|
+
# @return [Array<Emoji>] the emotes that were used/mentioned in this message (Only returns Emoji the bot has access to, else nil).
|
1771
|
+
def emoji
|
1772
|
+
return if @content.nil?
|
1773
|
+
|
1774
|
+
emoji = scan_for_emoji
|
1775
|
+
emoji.each do |element|
|
1776
|
+
@emoji << @bot.parse_mention(element)
|
1777
|
+
end
|
1778
|
+
@emoji
|
1779
|
+
end
|
1780
|
+
|
1781
|
+
# Check if any emoji got used in this message
|
1782
|
+
# @return [true, false] whether or not any emoji got used
|
1783
|
+
def emoji?
|
1784
|
+
emoji = scan_for_emoji
|
1785
|
+
return true unless emoji.empty?
|
1786
|
+
end
|
1787
|
+
|
1703
1788
|
# The inspect method is overwritten to give more useful output
|
1704
1789
|
def inspect
|
1705
1790
|
"<Message content=\"#{@content}\" id=#{@id} timestamp=#{@timestamp} author=#{@author} channel=#{@channel}>"
|
1706
1791
|
end
|
1707
1792
|
end
|
1708
1793
|
|
1794
|
+
# Server emoji
|
1795
|
+
class Emoji
|
1796
|
+
include IDObject
|
1797
|
+
|
1798
|
+
# @return [String] the emoji name
|
1799
|
+
attr_reader :name
|
1800
|
+
|
1801
|
+
# @return [Server] the server of this emoji
|
1802
|
+
attr_reader :server
|
1803
|
+
|
1804
|
+
# @return [Array<Role>] roles this emoji is active for
|
1805
|
+
attr_reader :roles
|
1806
|
+
|
1807
|
+
def initialize(data, bot, server)
|
1808
|
+
@bot = bot
|
1809
|
+
@roles = nil
|
1810
|
+
|
1811
|
+
@name = data['name']
|
1812
|
+
@server = server
|
1813
|
+
@id = data['id'].to_i
|
1814
|
+
|
1815
|
+
process_roles(data['roles']) if server
|
1816
|
+
end
|
1817
|
+
|
1818
|
+
# @return [String] the layout to mention it (or have it used) in a message
|
1819
|
+
def mention
|
1820
|
+
"<:#{@name}:#{@id}>"
|
1821
|
+
end
|
1822
|
+
|
1823
|
+
alias_method :use, :mention
|
1824
|
+
alias_method :to_s, :mention
|
1825
|
+
|
1826
|
+
# @return [String] the icon URL of the emoji
|
1827
|
+
def icon_url
|
1828
|
+
API.emoji_icon_url(@id)
|
1829
|
+
end
|
1830
|
+
|
1831
|
+
# The inspect method is overwritten to give more useful output
|
1832
|
+
def inspect
|
1833
|
+
"<Emoji name=#{@name} id=#{@id}>"
|
1834
|
+
end
|
1835
|
+
|
1836
|
+
# @!visibility private
|
1837
|
+
def process_roles(roles)
|
1838
|
+
@roles = []
|
1839
|
+
return unless roles
|
1840
|
+
roles.each do |role_id|
|
1841
|
+
role = server.role(role_id)
|
1842
|
+
@roles << role
|
1843
|
+
end
|
1844
|
+
end
|
1845
|
+
end
|
1846
|
+
|
1847
|
+
# Emoji that is not tailored to a server
|
1848
|
+
class GlobalEmoji
|
1849
|
+
include IDObject
|
1850
|
+
|
1851
|
+
# @return [String] the emoji name
|
1852
|
+
attr_reader :name
|
1853
|
+
|
1854
|
+
# @return [Hash<Integer => Array<Role>>] roles this emoji is active for in every server
|
1855
|
+
attr_reader :role_associations
|
1856
|
+
|
1857
|
+
def initialize(data, bot)
|
1858
|
+
@bot = bot
|
1859
|
+
@roles = nil
|
1860
|
+
|
1861
|
+
@name = data.name
|
1862
|
+
@id = data.id
|
1863
|
+
@role_associations = Hash.new([])
|
1864
|
+
@role_associations[data.server.id] = data.roles
|
1865
|
+
end
|
1866
|
+
|
1867
|
+
# @return [String] the layout to mention it (or have it used) in a message
|
1868
|
+
def mention
|
1869
|
+
"<:#{@name}:#{@id}>"
|
1870
|
+
end
|
1871
|
+
|
1872
|
+
alias_method :use, :mention
|
1873
|
+
alias_method :to_s, :mention
|
1874
|
+
|
1875
|
+
# @return [String] the icon URL of the emoji
|
1876
|
+
def icon_url
|
1877
|
+
API.emoji_icon_url(@id)
|
1878
|
+
end
|
1879
|
+
|
1880
|
+
# The inspect method is overwritten to give more useful output
|
1881
|
+
def inspect
|
1882
|
+
"<GlobalEmoji name=#{@name} id=#{@id}>"
|
1883
|
+
end
|
1884
|
+
|
1885
|
+
# @!visibility private
|
1886
|
+
def process_roles(roles)
|
1887
|
+
new_roles = []
|
1888
|
+
return unless roles
|
1889
|
+
roles.each do
|
1890
|
+
role = server.role(role_id)
|
1891
|
+
new_roles << role
|
1892
|
+
end
|
1893
|
+
new_roles
|
1894
|
+
end
|
1895
|
+
end
|
1896
|
+
|
1709
1897
|
# Basic attributes a server should have
|
1710
1898
|
module ServerAttributes
|
1711
1899
|
# @return [String] this server's name.
|
@@ -1724,7 +1912,7 @@ module Discordrb
|
|
1724
1912
|
|
1725
1913
|
# Integration Account
|
1726
1914
|
class IntegrationAccount
|
1727
|
-
# @return [String] this
|
1915
|
+
# @return [String] this account's name.
|
1728
1916
|
attr_reader :name
|
1729
1917
|
|
1730
1918
|
# @return [Integer] this account's ID.
|
@@ -1819,6 +2007,10 @@ module Discordrb
|
|
1819
2007
|
# @return [Array<Role>] an array of all the roles created on this server.
|
1820
2008
|
attr_reader :roles
|
1821
2009
|
|
2010
|
+
# @return [Array<Emoji>] an array of all the emoji available on this server.
|
2011
|
+
attr_reader :emoji
|
2012
|
+
alias_method :emojis, :emoji
|
2013
|
+
|
1822
2014
|
# @return [true, false] whether or not this server is large (members > 100). If it is,
|
1823
2015
|
# it means the members list may be inaccurate for a couple seconds after starting up the bot.
|
1824
2016
|
attr_reader :large
|
@@ -1857,8 +2049,10 @@ module Discordrb
|
|
1857
2049
|
@features = data['features'].map { |element| element.downcase.to_sym }
|
1858
2050
|
@members = {}
|
1859
2051
|
@voice_states = {}
|
2052
|
+
@emoji = {}
|
1860
2053
|
|
1861
2054
|
process_roles(data['roles'])
|
2055
|
+
process_emoji(data['emojis'])
|
1862
2056
|
process_members(data['members'])
|
1863
2057
|
process_presences(data['presences'])
|
1864
2058
|
process_channels(data['channels'])
|
@@ -2172,6 +2366,14 @@ module Discordrb
|
|
2172
2366
|
update_server_data(afk_timeout: afk_timeout)
|
2173
2367
|
end
|
2174
2368
|
|
2369
|
+
# @return [true, false] whether this server has any emoji or not.
|
2370
|
+
def any_emoji?
|
2371
|
+
@emoji.any?
|
2372
|
+
end
|
2373
|
+
|
2374
|
+
alias_method :has_emoji?, :any_emoji?
|
2375
|
+
alias_method :emoji?, :any_emoji?
|
2376
|
+
|
2175
2377
|
# Processes a GUILD_MEMBERS_CHUNK packet, specifically the members field
|
2176
2378
|
# @note For internal use only
|
2177
2379
|
# @!visibility private
|
@@ -2239,6 +2441,14 @@ module Discordrb
|
|
2239
2441
|
end
|
2240
2442
|
end
|
2241
2443
|
|
2444
|
+
def process_emoji(emoji)
|
2445
|
+
return if emoji.empty?
|
2446
|
+
emoji.each do |element|
|
2447
|
+
new_emoji = Emoji.new(element, @bot, self)
|
2448
|
+
@emoji[new_emoji.id] = new_emoji
|
2449
|
+
end
|
2450
|
+
end
|
2451
|
+
|
2242
2452
|
def process_members(members)
|
2243
2453
|
return unless members
|
2244
2454
|
members.each do |element|
|
@@ -6,7 +6,7 @@ require 'discordrb/data'
|
|
6
6
|
module Discordrb::Events
|
7
7
|
# Module to make sending messages easier with the presence of a text channel in an event
|
8
8
|
module Respondable
|
9
|
-
# @return [Channel] the channel in which this event
|
9
|
+
# @return [Channel] the channel in which this event occurred
|
10
10
|
attr_reader :channel
|
11
11
|
|
12
12
|
# Sends a message to the channel this message was sent in, right now. It is usually preferable to use {#<<} instead
|
data/lib/discordrb/gateway.rb
CHANGED
@@ -609,7 +609,7 @@ module Discordrb
|
|
609
609
|
|
610
610
|
# Op 9
|
611
611
|
def handle_invalidate_session
|
612
|
-
LOGGER.debug('Received op 9, invalidating session and
|
612
|
+
LOGGER.debug('Received op 9, invalidating session and re-identifying.')
|
613
613
|
|
614
614
|
if @session
|
615
615
|
@session.invalidate
|
data/lib/discordrb/logger.rb
CHANGED
@@ -44,7 +44,7 @@ module Discordrb
|
|
44
44
|
|
45
45
|
MODES.each do |mode, hash|
|
46
46
|
define_method(mode) do |message|
|
47
|
-
write(message, hash) if @enabled_modes.include? mode
|
47
|
+
write(message.to_s, hash) if @enabled_modes.include? mode
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -91,13 +91,17 @@ module Discordrb
|
|
91
91
|
timestamp = Time.now.strftime(LOG_TIMESTAMP_FORMAT)
|
92
92
|
|
93
93
|
# Redact token if set
|
94
|
-
|
94
|
+
log = if @token
|
95
|
+
message.to_s.gsub(@token, 'REDACTED_TOKEN')
|
96
|
+
else
|
97
|
+
message.to_s
|
98
|
+
end
|
95
99
|
|
96
100
|
@streams.each do |stream|
|
97
101
|
if @fancy && !stream.is_a?(File)
|
98
|
-
fancy_write(stream,
|
102
|
+
fancy_write(stream, log, mode, thread_name, timestamp)
|
99
103
|
else
|
100
|
-
simple_write(stream,
|
104
|
+
simple_write(stream, log, mode, thread_name, timestamp)
|
101
105
|
end
|
102
106
|
end
|
103
107
|
end
|
data/lib/discordrb/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: discordrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- meew0
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -171,15 +171,6 @@ files:
|
|
171
171
|
- bin/console
|
172
172
|
- bin/setup
|
173
173
|
- discordrb.gemspec
|
174
|
-
- examples/commands.rb
|
175
|
-
- examples/data/music.dca
|
176
|
-
- examples/data/music.mp3
|
177
|
-
- examples/eval.rb
|
178
|
-
- examples/ping.rb
|
179
|
-
- examples/ping_with_respond_time.rb
|
180
|
-
- examples/pm_send.rb
|
181
|
-
- examples/shutdown.rb
|
182
|
-
- examples/voice_send.rb
|
183
174
|
- lib/discordrb.rb
|
184
175
|
- lib/discordrb/api.rb
|
185
176
|
- lib/discordrb/api/channel.rb
|
data/examples/commands.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# This bot has various commands that show off CommandBot.
|
2
|
-
|
3
|
-
require 'discordrb'
|
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.
|
7
|
-
bot = Discordrb::Commands::CommandBot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543, prefix: '!'
|
8
|
-
|
9
|
-
bot.command :user do |event|
|
10
|
-
# Commands send whatever is returned from the block to the channel. This allows for compact commands like this,
|
11
|
-
# but you have to be aware of this so you don't accidentally return something you didn't intend to.
|
12
|
-
# To prevent the return value to be sent to the channel, you can just return `nil`.
|
13
|
-
event.user.name
|
14
|
-
end
|
15
|
-
|
16
|
-
bot.command :bold do |_event, *args|
|
17
|
-
# Again, the return value of the block is sent to the channel
|
18
|
-
"**#{args.join(' ')}**"
|
19
|
-
end
|
20
|
-
|
21
|
-
bot.command :italic do |_event, *args|
|
22
|
-
"*#{args.join(' ')}*"
|
23
|
-
end
|
24
|
-
|
25
|
-
bot.command(:join, permission_level: 1, chain_usable: false) do |event, invite|
|
26
|
-
event.bot.join invite
|
27
|
-
|
28
|
-
# The `join` call above returns the data Discord sends as a response to joining the server. We don't want that
|
29
|
-
# in the channel so here we're just returning `nil` afterwards
|
30
|
-
nil
|
31
|
-
end
|
32
|
-
|
33
|
-
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|
|
34
|
-
# The `if` statement returns one of multiple different things based on the condition. Its return value
|
35
|
-
# is then returned from the block and sent to the channel
|
36
|
-
if max
|
37
|
-
rand(min.to_i..max.to_i)
|
38
|
-
elsif min
|
39
|
-
rand(0..min.to_i)
|
40
|
-
else
|
41
|
-
rand
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
bot.command :long do |event|
|
46
|
-
event << 'This is a long message.'
|
47
|
-
event << 'It has multiple lines that are each sent by doing `event << line`.'
|
48
|
-
event << 'This is an easy way to do such long messages, or to create lines that should only be sent conditionally.'
|
49
|
-
event << 'Anyway, have a nice day.'
|
50
|
-
|
51
|
-
# Here we don't have to worry about the return value because the `event << line` statement automatically returns nil.
|
52
|
-
end
|
53
|
-
|
54
|
-
bot.run
|
data/examples/data/music.dca
DELETED
Binary file
|
data/examples/data/music.mp3
DELETED
Binary file
|
data/examples/eval.rb
DELETED
@@ -1,20 +0,0 @@
|
|
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.
|
5
|
-
|
6
|
-
require 'discordrb'
|
7
|
-
|
8
|
-
bot = Discordrb::Commands::CommandBot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543, prefix: '!'
|
9
|
-
|
10
|
-
bot.command(:eval, help_available: false) do |event, *code|
|
11
|
-
break unless event.user.id == 66237334693085184 # Replace number with your ID
|
12
|
-
|
13
|
-
begin
|
14
|
-
eval code.join(' ')
|
15
|
-
rescue
|
16
|
-
'An error occured 😞'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
bot.run
|
data/examples/ping.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# This simple bot responds to every "Ping!" message with a "Pong!"
|
2
|
-
|
3
|
-
require 'discordrb'
|
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.
|
14
|
-
bot = Discordrb::Bot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543
|
15
|
-
|
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
|
17
|
-
# done once, afterwards, you can remove this part if you want
|
18
|
-
puts "This bot's invite URL is #{bot.invite_url}."
|
19
|
-
puts 'Click on it to invite it to your server.'
|
20
|
-
|
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|
|
24
|
-
event.respond 'Pong!'
|
25
|
-
end
|
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.
|
29
|
-
bot.run
|
@@ -1,15 +0,0 @@
|
|
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.
|
3
|
-
|
4
|
-
require 'discordrb'
|
5
|
-
|
6
|
-
bot = Discordrb::Bot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543
|
7
|
-
|
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.
|
11
|
-
m = event.respond('Pong!')
|
12
|
-
m.edit "Pong! Time taken: #{Time.now - event.timestamp} seconds."
|
13
|
-
end
|
14
|
-
|
15
|
-
bot.run
|
data/examples/pm_send.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# This bot shows off PM functionality by sending a PM every time the bot is mentioned.
|
2
|
-
|
3
|
-
require 'discordrb'
|
4
|
-
|
5
|
-
bot = Discordrb::Bot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543
|
6
|
-
|
7
|
-
# The `mention` event is called if the bot is *directly mentioned*, i.e. not using a role mention or @everyone/@here.
|
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.
|
11
|
-
event.user.pm('You have mentioned me!')
|
12
|
-
end
|
13
|
-
|
14
|
-
bot.run
|
data/examples/shutdown.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# This bot doesn't do anything except for letting a specifically authorised user shutdown the bot on command.
|
2
|
-
|
3
|
-
require 'discordrb'
|
4
|
-
|
5
|
-
bot = Discordrb::Commands::CommandBot.new token: 'B0T.T0KEN.here', application_id: 160123456789876543, prefix: '!'
|
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.
|
10
|
-
bot.command(:exit, help_available: false) do |event|
|
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
|
14
|
-
|
15
|
-
bot.send_message(event.channel.id, 'Bot is shutting down')
|
16
|
-
exit
|
17
|
-
end
|
18
|
-
|
19
|
-
bot.run
|
data/examples/voice_send.rb
DELETED
@@ -1,51 +0,0 @@
|
|
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
|