Conversations
A conversation is a chat channel where messages can be sent. Users can participate in many conversations at once.
| participant | Get a reference to a message in this conversation |
| message | Get a reference to a participant in this conversation |
| get | Fetches a snapshot of the conversation. This contains all of the information related to the conversation and the current user's participation in the conversation. |
| set | Sets properties of this conversation and your participation in it. The conversation is created if a conversation with this ID doesn't already exist. You are added as a participant if you are not already a participant in the conversation. |
| deleteFields | |
| createIfNotExists | Creates this conversation if it does not already exist. Adds you as a participant in this conversation, if you are not already a participant. If the conversation already exists or you are already a participant, this operation is still considered successful and the promise will still resolve. |
| markAsRead | Marks the conversation as read. |
| markAsUnread | Marks the conversation as unread. |
| send | Sends a message in the conversation |
| _send | |
| subscribeMessages | Subscribes to the messages in the conversation. Initially, you will be subscribed to the 10 most recent messages and any new messages. Call Whenever a message is edited, a new message is received, or you load more messages, The snapshot is |
| subscribeParticipants | |
| subscribe | Subscribes to the conversation. |
| subscribeTyping | Subscribes to the typing status of the conversation. |
| markAsTyping | Marks the current user as typing in this conversation for 10 seconds. |
| constructor |
The ID of the referenced conversation.
Immutable: if you want to reference a different conversation, get a new ConversationRef instead.
conversationRef.participant(user): ParticipantRef
Get a reference to a message in this conversation
Parameters
the user's ID
Returns
A reference to the given participant
conversationRef.participant(user): ParticipantRef
Get a reference to a message in this conversation
Parameters
a reference to the user
Returns
A reference to the given participant
conversationRef.message(id): MessageRef
Get a reference to a participant in this conversation
Parameters
the message ID
Returns
A reference to the message with the given ID
conversationRef.get(): ConversationSnapshot?
Fetches a snapshot of the conversation.
This contains all of the information related to the conversation and the current user's participation in the conversation.
Returns
A snapshot of the current user's view of the conversation, or null if the current user is not a participant (including if the conversation doesn't exist)
conversationRef.set(data): Unit
Sets properties of this conversation and your participation in it.
The conversation is created if a conversation with this ID doesn't already exist. You are added as a participant if you are not already a participant in the conversation.
Parameters
interface SetConversationParams
Parameters you can pass when updating a conversation.
Properties that are undefined will not be changed. To clear / reset a property to the default , pass null.
The conversation subject to display in the chat header. Default = no subject, list participant names instead.
The URL for the conversation photo to display in the chat header. Default = no photo, show a placeholder image.
System messages which are sent at the beginning of a conversation. Default = no messages.
Custom metadata you have set on the conversation. This value acts a patch. Remove specific properties by setting them to null. Default = no custom metadata
Your access to the conversation. Default = "ReadWrite" access.
YOur notification settings. Default = true
Returns
Resolves when the operation completes. When client-side conversation syncing is disabled, you may only set your notify property, when you are already a participant. Everything else requires client-side conversation syncing to be enabled, and will cause the promise to reject.
conversationRef.createIfNotExists(data): Unit
Creates this conversation if it does not already exist. Adds you as a participant in this conversation, if you are not already a participant.
If the conversation already exists or you are already a participant, this operation is still considered successful and the promise will still resolve.
Parameters
interface CreateConversationParams
Parameters you can pass when creating a conversation.
Properties that are undefined will be set to the default
The conversation subject to display in the chat header. Default = no subject, list participant names instead
The URL for the conversation photo to display in the chat header. Default = no photo, show a placeholder image.
System messages which are sent at the beginning of a conversation. Default = no messages.
Custom metadata you have set on the conversation. This value acts as a patch. Remove specific properties by setting them null. Default = no custom metadata
Your access to the conversation. Default = "ReadWrite" access.
Your notification settings. Default = true
Returns
Resolves when the operation completes. The promise rejects (throws an error) if you are not already a participant and client-side conversation syncing is disabled.
conversationRef.markAsRead(): Unit
Marks the conversation as read.
Returns
Resolves when the operation completes. The promise rejects (throws an error) if you are not a participant in the conversation.
conversationRef.markAsUnread(): Unit
Marks the conversation as unread.
Returns
Resolves when the operation completes. The promise rejects (throws an error) if you are not a participant in the conversation.
conversationRef.send(params): MessageRef
Sends a message in the conversation
Parameters
interface SendTextMessageParams
Parameters you can pass when sending a message
The text to send in the message.
Custom metadata you have set on the user. Default = no custom metadata
The message that you are replying to. Default = not a reply
interface SendMessageParams
Parameters you can pass to {@link ConversationRef.send}.
Properties that are undefined will be set to the default.
This is the more advanced method for editing a message, giving full control over the message content. You can decide exactly how a text message should be formatted, edit an attachment, or even turn a text message into a location.
The most important part of the message, either some text, a file attachment, or a location.
By default users do not have permission to send {@link LinkNode}, {@link ActionLinkNode}, or {@link ActionButtonNode}, as they can be used to trick the recipient.
Custom metadata you have set on the user. Default = no custom metadata
The message that you are replying to. Default = not a reply
Returns
Resolves with a reference to the newly created message. The promise rejects (throws an error) if you are not a participant with write access in this conversation.
conversationRef.send(params): MessageRef
Sends a message in the conversation
Parameters
interface SendTextMessageParams
Parameters you can pass when sending a message
The text to send in the message.
Custom metadata you have set on the user. Default = no custom metadata
The message that you are replying to. Default = not a reply
interface SendMessageParams
Parameters you can pass to {@link ConversationRef.send}.
Properties that are undefined will be set to the default.
This is the more advanced method for editing a message, giving full control over the message content. You can decide exactly how a text message should be formatted, edit an attachment, or even turn a text message into a location.
The most important part of the message, either some text, a file attachment, or a location.
By default users do not have permission to send {@link LinkNode}, {@link ActionLinkNode}, or {@link ActionButtonNode}, as they can be used to trick the recipient.
Custom metadata you have set on the user. Default = no custom metadata
The message that you are replying to. Default = not a reply
Returns
Resolves with a reference to the newly created message. The promise rejects (throws an error) if you are not a participant with write access in this conversation.
conversationRef.send(params): MessageRef
Sends a message in the conversation
Parameters
interface SendTextMessageParams
Parameters you can pass when sending a message
The text to send in the message.
Custom metadata you have set on the user. Default = no custom metadata
The message that you are replying to. Default = not a reply
interface SendMessageParams
Parameters you can pass to {@link ConversationRef.send}.
Properties that are undefined will be set to the default.
This is the more advanced method for editing a message, giving full control over the message content. You can decide exactly how a text message should be formatted, edit an attachment, or even turn a text message into a location.
The most important part of the message, either some text, a file attachment, or a location.
By default users do not have permission to send {@link LinkNode}, {@link ActionLinkNode}, or {@link ActionButtonNode}, as they can be used to trick the recipient.
Custom metadata you have set on the user. Default = no custom metadata
The message that you are replying to. Default = not a reply
Returns
Resolves with a reference to the newly created message. The promise rejects (throws an error) if you are not a participant with write access in this conversation.
conversationRef._send(content, referencedMessageId, custom, idempotencyKey): MessageRef
Parameters
Returns
conversationRef.subscribeMessages(onSnapshot): MessageSubscription
Subscribes to the messages in the conversation.
Initially, you will be subscribed to the 10 most recent messages and any new messages. Call loadMore to load additional older messages.
Whenever a message is edited, a new message is received, or you load more messages, onSnapshot will fire and Subscription.latestSnapshot will be updated. loadedAll is true when the snapshot contains all the messages in the conversation.
The snapshot is null if you are not a participant in the conversation (including when the conversation doesn't exist)
Parameters
function called when the list of messages is updated
Returns
A subscription to messages.
conversationRef.subscribeParticipants(onSnapshot): ParticipantSubscription
Parameters
Returns
conversationRef.subscribe(onSnapshot): ConversationSubscription
Subscribes to the conversation.
Whenever Subscription.state.type is "active" and something about the conversation changes, onSnapshot will fire and Subscription.state.latestSnapshot will be updated. This includes changes to nested data. As an extreme example, onSnapshot would be called if snapshot.lastMessage.referencedMessage.sender.name changes.
The snapshot is null if you are not a participant in the conversation (including when the conversation doesn't exist)
Parameters
Returns
conversationRef.subscribeTyping(onSnapshot): TypingSubscription
Subscribes to the typing status of the conversation.
Whenever Subscription.state.type is "active" and the typing status changes, onSnapshot will fire and Subscription.state.latestSnapshot will be updated. This includes changes to nested data, such as when a user who is typing changes their name.
The snapshot is null if you are not a participant in the conversation (including when the conversation doesn't exist)
Note that if there are "many" people typing and another person starts to type, onSnapshot will not be called. This is because your existing {@link ManyTypingSnapshot} is still valid and did not change when the new person started to type.
Parameters
Returns
conversationRef.markAsTyping(): Unit
Marks the current user as typing in this conversation for 10 seconds.
This means that other users will see a typing indicator in the UI, from the current user.
The user will automatically stop typing after 10 seconds. You cannot manually mark a user as "not typing". Users are also considered "not typing" when they send a message, even if that message was sent from a different tab or using the REST API.
To keep the typing indicator visible for longer, call this function again to reset the 10s timer.
Returns
Usage
Example implementation
1let lastMarkedAsTyping = 0;inputElement.addEventListener("change", event => { const text = event.target.value; // Deleting your draft never counts as typing if (text.length === 0) { return; } const now = Date.now(); // Don't mark as typing more than once every 5s if (now - lastMarkedAsTyping 5000) { lastMarkedAsTyping = now; convRef.markAsTyping(); }});// When you send a message, you are no longer considered typing// So we need to send markAsTyping as soon as you type somethingfunction onSendMessage() { lastMarkedAsTyping = 0;}
A snapshot of a conversation's attributes at a given moment in time.
Also includes information about the current user's view of that conversation, such as whether or not notifications are enabled.
The ID of the conversation
Contains the conversation subject if it was set using ConversationBuilder.subject
Contains the URL of a photo was set using ConversationBuilder.subject
One of more welcome messages that will display to the user as a SystemMessage
Custom metadata you have set on the conversation
The date that the conversation was created, as a unix timestamp in milliseconds.
The date that the current user joined the conversation, as a unix timestamp in milliseconds.
The last message sent in this conversation, or null if not messages have been sent.
The number of messages in this conversation that the current user hasn't read.
The most recent date that the current user read the conversation.
This value is updated whenever you read a message in a chat UI, open an email notification, or mark the conversation as read using an API like ConversationRef.markAsRead.
Any messages sent after this timestamp are unread messages.
Everyone in the conversation has read any messages sent on or before this date.
This is the minimum of all the participants' readUntil values. Any messages sent on or before this timestamp should show a "read" indicator in the UI.
This value will rarely change in very large conversations. If just one person stops checking their messages, everyoneReadUntil will never update.
Whether the conversation should be considered unread.
This can be true even when unreadMessageCount is zero, if the user has manually marked the conversation as unread.
The current user's permission level in this conversation.
The current user's notification settings for this conversation.
false means no notifications, true means notifications for all messages, and "MentionsOnly" means that the user will only be notified when they are mentioned with an @.
new ConversationSnapshot.constructor(id, subject, photoUrl, welcomeMessages, custom, createdAt, joinedAt, lastMessage, unreadMessageCount, readUntil, everyoneReadUntil, isUnread, access, notify, lastMessageAt)
Parameters
A subscription to a specific conversation.
Get a ConversationSubscription by calling {@link ConversationRef.subscribe}
The current state of the subscription
An object with the following fields:
type is one of "pending", "active", "unsubscribed", or "error".
When type is "active", includes latestSnapshot: ConversationSnapshot | null, the current state of the conversation. latestSnapshot is null when you are not a participant or the conversation does not exist.
When type is "error", includes the error field. It is a JS Error object explaining what caused the subscription to be terminated.
Resolves when the subscription starts receiving updates from the server.
Resolves when the subscription permanently stops receiving updates from the server.
This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
Unsubscribe from this resource and stop receiving updates.
If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
A subscription to your most recently active conversations.
Get a ConversationListSubscription by calling {@link Session.subscribeConversations}.
The subscription is 'windowed'. Initially, this window contains the 20 most recent conversations. Conversations are ordered by last activity. The last activity of a conversation is either joinedAt or lastMessage.createdAt, whichever is higher.
The window will automatically expand to include any conversations you join, and any old conversations that receive new messages after subscribing.
You can expand this window by calling {@link ConversationListSubscription.loadMore}, which extends the window further into the past.
Remember to .unsubscribe the subscription once you are done with it.
The current state of the subscription
An object with the following fields:
type is one of "pending", "active", "unsubscribed", or "error".
When type is "active", includes latestSnapshot and loadedAll.
latestSnapshot: ConversationSnapshot[] the current state of the conversations in the window
loadedAll: boolean true when latestSnapshot contains all the conversations you are in
When type is "error", includes the error field. It is a JS Error object explaining what caused the subscription to be terminated.
Resolves when the subscription starts receiving updates from the server.
Wait for this promise if you want to perform some action as soon as the subscription is active.
The promise rejects if the subscription is terminated before it connects.
Resolves when the subscription permanently stops receiving updates from the server.
This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
Expand the window to include older conversations
Calling loadMore multiple times in parallel will still only load one page of conversations.
Avoid calling .loadMore in a loop until you have loaded all conversations. This is usually unnecessary: any time a conversation receives a message, it appears at the start of the list of conversations. If you do need to call loadMore in a loop, make sure you set a small upper bound (e.g. 100) on the number of conversations, where the loop will exit.
Unsubscribe from this resource and stop receiving updates.
If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
A snapshot of the typing indicators in a conversation at a given moment in time. Will be either {@link FewTypingSnapshot} when only a few people are typing, or {@link ManyTypingSnapshot} when many people are typing.
Currently {@link FewTypingSnapshot} is used when there are 5 or less people typing in the conversation, and {@link ManyTypingSnapshot} is used when more than 5 people are typing. This limit may change in the future, which will not be considered a breaking change.
Converting a TypingSnapshot to text
1function formatTyping(snapshot: TypingSnapshot): string { if (snapshot.many) { return "Several people are typing"; } const names = snapshot.users.map(user => user.name); if (names.length === 0) { return ""; } if (names.length === 1) { return names[0] + " is typing"; } if (names.length === 2) { return names.join(" and ") + " are typing"; } // Prefix last name with "and " names.push("and " + names.pop()); return names.join(", ") + " are typing";}
Check this to differentiate between FewTypingSnapshot (false) and ManyTypingSnapshot (true).
When false, you can see the list of users who are typing in the users property.
The users who are currently typing in this conversation.
The list is in chronological order, starting with the users who have been typing the longest. The current user is never contained in the list, only other users.
A subscription to the typing status in a specific conversation
Get a TypingSubscription by calling {@link ConversationRef.subscribeTyping}.
When there are "many" people typing (meaning you received {@link ManyTypingSnapshot}), the next update you receive will be {@link FewTypingSnapshot} once enough people stop typing. Until then, your {@link ManyTypingSnapshot} is still valid and doesn not need to changed, so onSnapshot will not be called.
The current state of the subscription
An object with the following fields:
type is one of "pending", "active", "unsubscribed", or "error".
When type is "active", includes latestSnapshot: TypingSnapshot | null. It is the current state of the typing indicators, or null if you're not a participant in the conversation
When type is "error", includes the error: Error field. It is a JS Error object explaining what caused the subscription to be terminated.
Resolves when the subscription starts receiving updates from the server.
Wait for this promise if you want to perform some action as soon as the subscription is active.
The promise rejects if the subscription is terminated before it connects.
Resolves when the subscription permanently stops receiving updates from the server.
This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
Unsubscribe from this resource and stop receiving updates.
If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.