Sariska provides a JavaScript API and easy-to-integrate SDKs for web, mobile, front-end, and cloud infrastructure to add real-time features in your applications.
Real-time messaging for in-app chats and instant messaging
Support for various JavaScript frameworks (Vanilla, React, Angular, Vue, Electron, React Native)
Easy installation using NPM or CDN
Socket creation and management
Channel creation, joining, and leaving
Sending messages, poll votes, and message replies
Presence management (track: typing, joining and leaving users)
History management (fetching chat history and specific messages)
Install the Phoenix library by running the following command in your project directory using NPM.
Alternatively, install the Phoenix library by adding the following script to your website's HTML <head> tag for seamless API access.
Establish a WebSocket connection to the Sariska server to join channels, receive events, and send messages.
Close the WebSocket connection to the Sariska server. This will terminate all active channels and prevent further communication with the server.
Channels cannot be created directly; instead, they are created through the socket object by calling socket.channel(topic) with the topic of the channel. The topic is a string that identifies the channel, and it can be any string you like.
Each channel name starts with a prefix that determines the message serialization format and persistence behavior.
chat: Use this prefix for persisting messages to the database. This prefix requires a fixed schema and is ideal for chat applications.
rtc: Use this prefix for scenarios where message persistence is not necessary. This prefix allows sending arbitrary JSON data, making it suitable for events in multiplayer games, IoT applications, and others.
sariska: Use this prefix for performance-critical applications that utilize Flatbuffers as the serialization format and do not require message persistence. This prefix provides zero-copy serialization/deserialization, significantly enhancing performance.
When an error occurs on the channel, the onError callback is triggered. The callback receives the error information in payload, if available.
When the channel is closed, the onClose callback is invoked. This signifies that the communication on the channel has ended and no further data can be exchanged.
To join a channel, call the join() method on the channel object. The join() method returns a promise that resolves when the client has successfully joined the channel. When sending data, you can utilize the .receive() hook to monitor the status of the outgoing push message.
Once you've established a connection to a channel, you can start sending messages to other connected clients. To send a message, use the push() method on the channel object.
Attaching media files to chat messages involves obtaining a presigned URL, uploading the file to the presigned URL, and then sending the file information to the chat server.
To obtain a presigned URL, make a POST request to the API endpoint. The request payload should be empty, and the Authorization header should contain your bearer token.
After obtaining the presigned URL, the file can be uploaded to the URL using the PUT method.
Retrieve the chat history using two methods:
By Subscribing to Events
Subscribe to the archived_message event to receive the last 1000 messages in reverse chronological order.
Subscribe to the archived_message_count event to get the total number of messages in the chat history.
To retrieve a list of messages in the chat history, trigger the archived_message event to obtain the messages. Specify the size parameter to determine the number of messages you wish to fetch, and set the offset parameter as the starting index of the messages and group_by_day to group messages by day.
To receive the total count of messages at any given time, initiate the archived_message_count trigger and subscribe to the corresponding event by listening for archived_message_count.
Using the Messages API
Make a GET request to the API endpoint to fetch the chat history for a specific room.
Fetch Specific Message
Retrieve any specific message from a room. It takes the room ID and message ID as parameters and sends a GET request to the Sariska API to fetch the specified message.
Delete chat history for a specific room.
The Presence object facilitates real-time synchronization of presence information between the server and the client, enabling the detection of user join and leave events.
Create a Presence Instance
To establish presence synchronization, instantiate a Presence object and provide the channel to track presence lifecycle events:
State Synchronization
Utilize the presence.onSync callback to respond to state changes initiated by the server. For instance, to dynamically render the user list upon every list modification, implement the following:
Handle Individual Join and Leave Events
The presence.onJoin and presence.onLeave callbacks allow for handling individual user join and leave events. Here is an instance:
Retrieve Presence Information
The presence.list(by:) method retrieves a list of presence information based on the local metadata state. By default, it returns the entire presence metadata. Alternatively, a listBy function can be provided to filter the metadata for each presence.
For instance, if a user is online from multiple devices, each with a metadata status of "online," but their status is set to "away" on another device, the application might prefer to display the "away" status in the UI.
The following example defines a listBy function that prioritizes the first metadata registered for each user, representing the first tab or device they used to connect:
Send information about a user who is typing. This information can be used to update the chat interface, such as displaying a "user is typing" indicator next to the user's name.
Send User Typing Event
When a user starts typing, the following code sends a typing event to other peers.
Receive User Typing Event
Other peers in the chat can listen for the typing event on the same channel.
For detailed real-time messaging API's, refer to .
For detailed management of chat and room APIs, refer to Sariska .
avatar: The user's avatar URL
email: The user's email address
created_by: The ID of the user who created the room
status: The status of the room (e.g., "active", "inactive")
name: The sender's name
content_type: The message content type (media, emoji, text)
is_delivered: Whether the message has been delivered to the recipient
created_by: The ID of the user who sent the message
created_by_name: The name of the user who sent the message
timestamp: The message timestamp
options: An array of vote options
npm install phoenix<script src="https://sdk.sariska.io/bundle.messaging.js"></script>const socket = new Socket("wss://api.sariska.io/api/v1/messaging/websocket", {token: "your-token"});
// Handles socket opening event
socket.onOpen = () => {
console.log("Socket opened");
};
// Handles socket closing event
socket.onClose = () => {
console.log("Connection dropped");
// Handles socket error events
socket.onError = () => {
console.error("There was an error with the connection");
};
// Open connection to the server
socket.connect();// Close connection to the server
socket.disconnect(); let channel = socket.channel("chat:room123");let channel = socket.channel("rtc:room123");let channel = socket.channel("sariska:room123");channel.onError( () => console.log("There was an error!") )channel.onClose( () => console.log("Channel Closed") )// Join the channel
channel.join()
.receive("ok", ()=>console.log("Channel joined"))
.receive("error", ()=>console.log("Failed to join"))
.receive("timeout", () => console.log("Encountering network connectivity problems. Waiting for the connection to stabilize."))
// Leave the channel
channel.leave();channel.on("user_joined", (payload) => {
// Extract user and room information from the payload
const user = payload.user;
const room = payload.room;
// Log the user and room details to the console
console.log(user);
console.log(room);
});channel.on("new_message", (message) => {
// Log the received message to the console
console.log(message);
});channel.push("new_message", {
content: "Hi, From nick"
})// Push a new message reply to the channel
channel.push("new_message_reply", {
content: "How is the Weather today?",
message_id: 1
})channel.on("new_vote", (vote) => {
// Log the received vote to the console
console.log(vote);
});let responseBody;
// Construct the request payload
const payload = {
method: "POST",
headers: {Authorizaton: "Bearer your-token"}
};
// Send the POST request to the API endpoint
const response = await fetch("https://api.sariska.io/api/v1/misc/get-presigned", payload);
// Check for successful response
if (response.ok) {
responseBody = await response.json();
}const file = event.target.files[0];
const signedUrl = responseBody.presignedUrl;
const headers = {
"ACL": "public-read",
"Content-Disposition": "attachment"
}
await fetch(signedUrl, {
method: 'PUT',
body: file, headers
})channel.on("archived_message", (messages)=> {
// Handle received messages
});channel.on("archived_message_count", (payload)=> {
const { page: { count } } = payload;
// Log the received count of total messages to the console
console.log(count);
});channel.push("archived_message", { page: { size: 100, offset: 0, group_by_day: false }}); channel.push("archived_message_count");const fetchChatHistory = async () => {
// Construct the request payload
const payload = {
method: "GET",
headers: { Authorizaton: "Bearer your-token" }
};
// Send the POST request to the API endpoint
const response = await fetch("https://api.sariska.io/api/v1/messaging/rooms/{room_name}/messages", payload);
// Check for successful response
if (response.ok) {
// Return the chat history data
return await response.json();
}
}const fetchSpecificMessage = async () => {
// Construct the request payload
const payload = {
method: "GET",
headers: { Authorizaton: "Bearer your-token" }
};
// Send the GET request to the API endpoint
const response = await fetch("https://api.sariska.io/api/v1/messaging/rooms/{room_name}/messages/{message_id}", payload);
// Check for successful response
if (response.ok) {
// Return the specific message
return await response.json();
}
}const EmptyChat = async () => {
// Construct the request payload
const payload = {
method: "DELETE",
headers: { Authorizaton: "Bearer your-token" },
body: JSON.stringify({
message_ids: [message_id_1, message_id_2, ...],
is_empty: false
})
};
// Send the DELETE request to the API endpoint
const response = await fetch("https://api.sariska.io/api/v1/messaging/rooms/{room_name}/messages", payload);
// Check for successful response
if (response.ok) {
return await response.json();
}
}const EmptyChat = async () => {
// Construct the request payload
const payload = {
method: "DELETE",
headers: {Authorizaton: "Bearer your-token"},
body: JSON.stringify({
message_ids: [],
is_empty: true
})
};
// Send the DELETE request to the API endpoint
const response = await fetch("https://api.sariska.io/api/v1/messaging/rooms/{room_name}/messages", payload);
// Check for successful response
if (response.ok) {
return await response.json();
}
}let channel = socket.channel("chat:room123")
let presence = Presence(channel)presence.onSync(() => {
myRenderUsersFunction(presence.list());
})let presence = new Presence(channel)
// Detect if the user has joined for the first time or from another tab/device
presence.onJoin((id, current, newPres) => {
if(!current){
console.log("User has joined for the first time", newPres)
} else {
console.log("User additional presence", newPres)
}
})
// Detect if the user has left all tabs/devices, or is still present
presence.onLeave((id, current, leftPres) => {
if(current.metas.length === 0){
console.log("User has left from all devices", leftPres);
} else {
console.log("User left from a device", leftPres);
}
})
// Receive presence data from server
presence.onSync(() => {
presence.list(); // List of users
})let listBy = (id, { metas: [first, ...rest] }) => {
// Increment the presence count for the user
first.count = rest.length + 1
// Set the user ID for the presence metadata
first.id = id
// Return the prioritized presence metadata
return first
}
// Retrieve a list of online users based on the prioritized presence metadata
let onlineUsers = presence.list(listBy) channel.push('user_typing', { typing: true })channel.on("user_typing", (typing_response) => {
console.log(typing_response);
});