Class: Discordrb::Bot

Inherits:
Object
  • Object
show all
Includes:
Events
Defined in:
lib/discordrb/bot.rb

Overview

Represents a Discord bot, including servers, users, etc.

Direct Known Subclasses

Commands::CommandBot

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Events

matches_all

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.

Parameters:

  • email (String)

    The email for your (or the bot's) Discord account.

  • password (String)

    The valid password that should be used to log in to the account.

  • debug (Boolean) (defaults to: false)

    Whether or not the bug should run in debug mode, which gives increased console output.



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 = 

  @event_handlers = {}

  @channels = {}
  @users = {}

  @awaits = {}

  @event_threads = []
  @current_thread = 0
end

Instance Attribute Details

#bot_userUser (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.

Returns:

  • (User)

    The bot user.



37
38
39
# File 'lib/discordrb/bot.rb', line 37

def bot_user
  @bot_user
end

#event_threadsArray<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.

Returns:

  • (Array<Thread>)

    The threads.



52
53
54
# File 'lib/discordrb/bot.rb', line 52

def event_threads
  @event_threads
end

#nameObject

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

#profileProfile (readonly)

The bot's user profile. This special user object can be used to edit user data like the current username (see Profile#username=).

Returns:

  • (Profile)

    The bot's profile that can be used to edit data.



57
58
59
# File 'lib/discordrb/bot.rb', line 57

def profile
  @profile
end

#serversArray<Server> (readonly)

The list of servers the bot is currently in.

Returns:

  • (Array<Server>)

    The servers.



45
46
47
# File 'lib/discordrb/bot.rb', line 45

def servers
  @servers
end

#should_parse_selfObject

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

#usersArray<User> (readonly)

The list of users the bot shares a server with.

Returns:

  • (Array<User>)

    The users.



41
42
43
# File 'lib/discordrb/bot.rb', line 41

def users
  @users
end

#voiceObject (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.

Parameters:

  • key (Symbol)

    The key that uniquely identifies the await for Events::AwaitEvents to listen to (see #await).

  • type (Class)

    The event class that should be listened for.

  • attributes (Hash) (defaults to: {})

    The attributes the event should check for. The block will only be executed if all attributes match.

Yields:

  • Is executed when the await is triggered.

Yield Parameters:

  • event (Event)

    The event object that was triggered.

Returns:

  • (Await)

    The await that was created.



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.

Parameters:

  • attributes (Hash) (defaults to: {})

    The event's attributes.

Options Hash (attributes):

  • :key (Symbol)

    Exactly matches the await's key.

  • :type (Class)

    Exactly matches the event's type.

Yields:

  • The block is executed when the event is raised.

Yield Parameters:

  • event (AwaitEvent)

    The event that was raised.

Returns:



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.

Parameters:

  • id (Integer)

    The channel ID for which to search for.

Returns:

  • (Channel)

    The channel identified by the ID.



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

Note:

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.

Parameters:

  • name (String)

    The name the new server should have. Doesn't have to be alphanumeric.

  • region (Symbol) (defaults to: :london)

    The region where the server should be created. Possible regions are:

    • :london
    • :amsterdam
    • :frankfurt
    • :us-east
    • :us-west
    • :singapore
    • :sydney

Returns:

  • (Server)

    The server that was created.



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(message, important = false)
  LOGGER.debug(message, 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.

Parameters:



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.

Parameters:

  • channel_name (String)

    The channel to search for.

  • server_name (String) (defaults to: nil)

    The server to search for, or nil if only the channel should be searched for.

  • threshold (Integer) (defaults to: 0)

    The threshold for the Levenshtein algorithm. The larger the threshold is, the more misspellings will be allowed.

Returns:

  • (Array<Channel>)

    The array of channels that were found. May be empty if none were found.



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

Parameters:

  • username (String)

    The username to look for.

  • threshold (Integer) (defaults to: 0)

    The threshold for the Levenshtein algorithm. The larger the threshold is, the more misspellings will be allowed.

Returns:

  • (Array<User>)

    The array of users that were found. May be empty if none were found.



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.

Parameters:

  • name (String)

    The name of the game to be played.

Returns:

  • (String)

    The game that is being played now.



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.

Parameters:

Returns:

  • (Invite)

    The invite with information about the given invite URL.



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.

Parameters:



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.

Parameters:

  • attributes (Hash) (defaults to: {})

    The event's attributes.

Options Hash (attributes):

  • :start_with (String, Regexp)

    Matches the string the message starts with.

  • :end_with (String, Regexp)

    Matches the string the message ends with.

  • :contains (String, Regexp)

    Matches a string the message contains.

  • :in (String, Integer, Channel)

    Matches the channel the message was sent in.

  • :from (String, Integer, User)

    Matches the user that sent the message.

  • :content (String)

    Exactly matches the entire content of the message.

  • :content (String)

    Exactly matches the entire content of the message.

  • :after (Time)

    Matches a time after the time the message was sent at.

  • :before (Time)

    Matches a time before the time the message was sent at.

  • :private (Boolean)

    Matches whether or not the channel is private.

Yields:

  • The block is executed when the event is raised.

Yield Parameters:

Returns:



475
476
477
# File 'lib/discordrb/bot.rb', line 475

def message(attributes = {}, &block)
  register_event(MessageEvent, attributes, block)
end

#message_delete(attributes = {}, &block) ⇒ Object



495
496
497
# File 'lib/discordrb/bot.rb', line 495

def message_delete(attributes = {}, &block)
  register_event(MessageDeleteEvent, attributes, block)
end

#message_edit(attributes = {}, &block) ⇒ Object



491
492
493
# File 'lib/discordrb/bot.rb', line 491

def message_edit(attributes = {}, &block)
  register_event(MessageEditEvent, attributes, block)
end

#parse_mention(mention) ⇒ User

Gets the user from a mention of the user.

Parameters:

  • mention (String)

    The mention, which should look like <@12314873129>.

Returns:

  • (User)

    The user identified by the mention, or nil if none exists.



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 playing(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.

Parameters:

  • id (Integer)

    The user ID to generate a private channel for.

Returns:

  • (Channel)

    A private channel for that user.



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.

Parameters:

  • invite (String, Invite)

    The invite to get the code for. Possible formats are:

    • An Invite object
    • The code for an invite
    • A fully qualified invite URL (e. g. https://discordapp.com/invite/0A37aN7fasF7n83q)
    • A short invite URL with protocol (e. g. https://discord.gg/0A37aN7fasF7n83q)
    • A short invite URL without protocol (e. g. discord.gg/0A37aN7fasF7n83q)

Returns:

  • (String)

    Only the code for the 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.

Parameters:

  • async (Symbol) (defaults to: false)

    If it is :async, then the bot will allow further execution. It doesn't necessarily have to be that, anything truthy will work, however it is recommended to use :async for code readability reasons. If the bot is run in async mode, make sure to eventually run #sync so the script doesn't stop prematurely.



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_asyncObject



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 = 
    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

Note:

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.

Parameters:

  • channel_id (Integer)

    The ID that identifies the channel to send something to.

  • file (File)

    The file that should be sent.



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.

Parameters:

  • channel_id (Integer)

    The ID that identifies the channel to send something to.

  • content (String)

    The text that should be sent as a message. It is limited to 2000 characters (Discord imposed).

Returns:

  • (Message)

    The message that was sent.



363
364
365
366
367
368
# File 'lib/discordrb/bot.rb', line 363

def send_message(channel_id, content)
  debug("Sending message to #{channel_id} with content '#{content}'")

  response = API.send_message(token, channel_id, content)
  Message.new(JSON.parse(response), self)
end

#server(id) ⇒ Server?

Note:

This can only resolve servers the bot is currently in.

Gets a server by its ID.

Parameters:

  • id (Integer)

    The server ID that should be resolved.

Returns:

  • (Server, nil)

    The server identified by the ID, or nil if it couldn't be found.



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

#stopObject

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_debugObject

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

#syncObject

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

#tokenString

The Discord API token received when logging in. Useful to explicitly call API methods.

Returns:



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?

Note:

This can only resolve users known by the bot (i.e. that share a server with the bot).

Gets a user by its ID.

Parameters:

  • id (Integer)

    The user ID that should be resolved.

Returns:

  • (User, nil)

    The user identified by the ID, or nil if it couldn't be found.



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.

Parameters:

  • chan (Channel)

    The voice channel to connect to.

  • encrypted (true, false) (defaults to: true)

    Whether voice communication should be encrypted using RbNaCl's SecretBox (uses an XSalsa20 stream cipher for encryption and Poly1305 for authentication)

Returns:

  • (Voice::VoiceBot)

    the initialized bot over which audio data can then be sent.



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