From 680d0ce5479022fbf0acb2dbf7747f5274bf3ad4 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:22:38 +0200 Subject: [PATCH 01/18] Chat JS API refs: authentication --- src/pages/docs/chat/api/javascript/auth.mdx | 193 ++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/auth.mdx diff --git a/src/pages/docs/chat/api/javascript/auth.mdx b/src/pages/docs/chat/api/javascript/auth.mdx new file mode 100644 index 0000000000..30b46282c3 --- /dev/null +++ b/src/pages/docs/chat/api/javascript/auth.mdx @@ -0,0 +1,193 @@ +--- +title: Authentication +meta_description: "" +--- + +The [ChatClient](/docs/chat/api/javascript/chat-client) requires a realtime client generated by the core [Pub/Sub SDK](LINK) to establish a connection with Ably. This realtime client is used to handle authentication with Ably. + +There are broadly three mechanisms of authentication with Ably: + +* JSON Web Tokens (JWT): a standard JWT constructed to be compatible with Ably. +* Ably Tokens: a token generated by the Ably service for authentication. Your server can create a tokenRequest for clients to authenticate with Ably, or it can request an Ably Token directly from Ably and pass that to clients. +* Basic authentication: a method of authenticating using only your API key. This should only be used during development or server-side where it cannot be exposed. + +JWTs are recommended for authenticating in a production environment. Use Ably Tokens if your JWT is too large, such as when you are requesting a large set of capabilities, or have very long clientIds. This is because there is a limit on URL length in browsers when using JWTs as an accessToken query param. The other use-case for Ably Tokens is because claims are publicly visible in JWTs. Ably Tokens are encrypted so clientIds and capabilities cannot be inspected. + +--- + +## Pub/Sub constructor + +The Pub/Sub constructor instantiates a realtime client that can be passed to the [`ChatClient`](/docs/chat/api/javascript/chat-client). + +`new Ably.Realtime(ClientOptions clientOptions)` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `clientOptions` | The options to pass to customize the client connection. | [`ClientOptions`](#clientoptions) | + +### ClientOptions + +The following `ClientOptions` can be set: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `clientId` | *Optional* The identity of the client. It may also be implicit within an Ably Token or JWT. This is required to use the Chat SDK. | String | +| `authUrl` | *Optional* A URL that the SDK uses to obtain a fresh Ably Token or JWT. | String | +| `authCallback` | *Optional* A function in the form `function(tokenParams, callback(err, tokenOrTokenRequest))` which is called when a fresh Ably Token or JWT is required. | Callable | +| `key` | *Optional* A full API key obtained from your Ably dashboard. This should only used with basic authentication for your authentication server or for clients in development environments. | String | + +--- + +## Auth + +The `Auth` interface creates TokenRequest objects and obtains Ably Tokens from Ably to issue to less-trusted clients. + +Access it via `RealtimeClient.Auth`. + +### Properties + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `clientId` | The identity of the client. It may also be implicit within an Ably Token or JWT. This is required to use the Chat SDK. | String | + +--- + +## Fetch a new token + +`auth.authorize()` + +Instructs the SDK to fetch a new Ably Token or JWT. + +It upgrades the current realtime connection to use the new token if the client is already connected. If they haven't yet connected then it initiates a connection to Ably. + +Any [`TokenParams`](#tokenparams) and [`AuthOptions`](#authoptions) will be used as the new defaults for subsequent implicit and explicit token requests. They also entirely replace, as opposed to merging with, the current stored values. + +`authorize(TokenParams tokenParams?, AuthOptions authOptions?): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `tokenParams` | *Optional* The parameters of the token for the request. | [`TokenParams`](#tokenparams) | +| `authOptions` | *Optional* The authentication options for the request. | [`AuthOptions`](#authoptions) | + +#### TokenParams + +An object used in the parameters of token authentication requests for defining the required attributes of a token. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `capability` | *Optional* The JSON stringified [capabilities](/docs/auth/capabilities) for the token. If the request is successful, this will be an intersection of these capabilities and the issuing API key. | String | +| `clientId` | *Optional* The identity of the client. This is required to use the Chat SDK. | String | +| `nonce` | *Optional* An opaque string of at least 16 characters to ensure uniqueness of the request. | String | +| `timestamp` | *Optional* The timestamp of the request in milliseconds since the Unix epoch. Used with the `nonce` to ensure uniqueness of the request. | Integer | +| `ttl` | *Optional* The time to live for the token in milliseconds. The default is 60 minutes. | Integer | + +#### AuthOptions + +An object used when making authentication requests. If supplied it will replace the default values provided when the connection was established rather than merging with them. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `authCallback` | *Optional* A function in the form `function(tokenParams, callback(err, tokenOrTokenRequest))` which is called when a fresh Ably Token or JWT is required. | Callable | +| `authUrl` | *Optional* A URL that the SDK uses to obtain a fresh Ably Token or JWT. | String | +| `authMethod` | *Optional* The HTTP method to use for `authUrl` requests. Either `GET` or `POST`. The default is `GET`. | String | +| `authHeaders` | *Optional* A set of key-value pair headers to add to `authUrl` requests. | Object | +| `authParams` | *Optional* A set of key-value pairs to add to `authUrl` requests. When the `authMethod` is `GET` params are added to the URL. When the `authMethod` is `POST` they are sent as URL-encoded form data. | Object | +| `tokenDetails` | *Optional* An authenticated `TokenDetails` object. This is commonly used in testing. In production it is preferable to use a method that renews the token automatically since they are short-lived. | [`TokenDetails`](#tokendetails) | +| `key` | *Optional* A full API key string. Used for basic authentication requests. | String | +| `token` | *Optional* An authenticated token. Either a `TokenDetails` object, a token string from the `token` property of a `TokenDetails` component of a `TokenRequest` response, or a JWT. This is commonly used in testing. In production it is preferable to use a method that renews the token automatically since they are short-lived. | String \| Object | +| `queryTime` | *Optional* If `true`, queries Ably for the current time when issuing `TokenRequests`. The default is `false`. | Boolean | +| `useTokenAuth` | *Optional* If `true`, forces the SDK to use token authentication. | Boolean | + +#### TokenDetails + +Contains an Ably Token and its associated metadata. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `token` | The Ably Token itself. | String | +| `expires` | The timestamp of when the token expires in milliseconds since the Unix epoch. | Integer | +| `issued` | The timestamp of when the token was issued in milliseconds since the Unix epoch. | Integer | +| `capability` | *Optional* The [capabilities](/docs/auth/capabilities) associated with the token. | String | +| `clientId` | *Optional* The identity of the client. This is required to use the Chat SDK. | String | + +#### TokenRequest + +Contains the properties of a request for a token to Ably. Tokens are generated using [`requestToken()`](#requesttoken). + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `keyName` | The name of the API key against which the request was is made. Note that the name is public, whereas the secret is private. | String | +| `timestamp` | The timestamp of when the request was made in milliseconds since the Unix epoch. | Integer | +| `capability` | The [capabilities](/docs/auth/capabilities) for the token. If the request is successful, this will be an intersection of these capabilities and the issuing API key. | String | +| `nonce` | An opaque string of at least 16 characters to ensure uniqueness of the request. | String | +| `mac` | The Message Authentication Code (MAC) for the request. | String | +| `ttl` | *Optional* The time to live for the token in milliseconds. | Integer | +| `clientId` | *Optional* The identity of the client. This is required to use the Chat SDK. | String | + +### Returns + +Returns a promise. On success, the promise is fulfilled with the new [`TokenDetails`](#tokendetails) once the connection has been upgraded or initiated. On failure, the connection will move to the `SUSPENDED` or `FAILED` state, and the promise will be rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info) object which explains the error. + +--- + +## Create a tokenRequest + +`auth.createTokenRequest()` + +Creates and signs an Ably [`TokenRequest`](#tokenrequest) based on the specified [`TokenParams`](#tokenparams) and [`AuthOptions`](#authoptions). If no `TokenParams` or `AuthOptions` are specified it will use those already stored by the SDK, set in the [`ClientOptions`](#clientoptions) when the SDK was instantiated or updated via an [`authorize()`](#authorize) request. New values replace the existing ones rather than merging with them. + +`createTokenRequest(TokenParams tokenParams?, AuthOptions authOptions?): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `tokenParams` | *Optional* The parameters of the token for the request. | [`TokenParams`](#tokenparams) | +| `authOptions` | *Optional* The authentication options for the request. | [`AuthOptions`](#authoptions) | + +### Returns + +Returns a promise. On success it will be fulfilled with a [`TokenRequest`](#tokenrequest) object. Upon failure, the promise will be rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info) object which explains the error. + +--- + +## Request a token + +`auth.requestToken()` + +Calls the `requestToken` endpoint to obtain an Ably Token according to the specified [`TokenParams`](#tokenparams) and [`AuthOptions`](#authoptions). If no `TokenParams` or `AuthOptions` are specified it will use those already stored by the SDK, set in the [`ClientOptions`](#clientoptions) when the SDK was instantiated or updated via an [`authorize()`](#authorize) request. New values replace the existing ones rather than merging with them. + +`requestToken(TokenParams tokenParams?, AuthOptions authOptions?): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `tokenParams` | *Optional* The parameters of the token for the request. | [`TokenParams`](#tokenparams) | +| `authOptions` | *Optional* The authentication options for the request. | [`AuthOptions`](#authoptions) | + +### Returns + +Returns a promise. On success it will be fulfilled with a [`TokenDetails`](#tokendetails) object. Upon failure, the promise will be rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info) object which explains the error. From 51102cb09f5faff91e16616c96cc47b9ba9846c3 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:23:01 +0200 Subject: [PATCH 02/18] Chat JS API refs: chatClient --- .../docs/chat/api/javascript/chat-client.mdx | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/chat-client.mdx diff --git a/src/pages/docs/chat/api/javascript/chat-client.mdx b/src/pages/docs/chat/api/javascript/chat-client.mdx new file mode 100644 index 0000000000..ea05bc1a99 --- /dev/null +++ b/src/pages/docs/chat/api/javascript/chat-client.mdx @@ -0,0 +1,126 @@ +--- +title: ChatClient +meta_description: "" +--- + +The `ChatClient` class is the core client for Ably Chat. + +--- + +## Accessors + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `clientId` | The clientId of the current client. | String | +| `clientOptions` | The resolved client options for the client, including any defaults that have been set. | [`ChatClientOptions`](#chatclientoptions) | +| `connection` | The underlying connection to Ably, which can be used to monitor the client's connection to Ably servers. | [`Connection`](/docs/chat/api/javascript/connection) | +| `realtime` | The underlying Ably Realtime client. | [`Realtime`](#realtime) | +| `rooms` | The rooms object, which provides access to chat rooms. | [`Rooms`](/docs/chat/api/javascript/rooms) | + +--- + +## Constructor + +`new ChatClient()` + +Creates a new ChatClient instance. + +`new ChatClient(realtime: Realtime, clientOptions?: ChatClientOptions): ChatClient` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `realtime` | The Ably Realtime client. | [`Realtime`](https://sdk.ably.com/builds/ably/ably-js/main/typedoc/) | +| `clientOptions` | *Optional* The client options. | [`ChatClientOptions`](#chatclientoptions) | + +#### ChatClientOptions + +The following `ChatClientOptions` can be set: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `logLevel` | *Optional* The logging level to use. The default is `LogLevel.Error`. | [`LogLevel`](#loglevel) | +| `logHandler` | *Optional* A custom log handler. The default behavior will log messages to the console. | [`LogHandler`](#loghandler) | + +#### LogLevel + +An enum representing the different log levels. + +Logs of higher severity than the specified `LogLevel` are automatically logged. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Silent` | No logging will be performed. | +| `Trace` | Something routine and expected has occurred. This level will provide logs for the vast majority of operations and function calls. | +| `Debug` | Development information, messages that are useful when trying to debug library behavior, but superfluous to normal operation. | +| `Info` | Informational messages. Operationally significant to the library but not out of the ordinary. | +| `Warn` | Anything that is not immediately an error, but could cause unexpected behavior in the future. For example, passing an invalid value to an option. Indicates that some action should be taken to prevent future errors. | +| `Error` | A given operation has failed and cannot be automatically recovered. The error may threaten the continuity of operation. | + +#### LogHandler + +A function that handles log messages. + +`LogHandler: (message: string, level: LogLevel, context?: LogContext) => void` + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `message` | The message being logged. | String | +| `logLevel` | The log level of the message. | [`LogLevel`](#loglevel) | +| `context` | *Optional* The context of the log message as key-value pairs. | [`LogContext`](#logcontext) | + +#### LogContext + +Represents the context of a log message. It is an object of key-value pairs that can be used to provide additional context to a log message. + +`LogContext: Record` + +### Returns + +Returns a new `ChatClient` instance. + + +```javascript +import * as Ably from 'ably'; +import { ChatClient, LogLevel } from '@ably/chat'; + +const realtimeClient = new Ably.Realtime({ key: 'your-api-key' }); +const chatClient = new ChatClient(realtimeClient, { + logLevel: 'LogLevel.Debug' +}); +``` + + +--- + +## Realtime + +The Chat constructor requires a realtime client generated using the core [Pub/Sub SDK]() to establish a connection with Ably. The realtime client handles [authentication](/docs/chat/api/javascript/auth) with Ably. + +`new Ably.Realtime(ClientOptions clientOptions)` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `clientOptions` | The options to pass to customize the client connection. | [`ClientOptions`](#clientoptions) | + +### ClientOptions + +The following `ClientOptions` can be set: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `clientId` | *Optional* The identity of the client. It may also be implicit within an Ably Token or JWT. This is required to use the Chat SDK. | String | +| `authUrl` | *Optional* A URL that the SDK uses to obtain a fresh Ably Token or JWT. | String | +| `authCallback` | *Optional* A function in the form `function(tokenParams, callback(err, tokenOrTokenRequest))` which is called when a fresh Ably Token or JWT is required. | Callable | +| `key` | *Optional* A full API key obtained from your Ably dashboard. This should only used with basic authentication for your authentication server or for clients in development environments. | String | From a42b00f08d9113f7b42a9204b5fa857c76283912 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:23:13 +0200 Subject: [PATCH 03/18] Chat JS API refs: connection --- .../docs/chat/api/javascript/connection.mdx | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/connection.mdx diff --git a/src/pages/docs/chat/api/javascript/connection.mdx b/src/pages/docs/chat/api/javascript/connection.mdx new file mode 100644 index 0000000000..2ecb44bf0f --- /dev/null +++ b/src/pages/docs/chat/api/javascript/connection.mdx @@ -0,0 +1,103 @@ +--- +title: Connection +meta_description: "" +--- + +The `Connection` interface represents a connection to Ably. + +Access it via `chatClient.connection`. + +--- + +## Accessors + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `error` | The current error, if any, that caused the connection to enter the current status. | [`ErrorInfo`](/docs/chat/api/javascript/error-info) \| `undefined` | +| `status` | The current status of the connection. | [`ConnectionStatus`](#connectionstatus) | + +--- + +### ConnectionStatus + +A `Connection` is in one of the following states: + +| ConnectionStatus | Description | +| ---------------- | ----------- | +| `Initialized` | The connection has been initialized but has not yet been opened. | +| `Connecting` | The connection is currently attempting to open. | +| `Connected` | The connection is open and messages can be sent and received. | +| `Disconnected` | The connection is temporarily disconnected and will attempt to reconnect automatically. | +| `Suspended` | The connection is in an extended period of disconnection, but it will attempt to reconnect. Rooms will be reattached on a successful reconnection, however message history will not be automatically recovered. | +| `Failed` | The connection has permanently failed and will not attempt to reconnect. | + +--- + +## Listen for connection status changes + +`connection.onStatusChange()` + +Registers a listener that will be called whenever the connection status changes. + +`onStatusChange(listener: ConnectionStatusListener): StatusSubscription` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | The function to call when the status changes. | [`ConnectionStatusListener`](#connectionstatuslistener) | + +#### ConnectionStatusListener + +A function that can be called when the connection status changes. + +`ConnectionStatusListener: (change: ConnectionStatusChange) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `change` | The change in connection status. | [`ConnectionStatusChange`](#connectionstatuschange) | + +#### ConnectionStatusChange + +An interface that represents a change in connection status. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `previous` | The previous connection status. | [`ConnectionStatus`](#connectionstatus) | +| `current` | The current connection status. | [`ConnectionStatus`](#connectionstatus) | +| `reason` | *Optional* The error that caused the change, if any. | [`ErrorInfo`](/docs/chat/api/javascript/error-info) | +| `timestamp` | The time at which the status change occurred. | Date | + +### Returns + +Returns a [`StatusSubscription`](#statussubscription) object that can be used to unregister the listener. + +#### StatusSubscription + +An interface that represents a subscription to status change events. It also provides a method of cleaning up subscriptions that are no longer needed. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `off` | Unsubscribes from the status change events. | `() => void` | + + +```javascript +const subscription = chatClient.connection.onStatusChange((change) => { + console.log(`Connection status changed from ${change.previous} to ${change.current}`); + if (change.reason) { + console.error('Error:', change.reason); + } +}); + +// Unsubscribe when done +subscription.off(); +``` + From cb791e9e411f25338a62cfc379ec414e88fbe6a4 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:23:28 +0200 Subject: [PATCH 04/18] Chat JS API refs: errorInfo --- .../docs/chat/api/javascript/error-info.mdx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/error-info.mdx diff --git a/src/pages/docs/chat/api/javascript/error-info.mdx b/src/pages/docs/chat/api/javascript/error-info.mdx new file mode 100644 index 0000000000..7af7d207d0 --- /dev/null +++ b/src/pages/docs/chat/api/javascript/error-info.mdx @@ -0,0 +1,17 @@ +--- +title: ErrorInfo +meta_description: "" +--- + +The `ErrorInfo` class is a generic Ably error object that contains an Ably-specific status code, and a generic status code. Errors returned from the Ably server are compatible with the `ErrorInfo` structure and should result in errors that inherit from `ErrorInfo`. + +--- + +## Properties + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `code` | The Ably [error code](https://github.com/ably/ably-common/blob/main/protocol/errors.json). | Number | +| `statusCode` | The HTTP status code corresponding to this error, where applicable. | Number | +| `message` | Additional message information, where available. | String | +| `cause` | *Optional* The underlying cause of the error, where applicable. | String \| `ErrorInfo` \| `Error` | From 42595f1884d5000e7ea9249c4fa66f0f60486d1f Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:23:58 +0200 Subject: [PATCH 05/18] Chat JS API refs: message --- .../docs/chat/api/javascript/message.mdx | 393 ++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/message.mdx diff --git a/src/pages/docs/chat/api/javascript/message.mdx b/src/pages/docs/chat/api/javascript/message.mdx new file mode 100644 index 0000000000..f72a8a0929 --- /dev/null +++ b/src/pages/docs/chat/api/javascript/message.mdx @@ -0,0 +1,393 @@ +--- +title: Message +meta_description: "" +--- + +The `Message` interface represents a single message in a chat room. + +--- + +## Accessors + +It has the following accessors: + +| Accessor | Description | Type | +| -------- | ----------- | ---- | +| `isDeleted` | Indicates if the message has been deleted. | Boolean | +| `deletedAt` | The timestamp at which the message was deleted. | Date \| `undefined` | +| `deletedBy` | The clientId of the user who deleted the message. | String \| `undefined` | +| `isUpdated` | Indicates if the message has been updated. | Boolean | +| `updatedAt` | The timestamp at which the message was updated. | Date \| `undefined` | +| `updatedBy` | The clientId of the user who updated the message. | String \| `undefined` | + +--- + +## Properties + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `action` | The action type of the message. This can be used to determine if the message was created, updated, or deleted. | [`ChatMessageAction`](#chatmessageaction) | +| `clientId` | The clientId of the user who created the message. | String | +| `createdAt` | The timestamp at which the message was created. | Date | +| `headers` | The headers of a chat message. Headers enable attaching extra info to a message, which can be used for various features such as linking to a relative point in time of a livestream video or flagging this message as important or pinned. This value is always set. If there are no headers, this is an empty object. Do not use the headers for authoritative information. There is no server-side validation. When reading the headers, treat them like user input. | [`MessageHeaders`](#messageheaders) | +| `metadata` | The metadata of a chat message. Allows for attaching extra info to a message, which can be used for various features such as animations, effects, or simply to link it to other resources such as images, relative points in time, etc. This value is always set. If there is no metadata, this is an empty object. Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata treat it like user input. | [`MessageMetadata`](#messagemetadata) | +| `operation` | *Optional* The details of the operation that modified the message. This is only set for update and delete actions. It contains information about the operation: the clientId of the user who performed the operation, a description, and metadata. | [`Operation`](#operation) | +| `reactions` | The reactions summary for this message. | [`MessageReactions`](#messagereactions) | +| `serial` | The unique identifier of the message. | String | +| `text` | The text of the message. | String | +| `timestamp` | The timestamp at which this version was updated, deleted, or created. | Date | +| `version` | A unique identifier for the latest version of this message. | String | + +--- + +### ChatMessageAction + +An enum that represents the types of action of a message. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Create` | The message was created. | +| `Update` | The message was updated. | +| `Delete` | The message was deleted. | + +### MessageHeaders + +MessageHeaders enable attaching extra info to a message. Uses include linking to a relative point in time of a livestream video or flagging this message as important or pinned. + +`MessageHeaders: Record` + +### MessageMetadata + +MessageMetadata enables attaching extra info to a message. Uses include animations, effects, or simply to link it to other resources such as images or relative points in time. + +`MessageMetadata: Record` + +### Operation + +The details of an operation that modified a message. + +It has the following properties: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `clientId` | The clientId of the user who performed the operation. | String | +| `description` | A description of the operation. | String | +| `metadata` | Metadata associated with the operation. | [`MessageOperationMetadata`](#messageoperationmetadata) | + +#### MessageOperationMetadata + +The metadata contained in the `operations` field of a message. It represents the metadata supplied to a message update or deletion request. + +Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata, treat it like user input. + +`MessageOperationMetadata: Record` + +### MessageReactions + +Represents a summary of all [reactions on a message](/docs/chat/api/javascript/messages-reactions). + +It has the following properties: + +| Property | Description | +| -------- | ----------- | +| `distinct` | Map of reaction to the summary (total and clients) for reactions of type `MessageReactionType.Distinct`. | +| `multiple` | Map of reaction to the summary (total and clients) for reactions of type `MessageReactionType.Multiple`. | +| `unique` | Map of reaction to the summary (total and clients) for reactions of type `MessageReactionType.Unique`. | + +--- + +## Was message created after a given message + +`message.after()` + +Determines if the message was created after a given message. This comparison is based on global order, so does not necessarily represent the order that messages are received in realtime from the backend. + +`after(message: Message): boolean` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `message` | The message to compare against. | [`Message`](#message) | + +### Returns + +Returns `true` if this message was created after the given message, in global order. + +Throws an [`ErrorInfo`](/docs/chat/api/javascript/error-info) if: + +* The `serial` of either message is invalid. + + +```javascript +const isAfter = message1.after(message2); +``` + + +## Was message created before a given message + +`message.before()` + +Determines if the message was created before a given message. This comparison is based on global order, so does not necessarily represent the order that messages are received in realtime from the backend. + +`before(message: Message): boolean` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `message` | The message to compare against. | [`Message`](#message) | + +### Returns + +Returns `true` if this message was created before the given message, in global order. + +Throws an [`ErrorInfo`](/docs/chat/api/javascript/error-info) if: + +* The `serial` of either message is invalid. + + +```javascript +const isBefore = message1.before(message2); +``` + + +## Is message equal to a given message + +`message.equal()` + +Determines if the message is equal to a given message. + +Note that this method compares messages based on `Message.serial` alone. It returns `true` if the two messages represent different versions of the same message. + +`equal(message: Message): boolean` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `message` | The message to compare against. | [`Message`](#message) | + +### Returns + +Returns `true` if the two messages are the same message. + + +```javascript +const isEqual = message1.equal(message2); +``` + + +## Is message the same as a given message + +`message.isSameAs()` + +Alias for [`message.equal()`](LINK). + +`isSameAs(message: Message): boolean` + +## Is message a newer version of a given message + +`message.isNewerVersionOf()` + +Determines if a message is a newer version of a given message. + +Note that negating this function does not mean that the message is an older version of the same message, as the two may be different messages entirely. + +`isNewerVersionOf(message: Message): boolean` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `message` | The message to compare against. | [`Message`](#message) | + +### Returns + +Returns `true` if the two messages are the same message (`isSameAs` returns `true`) and this message is a newer version. + + +```javascript +const isNewer = message1.isNewerVersionOf(message2); +``` + + +## Is message an older version of a given message + +`message.isOlderVersionOf()` + +Determines if the message is an older version of a given message. + +Note that negating this function does not mean that the message is a newer version of the same message, as the two may be different messages entirely. + +`isOlderVersionOf(message: Message): boolean` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `message` | The message to compare against. | [`Message`](#message) | + +### Returns + +Returns `true` if the two messages are the same message (`isSameAs` returns true) and this message is an older version. + + +```javascript +const isOlder = message1.isOlderVersionOf(message2); +``` + + +## Is message the same version as a given message + +`message.isSameVersionAs()` + +Determines if the message is the same version as a given message. + +`isSameVersionAs(message: Message): boolean` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `message` | The message to compare against. | [`Message`](#message) | + +### Returns + +Returns `true` if the two messages are the same message and have the same version. + + +```javascript +const isSameVersion = message1.isSameVersionAs(message2); +``` + + +## Create a copy of a message + +`message.copy()` + +Creates a copy of the message with fields replaced per the parameters. This is used with [`messages.update()`](/docs/chat/api/javascript/messages#update) to easily create a copy of an existing message in order to update it. + +`copy(params?: MessageCopyParams): Message` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `params` | *Optional* The parameters to replace in the message. | [`MessageCopyParams`](#messagecopyparams) | + +#### MessageCopyParams + +The following `MessageCopyParams` can be set: + +| Parameters | Description | Type | +| ---------- | ----------- | ---- | +| `text` | *Optional* The new text for the message. | String | +| `metadata` | *Optional* The new metadata for the message. | [`MessageMetadata`](#messagemetadata) | +| `headers` | *Optional* The new headers for the message. | [`MessageHeaders`](#messageheaders) | + +### Returns + +Returns the message copy. + + +```javascript +const copiedMessage = message.copy({text: 'Updated text'}); +``` + + +## Create a new message with an event applied + +`message.with()` + +Creates a new message instance with the event applied. + +Note: This method will not replace the message reactions if the event is of type `Message`. + +`with(event: Message | ChatMessageEvent | MessageReactionSummaryEvent): Message` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `event` | The event to be applied to the returned message. | [`Message`](#message) \| [`ChatMessageEvent`](#chatmessageevent) \| [`MessageReactionSummaryEvent`](#messagereactionsummaryevent) | + +#### ChatMessageEvent + +The payload of a message event. + +It has the following properties: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `type` | The type of the message event. | [`ChatMessageEventType`](#chatmessageeventtype) | +| `data` | The message data. | [`Message`](#message) | + +#### ChatMessageEventType + +An enum that represents the types of message events. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Created` | Fires when a new message is created. | +| `Updated` | Fires when a message is updated. | +| `Deleted` | Fires when a message is deleted. | + +#### MessageReactionSummaryEvent + +An interface that represents a summary of message reactions. This event aggregates different types of reactions for a specific message. + +It has the following properties: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `type` | The type of the reaction event. | [`MessageReactionEventType`](#messagereactioneventtype) | +| `data` | The reaction summary data. | [`MessageReactions`](#messagereactions) | + +#### MessageReactionEventType + +An enum representing the different message reaction events. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Added` | A reaction was added. | +| `Removed` | A reaction was removed. | + +### Returns + +Returns a new message instance with the event applied. If the event is a no-op, such as an event for an old version, the same message is returned (not a copy). + +Throws an [`ErrorInfo`](/docs/chat/api/javascript/error-info) if: + +* The event is for a different message. +* The event if of the type `ChatMessageEventType.Created`. + + +```javascript +const updatedMessage = message.with(messageEvent); +``` + From 23883ca0a4db4c344f79fd44f998cc9b7d516b33 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:24:24 +0200 Subject: [PATCH 06/18] Chat JS API refs: messages --- .../docs/chat/api/javascript/messages.mdx | 414 ++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/messages.mdx diff --git a/src/pages/docs/chat/api/javascript/messages.mdx b/src/pages/docs/chat/api/javascript/messages.mdx new file mode 100644 index 0000000000..2fb4b728fc --- /dev/null +++ b/src/pages/docs/chat/api/javascript/messages.mdx @@ -0,0 +1,414 @@ +--- +title: Messages +meta_description: "" +--- + +The `Messages` interface is used to send and subscribe to messages in a chat room. + +Access it via `room.messages`. + +--- + +## Properties + +| Property | Description | Type | +| -------- | ----------- | ---- | +| reactions | Add, delete, and subscribe to message reactions. | [`MessageReactions`](/docs/chat/api/javascript/messages-reactions) | + +--- + +## Send a message + +`room.messages.send()` + +Send a message in the chat room. + +This method uses the Ably Chat API endpoint for sending messages. + +Note that the Promise may resolve before OR after the message is received from the realtime channel. This means you may see the message that was just sent in a callback to `subscribe()` before the returned promise resolves. + +`send(params: SendMessageParams): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `params` | An object containing the text, headers and metadata for the message. | [`SendMessageParams`](#sendmessageparams) | + +#### SendMessageParams + +The following `SendMessageParams` can be set: + +| Parameters | Description | Type | +| ---------- | ----------- | ---- | +| `text` | The text content of the message. | String | +| `metadata` | *Optional* Metadata to attach to the message. Allows for attaching extra info to a message, which can be used for various features such as animations, effects, or simply to link it to other resources such as images, relative points in time, etc. This value is always set on received messages. If there is no metadata, this is an empty object. Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata, treat it like user input. | [`MessageMetadata`](#messagemetadata) | +| `headers` | *Optional* Headers to attach to the message. Headers enable attaching extra info to a message, which can be used for various features such as linking to a relative point in time of a livestream video or flagging this message as important or pinned. This value is always set on received messages. If there are no headers, this is an empty object. Do not use the headers for authoritative information. There is no server-side validation. When reading the headers, treat them like user input. | [`MessageHeaders`](#messageheaders) | + +#### MessageMetadata + +Metadata enables attaching extra info to a message. Uses include animations, effects, or simply to link it to other resources such as images or relative points in time. + +`MessageMetadata: Record` + +#### MessageHeaders + +Headers enable attaching extra info to a message. Uses include linking to a relative point in time of a livestream video or flagging this message as important or pinned. + +`MessageHeaders: Record` + +### Returns + +Returns a promise. On success, the promise is fulfilled with the [`Message`](/docs/chat/api/javascript/message) object that was sent. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +const message = await room.messages.send({ + text: 'Hello, world!', + metadata: { priority: 'high' }, + headers: { timestamp: Date.now() } +}); +``` + + +--- + +## Update a message + +`room.messages.update()` + +Update a message in the chat room. + +Note that the Promise may resolve before or after the updated message is received from the room. This means you may see the update that was just sent in a callback to `subscribe()` before the returned promise resolves. + +The [`Message`](/docs/chat/api/javascript/message) instance returned by this method is the state of the message as a result of the update operation. If you have a subscription to message events via `subscribe()`, you should discard the message instance returned by this method and use the event payloads from the subscription instead. + +This method uses PUT-like semantics: if headers and metadata are omitted from the [`updateParams`](#updateparams), then the existing headers and metadata are replaced with the empty objects. + +`update(serial: Serial, updateParams: UpdateMessageParams, details?: OperationDetails): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `serial` | A string or object that conveys the serial of the message to update. | [`Serial`](#serial) | +| `updateParams` | The parameters for updating the message. | [`UpdateMessageParams`](#updatemessageparams) | +| `details` | *Optional* Optional details to record about the update action. | [`OperationDetails`](#operationdetails) | + +#### Serial + +A serial is used to identify a particular message, reaction or other chat event. It is the identifier for that event in the chat history. + +Serials can be conveyed either as a string, or an object that contains serial as a property. Message is included for type hinting and LLM purposes. + +The string-form of the serial should not be parsed or interpreted in any way, as it is subject to change without warning. + +`Serial: Message | string | { serial: string }` + +#### UpdateMessageParams + +The following `UpdateMessageParams` can be set: + +| Parameters | Description | Type | +| ---------- | ----------- | ---- | +| `text` | The new text content for the message. | String | +| `metadata` | *Optional* Metadata to attach to the message. This will replace the existing metadata on the message. Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata, treat it like user input. | [`MessageMetadata`](#messagemetadata) | +| `headers` | *Optional* Headers to attach to the message. This will replace the existing headers on the message. Do not use the headers for authoritative information. There is no server-side validation. When reading the headers, treat them like user input. | [`MessageHeaders`](#messageheaders) | + +#### OperationDetails + +Details to record about an operation (update or delete). + +| Parameters | Description | Type | +| ---------- | ----------- | ---- | +| `description` | *Optional* A description of the operation. | String | +| `metadata` | *Optional* Metadata associated with the operation. Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata, treat it like user input. | [`OperationMetadata`](#operationmetadata) | + +#### MessageOperationMetadata + +The metadata contained in the `operations` field of a message. It represents the metadata supplied to a message update or deletion request. + +Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata, treat it like user input. + +`OperationMetadata: Record` + +### Returns + +Returns a promise. On success, the promise is fulfilled with the updated [`Message`](/docs/chat/api/javascript/message) object. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +const updatedMessage = await room.messages.update( + message.serial, + { + text: 'Updated message text', + metadata: { edited: true, editedAt: Date.now() } + }, + { + description: 'Fixed typo' + } +); +``` + + +--- + +## Delete a message + +`room.messages.delete()` + +Delete a message in the chat room. + +This method performs a 'soft' delete, meaning the message is marked as deleted. + +Note that the Promise may resolve before or after the message is deleted from the realtime channel. This means you may see the message that was just deleted in a callback to `subscribe` before the returned promise resolves. + +The [`Message`](/docs/chat/api/javascript/message) instance returned by this method is the state of the message as a result of the delete operation. If you have a subscription to message events via `subscribe()`, you should discard the message instance returned by this method and use the event payloads from the subscription instead. + +Should you wish to restore a deleted message, and providing you have the appropriate permissions, you can simply send an update to the original message. + +`delete(serial: Serial, deleteMessageParams?: DeleteMessageParams): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `serial` | A string or object that conveys the serial of the message to delete. | [`Serial`](#serial) | +| `deleteMessageParams` | *Optional* Optional details to record about the delete action. | [`DeleteMessageParams`](#deletemessageparams) | + +#### DeleteMessageParams + +The following `DeleteMessageParams` can be set: + +| Parameters | Description | Type | +| ---------- | ----------- | ---- | +| `description` | *Optional* A description of why the message was deleted. | String | +| `metadata` | *Optional* Metadata associated with the deletion. Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata, treat it like user input. | [`OperationMetadata`](#operationmetadata) | + +### Returns + +Returns a promise. On success, the promise is fulfilled with the deleted [`Message`](/docs/chat/api/javascript/message) object. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +const deletedMessage = await room.messages.delete( + message.serial, + { + description: 'Message violated community guidelines', + metadata: { reason: 'inappropriate content' } + } +); +``` + + +--- + +## Get message history + +`room.messages.history()` + +Get messages that have been previously sent to the chat room, based on the provided options. + +Note that the [`historyBeforeSubscribe()`](#historybeforesubscribe) method enables clients to retrieve messages in a continuous manner when they first subscribe to a room, or rejoin after a period of disconnection. + +`history(options: QueryOptions): Promise>` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `options` | Options for the query. | [`QueryOptions`](#queryoptions) | + +#### QueryOptions + +The following `QueryOptions` can be set: + +| Parameters | Description | Type | +| ---------- | ----------- | ---- | +| `start` | *Optional* The start of the time window to query from. Messages with `timestamps` equal to or greater than this value will be returned. The default is the beginning of time. | Number | +| `end` | *Optional* The end of the time window to query to. Messages with `timestamps` less than this value will be returned. The default is now. | Number | +| `orderBy` | *Optional* The direction to query messages in. The default is `NewestFirst`. | [`OrderBy`](#orderby) | +| `limit` | *Optional* The maximum number of messages to return. The default is 100. | Number | + +#### OrderBy + +The order in which messages are returned in a history request. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `NewestFirst` | Query messages in descending order (newest to oldest). | +| `OldestFirst` | Query messages in ascending order (oldest to newest). | + +### Returns + +Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](#paginatedresult) containing an array of [`Message`](/docs/chat/api/javascript/message) objects. This paginated result can be used to fetch more messages if available. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +#### PaginatedResult + +A paginated result containing messages and methods to navigate through pages. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `items` | The array of messages in the current page. | [`Message`](/docs/chat/api/javascript/message)[] | +| `next` | A method to fetch the next page of results. Returns a promise with the next `PaginatedResult`. Throws if there are no more pages. | `() => Promise>` | +| `hasNext` | Indicates whether there are more pages available. | Boolean | +| `isLast` | Indicates whether this is the last page. | Boolean | + + +```javascript +const result = await room.messages.history({ + limit: 50, + direction: 'backwards' +}); + +console.log(`Retrieved ${result.items.length} messages`); + +if (result.hasNext) { + const nextPage = await result.next(); + console.log(`Retrieved ${nextPage.items.length} more messages`); +} +``` + + +--- + +## Subscribe to message events + +`room.messages.subscribe()` + +Subscribe to new messages in this chat room. + +`subscribe(listener: MessageListener): MessageSubscriptionResponse` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | Callback that will be called when a message event is received. | [`MessageListener`](#messagelistener) | + +#### MessageListener + +A listener that listens for message events. + +`MessageListener: (event: ChatMessageEvent) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `event` | A message event. | [`ChatMessageEvent`](#chatmessageevent) | + +#### ChatMessageEvent + +An interface that represents a message event. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `type` | The type of message event. | [`ChatMessageEventType`](#chatmessageeventtype) | +| `message` | The message associated with the event. | [`Message`](/docs/chat/api/javascript/message) | + +#### ChatMessageEventType + +An enum that represents the types of message events. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Created` | A new message was created. | +| `Updated` | A message was updated. | +| `Deleted` | A message was deleted. | + +### Returns + +Returns a [`MessageSubscriptionResponse`](#messagesubscriptionresponse) object that allows you to control the subscription. + +#### MessageSubscriptionResponse + +A response object that allows you to control the subscription. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `unsubscribe` | A method to unsubscribe from message events. | `() => Promise` | + +There is a difference between unsubscribing from messages and detaching from a room. Messages are sent to users as soon as they attach to a room, irrespective of whether a listener has been registered by calling `subscribe()`. Calling `unsubscribe()` only deregisters the listener. The `detach()` method detaches a user from the room. At that point a user will no longer receive any messages that are sent to the room. + +It has the following methods: + +| Method | Description | +| ------ | ----------- | +| [`historyBeforeSubscribe()`](#historybeforesubscribe) | Get the messages sent before the listener was subscribed. | + + +```javascript +const subscription = room.messages.subscribe((event) => { + switch (event.type) { + case 'message.created': + console.log('New message:', event.message.text); + break; + case 'message.updated': + console.log('Updated message:', event.message.text); + break; + case 'message.deleted': + console.log('Deleted message:', event.message.serial); + break; + } +}); + +// Unsubscribe when done +await subscription.unsubscribe(); +``` + + +--- + +## Get message history from before a subscription + +`historyBeforeSubscribe()` + +Get the messages that were sent to the room before the [listener was subscribed](#subscribe). This method is useful for providing conversational context when a user first joins a room, or when they subsequently rejoin it later on. It also ensures that the message history they see is continuous, without any overlap of messages being returned between their subscription and their history call. + +If the client experiences a discontinuity event, where the connection was lost and could not be resumed, the starting point of `historyBeforeSubscribe` is reset. Calls to `historyBeforeSubscribe` will wait for continuity to be restored before resolving. + +To ensure that no messages are missed, you should call `historyBeforeSubscribe` after any period of discontinuity to fill any gaps in the message history. + +`historyBeforeSubscribe( params: Omit,): Promise>` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `params` | The options for the query, omitting `orderBy`. | [`QueryOptions`](#queryoptions) | + + +### Returns + +Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](#paginatedresult) containing an array of [`Message`](/docs/chat/api/javascript/message) objects from newest to oldest. This paginated result can be used to fetch more messages if available. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +const { historyBeforeSubscribe } = room.messages.subscribe(listener); + +await historyBeforeSubscribe({ limit: 10 }); +``` + From 7b988ede49946542530ca202ec57c176bb937e6b Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:24:34 +0200 Subject: [PATCH 07/18] Chat JS API refs: messagesReactions --- .../api/javascript/messages-reactions.mdx | 265 ++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/messages-reactions.mdx diff --git a/src/pages/docs/chat/api/javascript/messages-reactions.mdx b/src/pages/docs/chat/api/javascript/messages-reactions.mdx new file mode 100644 index 0000000000..54f50cdc9f --- /dev/null +++ b/src/pages/docs/chat/api/javascript/messages-reactions.mdx @@ -0,0 +1,265 @@ +--- +title: MessagesReactions +meta_description: "" +--- + +The `MessagesReactions` interface is used to add, delete, and subscribe to reactions on individual messages. + +Access it via `room.messages.reactions`. + +--- + +## Send a message reaction + +`room.messages.reactions.send()` + +React to an existing message. + +`send(messageSerial: Serial, params: AddMessageReactionParams): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `messageSerial` | The serial of the message to react to. | [`Serial`](#serial) | +| `params` | Describe the reaction to add. | [`AddMessageReactionParams`](#addmessagereactionparams) | + +#### Serial + +A serial is used to identify a particular message, reaction or other chat event. It is the identifier for that event in the chat history. + +Serials can be conveyed either as a string, or an object that contains serial as a property. Message is included for type hinting and LLM purposes. + +The string-form of the serial should not be parsed or interpreted in any way, as it is subject to change without warning. + +`Serial: Message | string | { serial: string }` + +#### AddMessageReactionParams + +The parameters that can be added to a message reaction. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `count` | The count of the reaction for type `MessageReactionType.Multiple`. Defaults to 1 if not set. | Number | +| `name` | The reaction name to add, i.e. the emoji to use. | String | +| `type` | The type of reaction. Uses the default type configured in the [`MessageOptions`](/docs/chat/api/javascript/rooms#messageoptions) of the room if not set. | [`MessageReactionType`](#messagereactiontype) | + +#### MessageReactionType + +An enum that represents the types of reactions for a message. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Distinct` | Allows for at most one reaction of each type per client per message. It is possible for a client to add multiple reactions to the same message as long as they are different (e.g. different emojis). Duplicates are not counted in the summary. This is similar to reactions on Slack. | +| `Multiple` | Allows any number of reactions, including repeats, and they are counted in the summary. The reaction payload also includes a count of how many times each reaction should be counted (defaults to 1 if not set). This is similar to the clap feature on Medium. | +| `Unique` | Allows for at most one reaction per client per message. If a client reacts to a message a second time, only the second reaction is counted in the summary. This is similar to reactions on iMessage, Facebook Messenger or WhatsApp. | + +### Returns + +Returns a promise. On success, the promise is fulfilled when the reaction is added. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +await room.messages.reactions.send(message, { + name: '❤️', + type: MessageReactionType.Multiple, + count: 100, +}); +``` + + +--- + +## Delete a reaction from a message + +`room.messages.reactions.delete()` + +Delete a message reaction. + +`delete(messageSerial: Serial, params?: DeleteMessageReactionParams): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `messageSerial` | The serial of the message to remove the reaction from. | [`Serial`](#serial) | +| `params` | *Optional* The type of reaction annotation and the specific reaction to remove. The reaction to remove is required for all types except [`MessageReactionType.Unique`](#messagereactiontype). | [`DeleteMessageReactionParams`](#deletemessagereactionparams) | + +#### DeleteMessageReactionParams + +The following `DeleteMessageReactionParams` can be set: + +| Parameters | Description | Type | +| ---------- | ----------- | ---- | +| `name` | *Optional* The reaction to remove. Required for all reaction types except `Unique`. | String | +| `type` | *Optional* The type of reaction annotation. Defaults to the room's default reaction type if not specified. | [`MessageReactionType`](#messagereactiontype) | + +### Returns + +Returns a promise. On success, the promise is fulfilled when the reaction is deleted. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +await room.messages.reactions.delete(message.serial, { + type: '👍', + reactionType: 'reaction:unique.v1' +}); +``` + + +--- + +## Subscribe to message reaction summaries + +`room.messages.reactions.subscribe()` + +Subscribe to message reaction summaries. Use this to keep message reaction counts up to date efficiently in the UI. + +`subscribe(listener: MessageReactionListener): Subscription` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | The listener to call when a message reaction summary is received. | [`MessageReactionListener`](#messagereactionlistener) | + +#### MessageReactionListener + +A listener that listens for message reaction summary events. + +`MessageReactionListener: (event: MessageReactionSummaryEvent) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `event` | A message reaction summary event. Use with [`message.with()`](/docs/chat/api/javascript/message#with) to keep an up-to-date reaction count. | [`MessageReactionSummaryEvent`](#messagereactionsummaryevent) | + +#### MessageReactionSummaryEvent + +An interface that represents a summary of message reactions. It aggregates different reaction types such as distinct, multiple, and unique for a specific message. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `type` | The type of reaction event. | [`MessageReactionEventType.Summary`](#messagereactioneventtype) | +| `summary` | The message reactions summary. | `{summary: { distinct: SummaryDistinct Values, messageSerial: string, multiple: SummaryMultipleValues, unique: SummaryUniqueValues, }` | + +The properties of a `summary` are: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `distinct` | Map of distinct reactions. | `SummaryDistinctValues` | +| `multiple` | Map of multiple reactions. | `SummaryMultipleValues` | +| `distinct` | Map of unique reactions. | `SummaryUniqueValues` | +| `messageSerial` | The message serial. | String | + +#### MessageReactionEventType + +An enum representing the different message reaction events. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Create` | A reaction was added. | +| `Delete` | A reaction was removed. | +| `Summary` | The reaction summary was updated for the message. | + +### Returns + +Returns a [`Subscription`](#subscription) object that can be used to unsubscribe from message reactions. + +#### Subscription + +A response object that allows you to control the subscription. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `unsubscribe` | A method to unsubscribe from message reaction events. | `() => Promise` | + +--- + +## Subscribe to individual reaction events + +`room.messages.reactions.subscribeRaw()` + +Subscribe to individual reaction events. + +Note that [reaction summaries](#subscribe) are recommended for the majority of use cases, especially if you only need to keep track of reaction counts and clients. + +`subscribeRaw(listener: MessageRawReactionListener): Subscription` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | The listener to call when a message reaction event is received. | [`MessageRawReactionListener`](#messagerawreactionlistener) | + +#### MessageRawReactionListener + +A listener that listens for individual message reaction events. + +`MessageRawReactionListener: (event: MessageRawReactionEvent) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `event` | An individual message reaction event. | [`MessageRawReactionEvent`](#messagerawreactionevent) | + +#### MessageRawReactionEvent + +An interface that represents an individual message reaction event. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `timestamp` | The timestamp when the reaction event occurred. | Date | +| `type` | The type of reaction event. | [`MessageReactionEventType.Create`](#messagereactioneventtype) \| [`MessageReactionEventType.Delete`](#messagereactioneventtype) | +| `reaction` | The message reaction that was received. | `reaction: { clientId: string; count?: number; messageSerial: string; name: string; type: MessageReactionType;}` | + +The properties of a `reaction` are: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `clientId` | The client ID of the user who added or removed the reaction. | String | +| `count` | The count of the reaction for type `MessageReactionType.Multiple`. | Number | +| `messageSerial` | The serial of the message that was reacted to. | String | +| `name` | The reaction name, i.e. the emoji that was used. | String | +| `type` | The reaction that was added or removed. | [`MessageReactionType`](#messagereactiontype) | + +### Returns + +Returns a [`Subscription`](#subscription) object that can be used to unsubscribe from message reactions. + + +```javascript +const subscription = room.messages.reactions.subscribeRaw((event) => { + if (event.type === 'MessageReactionEventType.Create') { + console.log(`${event.clientId} reacted to message ${event.messageSerial} with ${event.reaction}`); + } else { + console.log(`${event.clientId} removed ${event.reaction} from message ${event.messageSerial}`); + } +}); + +// Unsubscribe when done +await subscription.unsubscribe(); +``` + From c8c657c5a698314a84f712dfaa242c47bb9e1d12 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:24:54 +0200 Subject: [PATCH 08/18] Chat JS API refs: occupancy --- .../docs/chat/api/javascript/occupancy.mdx | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/occupancy.mdx diff --git a/src/pages/docs/chat/api/javascript/occupancy.mdx b/src/pages/docs/chat/api/javascript/occupancy.mdx new file mode 100644 index 0000000000..643d81aef6 --- /dev/null +++ b/src/pages/docs/chat/api/javascript/occupancy.mdx @@ -0,0 +1,102 @@ +--- +title: Occupancy +meta_description: "" +--- + +The `Occupancy` interface is used to subscribe to occupancy updates and fetch the occupancy metrics of a room. + +Access it via `room.occupancy`. + +--- + +## Get the room occupancy + +`room.occupancy.get()` + +Get the current occupancy of the room as an instantaneous value from the server. + +`get(): Promise` + +### Returns + +Returns a promise. On success, the promise is fulfilled with an `OccupancyData` object containing the current occupancy metrics. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +#### OccupancyData + +An interface that represents an occupancy data of a chat room. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `connections` | The number of connections attached to the channel. | `number` | +| `presenceMembers` | The number of users entered into the [presence](/docs/chat/api/javascript/presence) set. | `number` | + +--- + +## Get the current room occupancy + +`room.occupancy.current()` + +Get the latest occupancy data received from realtime events. + +`current(): undefined | OccupancyData` + +### Returns + +The latest occupancy data, or undefined if no realtime events have been received in the room yet. + +-- + +## Subscribe to occupancy + +`room.occupancy.subscribe()` + +Subscribe the provided listener to occupancy occupancy events. + +`subscribe(listener: OccupancyListener): Subscription` + +### Parameters + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | Function called when an occupancy update is received | `OccupancyListener` | + +#### OccupancyListener + +A listener that listens for occupancy events. + +`OccupancyListener: (event: OccupancyEvent) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `event` | An occupancy event. | [`OccupancyEvent`](#occupancyevent) | + +#### OccupancyEvent + +An interface that represents an occupancy event. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `occupancy` | The occupancy data associated with the event. Contains the number of `connections` and `presenceMembers`. | `occupancy: { connections: number; presenceMembers: number }` | +| `type` | The type of the occupancy event. Will always be `Updated`. || + +### Returns + +Returns a [`Subscription`](#subscription) object that can be used to unsubscribe the listener. + +#### Subscription + +A response object that allows you to control the subscription. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `unsubscribe` | A method to unsubscribe from occupancy events. | `() => Promise` | From db7fc3548745fc7887101816585082f49975973e Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:25:07 +0200 Subject: [PATCH 09/18] Chat JS API refs: presence --- .../docs/chat/api/javascript/presence.mdx | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/presence.mdx diff --git a/src/pages/docs/chat/api/javascript/presence.mdx b/src/pages/docs/chat/api/javascript/presence.mdx new file mode 100644 index 0000000000..7851a6b9ec --- /dev/null +++ b/src/pages/docs/chat/api/javascript/presence.mdx @@ -0,0 +1,311 @@ +--- +title: Presence +meta_description: "" +--- + +The `Presence` interface is used to enter and subscribe to the presence set of a chat room. + +Access it via `room.presence`. + +--- + +## Enter the presence set + +`room.presence.enter()` + +Enters the client into the presence set. Will emit an `enter` event to all subscribers. Repeat calls will trigger `update` events. + +`enter(data?: unknown): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `data` | *Optional* The user's data, a JSON serializable object that will be sent to all subscribers. | Unknown | + +### Returns + +Returns a promise. On success, the promise is fulfilled. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +Throws if: + +* The room is not in the `attached` or `attaching` state. + + +```javascript +await room.presence.enter({status: 'online', activity: 'viewing'}); +``` + + +--- + +## Update presence data + +`room.presence.update()` + +Updates a client's presence `data`. Will emit an `update` event to all subscribers. If the client is not already in the presence set, it will be treated as an [`enter`](LINK) event. + +`update(data?: unknown): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `data` | *Optional* The user's data, a JSON serializable object that will be sent to all subscribers. | Unknown | + +### Returns + +Returns a promise. On success, the promise is fulfilled. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +Throws if: + +* The room is not in the `attached` or `attaching` state. + + +```javascript +await room.presence.update({status: 'away', lastSeen: new Date()}); +``` + + +--- + +## Leave the presence set + +`room.presence.leave()` + +Removes the client from the presence set. Will emit a `leave` event to all subscribers. If the client is not already part of the presence set, it will be treated as a no-op. + +`leave(data?: unknown): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `data` | *Optional* The user's data, a JSON serializable object that will be sent to all subscribers. | Unknown | + +### Returns + +Returns a promise. On success, the promise is fulfilled. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +Throws if: + +* The room is not in the `attached` or `attaching` state. + + +```javascript +await room.presence.leave({reason: 'User logged out'}); +``` + + +--- + +## Get current presence members + +`room.presence.get()` + +Get a list of the current users in the presence set by returning the latest presence message for each. + +`get(params?: RealtimePresenceParams): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `params` | *Optional* Parameters that control how the presence set is retrieved. | [`RealtimePresenceParams`](#realtimepresenceparams) | + +#### RealtimePresenceParams + +Parameters for retrieving presence members. + +It has the following properties: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `waitForSync` | *Optional* Whether to wait for a full presence set synchronization between Ably and the clients on the channel before returning the results. Synchronization begins as soon as the channel is attached. When set to `true`, the results will be returned as soon as the sync is complete. When set to `false`, the current list of members will be returned without the sync completing. The default is `true`. | Boolean | +| `clientId` | *Optional* Filters the array of returned presence members for a specific client using its ID. | String | +| `connectionId` | *Optional* Filters the array of returned presence members for a specific connection. | String | + +### Returns + +Returns a promise. On success, the promise is fulfilled with an array of [`PresenceMember`](#presencemember). On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +#### PresenceMember + +Represents a member in the presence set. + +It has the following properties: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `clientId` | The client ID of the presence member. | String | +| `data` | The data associated with the presence member. | Unknown | +| `extras` | The extras associated with the presence member. | Unknown | +| `updatedAt` | The timestamp when this presence member was last updated. | Number | + + +```javascript +const members = await room.presence.get(); +console.log(`${members.length} users present`); +``` + + +--- + +## Check if a user is present + +`room.presence.isUserPresent()` + +Check if a user is part of the presence set using their `clientId`. + +`isUserPresent(clientId: string): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `clientId` | The client ID to check if it is present in the room. | String | + +### Returns + +Returns a promise. On success, the promise is fulfilled with a boolean indicating whether the user is present. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +Throws if: + +* The room is not in the `attached` or `attaching` state. + + +```javascript +const isPresent = await room.presence.isUserPresent('user123'); +if (isPresent) { + console.log('User is currently in the room'); +} +``` + + +--- + +## Subscribe to specific presence events + +`room.presence.subscribe()` + +Subscribe the provided listener to a list of presence events. + +Note: This requires presence events to be enabled via the `enableEvents` option in the [`PresenceOptions`](LINK) provided to the room. If this is not enabled, an error will be thrown. + +`subscribe(eventOrEvents: PresenceEventType | PresenceEventType[], listener?: PresenceListener): Subscription` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `eventOrEvents` | Single event name or array of events to subscribe to. | [`PresenceEventType`](#presenceeventtype) \| `PresenceEventType`[] | +| `listener` | *Optional* Listener to register. | [`PresenceListener`](#presencelistener) | + +#### PresenceEventType + +An enum that represents the types of presence events. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Enter` | A member has entered the presence set. | +| `Leave` | A member has left the presence set. | +| `Update` | A member has updated their presence data. | +| `Present` | Get the current presence set when subscribing. | + +#### PresenceListener + +A listener that listens for presence events. + +`PresenceListener: (event: PresenceEvent) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `event` | A presence event. | [`PresenceEvent`](#presenceevent) | + +#### PresenceEvent + +Represents a presence event. + +It has the following properties: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `type` | The type of presence event. | [`PresenceEventType`](#presenceeventtype) | +| `member` | The presence member associated with the event. | [`PresenceMember`](#presencemember) | + +### Returns + +Returns a [`Subscription`](#subscription) object. + +Throws an [`ErrorInfo`](/docs/chat/api/javascript/error-info) with `code` 40000 if: + +* Presence events are not enabled. + + +```javascript +const subscription = room.presence.subscribe(['enter', 'leave'], (presenceEvent) => { + console.log(`${presenceEvent.member.clientId} ${presenceEvent.type} the room`); +}); + +// Unsubscribe when done +subscription.unsubscribe(); +``` + + +#### Subscription + +A response object that allows you to control the subscription. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `unsubscribe` | A method to unsubscribe from room presence events. | `() => Promise` | + +--- + +## Subscribe to all presence events + +`subscribe(listener?: PresenceListener): Subscription` + +Subscribe the provided listener to all presence events. + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | *Optional* Listener to subscribe. | [`PresenceListener`](#presencelistener) | + +#### Returns + +Returns a [`Subscription`](#subscription) object. + +Throws an [`ErrorInfo`](/docs/chat/api/javascript/error-info) with code 40000 if: + +* Presence events are not enabled. + + +```javascript +const subscription = room.presence.subscribe((presenceEvent) => { + console.log('Presence event:', presenceEvent.type, presenceEvent.member); +}); +``` + From 0594d1e089c1edd409ecc8db01e1d4bce4705185 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:25:22 +0200 Subject: [PATCH 10/18] Chat JS API refs: roomReactions --- .../chat/api/javascript/room-reactions.mdx | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/room-reactions.mdx diff --git a/src/pages/docs/chat/api/javascript/room-reactions.mdx b/src/pages/docs/chat/api/javascript/room-reactions.mdx new file mode 100644 index 0000000000..32d857ac2f --- /dev/null +++ b/src/pages/docs/chat/api/javascript/room-reactions.mdx @@ -0,0 +1,147 @@ +--- +title: RoomReactions +meta_description: "" +--- + +The `RoomReactions` interface is used to send and subscribe to ephemeral, room-level reactions. + +Access it via `room.reactions`. + +--- + +## Send a room reaction + +`room.reactions.send()` + +Send a reaction to the room including some metadata. + +`send(params: SendReactionParams): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `params` | An object containing the type, headers and metadata of the room reaction. | [`SendReactionParams`](#sendreactionparams) | + +#### SendReactionParams + +The following `SendReactionParams` parameters can be set: + +| Parameters | Description | Type | +| ---------- | ----------- | ---- | +| `name` | The name of the reaction. | String | +| `metadata` | *Optional* Metadata associated with the reaction. | [`Metadata`](#roomreactionmetadata) | +| `headers` | *Optional* Headers associated with the reaction. | [`Headers`](#roomreactionheaders) | + +#### RoomReactionHeaders + +`RoomReactionHeaders` enable attaching extra info to a reaction. Do not use headers for authoritative information. There is no server-side validation. When reading the headers, treat them like user input. + +`RoomReactionHeaders: Record` + +#### RoomReactionMetadata + +`RoomReactionMetadata` enables attaching extra info to a reaction. Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata, treat it like user input. + +`RoomReactionMetadata: Record` + +### Returns + +Returns a promise. On success, the promise is fulfilled when the reaction was sent. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +Note that it is possible to receive your own reaction via the reactions listener before this promise resolves. + +Throws if: + +* The `Connection` is not in the `Connected` state. + + +```javascript +await room.reactions.send({ + name: '👍', + metadata: { userId: 'user123' } +}); +``` + + +--- + +## Subscribe to room reactions + +`room.reactions.subscribe()` + +Subscribe to receive room-level reactions. + +`subscribe(listener: RoomReactionListener): Subscription` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | The listener function to be called when a reaction is received. | [`RoomReactionListener`](#roomreactionlistener) | + +#### RoomReactionListener + +A listener that listens for room reaction events. + +`RoomReactionListener: (event: RoomReactionEvent) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `event` | A room reaction event. | [`RoomReaction`](#roomreactionevent) | + +#### RoomReactionEvent + +An interface that represents a room reaction event. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `roomReaction` | The reaction that was received. | [`RoomReaction`](#roomreaction) | +| `type` | The type of reaction. | Reaction | + +#### RoomReaction + +An interface that represents a room reaction event. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `name` | The name of the reaction. | String | +| `clientId` | The client ID of the user who sent the reaction. | String | +| `timestamp` | The timestamp when the reaction was sent. | Date | +| `metadata` | *Optional* Metadata associated with the reaction. | [`RoomReactionMetadata`](#roomreactionmetadata) | +| `headers` | *Optional* Headers associated with the reaction. | [`RoomReactionHeaders`](#roomreactionheaders) | + +### Returns + +Returns a [`Subscription`](#subscription) object that allows you to control the subscription. + +#### Subscription + +A response object that allows you to control the subscription. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `unsubscribe` | A method to unsubscribe from room reaction events. | `() => Promise` | + + +```javascript +const subscription = room.reactions.subscribe((reaction) => { + console.log(`${reaction.clientId} reacted with ${reaction.type}`); +}); + +// Unsubscribe when done +await subscription.unsubscribe(); +``` + From 106701a54303ced9b4fed32bf313e6d3186aafb4 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:25:31 +0200 Subject: [PATCH 11/18] Chat JS API refs: room --- src/pages/docs/chat/api/javascript/room.mdx | 218 ++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/room.mdx diff --git a/src/pages/docs/chat/api/javascript/room.mdx b/src/pages/docs/chat/api/javascript/room.mdx new file mode 100644 index 0000000000..5001eb0595 --- /dev/null +++ b/src/pages/docs/chat/api/javascript/room.mdx @@ -0,0 +1,218 @@ +--- +title: Room +meta_description: "" +--- + +The `Room` interface represents a chat room. + +Access it via `ChatClient.rooms.get(name)`. + +--- + +## Accessors + +It has the following accessors: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `name` | The unique name of the room. | String | +| `status` | The current status of the room. | [`RoomStatus`](#roomstatus) | +| `error` | The current error, if any, that caused the room to enter the current status. | [`ErrorInfo`](/docs/chat/api/javascript/error-info) \| `undefined` | +| `channel` | The underlying Ably realtime channel used for the room. | [`RealtimeChannel`](LINK) | +| `messages` | Allows you to send, subscribe to, and query messages in the room. | [`Messages`](LINK) | +| `presence` | Interact with presence events in the room. | [`Presence`](LINK) | +| `occupancy` | Interact with occupancy metrics for the room. | [`Occupancy`](LINK) | +| `reactions` | Interact with room-level reactions. | [`RoomReactions`](LINK) | +| `typing` | Interact with typing events in the room. | [`Typing`](LINK) | + +--- + +## RoomStatus + +A `Room` is in one of the following states: + +| RoomStatus | Description | +| ---------- | ----------- | +| `Initializing` | The SDK is initializing the room. | +| `Initialized` | A temporary state when a room is first initialized. | +| `Attaching` | The room is attaching to Ably. | +| `Attached` | The room is attached to Ably. | +| `Detaching` | The room is detaching from Ably. | +| `Detached` | The room is detached from Ably. | +| `Failed` | The room failed to attach to Ably. | +| `Suspended` | The room is suspended, and automatic reattachment has been temporarily disabled. | +| `Releasing` | The room is in the process of releasing and is no long usable. | +| `Released` | The room is released and no longer usable. | + +--- + +## Attach to a room + +`room.attach()` + +Attaches to the room in order to receive events in realtime. + +If a room fails to attach, it will enter either the `Suspended` or `Failed` [state](#roomstatus). + +If the room enters the `Failed` state, then the SDK will not automatically retry attaching and intervention is required. + +If the room enters the `Suspended` state, then the call to attach will reject with an [`ErrorInfo`](/docs/chat/api/javascript/error-info) that caused the suspension. However, the SDK will retry attaching to the room automatically after a delay. + +`attach(): Promise` + +### Returns + +Returns a promise. On success, the promise is fulfilled and the room begins receiving real-time events. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +const room = await client.rooms.get('room:general'); +await room.attach(); +``` + + +--- + +## Detach from a room + +`room.detach()` + +Detaches from the room to stop receiving events. + +`detach(): Promise` + +### Returns + +Returns a promise. On success, the promise is fulfilled and the room stops receiving events. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +await room.detach(); +``` + + +--- + +## Listen for RoomStatus changes + +`room.onStatusChange()` + +Registers a listener that is called whenever the [`RoomStatus`](#roomstatus) changes. + +`onStatusChange(listener: RoomStatusListener): StatusSubscription` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | Function called when the room status changes. | [`RoomStatusListener`](#roomstatuslistener) | + +#### RoomStatusListener + +A function that is called when the [`RoomStatus`](#roomstatus) of a room changes. + +`RoomStatusListener: (change: RoomStatusChange) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `change` | The change in `RoomStatus`. | [`RoomStatusChange`](#roomstatuschange) | + +#### RoomStatusChange + +An interface that represents a change in the [`RoomStatus`](#roomstatus) of a room. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `previous` | The previous status of the room. | [`RoomStatus`](#roomstatus) | +| `current` | The current status of the room. | [`RoomStatus`](#roomstatus) | +| `error` | *Optional* The error that caused the change. | [`ErrorInfo`](/docs/chat/api/javascript/error-info) | + +### Returns + +Returns a `StatusSubscription` object with an `off()` method to remove the listener. + + +```javascript +room.onStatusChange((status) => { + console.log(`Room status changed to: ${status}`); +}); +``` + + +#### StatusSubscription + +An interface that represents a subscription to status change events. It also provides a method of cleaning up subscriptions that are no longer needed. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `off` | Unsubscribes from the status change events. It will ensure that no further status change events will be sent to the subscriber and that references to the subscriber are cleaned up. | Method | + +`off: () => void` + +--- + +## Register a discontinuity handler + +`room.onDiscontinuity()` + +Registers a handler that is called whenever a discontinuity is detected. Discontinuity occurs when a connection is interrupted and a `Room` cannot be resumed from its previous state. + +If the discontinuity lasts for less than 2 minutes, then the SDK will automatically reattach to any rooms and replay any missed messages once it reconnects. + +If the discontinuity last for longer than 2 minutes, then use [`historyBeforeSubscribe()`](/docs/chat/api/javascript/messages#historybeforesubscribe) to retrieve any missed messages. + +`onDiscontinuity(handler: DiscontinuityListener): StatusSubscription` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `handler` | Function called when a discontinuity is detected. | `DiscontinuityListener` | + +#### DiscontinuityListener + +A handler for discontinuity events. + +`DiscontinuityListener: (error: ErrorInfo) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `error` | The error that occurred to cause the discontinuity. | [`ErrorInfo`](/docs/chat/api/javascript/error-info) | + +### Returns + +Returns a `StatusSubscription` object with an `off()` method to remove the handler. + + +```javascript +const { off } = room.onDiscontinuity((reason: ErrorInfo) => { + // Recover from the discontinuity +}); +``` + + +--- + +## Get RoomOptions + +`room.options()` + +Returns the [`RoomOptions`](/docs/chat/api/javascript/rooms#roomoptions) used to create the room. + +`options(): RoomOptions` + +### Returns + +Returns a copy of the [`RoomOptions`](/docs/chat/api/room#roomoptions) used to create the room. From 6d9d9a998922520ddf39bed0248060a5c3bc20a9 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:25:37 +0200 Subject: [PATCH 12/18] Chat JS API refs: rooms --- src/pages/docs/chat/api/javascript/rooms.mdx | 127 +++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/rooms.mdx diff --git a/src/pages/docs/chat/api/javascript/rooms.mdx b/src/pages/docs/chat/api/javascript/rooms.mdx new file mode 100644 index 0000000000..d9c448371c --- /dev/null +++ b/src/pages/docs/chat/api/javascript/rooms.mdx @@ -0,0 +1,127 @@ +--- +title: Rooms +meta_description: "" +--- + +The `Rooms` interface manages the lifecycle of chat rooms. + +Access it via `ChatClient.rooms`. + +--- + +## Create a room + +`ChatClient.Rooms.get()` + +Create or retrieve `Room` object. Optionally provide custom configuration to the room. + +Call [`release()`](#release-a-room) when the `Room` object is no longer needed. If a call to `get()` is made for a room that is currently being released, then the promise will only resolve when the release operation is complete. + +If a call to `get()` is made, followed by a subsequent call to `release()` before the promise resolves, then the promise will reject with an error. + +`get(name: string, options?: RoomOptions): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `name` | The name of the room to create or retrieve. | String | +| `options` | *Optional* Custom configuration options for the room. | [`RoomOptions`](#roomoptions) | + +#### RoomOptions + +The following `RoomOptions` can be set: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `messages` | *Optional* The configuration for messages in the room. | [`MessageOptions`](#messageoptions) | +| `occupancy` | *Optional* The configuration for occupancy in the room. | [`OccupancyOptions`](#occupancyoptions) | +| `presence` | *Optional* The configuration for presence in the room. | [`PresenceOptions`](#presenceoptions) | +| `typing` | *Optional* The configuration for typing indicators in the room. | [`TypingOptions`](#typingoptions) | + +#### MessageOptions + +The following `MessageOptions` can be set: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `defaultMessageReactionType` | *Optional* The default type of message reaction. Other types can still be sent by specifying the `type` parameter when reacting to a message. The default value is `distinct`. | [`MessageReactionType`](#messagereactiontype) | +| `rawMessageReactions` | *Optional* Whether subscribers should receive individual message reactions, rather than just aggregates. The default value is `false`. | Boolean | + +#### MessageReactionType + +An enum that represents the types of reactions for a message. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `Distinct` | Allows for at most one reaction of each type per client per message. It is possible for a client to add multiple reactions to the same message as long as they are different (e.g. different emojis). Duplicates are not counted in the summary. This is similar to reactions on Slack. | +| `Multiple` | Allows any number of reactions, including repeats, and they are counted in the summary. The reaction payload also includes a count of how many times each reaction should be counted (defaults to 1 if not set). This is similar to the clap feature on Medium. | +| `Unique` | Allows for at most one reaction per client per message. If a client reacts to a message a second time, only the second reaction is counted in the summary. This is similar to reactions on iMessage, Facebook Messenger or WhatsApp. | + +#### OccupancyOptions + +The following `OccupancyOptions` can be set: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `enableEvents` | *Optional* Sets whether the client should receive [occupancy](#occupancy) events. If enabled, the client will receive messages detailing the changing room occupancy. The default value is `false`. | Boolean | + +#### PresenceOptions + +The following `PresenceOptions` can be set: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `enableEvents` | *Optional* Sets whether the client should receive [presence](#presence) events. If enabled, the client will presence updates about other clients in the room. Note that even if the client hasn't subscribed to presence, they are still streamed presence events by the server. Clients can also still register their presence in the room without receiving presence events. The default value is `true`. | Boolean | + +#### TypingOptions + +The following `TypingOptions` can be set: + +| Properties | Description | Type | +| ---------- | ----------- | ---- | +| `heartbeatThrottleMs` | *Optional* Set the minimum time interval between consecutive `typing.started` events. The interval is reset after a `typing.stopped` event. The default value is `10000`. | Number | + +### Returns + +Returns a promise. On success, the promise is fulfilled with the new or existing room object. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info) if a room with the same name but different `options` already exists. + + +```javascript +const room = await chatClient.rooms.get('livestream-1', {occupancy: {enableEvents: true}}); +``` + + +--- + +## Release a room + +`ChatClient.Rooms.release()` + +Releases a `Room` object, allowing for it to be garbage collected. + +This will release the reference to the `Room` object from the `Rooms` collection and detach it from Ably. It does not unsubscribe the client from any events. Call [`Rooms.get()`](LINK) if you want to get the `Room` object back. + +`release(name: string): Promise` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `name` | The name of the room to release. | String | + +### Returns + +Returns a promise. On success, the promise is fulfilled. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + + +```javascript +await rooms.release('livestream-1'); +``` + From d630b74acd4cacf8505c59b2c00ccb2c57015cbb Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:25:49 +0200 Subject: [PATCH 13/18] Chat JS API refs: typing --- src/pages/docs/chat/api/javascript/typing.mdx | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/pages/docs/chat/api/javascript/typing.mdx diff --git a/src/pages/docs/chat/api/javascript/typing.mdx b/src/pages/docs/chat/api/javascript/typing.mdx new file mode 100644 index 0000000000..ce373df019 --- /dev/null +++ b/src/pages/docs/chat/api/javascript/typing.mdx @@ -0,0 +1,193 @@ +--- +title: Typing +meta_description: "" +--- + +The `Typing` interface is used to send typing events on keystrokes and subscribe to typing events emitted by other users. + +Access it via `room.typing`. + +--- + +## Get the users currently typing + +`room.typing.current()` + +Get the set of users that are currently typing in the room by their `clientId`s. + +`current(): Set` + +### Returns + +Returns the set of `clientId`s of all users that are currently typing. + + +```javascript +const currentlyTypingClientIds = room.typing.current(); +``` + + +--- + +## Start typing + +`room.typing.keystroke()` + +Send a `typing.started` event to the server. Events are throttled according to the [`heartbeatThrottleMs RoomOption`](/docs/chat/api/javascript/rooms#typingoptions). If an event has already been sent within the configured interval then the operation is a no-op. + +Calls to `keystroke()` and `stop()` are serialized and will always resolve in the correct order. + +* For example, if multiple `keystroke()` calls are made in quick succession before the first `keystroke()` call has sent a `typing.started` event to the server, followed by one `stop()` call, the `stop()` call will execute as soon as the first `keystroke()` call completes. All intermediate `keystroke()` calls will be treated as no-ops. +* The most recent `keystroke()` or `stop()` will always determine the final state, ensuring operations resolve to a consistent and correct state. + +`keystroke(): Promise` + +#### Returns + +Returns a promise. On success, the promise is fulfilled. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +Throws if: + +* The `Connection` is not in the `Connected` state. +* The operation fails to send the event to the server. +* There is a problem acquiring the mutex that controls serialization. + + +```javascript +await room.typing.keystroke(); +``` + + +--- + +## Stop typing + +`room.typing.stop()` + +Send a `typing.stopped` event to the server. If an event has already been sent within the configured interval then the operation is a no-op. + +Calls to `keystroke()` and `stop()` are serialized and will always resolve in the correct order. + +* For example, if multiple `keystroke()` calls are made in quick succession before the first `keystroke()` call has sent a `typing.started` event to the server, followed by one `stop()` call, the `stop()` call will execute as soon as the first `keystroke()` call completes. All intermediate `keystroke()` calls will be treated as no-ops. +* The most recent `keystroke()` or `stop()` will always determine the final state, ensuring operations resolve to a consistent and correct state. + +`stop(): Promise` + +### Returns + +Returns a promise. On success, the promise is fulfilled. On failure, the promise is rejected with an [`ErrorInfo`](/docs/chat/api/javascript/error-info). + +Throws if: + +* The `Connection` is not in the `Connected` state. +* The operation fails to send the event to the server. +* There is a problem acquiring the mutex that controls serialization. + + +```javascript +await room.typing.stop(); +``` + + +--- + +## Subscribe to typing events + +`room.typing.subscribe()` + +Subscribe to all typing events by registering a listener. + +`subscribe(listener: TypingListener): Subscription` + +### Parameters + +Use the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `listener` | Function called when a typing event is received. | `TypingListener` | + +#### TypingListener + +A listener that listens for typing events. + +`TypingListener: (event: TypingSetEvent) => void` + +It uses the following parameters: + +| Parameter | Description | Type | +| --------- | ----------- | ---- | +| `event` | A typing event. | [`TypingSetEvent`](#typingsetevent) | + +#### TypingSetEvent + +An interface that represents a change in the state of currently typing users. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `change` | The change that resulted in the new set of users currently typing. Contains the `clientId` of the user and whether they started or stopped typing. | `change: { clientId: string; type: [TypingEventType](#typingeventtype) }` | +| `currentlyTyping` | The set of `clientId`s that are currently typing. | `Set` | +| `type` | The type of event. | [`TypingSetEventType`](#typingseteventtype) | + +The following is an example of a TypingSetEvent: + + +```json +{ + "type": "typing.set.changed", + "currentlyTyping": { + "clemons", + "zoranges", + }, + "change": { + "type": "typing.started", + "clientId": "clemons" + } +} +``` + + +#### TypingEventType + +An enum that represents the types of events emitted by users typing in a room. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `typing.started` | Sent when a user starts typing. | +| `typing.stopped` | Sent when a user stops typing. | + +#### TypingSetEventType + +An enum representing the typing set event types. + +It has the following members: + +| Member | Description | +| ------ | ----------- | +| `SetChanged` | Event triggered when a change occurs in the set of users currently typing. | + +### Returns + +Returns a [`Subscription`](#subscription) object with an `unsubscribe()` method to remove the listener. + + +```javascript +const {unsubscribe} = room.typing.subscribe((event) => { + console.log(event); +}); +``` + + +#### Subscription + +A response object that allows you to control the subscription. + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `unsubscribe` | A method to unsubscribe from typing events. | `() => Promise` | From 430bcd8a70de6f99e33b1d760863a6310a025e96 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:26:02 +0200 Subject: [PATCH 14/18] Chat JS API refs: update navigation --- src/data/nav/chat.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/data/nav/chat.ts b/src/data/nav/chat.ts index 9a2e2d828f..7aea59dc68 100644 --- a/src/data/nav/chat.ts +++ b/src/data/nav/chat.ts @@ -168,6 +168,63 @@ export default { link: '/docs/api/chat-rest', name: 'REST API', }, + { + name: 'JavaScript SDK', + pages: [ + { + name: 'ChatClient', + link: '/docs/chat/api/javascript/chat-client', + }, + { + name: 'Authentication', + link: '/docs/chat/api/javascript/auth', + }, + { + name: 'Connection', + link: '/docs/chat/api/javascript/connection', + }, + { + name: 'Rooms', + link: '/docs/chat/api/javascript/rooms', + }, + { + name: 'Room', + link: '/docs/chat/api/javascript/room', + }, + { + name: 'Room reactions', + link: '/docs/chat/api/javascript/room-reactions', + }, + { + name: 'Message', + link: '/docs/chat/api/javascript/message', + }, + { + name: 'Messages', + link: '/docs/chat/api/javascript/messages', + }, + { + name: 'Message reactions', + link: '/docs/chat/api/javascript/messages-reactions', + }, + { + name: 'Presence', + link: '/docs/chat/api/javascript/presence', + }, + { + name: 'Occupancy', + link: '/docs/chat/api/javascript/occupancy', + }, + { + name: 'Typing', + link: '/docs/chat/api/javascript/typing', + }, + { + name: 'ErrorInfo', + link: '/docs/chat/api/javascript/error-info', + }, + ], + }, ], }, ], From d836428d01a46c30217b3bef2f37d9c22e7689c7 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Fri, 11 Jul 2025 18:08:03 +0200 Subject: [PATCH 15/18] Ensure RoomOptions are referenced in relevant interfaces --- src/pages/docs/chat/api/javascript/occupancy.mdx | 2 ++ src/pages/docs/chat/api/javascript/presence.mdx | 2 ++ src/pages/docs/chat/api/javascript/typing.mdx | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/docs/chat/api/javascript/occupancy.mdx b/src/pages/docs/chat/api/javascript/occupancy.mdx index 643d81aef6..88db784ef6 100644 --- a/src/pages/docs/chat/api/javascript/occupancy.mdx +++ b/src/pages/docs/chat/api/javascript/occupancy.mdx @@ -5,6 +5,8 @@ meta_description: "" The `Occupancy` interface is used to subscribe to occupancy updates and fetch the occupancy metrics of a room. +Occupancy is disabled in a room by default. Enable it using the `enableEvents` property in the [`OccupancyOptions`](/docs/chat/api/javascript/rooms#OccupancyOptions) of a room. + Access it via `room.occupancy`. --- diff --git a/src/pages/docs/chat/api/javascript/presence.mdx b/src/pages/docs/chat/api/javascript/presence.mdx index 7851a6b9ec..6794636989 100644 --- a/src/pages/docs/chat/api/javascript/presence.mdx +++ b/src/pages/docs/chat/api/javascript/presence.mdx @@ -5,6 +5,8 @@ meta_description: "" The `Presence` interface is used to enter and subscribe to the presence set of a chat room. +Presence is enabled in a room by default. Disable it using the `enableEvents` property in the [`PresenceOptions`](/docs/chat/api/javascript/rooms#PresenceOptions) of a room. + Access it via `room.presence`. --- diff --git a/src/pages/docs/chat/api/javascript/typing.mdx b/src/pages/docs/chat/api/javascript/typing.mdx index ce373df019..82eb4c685f 100644 --- a/src/pages/docs/chat/api/javascript/typing.mdx +++ b/src/pages/docs/chat/api/javascript/typing.mdx @@ -33,7 +33,7 @@ const currentlyTypingClientIds = room.typing.current(); `room.typing.keystroke()` -Send a `typing.started` event to the server. Events are throttled according to the [`heartbeatThrottleMs RoomOption`](/docs/chat/api/javascript/rooms#typingoptions). If an event has already been sent within the configured interval then the operation is a no-op. +Send a `typing.started` event to the server. Events are throttled according to the [`heartbeatThrottleMs TypingOption`](/docs/chat/api/javascript/rooms#typingoptions). If an event has already been sent within the configured interval then the operation is a no-op. Calls to `keystroke()` and `stop()` are serialized and will always resolve in the correct order. From 04c3869b732fd277fc6e7ebd525e8f0b9edf11a9 Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Fri, 11 Jul 2025 18:40:00 +0200 Subject: [PATCH 16/18] Centralise all subscription interfaces --- src/data/nav/chat.ts | 4 + .../docs/chat/api/javascript/connection.mdx | 12 +-- .../api/javascript/messages-reactions.mdx | 14 +--- .../docs/chat/api/javascript/messages.mdx | 22 +---- .../docs/chat/api/javascript/occupancy.mdx | 12 +-- .../docs/chat/api/javascript/presence.mdx | 18 ++--- .../chat/api/javascript/room-reactions.mdx | 12 +-- src/pages/docs/chat/api/javascript/room.mdx | 14 +--- .../chat/api/javascript/subscriptions.mdx | 81 +++++++++++++++++++ src/pages/docs/chat/api/javascript/typing.mdx | 12 +-- 10 files changed, 100 insertions(+), 101 deletions(-) create mode 100644 src/pages/docs/chat/api/javascript/subscriptions.mdx diff --git a/src/data/nav/chat.ts b/src/data/nav/chat.ts index 7aea59dc68..bf7db4a56f 100644 --- a/src/data/nav/chat.ts +++ b/src/data/nav/chat.ts @@ -219,6 +219,10 @@ export default { name: 'Typing', link: '/docs/chat/api/javascript/typing', }, + { + name: 'Subscriptions', + link: '/docs/chat/api/javascript/subscriptions', + }, { name: 'ErrorInfo', link: '/docs/chat/api/javascript/error-info', diff --git a/src/pages/docs/chat/api/javascript/connection.mdx b/src/pages/docs/chat/api/javascript/connection.mdx index 2ecb44bf0f..84579f3410 100644 --- a/src/pages/docs/chat/api/javascript/connection.mdx +++ b/src/pages/docs/chat/api/javascript/connection.mdx @@ -76,17 +76,7 @@ It has the following properties: ### Returns -Returns a [`StatusSubscription`](#statussubscription) object that can be used to unregister the listener. - -#### StatusSubscription - -An interface that represents a subscription to status change events. It also provides a method of cleaning up subscriptions that are no longer needed. - -It has the following properties: - -| Property | Description | Type | -| -------- | ----------- | ---- | -| `off` | Unsubscribes from the status change events. | `() => void` | +Returns a [`StatusSubscription`](/docs/chat/api/javascript/subscriptions#statussubscription) object that can be used to unregister the listener. ```javascript diff --git a/src/pages/docs/chat/api/javascript/messages-reactions.mdx b/src/pages/docs/chat/api/javascript/messages-reactions.mdx index 54f50cdc9f..33b407a3ba 100644 --- a/src/pages/docs/chat/api/javascript/messages-reactions.mdx +++ b/src/pages/docs/chat/api/javascript/messages-reactions.mdx @@ -179,17 +179,7 @@ It has the following members: ### Returns -Returns a [`Subscription`](#subscription) object that can be used to unsubscribe from message reactions. - -#### Subscription - -A response object that allows you to control the subscription. - -It has the following properties: - -| Property | Description | Type | -| -------- | ----------- | ---- | -| `unsubscribe` | A method to unsubscribe from message reaction events. | `() => Promise` | +Returns a [`Subscription`](/docs/chat/api/javascript/subscriptions#subscription) object that can be used to unsubscribe from message reactions. --- @@ -247,7 +237,7 @@ The properties of a `reaction` are: ### Returns -Returns a [`Subscription`](#subscription) object that can be used to unsubscribe from message reactions. +Returns a [`Subscription`](/docs/chat/api/javascript/subscriptions#subscription) object that can be used to unsubscribe from message reactions. ```javascript diff --git a/src/pages/docs/chat/api/javascript/messages.mdx b/src/pages/docs/chat/api/javascript/messages.mdx index 2fb4b728fc..edd6fefb83 100644 --- a/src/pages/docs/chat/api/javascript/messages.mdx +++ b/src/pages/docs/chat/api/javascript/messages.mdx @@ -337,25 +337,7 @@ It has the following members: ### Returns -Returns a [`MessageSubscriptionResponse`](#messagesubscriptionresponse) object that allows you to control the subscription. - -#### MessageSubscriptionResponse - -A response object that allows you to control the subscription. - -It has the following properties: - -| Property | Description | Type | -| -------- | ----------- | ---- | -| `unsubscribe` | A method to unsubscribe from message events. | `() => Promise` | - -There is a difference between unsubscribing from messages and detaching from a room. Messages are sent to users as soon as they attach to a room, irrespective of whether a listener has been registered by calling `subscribe()`. Calling `unsubscribe()` only deregisters the listener. The `detach()` method detaches a user from the room. At that point a user will no longer receive any messages that are sent to the room. - -It has the following methods: - -| Method | Description | -| ------ | ----------- | -| [`historyBeforeSubscribe()`](#historybeforesubscribe) | Get the messages sent before the listener was subscribed. | +Returns a [`MessageSubscriptionResponse`](/docs/chat/api/javascript/subscriptions#messagesubscriptionresponse) object that allows you to control the subscription. ```javascript @@ -386,6 +368,8 @@ await subscription.unsubscribe(); Get the messages that were sent to the room before the [listener was subscribed](#subscribe). This method is useful for providing conversational context when a user first joins a room, or when they subsequently rejoin it later on. It also ensures that the message history they see is continuous, without any overlap of messages being returned between their subscription and their history call. +`historyBeforeSubscribe()` is returned in the [`MessageSubscriptionResponse`](/docs/chat/api/javascript/subscriptions#messagesubscriptionresponse) object when you call [`subscribe()`](#subscribe). + If the client experiences a discontinuity event, where the connection was lost and could not be resumed, the starting point of `historyBeforeSubscribe` is reset. Calls to `historyBeforeSubscribe` will wait for continuity to be restored before resolving. To ensure that no messages are missed, you should call `historyBeforeSubscribe` after any period of discontinuity to fill any gaps in the message history. diff --git a/src/pages/docs/chat/api/javascript/occupancy.mdx b/src/pages/docs/chat/api/javascript/occupancy.mdx index 88db784ef6..cf80b67d00 100644 --- a/src/pages/docs/chat/api/javascript/occupancy.mdx +++ b/src/pages/docs/chat/api/javascript/occupancy.mdx @@ -91,14 +91,4 @@ It has the following properties: ### Returns -Returns a [`Subscription`](#subscription) object that can be used to unsubscribe the listener. - -#### Subscription - -A response object that allows you to control the subscription. - -It has the following properties: - -| Property | Description | Type | -| -------- | ----------- | ---- | -| `unsubscribe` | A method to unsubscribe from occupancy events. | `() => Promise` | +Returns a [`Subscription`](/docs/chat/api/javascript/subscriptions#subscription) object that can be used to unsubscribe the listener. diff --git a/src/pages/docs/chat/api/javascript/presence.mdx b/src/pages/docs/chat/api/javascript/presence.mdx index 6794636989..45b45e76d4 100644 --- a/src/pages/docs/chat/api/javascript/presence.mdx +++ b/src/pages/docs/chat/api/javascript/presence.mdx @@ -253,7 +253,7 @@ It has the following properties: ### Returns -Returns a [`Subscription`](#subscription) object. +Returns a [`Subscription`](/docs/chat/api/javascript/subscriptions#subscription) object. Throws an [`ErrorInfo`](/docs/chat/api/javascript/error-info) with `code` 40000 if: @@ -270,24 +270,16 @@ subscription.unsubscribe(); ``` -#### Subscription - -A response object that allows you to control the subscription. - -It has the following properties: - -| Property | Description | Type | -| -------- | ----------- | ---- | -| `unsubscribe` | A method to unsubscribe from room presence events. | `() => Promise` | - --- ## Subscribe to all presence events -`subscribe(listener?: PresenceListener): Subscription` +`room.presence.subscribeAll()` Subscribe the provided listener to all presence events. +`subscribe(listener?: PresenceListener): Subscription` + ### Parameters Use the following parameters: @@ -298,7 +290,7 @@ Use the following parameters: #### Returns -Returns a [`Subscription`](#subscription) object. +Returns a [`Subscription`](/docs/chat/api/javascript/subscriptions#subscription) object. Throws an [`ErrorInfo`](/docs/chat/api/javascript/error-info) with code 40000 if: diff --git a/src/pages/docs/chat/api/javascript/room-reactions.mdx b/src/pages/docs/chat/api/javascript/room-reactions.mdx index 32d857ac2f..4dd22ab0bd 100644 --- a/src/pages/docs/chat/api/javascript/room-reactions.mdx +++ b/src/pages/docs/chat/api/javascript/room-reactions.mdx @@ -123,17 +123,7 @@ It has the following properties: ### Returns -Returns a [`Subscription`](#subscription) object that allows you to control the subscription. - -#### Subscription - -A response object that allows you to control the subscription. - -It has the following properties: - -| Property | Description | Type | -| -------- | ----------- | ---- | -| `unsubscribe` | A method to unsubscribe from room reaction events. | `() => Promise` | +Returns a [`Subscription`](/docs/chat/api/javascript/subscriptions#subscription) object that allows you to control the subscription. ```javascript diff --git a/src/pages/docs/chat/api/javascript/room.mdx b/src/pages/docs/chat/api/javascript/room.mdx index 5001eb0595..93cfe83eb7 100644 --- a/src/pages/docs/chat/api/javascript/room.mdx +++ b/src/pages/docs/chat/api/javascript/room.mdx @@ -135,7 +135,7 @@ It has the following properties: ### Returns -Returns a `StatusSubscription` object with an `off()` method to remove the listener. +Returns a [`StatusSubscription`](/docs/chat/api/javascript/subscriptions#statussubscription) object with an `off()` method to remove the listener. ```javascript @@ -145,18 +145,6 @@ room.onStatusChange((status) => { ``` -#### StatusSubscription - -An interface that represents a subscription to status change events. It also provides a method of cleaning up subscriptions that are no longer needed. - -It has the following properties: - -| Property | Description | Type | -| -------- | ----------- | ---- | -| `off` | Unsubscribes from the status change events. It will ensure that no further status change events will be sent to the subscriber and that references to the subscriber are cleaned up. | Method | - -`off: () => void` - --- ## Register a discontinuity handler diff --git a/src/pages/docs/chat/api/javascript/subscriptions.mdx b/src/pages/docs/chat/api/javascript/subscriptions.mdx new file mode 100644 index 0000000000..47fe458cf5 --- /dev/null +++ b/src/pages/docs/chat/api/javascript/subscriptions.mdx @@ -0,0 +1,81 @@ +--- +title: Subscriptions +meta_description: "" +--- + +The following interfaces are used to manage the lifecycle of subscriptions. + +## Subscription + +A response object that allows you to control the subscription. + +### Properties + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `unsubscribe` | A method to unsubscribe from events. | `() => Promise` | + +### Returned by + +It is returned by the following methods: + +* [`room.messages.reactions.subscribe()`](/docs/chat/api/javascript/messages-reactions#subscribe) +* [`room.messages.reactions.subscribeRaw()`](/docs/chat/api/javascript/messages-reactions#subscriberaw) +* [`room.occupancy.subscribe()`](/docs/chat/api/javascript/occupancy#subscribe) +* [`room.presence.subscribe()`](/docs/chat/api/javascript/presence#subscribe) +* [`room.presence.subscribeAll()`](/docs/chat/api/javascript/presence#subscribeall) +* [`room.reactions.subscribe()`](/docs/chat/api/javascript/room-reactions#subscribe) +* [`room.typing.subscribe()`](/docs/chat/api/javascript/typing#subscribe) + +--- + +## MessageSubscriptionResponse + +A response object that allows you to control the subscription to message events. + +### Properties + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `unsubscribe` | A method to unsubscribe from message events. | `() => Promise` | + +There is a difference between unsubscribing from messages and detaching from a room. Messages are sent to users as soon as they attach to a room, irrespective of whether a listener has been registered by calling `subscribe()`. Unsubscribing only deregisters the listener. The [`detach()`](/docs/chat/api/javascript/room#detach) method detaches a user from the room. At that point a user will no longer receive any messages that are sent to the room. + +### Methods + +It has the following methods: + +| Method | Description | +| ------ | ----------- | +| [`historyBeforeSubscribe()`](/docs/chat/api/javascript/messages#historybeforesubscribe) | Get the messages sent before the listener was subscribed. | + +### Returned by + +It is returned by the following methods: + +* [`room.messages.subscribe()`]()/docs/chat/api/javascript/messages#subscribe) + +--- + +## StatusSubscription + +An interface that represents a subscription to status change events. It also provides a method of cleaning up subscriptions that are no longer needed. + +### Properties + +It has the following properties: + +| Property | Description | Type | +| -------- | ----------- | ---- | +| `off` | Unsubscribes from the status change events. It will ensure that no further status change events will be sent to the subscriber and that references to the subscriber are cleaned up. | `() => void` | + +### Returned by + +It is returned by the following methods: + +* [`connection.onStatusChange()`](/docs/chat/api/javascript/connection#onstatuschange) +* [`room.onStatusChange()`](/docs/chat/api/javascript/room#onstatuschange) diff --git a/src/pages/docs/chat/api/javascript/typing.mdx b/src/pages/docs/chat/api/javascript/typing.mdx index 82eb4c685f..b70fdfc830 100644 --- a/src/pages/docs/chat/api/javascript/typing.mdx +++ b/src/pages/docs/chat/api/javascript/typing.mdx @@ -172,7 +172,7 @@ It has the following members: ### Returns -Returns a [`Subscription`](#subscription) object with an `unsubscribe()` method to remove the listener. +Returns a [`Subscription`](/docs/chat/api/javascript/subscriptions#subscription) object with an `unsubscribe()` method to remove the listener. ```javascript @@ -181,13 +181,3 @@ const {unsubscribe} = room.typing.subscribe((event) => { }); ``` - -#### Subscription - -A response object that allows you to control the subscription. - -It has the following properties: - -| Property | Description | Type | -| -------- | ----------- | ---- | -| `unsubscribe` | A method to unsubscribe from typing events. | `() => Promise` | From bcdbad11ae1d2da4a87182e32d3094e6150cf92d Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Wed, 16 Jul 2025 13:50:33 +0200 Subject: [PATCH 17/18] Update and add links for Chat API refs and add meta_descriptions --- src/pages/docs/chat/api/javascript/auth.mdx | 4 ++-- .../docs/chat/api/javascript/chat-client.mdx | 6 +++--- .../docs/chat/api/javascript/connection.mdx | 2 +- .../docs/chat/api/javascript/error-info.mdx | 2 +- .../docs/chat/api/javascript/message.mdx | 20 +++++++++---------- .../api/javascript/messages-reactions.mdx | 2 +- .../docs/chat/api/javascript/messages.mdx | 12 +++++------ .../docs/chat/api/javascript/occupancy.mdx | 2 +- .../docs/chat/api/javascript/presence.mdx | 6 +++--- .../chat/api/javascript/room-reactions.mdx | 2 +- src/pages/docs/chat/api/javascript/room.mdx | 16 +++++++-------- src/pages/docs/chat/api/javascript/rooms.mdx | 14 ++++++------- .../chat/api/javascript/subscriptions.mdx | 12 +++++------ src/pages/docs/chat/api/javascript/typing.mdx | 2 +- 14 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/pages/docs/chat/api/javascript/auth.mdx b/src/pages/docs/chat/api/javascript/auth.mdx index 30b46282c3..6f525b6287 100644 --- a/src/pages/docs/chat/api/javascript/auth.mdx +++ b/src/pages/docs/chat/api/javascript/auth.mdx @@ -1,9 +1,9 @@ --- title: Authentication -meta_description: "" +meta_description: "Ably Chat JavaScript API references for authentication." --- -The [ChatClient](/docs/chat/api/javascript/chat-client) requires a realtime client generated by the core [Pub/Sub SDK](LINK) to establish a connection with Ably. This realtime client is used to handle authentication with Ably. +The [ChatClient](/docs/chat/api/javascript/chat-client) requires a realtime client generated by the core [Pub/Sub SDK](/docs/basics) to establish a connection with Ably. This realtime client is used to handle authentication with Ably. There are broadly three mechanisms of authentication with Ably: diff --git a/src/pages/docs/chat/api/javascript/chat-client.mdx b/src/pages/docs/chat/api/javascript/chat-client.mdx index ea05bc1a99..2032288b4d 100644 --- a/src/pages/docs/chat/api/javascript/chat-client.mdx +++ b/src/pages/docs/chat/api/javascript/chat-client.mdx @@ -1,6 +1,6 @@ --- title: ChatClient -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the ChatClient constructor." --- The `ChatClient` class is the core client for Ably Chat. @@ -33,7 +33,7 @@ Use the following parameters: | Parameter | Description | Type | | --------- | ----------- | ---- | -| `realtime` | The Ably Realtime client. | [`Realtime`](https://sdk.ably.com/builds/ably/ably-js/main/typedoc/) | +| `realtime` | The Ably Realtime client. | [`Realtime`](#realtime) | | `clientOptions` | *Optional* The client options. | [`ChatClientOptions`](#chatclientoptions) | #### ChatClientOptions @@ -102,7 +102,7 @@ const chatClient = new ChatClient(realtimeClient, { ## Realtime -The Chat constructor requires a realtime client generated using the core [Pub/Sub SDK]() to establish a connection with Ably. The realtime client handles [authentication](/docs/chat/api/javascript/auth) with Ably. +The Chat constructor requires a realtime client generated using the core [Pub/Sub SDK](/docs/basics) to establish a connection with Ably. The realtime client handles [authentication](/docs/chat/api/javascript/auth) with Ably. `new Ably.Realtime(ClientOptions clientOptions)` diff --git a/src/pages/docs/chat/api/javascript/connection.mdx b/src/pages/docs/chat/api/javascript/connection.mdx index 84579f3410..44ffd01ca3 100644 --- a/src/pages/docs/chat/api/javascript/connection.mdx +++ b/src/pages/docs/chat/api/javascript/connection.mdx @@ -1,6 +1,6 @@ --- title: Connection -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the Connection interface." --- The `Connection` interface represents a connection to Ably. diff --git a/src/pages/docs/chat/api/javascript/error-info.mdx b/src/pages/docs/chat/api/javascript/error-info.mdx index 7af7d207d0..ef69ea524c 100644 --- a/src/pages/docs/chat/api/javascript/error-info.mdx +++ b/src/pages/docs/chat/api/javascript/error-info.mdx @@ -1,6 +1,6 @@ --- title: ErrorInfo -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the ErrorInfo class." --- The `ErrorInfo` class is a generic Ably error object that contains an Ably-specific status code, and a generic status code. Errors returned from the Ably server are compatible with the `ErrorInfo` structure and should result in errors that inherit from `ErrorInfo`. diff --git a/src/pages/docs/chat/api/javascript/message.mdx b/src/pages/docs/chat/api/javascript/message.mdx index f72a8a0929..71bce0a97c 100644 --- a/src/pages/docs/chat/api/javascript/message.mdx +++ b/src/pages/docs/chat/api/javascript/message.mdx @@ -1,6 +1,6 @@ --- title: Message -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the Message interface." --- The `Message` interface represents a single message in a chat room. @@ -114,7 +114,7 @@ Use the following parameters: | Parameter | Description | Type | | --------- | ----------- | ---- | -| `message` | The message to compare against. | [`Message`](#message) | +| `message` | The message to compare against. | `Message` | ### Returns @@ -144,7 +144,7 @@ Use the following parameters: | Parameter | Description | Type | | --------- | ----------- | ---- | -| `message` | The message to compare against. | [`Message`](#message) | +| `message` | The message to compare against. | `Message` | ### Returns @@ -176,7 +176,7 @@ Use the following parameters: | Parameter | Description | Type | | --------- | ----------- | ---- | -| `message` | The message to compare against. | [`Message`](#message) | +| `message` | The message to compare against. | `Message` | ### Returns @@ -192,7 +192,7 @@ const isEqual = message1.equal(message2); `message.isSameAs()` -Alias for [`message.equal()`](LINK). +Alias for [`message.equal()`](#equal). `isSameAs(message: Message): boolean` @@ -212,7 +212,7 @@ Use the following parameters: | Parameter | Description | Type | | --------- | ----------- | ---- | -| `message` | The message to compare against. | [`Message`](#message) | +| `message` | The message to compare against. | `Message` | ### Returns @@ -240,7 +240,7 @@ Use the following parameters: | Parameter | Description | Type | | --------- | ----------- | ---- | -| `message` | The message to compare against. | [`Message`](#message) | +| `message` | The message to compare against. | `Message` | ### Returns @@ -266,7 +266,7 @@ Use the following parameters: | Parameter | Description | Type | | --------- | ----------- | ---- | -| `message` | The message to compare against. | [`Message`](#message) | +| `message` | The message to compare against. | `Message` | ### Returns @@ -330,7 +330,7 @@ Use the following parameters: | Parameter | Description | Type | | --------- | ----------- | ---- | -| `event` | The event to be applied to the returned message. | [`Message`](#message) \| [`ChatMessageEvent`](#chatmessageevent) \| [`MessageReactionSummaryEvent`](#messagereactionsummaryevent) | +| `event` | The event to be applied to the returned message. | `Message` \| [`ChatMessageEvent`](#chatmessageevent) \| [`MessageReactionSummaryEvent`](#messagereactionsummaryevent) | #### ChatMessageEvent @@ -341,7 +341,7 @@ It has the following properties: | Properties | Description | Type | | ---------- | ----------- | ---- | | `type` | The type of the message event. | [`ChatMessageEventType`](#chatmessageeventtype) | -| `data` | The message data. | [`Message`](#message) | +| `data` | The message data. | `Message` | #### ChatMessageEventType diff --git a/src/pages/docs/chat/api/javascript/messages-reactions.mdx b/src/pages/docs/chat/api/javascript/messages-reactions.mdx index 33b407a3ba..3ca88fc7aa 100644 --- a/src/pages/docs/chat/api/javascript/messages-reactions.mdx +++ b/src/pages/docs/chat/api/javascript/messages-reactions.mdx @@ -1,6 +1,6 @@ --- title: MessagesReactions -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the MessageReactions interface." --- The `MessagesReactions` interface is used to add, delete, and subscribe to reactions on individual messages. diff --git a/src/pages/docs/chat/api/javascript/messages.mdx b/src/pages/docs/chat/api/javascript/messages.mdx index edd6fefb83..939e4030b7 100644 --- a/src/pages/docs/chat/api/javascript/messages.mdx +++ b/src/pages/docs/chat/api/javascript/messages.mdx @@ -1,6 +1,6 @@ --- title: Messages -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the Messages interface." --- The `Messages` interface is used to send and subscribe to messages in a chat room. @@ -47,13 +47,13 @@ The following `SendMessageParams` can be set: | `metadata` | *Optional* Metadata to attach to the message. Allows for attaching extra info to a message, which can be used for various features such as animations, effects, or simply to link it to other resources such as images, relative points in time, etc. This value is always set on received messages. If there is no metadata, this is an empty object. Do not use metadata for authoritative information. There is no server-side validation. When reading the metadata, treat it like user input. | [`MessageMetadata`](#messagemetadata) | | `headers` | *Optional* Headers to attach to the message. Headers enable attaching extra info to a message, which can be used for various features such as linking to a relative point in time of a livestream video or flagging this message as important or pinned. This value is always set on received messages. If there are no headers, this is an empty object. Do not use the headers for authoritative information. There is no server-side validation. When reading the headers, treat them like user input. | [`MessageHeaders`](#messageheaders) | -#### MessageMetadata +#### MessageMetadata Metadata enables attaching extra info to a message. Uses include animations, effects, or simply to link it to other resources such as images or relative points in time. `MessageMetadata: Record` -#### MessageHeaders +#### MessageHeaders Headers enable attaching extra info to a message. Uses include linking to a relative point in time of a livestream video or flagging this message as important or pinned. @@ -81,7 +81,7 @@ const message = await room.messages.send({ Update a message in the chat room. -Note that the Promise may resolve before or after the updated message is received from the room. This means you may see the update that was just sent in a callback to `subscribe()` before the returned promise resolves. +Note that the promise may resolve before or after the updated message is received from the room. This means you may see the update that was just sent in a callback to `subscribe()` before the returned promise resolves. The [`Message`](/docs/chat/api/javascript/message) instance returned by this method is the state of the message as a result of the update operation. If you have a subscription to message events via `subscribe()`, you should discard the message instance returned by this method and use the event payloads from the subscription instead. @@ -165,7 +165,7 @@ Delete a message in the chat room. This method performs a 'soft' delete, meaning the message is marked as deleted. -Note that the Promise may resolve before or after the message is deleted from the realtime channel. This means you may see the message that was just deleted in a callback to `subscribe` before the returned promise resolves. +Note that the promise may resolve before or after the message is deleted from the realtime channel. This means you may see the message that was just deleted in a callback to `subscribe` before the returned promise resolves. The [`Message`](/docs/chat/api/javascript/message) instance returned by this method is the state of the message as a result of the delete operation. If you have a subscription to message events via `subscribe()`, you should discard the message instance returned by this method and use the event payloads from the subscription instead. @@ -215,7 +215,7 @@ const deletedMessage = await room.messages.delete( Get messages that have been previously sent to the chat room, based on the provided options. -Note that the [`historyBeforeSubscribe()`](#historybeforesubscribe) method enables clients to retrieve messages in a continuous manner when they first subscribe to a room, or rejoin after a period of disconnection. +Note that the [`historyBeforeSubscribe()`](#historyBeforeSubscribe) method enables clients to retrieve messages in a continuous manner when they first subscribe to a room, or rejoin after a period of disconnection. `history(options: QueryOptions): Promise>` diff --git a/src/pages/docs/chat/api/javascript/occupancy.mdx b/src/pages/docs/chat/api/javascript/occupancy.mdx index cf80b67d00..8558cc0bb3 100644 --- a/src/pages/docs/chat/api/javascript/occupancy.mdx +++ b/src/pages/docs/chat/api/javascript/occupancy.mdx @@ -1,6 +1,6 @@ --- title: Occupancy -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the Occupancy interface." --- The `Occupancy` interface is used to subscribe to occupancy updates and fetch the occupancy metrics of a room. diff --git a/src/pages/docs/chat/api/javascript/presence.mdx b/src/pages/docs/chat/api/javascript/presence.mdx index 45b45e76d4..87e8cdf208 100644 --- a/src/pages/docs/chat/api/javascript/presence.mdx +++ b/src/pages/docs/chat/api/javascript/presence.mdx @@ -1,6 +1,6 @@ --- title: Presence -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the Presence interface." --- The `Presence` interface is used to enter and subscribe to the presence set of a chat room. @@ -47,7 +47,7 @@ await room.presence.enter({status: 'online', activity: 'viewing'}); `room.presence.update()` -Updates a client's presence `data`. Will emit an `update` event to all subscribers. If the client is not already in the presence set, it will be treated as an [`enter`](LINK) event. +Updates a client's presence `data`. Will emit an `update` event to all subscribers. If the client is not already in the presence set, it will be treated as an [`enter`](#enter) event. `update(data?: unknown): Promise` @@ -202,7 +202,7 @@ if (isPresent) { Subscribe the provided listener to a list of presence events. -Note: This requires presence events to be enabled via the `enableEvents` option in the [`PresenceOptions`](LINK) provided to the room. If this is not enabled, an error will be thrown. +Note: This requires presence events to be enabled via the `enableEvents` option in the [`PresenceOptions`](/docs/chat/api/javascript/rooms#PresenceOptions) provided to the room. If this is not enabled, an error will be thrown. `subscribe(eventOrEvents: PresenceEventType | PresenceEventType[], listener?: PresenceListener): Subscription` diff --git a/src/pages/docs/chat/api/javascript/room-reactions.mdx b/src/pages/docs/chat/api/javascript/room-reactions.mdx index 4dd22ab0bd..e6b823a910 100644 --- a/src/pages/docs/chat/api/javascript/room-reactions.mdx +++ b/src/pages/docs/chat/api/javascript/room-reactions.mdx @@ -1,6 +1,6 @@ --- title: RoomReactions -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the RoomReactions interface." --- The `RoomReactions` interface is used to send and subscribe to ephemeral, room-level reactions. diff --git a/src/pages/docs/chat/api/javascript/room.mdx b/src/pages/docs/chat/api/javascript/room.mdx index 93cfe83eb7..1effec5268 100644 --- a/src/pages/docs/chat/api/javascript/room.mdx +++ b/src/pages/docs/chat/api/javascript/room.mdx @@ -1,6 +1,6 @@ --- title: Room -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the Room interface." --- The `Room` interface represents a chat room. @@ -18,12 +18,12 @@ It has the following accessors: | `name` | The unique name of the room. | String | | `status` | The current status of the room. | [`RoomStatus`](#roomstatus) | | `error` | The current error, if any, that caused the room to enter the current status. | [`ErrorInfo`](/docs/chat/api/javascript/error-info) \| `undefined` | -| `channel` | The underlying Ably realtime channel used for the room. | [`RealtimeChannel`](LINK) | -| `messages` | Allows you to send, subscribe to, and query messages in the room. | [`Messages`](LINK) | -| `presence` | Interact with presence events in the room. | [`Presence`](LINK) | -| `occupancy` | Interact with occupancy metrics for the room. | [`Occupancy`](LINK) | -| `reactions` | Interact with room-level reactions. | [`RoomReactions`](LINK) | -| `typing` | Interact with typing events in the room. | [`Typing`](LINK) | +| `channel` | The underlying Ably realtime channel used for the room. | [`RealtimeChannel`](/docs/channels) | +| `messages` | Allows you to send, subscribe to, and query messages in the room. | [`Messages`](/docs/chat/api/javascript/messages) | +| `presence` | Interact with presence events in the room. | [`Presence`](/docs/chat/api/javascript/presence) | +| `occupancy` | Interact with occupancy metrics for the room. | [`Occupancy`](/docs/chat/api/javascript/occupancy) | +| `reactions` | Interact with room-level reactions. | [`RoomReactions`](/docs/chat/api/javascript/room-reactions) | +| `typing` | Interact with typing events in the room. | [`Typing`](/docs/chat/api/javascript/typing) | --- @@ -155,7 +155,7 @@ Registers a handler that is called whenever a discontinuity is detected. Discont If the discontinuity lasts for less than 2 minutes, then the SDK will automatically reattach to any rooms and replay any missed messages once it reconnects. -If the discontinuity last for longer than 2 minutes, then use [`historyBeforeSubscribe()`](/docs/chat/api/javascript/messages#historybeforesubscribe) to retrieve any missed messages. +If the discontinuity last for longer than 2 minutes, then use [`historyBeforeSubscribe()`](/docs/chat/api/javascript/messages#historyBeforeSubscribe) to retrieve any missed messages. `onDiscontinuity(handler: DiscontinuityListener): StatusSubscription` diff --git a/src/pages/docs/chat/api/javascript/rooms.mdx b/src/pages/docs/chat/api/javascript/rooms.mdx index d9c448371c..f04b611ef7 100644 --- a/src/pages/docs/chat/api/javascript/rooms.mdx +++ b/src/pages/docs/chat/api/javascript/rooms.mdx @@ -1,6 +1,6 @@ --- title: Rooms -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the Rooms interface." --- The `Rooms` interface manages the lifecycle of chat rooms. @@ -11,11 +11,11 @@ Access it via `ChatClient.rooms`. ## Create a room -`ChatClient.Rooms.get()` +`ChatClient.rooms.get()` Create or retrieve `Room` object. Optionally provide custom configuration to the room. -Call [`release()`](#release-a-room) when the `Room` object is no longer needed. If a call to `get()` is made for a room that is currently being released, then the promise will only resolve when the release operation is complete. +Call [`release()`](#release) when the `Room` object is no longer needed. If a call to `get()` is made for a room that is currently being released, then the promise will only resolve when the release operation is complete. If a call to `get()` is made, followed by a subsequent call to `release()` before the promise resolves, then the promise will reject with an error. @@ -68,7 +68,7 @@ The following `OccupancyOptions` can be set: | Properties | Description | Type | | ---------- | ----------- | ---- | -| `enableEvents` | *Optional* Sets whether the client should receive [occupancy](#occupancy) events. If enabled, the client will receive messages detailing the changing room occupancy. The default value is `false`. | Boolean | +| `enableEvents` | *Optional* Sets whether the client should receive [occupancy](docs/chat/api/javascript/occupancy) events. If enabled, the client will receive messages detailing the changing room occupancy. The default value is `false`. | Boolean | #### PresenceOptions @@ -76,7 +76,7 @@ The following `PresenceOptions` can be set: | Properties | Description | Type | | ---------- | ----------- | ---- | -| `enableEvents` | *Optional* Sets whether the client should receive [presence](#presence) events. If enabled, the client will presence updates about other clients in the room. Note that even if the client hasn't subscribed to presence, they are still streamed presence events by the server. Clients can also still register their presence in the room without receiving presence events. The default value is `true`. | Boolean | +| `enableEvents` | *Optional* Sets whether the client should receive [presence](docs/chat/api/javascript/presence) events. If enabled, the client will presence updates about other clients in the room. Note that even if the client hasn't subscribed to presence, they are still streamed presence events by the server. Clients can also still register their presence in the room without receiving presence events. The default value is `true`. | Boolean | #### TypingOptions @@ -100,11 +100,11 @@ const room = await chatClient.rooms.get('livestream-1', {occupancy: {enableEvent ## Release a room -`ChatClient.Rooms.release()` +`ChatClient.rooms.release()` Releases a `Room` object, allowing for it to be garbage collected. -This will release the reference to the `Room` object from the `Rooms` collection and detach it from Ably. It does not unsubscribe the client from any events. Call [`Rooms.get()`](LINK) if you want to get the `Room` object back. +This will release the reference to the `Room` object from the `Rooms` collection and detach it from Ably. It does not unsubscribe the client from any events. Call [`Rooms.get()`](#get) if you want to get the `Room` object back. `release(name: string): Promise` diff --git a/src/pages/docs/chat/api/javascript/subscriptions.mdx b/src/pages/docs/chat/api/javascript/subscriptions.mdx index 47fe458cf5..c39303898f 100644 --- a/src/pages/docs/chat/api/javascript/subscriptions.mdx +++ b/src/pages/docs/chat/api/javascript/subscriptions.mdx @@ -1,6 +1,6 @@ --- title: Subscriptions -meta_description: "" +meta_description: "Ably Chat JavaScript API references for interfaces that manage the lifecycle of subscriptions." --- The following interfaces are used to manage the lifecycle of subscriptions. @@ -22,10 +22,10 @@ It has the following properties: It is returned by the following methods: * [`room.messages.reactions.subscribe()`](/docs/chat/api/javascript/messages-reactions#subscribe) -* [`room.messages.reactions.subscribeRaw()`](/docs/chat/api/javascript/messages-reactions#subscriberaw) +* [`room.messages.reactions.subscribeRaw()`](/docs/chat/api/javascript/messages-reactions#subscribeRaw) * [`room.occupancy.subscribe()`](/docs/chat/api/javascript/occupancy#subscribe) * [`room.presence.subscribe()`](/docs/chat/api/javascript/presence#subscribe) -* [`room.presence.subscribeAll()`](/docs/chat/api/javascript/presence#subscribeall) +* [`room.presence.subscribeAll()`](/docs/chat/api/javascript/presence#subscribeAll) * [`room.reactions.subscribe()`](/docs/chat/api/javascript/room-reactions#subscribe) * [`room.typing.subscribe()`](/docs/chat/api/javascript/typing#subscribe) @@ -51,7 +51,7 @@ It has the following methods: | Method | Description | | ------ | ----------- | -| [`historyBeforeSubscribe()`](/docs/chat/api/javascript/messages#historybeforesubscribe) | Get the messages sent before the listener was subscribed. | +| [`historyBeforeSubscribe()`](/docs/chat/api/javascript/messages#historyBeforeSubscribe) | Get the messages sent before the listener was subscribed. | ### Returned by @@ -77,5 +77,5 @@ It has the following properties: It is returned by the following methods: -* [`connection.onStatusChange()`](/docs/chat/api/javascript/connection#onstatuschange) -* [`room.onStatusChange()`](/docs/chat/api/javascript/room#onstatuschange) +* [`connection.onStatusChange()`](/docs/chat/api/javascript/connection#onStatusChange) +* [`room.onStatusChange()`](/docs/chat/api/javascript/room#onStatusChange) diff --git a/src/pages/docs/chat/api/javascript/typing.mdx b/src/pages/docs/chat/api/javascript/typing.mdx index b70fdfc830..7075c269c1 100644 --- a/src/pages/docs/chat/api/javascript/typing.mdx +++ b/src/pages/docs/chat/api/javascript/typing.mdx @@ -1,6 +1,6 @@ --- title: Typing -meta_description: "" +meta_description: "Ably Chat JavaScript API references for the Typing interface." --- The `Typing` interface is used to send typing events on keystrokes and subscribe to typing events emitted by other users. From e039dcab14952520dcf1d61e7203599ad876b67b Mon Sep 17 00:00:00 2001 From: Mark Hulbert <39801222+m-hulbert@users.noreply.github.com> Date: Wed, 16 Jul 2025 13:50:50 +0200 Subject: [PATCH 18/18] Enable auto-generation of anchor links for h4 --- gatsby-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gatsby-config.ts b/gatsby-config.ts index 8a401ef7d0..3812a0491a 100644 --- a/gatsby-config.ts +++ b/gatsby-config.ts @@ -83,7 +83,7 @@ export const plugins = [ className: `gatsby-copyable-header`, removeAccents: true, isIconAfterHeader: true, - elements: [`h2`, `h3`], + elements: [`h2`, `h3`, `h4`], }, }, {