Using the SBSChatClient

Table of Contents


SBSChatClient is a Ruby class, provided by sbschatclient.rb, that acts as a basic client gateway to SmileBASIC Source chat. It is an abstraction on the websocket-client-simple gem, which uses event-emitter to provide an event-driven programming approach. For more details see the Chat Interface documentation.


It depends on the following gems:

  • websocket-client-simple
  • htmlentities

As expected, the dependencies of the required gems are included and required as well.


Setup is simple, just drop the sbschatclient.rb script into the same working folder as your project, and add:

require_relative 'sbschatclient'

Programming Usage

SBSChatClient is intended as a basic client gateway for the chat, so it provides the minimum functionality to interact with the chat. This does not mean it isn't pretty easy to use, though.

Get Connected

To log in and connect to the chat with a given user account, do the following:

client =
client.connect(username, password_hash)

username is the user name of the account you wish to use, and password_hash is the MD5 hash of that account's password. Do not send the password itself.

Logging in, authenticating, and binding is all handled for you. When binding is complete, the bind event will be fired, and the error event is fired on the event of any errors during websocket connection (more on this later.)

You will have to run some kind of loop after connecting to keep your client script alive. I suggest you use this to handle the Ping message.

loop do
  sleep 60

Using Events

As mentioned before, this client uses event-emitter. To give you an example of how event-emitter works, see this code:

client.on :event do |args|
   # stuff happens in here

This registers a handler to run every time the event event is emitted. Handlers can be registered to only run the first time the event is fired by using once instead of on. Multiple handlers can be registered to the same event, too.

The events emitted by the client are described below.


These events relate to messages sent to the chat. Even though the SBS chat protocol uses messageLists to send messages to the client, these are not exposed. The messageLists and repeat message IDs are handled internally, and events are propagated for each individual message. Each message event provides a Message Hash. Some messages may fall into more than one event category, so all of those events will propagate.

Emitted for any and all messages received in chat.
Emitted when any "normal" chat message, sent by a user, is received.
Emitted specifically on user messages sent to public tags.
Emitted specifically on user messages sent to PM rooms this client is a member of, or on messages from the PM module.
Emitted when a message sent from a module is received.
Emitted when the client receives a warning from the chat server.
Emitted when any generic system message is received.

User Presence

Emitted when a user joins the chat. Provides a User Hash.
Emitted when a user leaves the chat. Provides a User Hash.
Emitted when the client receives a userList message. Provides a UserList Hash.

Special Events

Emitted when the client completes the bind process, meaning it is ready to interact with chat. Typically this is used to request a UserList. This event provides the extras object on the bind Response.
Emitted when a request is completed. The entire Response Hash is provided.
Emitted when the client receives a shutdown message from the server. Doesn't provide anything.

Generic Events

Emitted when the socket is closed. Doesn't provide anything.
Emitted whenever any error is encountered. Provides an error object.
Emitted when the socket receives anything. This is an unabstracted event and should not be used unless absolutely necessary. Provides a raw WebSocket message.


These events provide a useful model for dealing with the data you receive from the chat. Here's a few examples.

client.on :user_message do |message|
  sender = message[:sender][:username]
  body = message[:message]
  puts "#{sender}: #{body}"

Hash Types

Every event, aside from the generics, provides one of these Hash structures.


  id:         unique ID,
  type:       message type name,
  subtype:    subtype of this message (used by warning/system)
  tag:        tag this message was sent in,
  sender:     User who sent this,
  recipients: Array of UIDs who will see this,
  safe:       true/false,
  time:       UTC timestamp of message,
  encoding:   type of data contained in this message (usually text),
  message:    content of message


  type:   "response",
  id:     unique ID,
  from:   request type this response comes from,
  result: success true/false,
  errors: Array of error message strings,
  extras: extra data associated with this request


  type:  "userList",
  id:    unique ID,
  users: Array of User Hashes for each user online,
  rooms: Array of Room Hashes for each available room


  username: their name as a string,
  uid:      unique user ID,
  stars:    rank as string,
  level:    rank as integer,
  joined:   Unix time this user joined,
  avatar:   URL pointing to this user's avatar,
  active:   true/false whether this user is active,
  banned:   true/false whether this user is chat banned

TODO: Room

Client Methods

The client provides a few additional methods to allow communication with the server.


ping(active = true)

This method sends a Ping message to the chat server, which updates your active status. The Ping message should be sent regularly if you want your presence to be accurate. By default, ping sets your status to active; if you pass false, you will be marked inactive.



This method makes a Request to the server for either a MessageList or a UserList. type is a Symbol, either :message or :user.


send_message(text, tag = "offtopic")

Send a message to the chat server. The tag can be specified to choose a room to send to, but it is "offtopic" by default.

Author: snail_

Created: 2017-12-07 Thu 20:31

Emacs 24.5.1 (Org mode 8.2.10)