A unified interface for Chats around the world.
- Twitch (Read/Write)
- YouTube (Read/Write)
- Facebook Live (Read/Write)
It is recommend to apply the following styles to emotes across all services.
.emoticon {
vertical-align: middle;
display: inline-block;
}
This interface connects to Twitch's chat socket server. New messages arrive instantly as they are sent on Twitch.
// Twitch.
import chinterface from 'chinterface';
async function twitch() {
const twitch = chinterface.service('twitch');
try {
// Set the default config values.
await twitch.setConfig({
// Main configuration
clientId: 'as545trdsFdgghNXoyit83nguf11gpOx', // REQUIRED. Your Twitch Application Client ID.
channel: 'oyed', // REQUIRED. If you do not know the channel, pass through accessToken and make a request to loadUser().
userId: 123456, // Optional; REQUIRED to fetch badges. If you do not know the user ID, pass through accessToken and make a request to loadUser().
// Settings
reconnect: false, // Default: true [auto reconnect if connection is lost]
parseEmoticon: false, // Default: true [convert emoticons to images]
formatMessages: false, // Default: true [process message and convert emoticons; body will be null if false]
// Optional; REQUIRED for sending/writing messages
username: 'oyed', // The user's Twitch username. This is ONLY used to authenticate to send messages.
accessToken: 'as545trdsFdgghNXoyit83nguf11gpOx', // The user's Twitch API access token. This is ONLY used to authenticate to send messages.
});
// If you do not know the username, channel or userId, make a request to loadUser(). It will set these values for you.
await twitch.loadUser();
// Connect to the socket server.
await twitch.connect();
// To receive and listen for new, formatted messages.
twitch.on('message', (data) => {
/**
* `data` will always return the following structure:
*
* {string} id - The chat message ID; generated by Twitch.
* {string} username
* {string} body - The processed message, with <img> tags for emotes.
* {string} raw - The unprocessed message, direct from the service.
* {number} timestamp - The time in milliseconds.
* {Object} extra - Service-specific information.
*/
console.log('New message', data);
});
// To send a message.
twitch.send('test message');
// Disconnect from the socket server.
await twitch.disconnect();
} catch (e) {
console.log(e);
}
}
Chinterface provides a set of unique events and functions that assist in the display and handling of messages for Twitch.
In cases where you do not know the userId
, channel
or username
, you can use the loadUser()
function to set the config for you.
Requires clientId
and accessToken
. This function will NOT overwrite any previously set properties.
await twitch.loadUser();
Chinterface provides a clean wrapper to directly access TMI Events. This is useful when you want to listen to clearchat, timeouts or bans.
See here for a list of events: https://docs.tmijs.org/v1.2.1/Events.html
twitch.clientOn('timeout', (channel, username, reason, duration) => {
// Remove all messages for the given channel and username
});
twitch.clientOn('ban', (channel, username, reason) => {
// Remove all messages for the given channel and username
]);
twitch.clientOn('clearchat', channel => {
// Remove all messages for the given channel
});
It's common to output a user's associated badges when displaying Twitch messages. You may use the getBadges()
function to return a list of badges and respective URLs for the connected channel.
Requires clientId
and userId
. If you do not know the user ID, make a request to loadUser()
first.
// Get all badges for all connected Twitch channels
const badges = await twitch.getBadges();
This interface polls the YouTube API every interval
milliseconds. New messages arrive periodically.
REMEMBER. YouTube auth tokens expire every 1 hour. You MUST listen for the refresh-token
event and update the
config value when you encounter this event.
// YouTube
import chinterface from 'chinterface';
async function youtube() {
const youtube = chinterface.service('youtube');
try {
// Set the default config values.
await youtube.setConfig({
// Main configuration
accessToken: '', // REQUIRED.
liveChatId: 'EiEKGFVDVW1mV2tPSWxoek1fZDA2cXpvc2lBQRIFL2xpdmU', // REQUIRED. If unknown, set accessToken and make a request to loadChatId() before connecting.
// Settings
parseEmoticon: false, // Default: true [convert emoticons to images]
parseUrl: false, // Default: true [convert URLs to anchor tags]
formatMessages: false, // Default: true [process message and convert emoticons; body will be null if false]
interval: 7000, // Default: 5000 [time in ms to check for next set of messages]
maxResults: 500, // Default: 200 [the number of messages to return each check]
profileImageSize: 32, // Default: 64 [size in pixels to return profile images at]
});
// If you do not know the liveChatId, set accessToken and make a request to this function.
// If you already know the liveChatId, this function is NOT required.
await youtube.loadChatId();
// Start fetching new messages.
youtube.connect();
// To receive and listen for new, formatted messages.
youtube.on('message', (data) => {
/**
* `data` will always return the following structure:
*
* {string} id - The chat message ID; generated by YouTube.
* {string} username
* {string} body - The processed message.
* {string} raw - The unprocessed message, direct from the service.
* {number} timestamp - The time in milliseconds.
* {Object} extra - Service-specific information.
*/
console.log('New message', data);
});
// To send a message.
youtube.send('test message');
// Listen for the refresh token event.
youtube.on('refresh-token', () => {
// Your refresh token logic here...
const accessToken = 'new';
youtube.setConfig({
accessToken,
});
// Start fetching messages again.
// If preferred, you can call youtube.fetchMessages() directly to avoid the connect logic.
youtube.connect();
});
// Listen out for any API errors so to react accordingly.
youtube.on('error', (error) => {
switch (error.errors[0].reason) {
case 'liveChatDisabled':
// lets just destroy the interface
break;
case 'liveChatEnded':
// lets disconnect
break;
}
});
// Disconnect from the socket server.
await youtube.disconnect();
} catch (e) {
// This will typically return the error detail as listed here: https://developers.google.com/youtube/v3/live/docs/errors
console.log(e);
}
}
Chinterface provides a set of unique events and functions that assist in the display and handling of messages for YouTube.
In cases where you do not know the liveChatId
, you can use the loadChatId()
function to set the config for you.
Requires accessToken
. This function will NOT overwrite any previously set properties.
await youtube.loadChatId();
The YouTube interface emits a number of different events for actions including message deletion, user banning, chat ending and many more.
This interface will also emit an 'error' event for every 'Error detail' listed here: https://developers.google.com/youtube/v3/live/docs/errors You will receive the error object in the payload.
// An API error occurred
youtube.on('error', (errorDetails) => {
console.log('API error', errorDetails);
});
// The user's token has expired
youtube.on('refresh-token', (errorDetails) => {
console.log('Token expired', errorDetails);
});
// A message is deleted
youtube.on('delete-message', (messageId) => {
console.log('Deleted Message (ID): ', messageId);
});
// A user is banned
youtube.on('user-banned', (data) => {
/**
* `data` will always return the following structure:
*
* {object} bannedUserDetails
* ** {string} channelId - The author's channel ID
* ** {string} channelUrl - The author's channel URL
* ** {string} displayName - The author's username
* ** {string} profileImageUrl - The author's avatar
* {string} banType - The type of ban, permanent or temporary
* {integer} banDurationSeconds - Length of time the ban is in effect for, only present if banType === temporary
*/
console.log('User banned: ', data);
});
// Chat ended
youtube.on('chat-ended', () => {
console.log('Chat has finished.');
youtube.disconnect();
});
// New super chat event
youtube.on('super-chat', (data) => {
/**
* `data` will always return the following structure:
*
* {integer} amountMicros - The amount super chatted
* {string} currency - The currency code that was super chatted
* {string} amountDisplayString - Formatted amount with currency symbol prefixed
* {string} userComment - The comment added by the user super chatting
* {integer} tier - The YouTube defined tier based on the amount super chatted. See: https://support.google.com/youtube/answer/7277005
*/
console.log('Super chat: ', data);
});
This interface connects to a Live Video on Facebook using EventSource(SSE). New messages arrive instantly as they are sent.
// Facebook
import chinterface from 'chinterface';
async function facebook() {
const facebook = chinterface.service('facebook');
try {
// facebook interface automatically identifies the user's details base from the given access token.
// Set the default config values.
facebook.setConfig({
// Settings
reconnect: false, // Default: true [auto reconnect per failed connection]
parseUrl: false, // Default: true [converts url to an anchor element]
commentRate: 'one_hundred_per_second', // Default: one_hundred_per_second [received comment per second]
// REQUIRED
liveVideoId: 1234567890, // REQUIRED. Live Video Id to connect to
accessToken: 'graph api access token', // REQUIRED
});
// Used to identify the message owner if its from the broadcaster
// If you know the user's userId AND/OR username(name), this function is NOT required.
await facebook.loadUser();
// connect to live video using event source
await facebook.connect();
// To receive and listen for new, formatted message.
facebook.on('message', (data) => {
/**
* `data` will always return the following structure:
*
* {string} id - The chat message ID; generated by Twitch.
* {string} username
* {string} body - The processed message, with <img> tags for emotes.
* {string} raw - The unprocessed message, direct from the service.
* {number} timestamp - The time in milliseconds.
* {Object} extra - Service-specific information.
* - {user_id} - int [sender's user id]
* - {picutre} - string [sender's profile image]
* - {broadcaster} - boolean [if message is from the owner]
*/
console.log('New Message', data);
});
// sending, only applicable for page access token
facebook.send('test message');
// Disconnect from the event source
twitch.disconnect();
} catch (e) {
console.log(e);
}
}
For browsers that does not support EventSource(SSE) like IE and Edge, you can use this polyfill or other library you prefer. The same for node, you can either use this polyfill or provide another.
// listen to error events
facebook.on('error', (data) => {
// Information about the error
console.error(data);
});
// listen to reconnection
facebook.on('reconnect', () => {
console.log('Reconnecting...');
});