Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The Chat SDK for Web is delivered as an npm module.
An easy-to-integrate module that delivers high-performance messaging services
From travel-loving retirees for cruise lines to hiking enthusiasts for camping equipment brands, there are groups and individuals everywhere seeking to find others with similar interests. Provide a place for your customers to join communities centered towards your brand and what it represents to boost customer loyalty and retention, build a positive association, as well as allow them to feel a deeper connection to your brand.
This page highlights the steps you will need to follow to begin integrating chat messaging into your products
The message payload is always the same regardless of which Development Kit the user is using. Users also have a choice on what type of message they want to send.
Amity supports the sending and receiving of 5 types of messages. They are Text, Image, Audio, File, and Custom.
Amity will automatically optimize the image and when queried, will return the image in small, medium and large sizes. If the image is marked as isFull
on upload, the original size of the image can also be returned.
When an image is uploaded, it is automatically resized into multiple sizing options. The size of the image is determined by its longest dimension (in pixels) with the aspect ratios being unchanged.
The maximum file size of an image cannot exceed 1 GB.
When a user is observing messages, the message will always appear in this format.
Messages are JSON content containers that can weigh up to 100KB and will be synchronized among all channel users in real-time. If a message requires larger binary data (such as when sending files), we recommend to upload the data to another cloud storage service, such as AWS S3, and store the URL to the content in the message data.
In addition the JSON message type, the SDK also provides support for common text and image message types. These additional types are built on top of the standard JSON message layer.
In case of image messages, the SDK freely provides a cloud storage service that will process and store all images uploaded: you don't need to setup and manage a separate cloud storage service for this common case.
All messaging methods are contained in a EkoMessageRepository
class. Before calling any messaging methods, you must ensure to first instantiate a repository instance using the EkoClient
instance you created on setup.
All message sending methods are designed to be robust enough to work under any network conditions. When you send any message, that message will automatically be put into a queue incase of any unforeseen unstable network conditions. Once the SDK reconnects to the server, it will automatically resend all the queued messages.
Additionally, sent messages are always returned in message queries, even before they have been delivered to the server. This provides the user with a fluid messaging flow: when a user sends a message, that sent message will appear in the message stream right away (instead of waiting until it has been confirmed by the server). To check or display the current status of message delivery for your application, use the syncState
property in the message model; for web you should useEkoMessage.getState()
method in the EkoMessage
object.
Initiate the messaging with the following scripts, depending on your platform of choice
To query for a list of all messages in a channel:
This method will return a LiveCollection of all messages in the specified channel. You can observe the LiveCollection in order to update your view whenever you receive new messages.
Since v1.3.0, messages can be organized in threads thanks to the parentId
property.
A message can be the root for a thread. To query the children of a message thread, you can add the parentId
parameter in a message query, along with the filterByParentId
flag.
When creating a message, we can also pass the parentId
to make it appear under a parent.
Users can flag messages and unflag messages that they have flagged using the MessageFlagRepository
class.
To flag a message, call the following method:
To unflag a message, call the following method:
The User can also check if they have previously flagged the message before by calling the following asynchronous method:
If this method has been called before in the current session, the user can also check the cached result on the message payload itself.
A special MessageEditorRepository
class is also provided for you to perform actions on messages you've sent or received. These actions include editing and deleting an existing message, as well as marking a message as being read by you.
To start, first instantiate a MessageEditor
instance with the EkoClient
instance you created on setup, as well as a valid messageId
.
You can only perform edit and delete operations on your own messages. Once the operation is complete, the message's editedAtDate
will be set to the current time. This allows you to provide UI to the user to inform the user of specific messages that has been edited, if needed. An optional completion block can be provided to notify you of operation success.
To mark a message as being read by you, simply call the following method with an optional completion block:
Marking a message as read will also retroactively mark all previous messages as read by you as well. You will only need to call this method once on the latest message.
This section outlines how you can set-up your project for success and begin using our Chat SDK for Web applications
Before using the Chat SDK, you will need to create a new SDK instance with your API key. Please find your account API key via the Admin Panel. If you have trouble finding this, you can send our support team an email at developer@amity.co
In order to use any Chat SDK feature, you must first register the current device with an userId
. A registered device will be tied to the registered userId
until the device is either proactively unregistered, or until the device has been inactive for over 90 days. A registered device will receive all the events messages belonging to the tied user.
An optional displayName
can be provided, which will be used in standard push notifications (related to user's actions, such as when the new message is sent).
The
displayName
is set only on the first time the device is registered, please follow your platforms necessary directions if you would like to rename this to something else.
When the user logs out, you should explicitly unregister the user from the SDK as well. This prevents the current device from receiving unnecessary and/or restricted data.
Each user can be registered, at the same time, to an unlimited number of devices. Amity's Chat SDK will automatically synchronize the user data across all registered devices. We will also automatically unregister any device that has not been connected to the server for more than 90 days.
When a device is unregistered due to inactivity, the SDK data on the device will be reset. You will need to re-register this device in order to connect to server again.
If you have any logic or UI around the connection status, you can observe the connectionStatus
property on the EkoClient
instance.
Since the Chat SDK automatically manages the network connection and queue up any requests in cases of bad connection, there should be little need to attach additional logic to this status. However the user may want to know the exact network status to determine if their actions will be performed in real-time, therefore this status is exposed.
You can also be notified about connectionStatus
changes via the connectionStatusChanged
event.
Our Sample app adopts an open source framework that highlights how Amity Social Cloud SDK's can be implemented into application builds pragmatically.
With real life use-cases, we guide you through ways you can get started with building stellar applications for yourself and your clients and their users
Amity SDK's do not store or manage any user data. This means that you do not have to import or migrate existing user profiles into the system, user management should be handled by your application code. Instead, every user is simply represented by a unique userID
, which can be any string that uniquely identifies the user and is immutable throughout its lifetime.
A database primary key would make an ideal
userID
. Conversely, something like username or emails is not recommended as those values may change overtime.
If you wish to assign additional permissions for a user, for example moderation privileges or different sending limits, you can provide an array of roles to assign to this user. Roles are defined in the admin panel and can be tied to an unlimited number of users. Once again, Amity does not store or manage any user data, which means you do not have to import or migrate existing users into the system. It also means that Amity cannot provide user management functionalities like lists of users, or limit actions of certain users (e.g. user permissions). Instead, these functionalities should be handled by the rest of your application's capabilities and your server.
Though the SDK does not store and should not be responsible for the handling User profile data for your application; We do provide tools to make some surface-level queries and searches for existing user accounts. With the help of our EkoUserRepository
class, you would be able to list all the users, search for list of users whose display name matches your search query and get EkoUser
object from user id.
All User methods are contained in a UserRepository
class. Before calling any User methods, you must first instantiate a repository instance.
The User Repository provides a method to get a single user, which will be returned as a LiveObject:
The User Repository provides a method to get a list of all users, which will be returned as a LiveCollection:
This method takes an optional sortBy
parameter which must be a EkoUserSortingMethod
- these include displayName
, firstCreated
, and lastCreated
:
The User Repository provides a method to search for users by their display name. The result of this search is returned as a LiveCollection.
The above example searches for all users whose display names start with "Test User 1". Note that the search is case sensitive.
To flag a user, call the following method:
To unflag a user, call the following method:
Both of these methods return a promise meaning they can be chained with .then
and .catch
handlers:
All data returned by the SDK are wrapped in the SDK's LiveObject API. The LiveObject API allows you to easily retrieve the queried data asynchronously, as well as subscribe to any new changes to the data.
Observing live changes to any object queries can be done by observing the dataUpdated
event on the LiveObject:
In this example the block observes the data of the currently authenticated user and prints out the displayName
. The observe block can be called multiple times throughout the lifetime of the application:
If the requested object data is stored locally on the device, the block will be called immediately with the local version of the data (you can verify this through the dataStatus
property).
In parallel, a network request for the latest version of the data is fired. Once the network returns the data, the observe block will be called again with the updated data.
Any future changes to the data (whenever the user changes its displayName
on another device, for example) can trigger additional callbacks.
We recommend you to always call removeAllListeners()
whenever you are done observing event to avoid any unnecessary callbacks.
The data provided by LiveObject is directly accessible via the model
property. The model
property is always kept up to date with the latest state changes; every time when dataUpdated
event is fired, the model
property has already been updated.
If in your UI you want to exclusively display fresh data (without using the potientially out-of-date local data), you can do so by reading the object's dataStatus
property, which reflects the status of the callback data, and check that its value is set to fresh.
You can also use the object's loadingStatus
property to determine the current state of network operations being performed by the LiveObject. This is useful for any UI element that needs to provide the loading state.
The LiveObject can also emit events for updates for dataStatus
as well as loadingStatus
. As with other events, please make sure to call removeAllListeners()
when you are done observing changes to these values in order to prevent memory leaks.
The LiveObject updates statuses and data in strict order and emits related events accordingly when an instance is created. Few different cases might occurs when you create a LiveObject instance:
Initial values:
loadingStatus = EkoLoadingStatus.Loading
dataStatus = EkoDataStatus.NotExist
model = undefined
Process received data:
emits loadingStatusChanged
emits dataStatusChanged
emits dataUpdated
Initial values:
loadingStatus = EkoLoadingStatus.Loading
dataStatus = EkoDataStatus.Local
model = localData
Process received data (same order):
emits loadingStatusChanged
emits dataStatusChanged
emits dataUpdated
- only if data is really different
loadingStatus = EkoLoadingStatus.Loaded
dataStatus = EkoDataStatus.Fresh
model = localFreshData
The LiveObject API supports queries that return a list of objects, this is known as a LiveCollection. LiveCollection has the same methods and properties as its object counterpart, but contains a few other helper methods around pagination.
Pagination with LiveCollections is very simple: the collection offers a convenient nextPage
method that you can call which will automatically trigger a local cache lookup, a network call, and multiple LiveObject updates once new data is returned. Every collection starts with one page of 20 models. After nextPage()
is successful, the dataUpdated
event will be triggered with a new array combining both the old objects as well as 20 newly fetched objects.
You can use the
hasMore
property to determine if you've scrolled to the end of the list. ThehasMore
property initially returns 'false' until the first collection query is finished.
Lastly, if there is a need to shrink the list of objects exported back to only the first 20 records (for example, if you pass the LiveCollection object to a new view), you can simply call resetPage()
.
Similar to model
property of the LiveObject, the LiveCollection provides models
property what is basically is an array of LiveObject's model
objects. models
is mutable and always contains same data as one what returned by dataUpdated
event.
Both LiveObject and LiveCollection can be subscribed to the dataError
event which is fired every time an error happens during the data update process. In other words, every time the LiveObject or LiveCollection fails to get data from the server - this error will be emmited.
We recommend you to always call dispose()
whenever you are done working with any LiveObject/LiveCollection.
Dispose is a very important functionality of the LiveObject. It allows you to avoid memory leaks and keeps your application performant. What does dispose()
do:
unsubscribe all listeners attached to the LiveObject instance;
stop all internall observers related to the LiveObject instance;
clean up an internall buffer of the LiveObject instance;
After you call dispose()
on a LiveObject instance, dataStatus and loadingStatus switch to Error
.
Our channels enable developers to implement different types of chat messaging capabilities into their applications easily
Users can create and join channels where they will be able to participate and chat with other users. A channel can support up to 300,000 members and can contain an unlimited number of messages. Any message exchanged in the channels will be pushed to all other members of the channel in real-time.
Amity's Chat SDK supports the creations of 4 types of chat channels. Each type is designed to match a particular use-case for chat channels. Here's a table showing what features each channel offers:
The community channel is our default channel type and can be discovered by all users and admins. It acts as a public chat channel that showcases all of the features that our SDK's have to offer.
Typical use cases:
Team collaboration
Online gaming
Celebrity fan club
Live streaming
Any type of public chat
Live channels offers the ability for users and admins to create channels with exclusive memberships. The live channel is identical to our Community channel in features with the caveat that users will not be able to discover the channel when querying for all channels unless they are already a member of it. However users and admins can still invite other users to join the channel.
Typical use cases:
Healthcare
Project Discussion
Any type of private chat
Community and Live channel types can use our SDK moderation tools:
Message and user flagging
Muting/Unmuting users
Banning/Unbanning users from channel
Profanity filters
Whitelisted URLs
User rate-limiting
All broadcast channels are visible on the Amity Social Cloud Console.
The Broadcast channel is heavily adopted by corporate users who constantly promote or advertise their products, or make the announcement to drive awareness. Unlink other channel types, broadcast channels only allow admin users to send messages from Console, and everyone else in the channel will be under read-only mode.
Since this is a one-way communication channel, a tailored moderation tools are provided as well, for instance, users won't be able to flag message / user in the channel.
Typical use cases:
Marketing & Advertising
School / Government Announcements
Conversation channels are NOT visible on the Amity Social Cloud Console.
The Conversation channel is our solution to 1-on-1 messaging. Unlike the other channel types, a Conversation channel can be created simply by knowing the userId of the user we want to converse with. Users can start conversations with any other user and only they will be able to see their conversation.
There are no moderation tools for Conversation channels, users will be able to converse freely with no oversight!
Typical use cases:
Hospitality
Financial Consultancy
Customer Support
When a user joins a channel, they are able to observe and chat with other users in that channel. They are also automatically considered a member of that channel. The Chat SDK provides the ability to view which users are currently in the channel as well as invite other users to join the channel.
Each channel is identified by an unique channelId
, which is any string that uniquely identifies the channel and is immutable through its lifetime. When creating channels, you can specify your own channelId
, or leave it to Amity's Chat SDK to automatically generate one for you.
There can be only one and one only channel with a given
channelId
: an error will be thrown when trying to generate two channels with the samechannelId
.
There are three ways of obtaining a channel: via create, join, or get. They all return a LiveObject with the complete channel model. However, createChannel:
guarantees that the requested channel is a new channel, whereas joinChannel:
will attempt to join an existing channel. If there is a requirement to create a new channel, then use of createChannel:
then call joinChannel:
. Lastly calling getChannel:
only gives you back the channel LiveObject, but it won't make the current user join said channel.
Channel management methods are contained in a EkoChannelRepository
class. Before being able to call any channel method, you must initialize a repository instance using the EkoClient
instance you created on setup:
EkoChannelRepository
provides createChannel()
method to create a new channel. It supports creating of 3 types of channels Community
, Live
and Conversation
. Each channel type has specific builder classes which helps you to create that particular channel. Build your channel information first and then create the particular channel.
The above code creates a channel and notifies you through observer block. It first instantiates the EkoChannelRepository
, a class that contain all channel related methods. Then it calls createChannel:
to obtain the LiveObject and observe it in order to obtain the final channel model.
The
EkoNotificationToken
returned by theobserve:
is saved inself.channelToken
, a strongly referenced property. This is needed in order to prevent the observe block to be released. Observe block can get called multiple time, when the underlying data for the channel updates. If you don't want to get notified, you can callchannelToken.invalidate()
. As soon as the token gets invalidated, observer is automatically removed from that channel.In the case that there is already an existing channel with the same
channelID
, the LiveObject will notify you with anerror
object.The
channelId
parameter increateChannel:
can benil
: when this happens, the SDK will generate an uniquechannelId
for this channel, ensuring no unique ID conflicts.3 channel types can be created through SDK i.e
Community
,Live
andConversation
. Creation ofPrivate
andStandard
type has been removed. Creation ofBroadcast
channel type is not supported through the SDK. But for query,channelCollection:
method supports all channel types includingBroadcast
,Private
andStandard
.
We do not currently support this method on Web, and will be working towards adding it shortly!
Conversation channel is unique based on its membership. When creating conversation the system will check if channel with the same membership already exists, if such channel already exists the system will return existing channel instead of creating a new one.
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.
In the case where you'd like to fetch a channel's data without joining, the getChannel:
method can be used:
EkoChannelRepository
provides a way to query list of channels using channelCollection()
method. It returns a EkoCollection
of all the matching channels available. This live collection returned will automatically update and notify you on any channel modifications.
SDK provides with 7 builder classes. EkoStandardChannelQueryBuilder
, EkoPrivateChannelQueryBuilder
, EkoByTypesChannelQueryBuilder
, EkoBroadcastChannelQueryBuilder
, EkoConversationChannelQueryBuilder
, EkoCommunityChannelQueryBuilder
and EkoLiveChannelQueryBuilder
. These builder classes should be used to construct a query and then used alongside channelCollection method to fetch list of channels.
Depreciated:
channelsForFilter()
,channelsForFilter(_:includingTags:excludingTags:)
method to query channels is now depreciated. SDK now doesnot support creation of Private & Standard channels but still supports query usingEkoStandardChannelQueryBuilder
EkoPrivateChannelQueryBuilder
.
If you use a UITableView
or UICollectionView
to display channel list data, the ideal location to reload table data is directly in the observe block of the LiveObject that you are displaying, as shown in the example above.
You can filter channels by various criteria such as includingTags, excludingTags, includeDeleted channels etc. All these filters are available in QueryBuilder classes for channel.
Metadata is a general purpose data store that is automatically synchronized to all the channel members. 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: 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 multiple writes on the data.
To set metadata, call the setMetadataForChannel:
method:
The completion block will be triggered with the outcome of the request. 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 EkoChannel
object.
You can set a channel's displayName
with the following method:
An optional completion callback is available to inform you on whether the request has succeeded or not.
All participation related methods in a channel falls under a separate EkoChannelParticipation
class. Before calling any participation methods, you must ensure to first instantiate a repository instance using the EkoClient
instance you created on setup and a valid channelId
:
Also you can access a ChannelMembershipRepository
instance by the membership
property of a channel LiveObject model:
The participation membership provides a list of all members in the given channel as a LiveObject.
The participation membership also provides classes to add and remove members, as well as removing yourself as a member of the channel (leaving the channel).
The EkoChannelRepository
object exposes an totalUnreadCount
property that reflects the number of messages that the current user has yet to read. This count is the sum of all the unreadCount
channels properties where the user is already a member.
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-device management: therefore a user can read multiple channels, from one or multiple devices 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 behalf.
EkoChannelModeration
class provides various methods to moderate the users present in channel. You can ban/unban/mute users, assign roles or remove it from user.
You can check your permission in channel using hasPermission(permission:forChannel:_:)
method from the "ekoclient"
Name
Data Type
Description
Attributes
messageId
string
The id of this message
Content
parentId
string
The messageId
of the parent of this message
Content
childrenNumber
integer
The number of messages with parentId
of this message
Content
channelId
string
The name of the channel this message was created in
Content
userId
string
The name of the user this message was created by
Content
type
string
The message type
enum*: text
custom
image
file
tags
Array.<string>
The message tags
Content
data
Object
The message data (any text will be stored in text
key)
text
: Text message
isDeleted
boolean
The message has been marked as deleted
Content
channelSegment
integer
The sequence number of a message in channel
Content
createdAt
date
The date/time the message was created at
Content
updatedAt
date
The date/time the message was updated at
Content
editedAt
date
The date/time the message was edited at
Content
flagCount
integer
The number of users that have flagged this message
Content
hashFlah
Object
A hash for checking internally if this message was flagged by the user
Content
reactions
Object
The reaction data (stored as a reactionName and counter key/value pair)
Example: { like
: 1, dislike
: 2 }
reactionsCount
integer
The total number of reactions on this message
Content
myReactions
Array.<string>
A list of user's reactions on this message
Content
Name | Data Type | Description | Attributes |
|
| The id of this user |
|
| A list of user's roles |
|
| The display name of the user |
|
| The number of users that have flagged this user |
|
| The metadata of the user |
|
| A hash for checking internally if this user was flagged by the user |
|
| The date/time the user was created at |
|
| The date/time the user was updated at |
Channel Type | Discoverable by | Message sending privileges | Moderation access |
Community | All users and admins | Users and admins | All Moderation tools |
Live | Only members and admins | Users and admins | All Moderation tools |
Broadcast | All users and admins | Admins | Admin Moderation tools |
Conversation | Only members | Users | No Moderation tools |
Channel Type | Discoverable by | Message sending privileges | Moderation access |
Community | All users and admins | Users and admins | All Moderation tools |
Live | Only members and admins | Users and admins | All Moderation tools |
Broadcast | All users and admins | Admins | Admin Moderation tools |
Conversation | Only members | Users | No Moderation tools |
Moderation is an important feature for building a safe community that encourages user participation and engagement.
Amity’s customer centric nature ensures that security needs are kept at the forefront of the work we do. Our purpose has been to continuously develop features that are safe and ready to use. We power our moderators with tools to control and impose permissions that make their applications a safer place, for all users. We put the utmost importance on giving power to our clients to implement protocols that keep their applications healthy, safe and compliant.
Interactions are more fun when you can express yourself! Let users react using emojis, stickers, or thumbs up to messages.
To maximize engagement on the content of your application, you can use reactions on messages, posts, or comments. The reaction is similar to the Facebook Like. While a user can add many reactions to a model, it can only add each reaction one time only.
Each model which can be reacted upon will carry a set of properties useful to display its reactions. You will find:
reactions
: an object containing the name of the reactions as key, and their count as value (ex: { like: 1, love: 1 }
)
reactionCount
: the sum of all the counts for all the reactions
myReactions
: an array containing the current's users reactions
First, simply import the ReactorRepository
and pass in the message you want to react upon.
Then call for addReaction()
and pass along the identifier for your reaction.
Just as you did for adding a reaction, you can call removeReaction()
to remove a reaction.
Both addReaction()
and removeReaction()
methods return a Promise resolving a boolean acknowledging the server's successful response. If necessary, you can use await
to receive the result of those operations.
When a user is muted, they can not send messages in a channel.
Moderators can mute and unmute users. When a user is muted, they cannot send messages in a channel. However muted users will still be allowed to observe messages in a channel. The status of being muted is indefinite but is only applied at the channel level.
When a user is muted, all messages sent by that user to that channel will be rejected. This method is useful for preventing certain users from sending inappropriate messages, but still allowing them to participate in the conversation in a read-only manner. The timeout property allows you to make the timeout temporary, or permanent by until unset by passing in -1
.
The above logic will mute user1
in the selected channel for 10 minutes (600 seconds). An optional completion block notifies you when the action is complete.
If you want to permanently mute a user, pass in
-1
as the mutePeriod. The user will stay muted until you explicitly unmute that user.
To unmute a user, call unmuteUsers()
:
Rate limiting a channel controls the speed of messages that is published to all concurrent clients in the channel
This method is useful when there is a large amount of messages going through the channel, which can make the message stream hard to follow. Setting a rate limit enables the SDK to queue up messages once the amount of message in a specified window
exceeds the defined limit
, allowing a slower stream of messages to be published to the user at the expense of adding more latency (because newer messages will be sent to the queue first and not delivered until all previous queued messages are delivered).
There is an internal limit of 1000 messages that can be queued by the rate limit service, if more than 1000 messages are queued up, the system may skip publishing the older messages in order to make room for newer messages. We believe this is the preferred behavior for users, as users will most likely want to see newer messages in a real-time conversation instead of waiting for a significant amount of time for old messages to be published to them first.
Note that the SDK permanently stores all messages it receives in the system before the rate limit comes into effect: in the case of a large spike of incoming messages, even if a message did not get published to a user in real-time, that user can still scroll up to see message history and see that past message.
The above method enables a rate limit of 5 messages every 60 seconds. Once a user sends more than 5 messages in 60 seconds, their messages will be queued on the server and not published to other channel members until 60 seconds have passed.
In order to disable the rate limit, simply call removeRateLimit()
:
When a user is banned in a channel, they are removed from a channel and no longer able to participate or observe messages in that channel.
Moderators can ban and unban users. When a user is banned in a channel, they are forcebly removed from channel and may no longer participate or observe messages in that channel. All their previous messages in the channel will also be automatically deleted.
A user that has been banned from a channel can not rejoin the channel until they have been unbanned.
As well as the banning and unbanning of users, admins also have the ability to global ban a user. When a user is globally banned, they can no longer access Amity's network and will be forcebly removed from all their existing channels. All the globally banned user's messages will also be deleted.
The globally banned user can not access Amity's network again until they have been globally unbanned.
Banning users is a more heavy handed moderation method. When a user is banned, all its messages are retroactively deleted, it will be removed from the channel, and it will not be allowed to join the channel again until he is explicitly unbanned.
There is a separate unban call to unban a user:
Note: This feature does not work with Broadcast
and Conversation
channels. Calling banUsers()
or unBanUsers()
on these channels will result in an error.
flag and unflag a message
While having moderators surveying your chats is great, it doesn't scale well. A way to overcome this is to let your users do the work for your moderators. By letting users flag other users or specific messages, the work of moderators is significantly reduced and democratized, thus allowing administrators to only respond to issues when deemed critical or absolutely necessary.
Users can flag messages and unflag messages that they have flagged using the MessageFlagRepository
class.
To flag a message, call the following method:
To unflag a message, call the following method:
The User can also check if they have previously flagged the message before by calling the following asynchronous method:
If this method has been called before in the current session, the user can also check the cached result on the message payload itself.
This page contains an overview of all relevant changes made to the Amity Chat SDK modules and the latest version releases
Reaction
Normalized API across the SDK
User
UserRepository.getAllUsers(sortBy?: EkoUserSortingMethod)
UserRepository.searchUserByDisplayName(search: string)
Added unreadCount in ChannelMembershipModel
exampleChannelMembershipModel.unreadCount;
Threaded messages:
MessageModel.parentId;
: Message ID of a parent message
MessageRepository.messagesForChannel
now allow parameters parentId: string
and filterByParentId: boolean
to perform queries on threads of messages
Reactions:
{ reactions: Object, reactionsCount: number, myReactions: string[] }
is added to MessageModel to support reactions
ReactorRepository(messageModel: MessageModel);
async ReactorRepository.addReaction(reactionName: string);
async ReactorRepository.removeReaction(reactionName: string);
A new Message Flagger Repository has been added and all message flagging has been moving to this repository:
MessageFlagRepository(messageId);
MessageFlagRepository.flag({ messageId });
MessageFlagRepository.unflag({ messageId });
You can check if you have flagged a message before
await MessageFlagRepository.isFlaggedByMe();
MessageModel now contains a cache for the isFlaggedByMe result
MessageModel.isFlaggedByMeCache;
You can now edit user metadata:
client.setUserMetadata({ test: "test" });
You can now filter channels by tags/excludingTags:
ChannelRepository.channelsWithFilters({ tags: [1,2,3], excludingTags: [4,5,6] });
You can now edit and delete message text:
MessageEditorRepository.editText('new edited text');
MessageEditorRepository.delete();
You can now read and unread channels:
ChannelMembershipRepository.startReading()
ChannelMembershipRepository.stopReading()
You can now be able to flag/unflag a message:
MessageRepository.flag({ messageId });
MessageRepository.unflag({ messageId });
You can now be able to flag/unflag a user:
UserRepository.flag({ userId });
UserRepository.unflag({ userId });
Fixed an issue with LiveObject and LiveCollection when they stop listen for updates from server after unregister/register. (case with SPA multiuser UI).
Enhanced Array.prototype.sort() comparison functions to be in sync with last updates in V8 (changes for sort()
already delivered in Chrome 70 and node-v11).
Ensure that your users don’t miss important content from each other.
This functionality is not currently supported for Web but will be coming soon! We will update the relevant sections accordingly
Flag and Unflag a channel user
While having moderators surveying your chats is great, this doesn't scale well. A way to overcome this is to let your users do the work for your moderators: by letting users report other users or specific messages, the work of moderators goes from scanning each message in each channel to investigate each user report (to both users and messages) and react only when deemed necessary.
To flag a user, call the following method:
To unflag a user, call the following method:
Both of these methods return a promise meaning they can be chained with .then
and .catch
handlers:
Error objects can be returned to you via LiveObjects, callbacks, or clientErrorDelegate
. All the errors returned by the SDK come in form of an NSError with domain Eko
. The possible error codes are listed in a public EkoErrorCode
enum: each case is named after its error and they're pretty self explanatory.
UnauthorizedError: 400100
ItemNotFound: 400400
BadRequestError: 400000
Conflict: 400900
ForbiddenError: 400300
PermissionDenied: 400301
UserIsMuted: 400302
ChannelIsMuted: 400303
UserIsBanned: 400304
NumberOfMemberExceed: 400305
ExemptFromBan: 400306
MaxRepetitionExceed: 400307
BanWordFound: 400308
LinkNotAllowed: 400309
GlobalBanError: 400312
BusinessError: 500000
Unknown: 800000
InvalidParameter: 800110
MalformedData: 800130
ErrorQueryInProgress: 800170
ConnectionError: 800210
When an error is returned as a result of an action from your side (e.g. trying to join a channel), the action is considered completed and the SDK will not execute any additional logic.
The EkoClient
includes a clientErrorDelegate
property that can be set to an error handler delegate class on your application. This error delegate gives you a chance to be notified of errors that can potentially break the functionality of the SDK. The SDK logic is usually robust enough to automatically handle most errors, as such, only unrecoverable errors are exposed through this delegate (for example, if the login session was invalidated).
We recommend you to always handle these errors in a production app by gracefully disabling messaging functionality in the event of an error.