Using the SBSChatClient

Table of Contents

Introduction

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.

Dependencies

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

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 = SBSChatClient.new
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
  client.ping
  sleep 60
end

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
end

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.

Messages

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.

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

User Presence

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

Special Events

bind
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.
response
Emitted when a request is completed. The entire Response Hash is provided.
shutdown
Emitted when the client receives a shutdown message from the server. Doesn't provide anything.

Generic Events

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

Examples

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}"
end

Hash Types

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

Message

{
  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
}

Response

{
  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
}

UserList

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

User

{
  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

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.

request

request(type)

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

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)

Validate