Class: Vox::Gateway::Client

Inherits:
Object
  • Object
show all
Includes:
EventEmitter
Defined in:
lib/vox/gateway/client.rb

Overview

A client for receiving and writing data from the gateway. The client uses an emitter pattern for emitting and registering events.

Examples:

client.on(:MESSAGE_CREATE) do |payload|
  puts "Hello!" if payload[:content] == "hello"
end

Defined Under Namespace

Classes: Session

Constant Summary collapse

GATEWAY_VERSION =

The gateway version to request.

'8'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url:, token:, port: nil, encoding: :json, compress: true, shard: [0, 1], properties: DEFAULT_PROPERTIES, large_threshold: nil, presence: nil, intents: nil) ⇒ Client

Returns a new instance of Client.

Parameters:

  • url (String)

    The url to use when connecting to the websocket. This can be retrieved from the API with HTTP::Routes::Gateway#get_gateway_bot.

  • token (String)

    The token to use for authorization.

  • port (Integer) (defaults to: nil)

    The port to use when connecting. If ‘nil`, it will be inferred from the URL scheme (80 for `ws`, and 443 for `wss`).

  • encoding (:json) (defaults to: :json)

    This only accepts ‘json` currently, but may support `:etf` in future versions.

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

    Whether to use ‘zlib-stream` compression.

  • shard (Array<Integer>) (defaults to: [0, 1])

    An array in the format ‘[ShardNumber, TotalShards]`.

  • large_threshold (Integer) (defaults to: nil)
  • presence (Object) (defaults to: nil)
  • intents (Integer) (defaults to: nil)

Raises:

  • (ArgumentError)


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/vox/gateway/client.rb', line 62

def initialize(url:, token:, port: nil, encoding: :json, compress: true, shard: [0, 1],
               properties: DEFAULT_PROPERTIES, large_threshold: nil, presence: nil, intents: nil)
  uri = create_gateway_uri(url, port: port, encoding: encoding, compress: compress)

  @encoding = encoding
  raise ArgumentError, 'Invalid gateway encoding' unless %i[json etf].include? @encoding

  if @encoding == :etf
    begin
      require 'vox/etf'
    rescue LoadError
      Logging.logger[self].error { 'ETF parsing lib not found. Please install vox-etf to use ETF encoding.' }
      raise Vox::Error.new('ETF lib not found')
    end
  end

  @websocket = WebSocket.new(uri.to_s, port: uri.port, compression: compress)
  @identify_opts = {
    token: token, properties: properties, shard: shard,
    large_threshold: large_threshold, presence: presence, intents: intents
  }.compact
  @session = Session.new
  @should_reconnect = Queue.new
  setup_handlers
end

Instance Attribute Details

#sessionSession (readonly)

Returns The connection’s session information.

Returns:

  • (Session)

    The connection’s session information.



49
50
51
# File 'lib/vox/gateway/client.rb', line 49

def session
  @session
end

Instance Method Details

#close(reason = nil, code = 1000, reconnect: false) ⇒ Object

Close the websocket.

Parameters:

  • code (Integer) (defaults to: 1000)

    The close code.

  • reason (String) (defaults to: nil)

    The reason for closing.



109
110
111
112
113
# File 'lib/vox/gateway/client.rb', line 109

def close(reason = nil, code = 1000, reconnect: false)
  @ws_thread.kill unless reconnect
  @websocket.close(reason, code)
  @websocket.thread.join unless reconnect
end

#connect(async: false) ⇒ Object

Connect the websocket to the gateway.



95
96
97
98
99
100
101
102
103
104
# File 'lib/vox/gateway/client.rb', line 95

def connect(async: false)
  @ws_thread = Thread.new do
    loop do
      @websocket.connect
      @websocket.thread.join
      break unless @should_reconnect.shift
    end
  end
  async ? @ws_thread : @ws_thread.join
end

#on(event, &block) ⇒ Object

Register an event handler for a GATEWAY event, or DISPATCH event. When registering an event corresponding to an opcode, the full payload is yielded. When registering a DISPATCH type, only the data portion of the payload is provided.



# File 'lib/vox/gateway/client.rb', line 88

#presence_update(status:, afk: false, game: nil, since: nil) ⇒ Object

Update the bot’s status.

Parameters:

  • status (String)

    The user’s new status.

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

    Whether or not the client is AFK.

  • game (Hash<Symbol, Object>, nil) (defaults to: nil)
  • since (Integer, nil) (defaults to: nil)

    Unix time (in milliseconds) of when the client went idle.



163
164
165
166
# File 'lib/vox/gateway/client.rb', line 163

def presence_update(status:, afk: false, game: nil, since: nil)
  opts = { status: status, afk: afk, game: game, since: since }.compact
  send_packet(OPCODES[:PRESENCE_UPDATE], opts)
end

#request_guild_members(guild_id, query: nil, limit: 0, presences: nil, user_ids: nil, nonce: nil) ⇒ Object

Request a guild member chunk, used to build a member cache.

Parameters:

  • guild_id (String, Integer)
  • query (defaults to: nil)
  • limit (Integer) (defaults to: 0)
  • presences (defaults to: nil)
  • user_ids (Array<String, Integer>) (defaults to: nil)
  • nonce (String, Integer) (defaults to: nil)


134
135
136
137
138
139
140
141
142
# File 'lib/vox/gateway/client.rb', line 134

def request_guild_members(guild_id, query: nil, limit: 0, presences: nil,
                          user_ids: nil, nonce: nil)
  opts = {
    guild_id: guild_id, query: query, limit: limit, presences: presences,
    user_ids: user_ids, nonce: nonce
  }.compact

  send_packet(OPCODES[:REQUEST_GUILD_MEMBERS], opts)
end

#send_packet(op_code, data) ⇒ Object

Send a packet with the correct encoding. Only supports JSON currently.

Parameters:

  • op_code (Integer)
  • data (Hash)


118
119
120
121
122
123
124
125
# File 'lib/vox/gateway/client.rb', line 118

def send_packet(op_code, data)
  LOGGER.debug { "Sending #{op_code.is_a?(Symbol) ? op_code : OPCODES[op_code]} #{data || 'nil'}" }
  if @encoding == :etf
    send_etf_packet(op_code, data)
  else
    send_json_packet(op_code, data)
  end
end

#voice_state_update(guild_id, channel_id, self_mute: false, self_deaf: false) ⇒ Object

Send a voice state update, used for establishing voice connections.

Parameters:

  • guild_id (String, Integer)
  • channel_id (String, Integer)
  • self_mute (true, false) (defaults to: false)
  • self_deaf (true, false) (defaults to: false)


149
150
151
152
153
154
155
156
# File 'lib/vox/gateway/client.rb', line 149

def voice_state_update(guild_id, channel_id, self_mute: false, self_deaf: false)
  opts = {
    guild_id: guild_id, channel_id: channel_id, self_mute: self_mute,
    self_deaf: self_deaf
  }.compact

  send_packet(OPCODES[:VOICE_STATE_UPDATE], opts)
end