advanced chat
introduction
Lets go deeper and create a telegram like app, unlike the previous example we will be using a framework (svelte). we will not explain each line but instead explain only necessary points, grab the code and follow along.
features
these are the features we are going to add to our example
- sending and receiving various message types across channels | groups
- channel management, create, add users, moderate users, remove users, etc
- calls private calls, group calls, broadcasts and streaming
routes
we have 3 routes in the src/routes
directory.
/user
- authorize users/
- main chat page/new
- create new channels and join open channels
authorization
For simplicity we are storing user information in the local storage. onMount we are first check if
there is the user key in local storage and if not redirect user to the /user
page where they put
in their details (name and id) and redirect them back to /
where they connect to cyxth.
connect to cyxth
Once we have collected the user info and saved it to localStorage. we call getToken()
from the previous example
that fetches token data which we connect()
to our cyxth instance.
If connect()
was successiful we get the user’s persistent channels using the channels.list()
function.
this function only gets the user’s channel information such as avatar,name and metadata.if user has
no channels they are redirected to /new
page where the can create and join channels.
To get messages and activity across all user channels we use the channels.getMessages()
function with a specific start time or start message id usually
the last message the user saw if offline is enabled. this will send the first 100 messages across all channels.
// start date
let channelActivity = await cyxth.channels.getMessages('7085164563653595136');
this returns messages grouped by channel starting from the given date or message id.
[
{
"breakout": [
{
messageId: '7085164563653595136',
type: 'message',
userId: 'bob',
timestamp: 'Date',
content: {
text: 'hello',
media: {
pictures: [
{
name: 'hello',
url: 'https://imgs.cyxth.com/xyz/1234',
thumb: 'https://imgs.cyxth.com/xyz/1234'
},
...
]
}
},
channelId: 'breakout'
},
...
],
"helloworld":[...],
...
}
];
on getting this information we can display the channel list and show last message and unread count.
It is recommended to enable offline option on cyxth initialization. to enable local cache using IndexedDb if you are building a chat application similar to this one.
let cyxth = new Cyxth(APP_URL, {
offline: true
});
messaging
once we have listed the channels on clicking any channel we can see all messages and send new messages. new messages are added to the channel’s messages object. on new message received we add it to the respective channel too and update unread count if user is currently not viewing the current channel.
const sendMessage = async (message) => {
cyxth
.send(channelId, message)
.then((sent) => {
// update message sent or delivery status
})
.catch((err) => {
// handle error
});
updateMessages(message);
};
cyxth.on('message', (message) => updateMessages(message));
cyxth.on('activity', (activity) => showChannelActivity(activity));
we don’t have wait for the message to be delivered to add it to the ui. we instead update the message status to sent,failed or delivered later. this might not be your case and you may need to wait for delivery status if you’d like to use the new message id.
edit and react to messages
cyxth supports editing and reacting to messages, all you just need is to provide the messageId
of the message you’d
wish to modify and new content. in this example by right clicking the user can edit,delete,reply and react to
a given message. check the message documentation to find out more.
channel activity
channel activity includes when a user joins, leaves, is blocked, is made admin and many more. this event can be
listened for and show relevant information. in this example we add them as special messages in channels, activity
can be private
visible to only a given user or public
visible to all users in the channel depending on the channel or application level
activity setting.
cyxth.on('activity', (activity) => showChannelActivity(activity));
i’ve went ahead and added emoji,gif and sticker functionality and file sharing in the same page check out the source code for more.
calls
intergrating calls to cyxth is easy with the @cyxth/calls
npm package. calls can utilize the existing channel or create a new
temporary call channel shared in the same parent channel or any other means (you can create a call link externally too).
for our case we are just going to build calls on top of existing persistent channels . Go ahead and install the @cyxth/calls
npm module
and add this to your cyxth initialization.
import Calls from '@cyxth/calls';
let cyxth = new Cyxth(APP_URL, {
offline: true,
calls: Calls
});
starting a call
cyxth supports private calls (one to one), group calls(many to many), broadcast (few to many), streams (one to many) and every thing in between, you can start at any of the calls and upgrade or downgrade to another.
for this implementation to start a call users click the call button in the far right corner in any channel.
const call = async () => {
let call = await cyxth.startCall('channel_id', {
video: true,
audio: true
});
handleCall(call);
};
cyxth.on('call', async (data) => {
// show a notification | ring
//add logic to accept or reject the call
let call = await data.request.accept({
video: true,
audio: true
});
handleCall(call);
});
read more on call configuration.
call events
In our handleCalls()
function we listen for call events connected
, join
, leave
, end
and update
and update the call interface.
to listen just add.
const handleCall = async (call) => {
call.on('join', (data) => {
// add user element
});
call.on('leave', (data) => {
// remove user
});
call.on('end', (data) => {
// show end or smth
});
call.on('update', (data) => {
if (data.action === 'toggle-mute') {
// update interface
} else if (data.action === 'toggle-on-off') {
//
}
// ....
});
// more events
};
read more on call events.
call methods
Beside listening for call events. you can toggle mic, toggle video and leave among other call methods.
In this example we have various ui elements to share screen, mute button for mute()
and unmute()
video toggle for enabling and disabling video stream that call cameraOn()
and cameraOff()
methods and finally leave to leave()
the call / meeting.
read more on call methods.
channels
on /new
page we first list all open channels using channels.list()
. this method returns all channels
marked as public. we also add a button to create new channels using channels.create()
. the user has to have the
permissions to create channel to do this. users can also join any channel using channels.join()
and list channel
users using channels.getMembers()
method.
next client guide