Class: Discordrb::Bot
Overview
Represents a Discord bot, including servers, users, etc.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#bot_user ⇒ User
readonly
The user that represents the bot itself.
-
#event_threads ⇒ Array<Thread>
readonly
The list of currently running threads used to parse and call events.
-
#name ⇒ Object
The bot's name which discordrb sends to Discord when making any request, so Discord can identify bots with the same codebase.
-
#profile ⇒ Profile
readonly
The bot's user profile.
-
#servers ⇒ Array<Server>
readonly
The list of servers the bot is currently in.
-
#should_parse_self ⇒ Object
Whether or not the bot should parse its own messages.
-
#users ⇒ Array<User>
readonly
The list of users the bot shares a server with.
-
#voice ⇒ Object
readonly
Returns the value of attribute voice.
Instance Method Summary collapse
-
#add_await(key, type, attributes = {}) {|event| ... } ⇒ Await
Add an await the bot should listen to.
- #add_handler(handler) ⇒ Object (also: #<<)
-
#await(attributes = {}) {|event| ... } ⇒ AwaitEventHandler
This event is raised when an Await is triggered.
-
#channel(id) ⇒ Channel
Gets a channel given its ID.
-
#channel_create(attributes = {}, &block) ⇒ Object
Handle channel creation Attributes: * type: Channel type ('text' or 'voice') * name: Channel name.
-
#channel_delete(attributes = {}, &block) ⇒ Object
Handle channel deletion Attributes: * type: Channel type ('text' or 'voice') * name: Channel name.
-
#channel_update(attributes = {}, &block) ⇒ Object
Handle channel update Attributes: * type: Channel type ('text' or 'voice') * name: Channel name.
-
#create_server(name, region = :london) ⇒ Server
Creates a server on Discord with a specified name and a region.
- #debug(message, important = false) ⇒ Object
-
#debug=(new_debug) ⇒ Object
Sets debug mode.
-
#delete_invite(code) ⇒ Object
Revokes an invite to a server.
- #disconnected(attributes = {}, &block) ⇒ Object
-
#find(channel_name, server_name = nil, threshold = 0) ⇒ Array<Channel>
Finds a channel given its name and optionally the name of the server it is in.
-
#find_user(username, threshold = 0) ⇒ Array<User>
Finds a user given its username.
-
#game=(name) ⇒ String
Sets the currently playing game to the specified game.
- #handler_class(event_class) ⇒ Object
-
#initialize(email, password, debug = false) ⇒ Bot
constructor
Makes a new bot with the given email and password.
-
#invite(invite) ⇒ Invite
Gets information about an invite.
-
#join(invite) ⇒ Object
Makes the bot join an invite to a server.
- #log_exception(e) ⇒ Object
- #member_join(attributes = {}, &block) ⇒ Object
- #member_leave(attributes = {}, &block) ⇒ Object
- #member_update(attributes = {}, &block) ⇒ Object
- #mention(attributes = {}, &block) ⇒ Object
-
#message(attributes = {}) {|event| ... } ⇒ MessageEventHandler
This event is raised when a message is sent to a text channel the bot is currently in.
- #message_delete(attributes = {}, &block) ⇒ Object
- #message_edit(attributes = {}, &block) ⇒ Object
-
#parse_mention(mention) ⇒ User
Gets the user from a mention of the user.
- #playing(attributes = {}, &block) ⇒ Object
- #pm(attributes = {}, &block) ⇒ Object (also: #private_message)
- #presence(attributes = {}, &block) ⇒ Object
-
#private_channel(id) ⇒ Channel
Creates a private channel for the given user ID, or if one exists already, returns that one.
- #ready(attributes = {}, &block) ⇒ Object
- #remove_handler(handler) ⇒ Object
-
#resolve_invite_code(invite) ⇒ String
Gets the code for an invite.
-
#run(async = false) ⇒ Object
Runs the bot, which logs into Discord and connects the WebSocket.
- #run_async ⇒ Object
-
#send_file(channel_id, file) ⇒ Object
Sends a file to a channel.
-
#send_message(channel_id, content) ⇒ Message
Sends a text message to a channel given its ID and the message's content.
-
#server(id) ⇒ Server?
Gets a server by its ID.
- #server_create(attributes = {}, &block) ⇒ Object
- #server_delete(attributes = {}, &block) ⇒ Object
- #server_update(attributes = {}, &block) ⇒ Object
-
#stop ⇒ Object
Kills the websocket thread, stopping all connections to Discord.
-
#suppress_ready_debug ⇒ Object
Prevents the READY packet from being printed regardless of debug mode.
-
#sync ⇒ Object
Prevents all further execution until the websocket thread stops (e. g. through a closed connection).
-
#token ⇒ String
The Discord API token received when logging in.
- #typing(attributes = {}, &block) ⇒ Object
-
#user(id) ⇒ User?
Gets a user by its ID.
- #user_ban(attributes = {}, &block) ⇒ Object
- #user_unban(attributes = {}, &block) ⇒ Object
-
#voice_connect(chan, encrypted = true) ⇒ Voice::VoiceBot
Connects to a voice channel, initializes network connections and returns the Voice::VoiceBot over which audio data can then be sent.
-
#voice_state_update(attributes = {}, &block) ⇒ Object
Handle a change to a voice state.
Methods included from Events
Constructor Details
#initialize(email, password, debug = false) ⇒ Bot
Makes a new bot with the given email and password. It will be ready to be added event handlers to and can eventually be run with #run.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/discordrb/bot.rb', line 70 def initialize(email, password, debug = false) # Make sure people replace the login details in the example files... if email.end_with? 'example.com' puts 'You have to replace the login details in the example files with your own!' exit end LOGGER.debug = debug @should_parse_self = false @email = email @password = password @name = '' debug('Creating token cache') @token_cache = Discordrb::TokenCache.new debug('Token cache created successfully') @token = login @event_handlers = {} @channels = {} @users = {} @awaits = {} @event_threads = [] @current_thread = 0 end |
Instance Attribute Details
#bot_user ⇒ User (readonly)
The user that represents the bot itself. This version will always be identical to the user determined by #user called with the bot's ID.
37 38 39 |
# File 'lib/discordrb/bot.rb', line 37 def bot_user @bot_user end |
#event_threads ⇒ Array<Thread> (readonly)
The list of currently running threads used to parse and call events.
The threads will have a local variable :discordrb_name
in the format of et-1234
, where
"et" stands for "event thread" and the number is a continually incrementing number representing
how many events were executed before.
52 53 54 |
# File 'lib/discordrb/bot.rb', line 52 def event_threads @event_threads end |
#name ⇒ Object
The bot's name which discordrb sends to Discord when making any request, so Discord can identify bots with the same codebase. Not required but I recommend setting it anyway.
64 65 66 |
# File 'lib/discordrb/bot.rb', line 64 def name @name end |
#profile ⇒ Profile (readonly)
The bot's user profile. This special user object can be used to edit user data like the current username (see Profile#username=).
57 58 59 |
# File 'lib/discordrb/bot.rb', line 57 def profile @profile end |
#servers ⇒ Array<Server> (readonly)
The list of servers the bot is currently in.
45 46 47 |
# File 'lib/discordrb/bot.rb', line 45 def servers @servers end |
#should_parse_self ⇒ Object
Whether or not the bot should parse its own messages. Off by default.
60 61 62 |
# File 'lib/discordrb/bot.rb', line 60 def should_parse_self @should_parse_self end |
#users ⇒ Array<User> (readonly)
The list of users the bot shares a server with.
41 42 43 |
# File 'lib/discordrb/bot.rb', line 41 def users @users end |
#voice ⇒ Object (readonly)
Returns the value of attribute voice.
220 221 222 |
# File 'lib/discordrb/bot.rb', line 220 def voice @voice end |
Instance Method Details
#add_await(key, type, attributes = {}) {|event| ... } ⇒ Await
Add an await the bot should listen to. For information on awaits, see Await.
386 387 388 389 390 |
# File 'lib/discordrb/bot.rb', line 386 def add_await(key, type, attributes = {}, &block) fail "You can't await an AwaitEvent!" if type == Discordrb::Events::AwaitEvent await = Await.new(self, key, type, attributes, block) @awaits[key] = await end |
#add_handler(handler) ⇒ Object Also known as: <<
603 604 605 606 |
# File 'lib/discordrb/bot.rb', line 603 def add_handler(handler) clazz = event_class(handler.class) @event_handlers[clazz] << handler end |
#await(attributes = {}) {|event| ... } ⇒ AwaitEventHandler
This event is raised when an Await is triggered. It provides an easy way to execute code on an await without having to rely on the await's block.
588 589 590 |
# File 'lib/discordrb/bot.rb', line 588 def await(attributes = {}, &block) register_event(AwaitEvent, attributes, block) end |
#channel(id) ⇒ Channel
Gets a channel given its ID. This queries the internal channel cache, and if the channel doesn't exist in there, it will get the data from Discord.
165 166 167 168 169 170 171 172 173 |
# File 'lib/discordrb/bot.rb', line 165 def channel(id) id = id.resolve_id debug("Obtaining data for channel with id #{id}") return @channels[id] if @channels[id] response = API.channel(token, id) channel = Channel.new(JSON.parse(response), self) @channels[id] = channel end |
#channel_create(attributes = {}, &block) ⇒ Object
Handle channel creation Attributes:
- type: Channel type ('text' or 'voice')
- name: Channel name
515 516 517 |
# File 'lib/discordrb/bot.rb', line 515 def channel_create(attributes = {}, &block) register_event(ChannelCreateEvent, attributes, block) end |
#channel_delete(attributes = {}, &block) ⇒ Object
Handle channel deletion Attributes:
- type: Channel type ('text' or 'voice')
- name: Channel name
531 532 533 |
# File 'lib/discordrb/bot.rb', line 531 def channel_delete(attributes = {}, &block) register_event(ChannelDeleteEvent, attributes, block) end |
#channel_update(attributes = {}, &block) ⇒ Object
Handle channel update Attributes:
- type: Channel type ('text' or 'voice')
- name: Channel name
523 524 525 |
# File 'lib/discordrb/bot.rb', line 523 def channel_update(attributes = {}, &block) register_event(ChannelUpdateEvent, attributes, block) end |
#create_server(name, region = :london) ⇒ Server
Discord's API doesn't directly return the server when creating it, so this method waits until the data has been received via the websocket. This may make the execution take a while.
Creates a server on Discord with a specified name and a region.
406 407 408 409 410 411 412 413 |
# File 'lib/discordrb/bot.rb', line 406 def create_server(name, region = :london) response = API.create_server(token, name, region) id = JSON.parse(response)['id'].to_i sleep 0.1 until @servers[id] server = @servers[id] debug "Successfully created server #{server.id} with name #{server.name}" server end |
#debug(message, important = false) ⇒ Object
608 609 610 |
# File 'lib/discordrb/bot.rb', line 608 def debug(, important = false) LOGGER.debug(, important) end |
#debug=(new_debug) ⇒ Object
Sets debug mode. If debug mode is on, many things will be outputted to STDOUT.
443 444 445 |
# File 'lib/discordrb/bot.rb', line 443 def debug=(new_debug) LOGGER.debug = new_debug end |
#delete_invite(code) ⇒ Object
Revokes an invite to a server. Will fail unless you have the Manage Server permission. It is recommended that you use Invite#delete instead.
264 265 266 267 |
# File 'lib/discordrb/bot.rb', line 264 def delete_invite(code) invite = resolve_invite_code(code) API.delete_invite(token, invite) end |
#disconnected(attributes = {}, &block) ⇒ Object
483 484 485 |
# File 'lib/discordrb/bot.rb', line 483 def disconnected(attributes = {}, &block) register_event(DisconnectEvent, attributes, block) end |
#find(channel_name, server_name = nil, threshold = 0) ⇒ Array<Channel>
Finds a channel given its name and optionally the name of the server it is in. If the threshold is not 0, it will use a Levenshtein distance function to find the channel in a fuzzy way, which allows slight misspellings.
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/discordrb/bot.rb', line 295 def find(channel_name, server_name = nil, threshold = 0) begin require 'levenshtein' if threshold > 0 levenshtein_available = true rescue LoadError; levenshtein_available = false; end results = [] @servers.values.each do |server| server.channels.each do |channel| if threshold > 0 fail LoadError, 'Levenshtein distance unavailable! Either set threshold to 0 or install the `levenshtein-ffi` gem' unless levenshtein_available distance = Levenshtein.distance(channel.name, channel_name) distance += Levenshtein.distance(server_name || server.name, server.name) next if distance > threshold else distance = 0 next if channel.name != channel_name || (server_name || server.name) != server.name end # Make a singleton accessor "distance" channel.instance_variable_set(:@distance, distance) class << channel attr_reader :distance end results << channel end end results end |
#find_user(username, threshold = 0) ⇒ Array<User>
Finds a user given its username. This allows fuzzy finding using Levenshtein distances, see #find
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/discordrb/bot.rb', line 332 def find_user(username, threshold = 0) begin require 'levenshtein' if threshold > 0 levenshtein_available = true rescue LoadError; levenshtein_available = false; end results = [] @users.values.each do |user| if threshold > 0 fail LoadError, 'Levenshtein distance unavailable! Either set threshold to 0 or install the `levenshtein-ffi` gem' unless levenshtein_available distance = Levenshtein.distance(user.username, username) next if distance > threshold else distance = 0 next if user.username != username end # Make a singleton accessor "distance" user.instance_variable_set(:@distance, distance) class << user attr_reader :distance end results << user end results end |
#game=(name) ⇒ String
Sets the currently playing game to the specified game.
427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'lib/discordrb/bot.rb', line 427 def game=(name) @game = name data = { op: 3, d: { idle_since: nil, game: name ? { name: name } : nil } } @ws.send(data.to_json) name end |
#handler_class(event_class) ⇒ Object
616 617 618 |
# File 'lib/discordrb/bot.rb', line 616 def handler_class(event_class) class_from_string(event_class.to_s + 'Handler') end |
#invite(invite) ⇒ Invite
Gets information about an invite.
208 209 210 211 |
# File 'lib/discordrb/bot.rb', line 208 def invite(invite) code = resolve_invite_code(invite) Invite.new(JSON.parse(API.resolve_invite(token, code)), self) end |
#join(invite) ⇒ Object
Makes the bot join an invite to a server.
215 216 217 218 |
# File 'lib/discordrb/bot.rb', line 215 def join(invite) resolved = invite(invite).code API.join_server(token, resolved) end |
#log_exception(e) ⇒ Object
612 613 614 |
# File 'lib/discordrb/bot.rb', line 612 def log_exception(e) LOGGER.log_exception(e) end |
#member_join(attributes = {}, &block) ⇒ Object
548 549 550 |
# File 'lib/discordrb/bot.rb', line 548 def member_join(attributes = {}, &block) register_event(GuildMemberAddEvent, attributes, block) end |
#member_leave(attributes = {}, &block) ⇒ Object
556 557 558 |
# File 'lib/discordrb/bot.rb', line 556 def member_leave(attributes = {}, &block) register_event(GuildMemberDeleteEvent, attributes, block) end |
#member_update(attributes = {}, &block) ⇒ Object
552 553 554 |
# File 'lib/discordrb/bot.rb', line 552 def member_update(attributes = {}, &block) register_event(GuildMemberUpdateEvent, attributes, block) end |
#mention(attributes = {}, &block) ⇒ Object
507 508 509 |
# File 'lib/discordrb/bot.rb', line 507 def mention(attributes = {}, &block) register_event(MentionEvent, attributes, block) end |
#message(attributes = {}) {|event| ... } ⇒ MessageEventHandler
This event is raised when a message is sent to a text channel the bot is currently in.
475 476 477 |
# File 'lib/discordrb/bot.rb', line 475 def (attributes = {}, &block) register_event(MessageEvent, attributes, block) end |
#message_delete(attributes = {}, &block) ⇒ Object
495 496 497 |
# File 'lib/discordrb/bot.rb', line 495 def (attributes = {}, &block) register_event(MessageDeleteEvent, attributes, block) end |
#message_edit(attributes = {}, &block) ⇒ Object
491 492 493 |
# File 'lib/discordrb/bot.rb', line 491 def (attributes = {}, &block) register_event(MessageEditEvent, attributes, block) end |
#parse_mention(mention) ⇒ User
Gets the user from a mention of the user.
418 419 420 421 422 |
# File 'lib/discordrb/bot.rb', line 418 def parse_mention(mention) # Mention format: <@id> return nil unless /<@(?<id>\d+)>?/ =~ mention user(id.to_i) end |
#playing(attributes = {}, &block) ⇒ Object
503 504 505 |
# File 'lib/discordrb/bot.rb', line 503 def (attributes = {}, &block) register_event(PlayingEvent, attributes, block) end |
#pm(attributes = {}, &block) ⇒ Object Also known as: private_message
592 593 594 |
# File 'lib/discordrb/bot.rb', line 592 def pm(attributes = {}, &block) register_event(PrivateMessageEvent, attributes, block) end |
#presence(attributes = {}, &block) ⇒ Object
499 500 501 |
# File 'lib/discordrb/bot.rb', line 499 def presence(attributes = {}, &block) register_event(PresenceEvent, attributes, block) end |
#private_channel(id) ⇒ Channel
Creates a private channel for the given user ID, or if one exists already, returns that one. It is recommended that you use User#pm instead, as this is mainly for internal use. However, usage of this method may be unavoidable if only the user ID is known.
180 181 182 183 184 185 186 187 188 |
# File 'lib/discordrb/bot.rb', line 180 def private_channel(id) id = id.resolve_id debug("Creating private channel with user id #{id}") return @private_channels[id] if @private_channels[id] response = API.create_private(token, @bot_user.id, id) channel = Channel.new(JSON.parse(response), self) @private_channels[id] = channel end |
#ready(attributes = {}, &block) ⇒ Object
479 480 481 |
# File 'lib/discordrb/bot.rb', line 479 def ready(attributes = {}, &block) register_event(ReadyEvent, attributes, block) end |
#remove_handler(handler) ⇒ Object
598 599 600 601 |
# File 'lib/discordrb/bot.rb', line 598 def remove_handler(handler) clazz = event_class(handler.class) @event_handlers[clazz].delete(handler) end |
#resolve_invite_code(invite) ⇒ String
Gets the code for an invite.
199 200 201 202 203 |
# File 'lib/discordrb/bot.rb', line 199 def resolve_invite_code(invite) invite = invite.code if invite.is_a? Discordrb::Invite invite = invite[invite.rindex('/') + 1..-1] if invite.start_with?('http', 'discord.gg') invite end |
#run(async = false) ⇒ Object
Runs the bot, which logs into Discord and connects the WebSocket. This prevents all further execution unless it is executed with async
= :async
.
115 116 117 118 119 120 121 |
# File 'lib/discordrb/bot.rb', line 115 def run(async = false) run_async return if async debug('Oh wait! Not exiting yet as run was run synchronously.') sync end |
#run_async ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/discordrb/bot.rb', line 123 def run_async # Handle heartbeats @heartbeat_interval = 1 @heartbeat_active = false @heartbeat_thread = Thread.new do Thread.current[:discordrb_name] = 'heartbeat' loop do sleep @heartbeat_interval send_heartbeat if @heartbeat_active end end @ws_thread = Thread.new do Thread.current[:discordrb_name] = 'websocket' loop do websocket_connect debug('Disconnected! Attempting to reconnect in 5 seconds.') sleep 5 @token = login end end debug('WS thread created! Now waiting for confirmation that everything worked') @ws_success = false sleep(0.5) until @ws_success debug('Confirmation received! Exiting run.') end |
#send_file(channel_id, file) ⇒ Object
This executes in a blocking way, so if you're sending long files, be wary of delays.
Sends a file to a channel. If it is an image, it will automatically be embedded.
374 375 376 377 |
# File 'lib/discordrb/bot.rb', line 374 def send_file(channel_id, file) response = API.send_file(token, channel_id, file) Message.new(JSON.parse(response), self) end |
#send_message(channel_id, content) ⇒ Message
Sends a text message to a channel given its ID and the message's content.
363 364 365 366 367 368 |
# File 'lib/discordrb/bot.rb', line 363 def (channel_id, content) debug("Sending message to #{channel_id} with content '#{content}'") response = API.(token, channel_id, content) Message.new(JSON.parse(response), self) end |
#server(id) ⇒ Server?
This can only resolve servers the bot is currently in.
Gets a server by its ID.
282 283 284 285 |
# File 'lib/discordrb/bot.rb', line 282 def server(id) id = id.resolve_id @servers[id] end |
#server_create(attributes = {}, &block) ⇒ Object
568 569 570 |
# File 'lib/discordrb/bot.rb', line 568 def server_create(attributes = {}, &block) register_event(GuildCreateEvent, attributes, block) end |
#server_delete(attributes = {}, &block) ⇒ Object
576 577 578 |
# File 'lib/discordrb/bot.rb', line 576 def server_delete(attributes = {}, &block) register_event(GuildDeleteEvent, attributes, block) end |
#server_update(attributes = {}, &block) ⇒ Object
572 573 574 |
# File 'lib/discordrb/bot.rb', line 572 def server_update(attributes = {}, &block) register_event(GuildUpdateEvent, attributes, block) end |
#stop ⇒ Object
Kills the websocket thread, stopping all connections to Discord.
157 158 159 |
# File 'lib/discordrb/bot.rb', line 157 def stop @ws_thread.kill end |
#suppress_ready_debug ⇒ Object
Prevents the READY packet from being printed regardless of debug mode.
448 449 450 |
# File 'lib/discordrb/bot.rb', line 448 def suppress_ready_debug @prevent_ready = true end |
#sync ⇒ Object
Prevents all further execution until the websocket thread stops (e. g. through a closed connection).
152 153 154 |
# File 'lib/discordrb/bot.rb', line 152 def sync @ws_thread.join end |
#token ⇒ String
The Discord API token received when logging in. Useful to explicitly call API methods.
104 105 106 107 |
# File 'lib/discordrb/bot.rb', line 104 def token API.bot_name = @name @token end |
#typing(attributes = {}, &block) ⇒ Object
487 488 489 |
# File 'lib/discordrb/bot.rb', line 487 def typing(attributes = {}, &block) register_event(TypingEvent, attributes, block) end |
#user(id) ⇒ User?
This can only resolve users known by the bot (i.e. that share a server with the bot).
Gets a user by its ID.
273 274 275 276 |
# File 'lib/discordrb/bot.rb', line 273 def user(id) id = id.resolve_id @users[id] end |
#user_ban(attributes = {}, &block) ⇒ Object
560 561 562 |
# File 'lib/discordrb/bot.rb', line 560 def user_ban(attributes = {}, &block) register_event(UserBanEvent, attributes, block) end |
#user_unban(attributes = {}, &block) ⇒ Object
564 565 566 |
# File 'lib/discordrb/bot.rb', line 564 def user_unban(attributes = {}, &block) register_event(UserUnbanEvent, attributes, block) end |
#voice_connect(chan, encrypted = true) ⇒ Voice::VoiceBot
Connects to a voice channel, initializes network connections and returns the Voice::VoiceBot over which audio data can then be sent. After connecting, the bot can also be accessed using #voice.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/discordrb/bot.rb', line 228 def voice_connect(chan, encrypted = true) if @voice debug('Voice bot exists already! Destroying it') @voice.destroy @voice = nil end chan = channel(chan.resolve_id) @voice_channel = chan @should_encrypt_voice = encrypted debug("Got voice channel: #{@voice_channel}") data = { op: 4, d: { guild_id: @voice_channel.server.id.to_s, channel_id: @voice_channel.id.to_s, self_mute: false, self_deaf: false } } debug("Voice channel init packet is: #{data.to_json}") @should_connect_to_voice = true @ws.send(data.to_json) debug('Voice channel init packet sent! Now waiting.') sleep(0.05) until @voice debug('Voice connect succeeded!') @voice end |
#voice_state_update(attributes = {}, &block) ⇒ Object
Handle a change to a voice state. This includes joining a voice channel or changing mute or deaf state. Attributes:
- from: User whose voice state changed
- mute: server mute status
- deaf: server deaf status
- self_mute: self mute status
- self_deaf: self deaf status
- channel: channel the user joined
544 545 546 |
# File 'lib/discordrb/bot.rb', line 544 def voice_state_update(attributes = {}, &block) register_event(VoiceStateUpdateEvent, attributes, block) end |