This is Moneypot's chat server which you can use to integrate a websocket chatbox on your site.
The chat-server uses socket.io, so you'll want to use a socket.io client to connect.
Our chat-server is running on https://a-chat-server.herokuapp.com
.
Here's how to connect:
<script src="vendor/javascript/socket.io-client.js"></script>
<script type="text/javascript">
var socket = io('https://a-chat-server.herokuapp.com');
socket.emit('connect', function() {
console.log('socket connected');
});
socket.emit('disconnect', function() {
console.log('socket disconnected');
});
</script>
When you connect to that chat server, immediately send an "auth" event with this payload:
{
app_id: Integer, (Required)
hashed_token: String (Optional)
}
For example:
socket.emit('connect', function() {
socket.emit('auth', authPayload, function(err, data) {
if (err) ...
})
});
The chat server will automatically subscribe you to the app's lobby channel.
hashed_token
is sha256
of either the confidential_token
or access_token)
(depending if the app is using confidential flow or implicit flow). In the case of confidential_flow, the hashed_token
should be computed by the server, and sent to the client, which will use it for login. If the hashed_token
is valid, it represents a logged-in user. If missing or if the hashed_token is invalid, then the socket will only be able to read new messages and will not be able to create any messages.
You must also provide a callback with signature fn(err, data)
.
If auth is successful, the data
response will provide you with the necessary information to sync your chatbox with the server.
data
looks like this:
{
// User of the hashed_token you provided
// Only exists if hashed_token was provided and valid
user: {
id: 69,
uname: 'donald',
role: 'admin' | 'mod' | 'owner'
},
// The state of the app's lobby channel
// Always present
room: {
// Object of users in the channel, keyed by their case-sensitive usernames
// Always present
users: {
<UNAME>: <OBJECT>,
foo: { id: 42, uname: 'foo', role: 'admin' | 'mod' | 'owner' }
},
// Array of messages in the channel (oldest to newest)
// - id: Integer, unique incrementing id of message
// - user: Object
// - text: String
// Always present
history: [
{
id: 2,
user: { uname: 'foo', role: 'owner' },
text: 'Hello, world!'
},
...
]
// Object of muted unames, keyed by lowercase unames
// - mins: Integer of mute duration in minutes
// - expires_at: String of ISO-format timestamp of when the mute ends
// e.g. var date = Date.parse(timestamp)
// TODO: Only present if auth'd user is owner|admin|mod
muteList: {
'foo': { uname: 'foo', mins: 30, expires_at: '2015-05-07T21:07:40.322Z' }
}
}
}
auth
callback error constants:
"INTERNAL_ERROR"
: There was a problem talking to Moneypot's API.- There are no other possible errors. If you don't send an
app_id
, then you'll get aclient_error
event and you need to fix your client. If you send an invalidhashed_token
, then you simply get the auth payload back without a user key.
Important: When displaying data/messages received from the chat server, ensure cross-site scripting like <script>alert("hello")</script>
is impossible by escaping it.
user_joined
: Sent when a user joins the chat. Payload is an object:{ uname: String, role: 'admin' | 'mod' | 'owner' }
.user_left
: Sent when a user leaves the chat. Payload is an object:{ uname: String, role: 'admin' | 'mod' | 'owner' }
.user_muted
: Sent when a user is muted. Payload is an object:{ uname: String, mins: Integer (duration in minutes), expires_at: String (ISO timestamp) }
.user_unmuted
: Sent when a user is unmuted. Payload is an object:{ uname: String }
.new_message
: Sent when the chat receives a new message. Payload is an object:{ user: { uname: String, role: String }, id: Integer, text: String }
.client_error
: Payload is a String. This event is emitted with a human-/developer-friendly error message any time your client disobeys the API. In other words, a client that complies with the chat-server API should never receive this event, but you should listen for it to help catch any client errors and bugs.system_message
: Payload is string. Sent as server feedback to the user. For example, if they type in/mute foo 10
, the server will send this event with the message"foo was muted for 10 min"
.
text
is a string. Must be 1-350 characters. You shouldtext.trim()
before sending.
socket.emit('new_message', text, function(err) {
if (err) {
...
}
});
If err
is present, it will be a string. Possible constants:
"USER_REQUIRED"
"INTERNAL_ERROR"
The server will send feedback to the user via a system_message
event with a string payload. Examples: "User not in mutelist"
, "User muted"
. These are intended to be displayed in the chatbox.
Here's a fully working chat-server client that may help you get started.
<script type="text/javascript">
var config = {
chat_uri: 'https://a-chat-server.herokuapp.com',
hashed_token: '5fef422fb4e79a1785868b87abb3d3932ea5621c23ab2e9b13ee2167f12542cb', // See section above about hashed tokens
app_id: 2
};
var socket = io(config.chat_uri);
socket.on('connect', function() {
console.log('[socket] Connected');
socket.on('disconnect', function() {
console.log('[socket] Disconnected');
});
socket.on('system_message', function(text) {
console.log('[socket] Received system message:', text);
});
// message is { text: String, user: { role: String, uname: String} }
socket.on('new_message', function(message) {
console.log('[socket] Received chat message:', message);
});
socket.on('user_muted', function(data) {
console.log('[socket] User muted:', data);
});
socket.on('user_unmuted', function(data) {
console.log('[socket] User unmuted:', data);
});
socket.on('user_joined', function(data) {
console.log('[socket] User joined:', data);
});
socket.on('user_left', function(data) {
console.log('[socket] User left:', data);
});
// Received when your client doesn't comply with chat-server api
socket.on('client_error', function(text) {
console.warn('[socket] Client error:', text);
});
// Once we connect to chat server, we send an auth message to join
// this app's lobby channel.
var authPayload = { app_id: config.app_id, hashed_token: config.hashed_token};
socket.emit('auth', authPayload, function(err, data) {
if (err) {
console.log('[socket] Auth failure:', err);
return;
}
console.log('[socket] Auth success:', data);
// If successful auth and if a user is connected to chat, then
// send a message:
if (data.user) {
socket.emit('new_message', 'Hello, world!', function(err) {
console.warn('[socket] err when sending message:', err);
return
});
console.log('[socket] Successfully sent message to server');
}
});
});
</script>