Each channel is identified by a unique channelId
, which is any string that uniquely identifies the channel and is immutable through its lifetime.
There can be only one channel with a particular
channelId
: if you try to create a channel with an existingchannelId
, an error will be thrown.
There are three ways of obtaining a channel: via create, join, or get. They all return a LiveObject with the final channel model. However, createChannel()
guarentees that the requested channel is a new channel, whereas joinChannel()
will attempt to join an existing channel first, and create a new channel if it does not exist yet. Unless there is an absoute requirement to create a new channel, we recommend to always use joinChannel()
, as its behavior is the most aligned with most chat room experiences. Lastly channelForId()
only gives you back the channel LiveObject, but it won't make the current user join said channel.
Channel management methods are all contained in a ChannelRepository
class. Before calling any channel methods, you must ensure to first instantiate a repository instance.
import { ChannelRepository } from 'eko-sdk';const channelRepo = new ChannelRepository();
import { EkoChannelType } from 'eko-sdk';​const liveChannel = channelRepo.createChannel({channelId: 'channel1',type: EkoChannelType.Standard,userIds: [ 'user1', 'user2' ],}).catch(err => {// Handle channel create error (non-unique channelID)});​liveChannel.once('dataUpdated', model => {console.log(`Channel created: ${model.channelId}`);});
The above code creates a channel and prints out the channelId
once it has been successfully created. It first instantiates the ChannelRepository
, a class that contains all channel related methods. Then it calls createChannel()
to obtain the LiveObject and observe it in order to obtain the final channel model.
Note that the event listener was registered using once()
. Unlike on()
, once()
will automatically unregister the event listener once the first event was emitted. This is useful if you just need to use the model once but do not need to listen to further events.
In the case that there is already an existing channel with the same
channelId
, the LiveObject will notify you with anerror
object.
const liveChannel = channelRepo.joinChannel({channelId: 'channel2',type: EkoChannelType.Standard,});​liveChannel.once('dataUpdated', data => {...});
joinChannel()
is an idempotent method, this means it can be called multiple times throughout the lifecycle of the application, and you can expect this method to always return the same channel. Because of this, you can also use joinChannel()
any time you need to fetch a channel, even if you know the user may already be in the channel.
If you want only to fetch a channel's data without joining, you can use the channelForId()
method:
const liveChannel = channelRepo.channelForId('channel3');​liveChannel.once('dataUpdated', data => {...});
The ChannelRepository
provides a simple allChannels
property that returns a LiveCollection of all the channels that belongs to the current user. Like other LiveCollections, the returned collection will automatically update and notify you on any channel modifications (e.g. new channel, left channel, modified channel).
const channels = channelRepo.allChannels();​channels.on('dataUpdated', models => {// reload data});​// unobserve data changes once you are finishedchannels.removeAllListeners('dataUpdated');
There are methods to obtain channels that only match specific criteria:
the filter
parameter let you filter channels based on the logged-in user membership status
the includingTags
and excludingTags
parameters let you filter channels based on the tags set (or not set) in each channel
const channels = channelRepo.channelsWithFilters({tags: [1,2,3],excludingTags: [4,5,6],})​channels.on('dataUpdated', models => {// reload data});
Metadata is a general purpose data store that is automatically synchronized to all users of a channel. It is meant as an elegant mechanism to store contextual information about a specific channel. The data can be any number of JSON key value pairs up to 100 kb. Example use cases include:
Conversation title or cover photo
Global conversation settings
Metadata is implemented with last writer wins semantics on the entire store. This means that multiple mutations by independent users to the metadata object will result in a single stored value. No locking, merging, or other coordination is performed across participants.
To set metadata, simply call the following method:
channelRepo.setMetadata({channelId: 'channel1',metadata: { hello: 'world' },}).then(() => {// success}).catch(error => {console.log('Metadata set fail');});
The promise notifies you when metadata has been successfully set. The latest metadata of the channel is always exposed as part of the metadata
property on the channel model.
Every channel contains an optional displayName
property. This property is mainly used to identify the channel in push notifications, but it is also exposed to the application via channel model.
You can set a channel's displayName
with the following methods:
channelRepo.setDisplayName({channelId: 'channel1',displayName: 'Channel Eko',}).then(() => {// success}).catch(error => {// handle error});
A promise is provided to inform you when the displayName
has been successfully set, or if there was an error in the request.
All participation related methods in a channel fall under a seperate ChannelMembershipRepository
class. Before calling any participation methods, you must ensure to first instantiate a repository instance using a valid channelId
:
import { ChannelMembershipRepository } from 'eko-sdk';const channelMembershipRepo = new ChannelMembershipRepository('channel1');
Also you can access a ChannelMembershipRepository
instance by the membership
property of a channel LiveObject model:
const channelMembershipRepo = liveChannel.model.membership;
The membership repository provides a list of all members in the given channel as a LiveObject.
const members = channelMembershipRepo.members();members.on('dataUpdated', models => {// reload member table});​// unobserve data changes once you are finishedmembers.removeAllListeners('dataUpdated');
The membership repository also provides classes to add and remove members, as well as removing yourself as a member of the channel (leaving the channel).
// add 'user1' and 'user2' to this channelchannelMembershipRepo.addMembers({userIds: [ 'user1', 'user2' ],}).then(() => {// success}).catch(error => {// handle error});​// remove 'user3' from this channelchannelMembershipRepo.removeUsers({userIds: [ 'user3' ],}).then(() => {// success}).catch(error => {// handle error});​// leave this channelchannelMembershipRepo.leave().catch(error => { ... });
The ChannelMembership
also exposes an unreadCount
property that reflects the number of messages that the current user has yet to read for a given channel.
console.log(channelMembership.unreadCount) // 0
To let the server know when the current user is reading one channel, hence resetting that channel unreadCount
to zero, the participation membership exposes the startReading
and stopReading
methods.
You can call both methods as much you want, the SDK takes care of multi-platform management: therefore a user can read multiple channels, from one or multiple platform at once. In case of an abrupt disconnection (whether because the app was killed, or the internet went down etc) the SDK backend will automatically call the stopReading
on the user's behalf.
// start reading a channelChannelMembershipRepository.startReading()​// stop reading a channelChannelMembershipRepository.stopReading()