# RealtimePresence
A `RealtimePresence` object enables a client to be present on a channel and to query and subscribe to the presence set; access it via the [`presence`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md) property of a [`RealtimeChannel`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md) instance.
#### Javascript
```
const presence = channel.presence;
```
## Properties
The `RealtimePresence` interface has the following properties:
| Property | Description | Type |
| --- | --- | --- |
| syncComplete | Indicates whether the presence member set is synchronized with the server after a channel attach. When a channel is attached, the Ably service immediately synchronizes the presence member set with the client. Typically this completes in milliseconds, however when the presence member set is very large, bandwidth constraints may slow this synchronization down. | Boolean |
## Subscribe to presence events
`presence.subscribe(listener: presenceMessageCallback): Promise`
Subscribe to presence events on the channel. The listener is invoked for every presence message received.
`presence.subscribe(action: PresenceAction | PresenceAction[], listener?: presenceMessageCallback): Promise`
Subscribe to presence events for a specific action (or array of actions). The listener is invoked only for matching events.
### Javascript
```
await channel.presence.subscribe((presenceMessage) => {
console.log(`${presenceMessage.action} from ${presenceMessage.clientId}`);
});
await channel.presence.subscribe('enter', (presenceMessage) => {
console.log(`${presenceMessage.clientId} entered`);
});
```
### Parameters
The `subscribe()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| action | Optional | The presence action(s) to subscribe to. If omitted, the listener fires for every presence event. | or `PresenceAction[]` |
| listener | Optional | A function invoked with a [`PresenceMessage`](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md) for each matching event. Required when subscribing to all events; with an `action` argument it may be omitted to attach the channel without registering a listener. | Function |
| Value | Description |
| --- | --- |
| absent | Reserved for internal use. This is an internal enum value and is not delivered to subscribers as a presence event. |
| present | A member is present at the time of channel attach. Synthesized for each existing member when a client first subscribes. |
| enter | A new member entered the presence set. |
| leave | A member left the presence set, either explicitly or implicitly (e.g. due to disconnection). |
| update | A present member updated their data. |
### Returns
`Promise`
Returns a promise. The promise is fulfilled when the channel has been attached and the subscription is active, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
### Considerations
Note the following behaviours when subscribing to presence events:
* If the channel is `initialized` (no attempt to attach has yet been made), calling `subscribe()` implicitly attaches the channel. The listener is still registered regardless of the outcome of the implicit attach.
* If `subscribe()` is called more than once with the same listener, the listener is registered each time. For example, if you subscribe twice with the same listener and a presence message is later received, that listener is invoked twice.
* The registered listener remains active regardless of the underlying channel state. For example, if the channel later becomes `detached` or `failed` and is then reattached, listeners originally registered are still invoked when a presence message is received. Listeners are only removed by calling [`unsubscribe()`](#unsubscribe) or by releasing the underlying channel with `realtime.channels.release(name)`.
* If an exception is thrown in a listener and bubbles up to the event emitter, it is caught and logged at `error` level so that it does not affect other listeners for the same event.
## Enter the presence set
`presence.enter(data?: any): Promise`
Enter the presence set for the channel, optionally with data that is associated with the present member. In order to enter the presence set the client must be [identified by having a client ID](https://ably.com/docs/auth/identified-clients.md), [have permission to be present](https://ably.com/docs/auth/capabilities.md), and be attached to the channel. The SDK will implicitly attach to the channel when entering. Entering when already entered is treated as an [`update()`](#update).
### Javascript
```
await channel.presence.enter('status string');
```
### Parameters
The `enter()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| data | Optional | The data payload for the present member. Supported payload types are strings, JSON objects and arrays, buffers containing arbitrary binary data, and `null`. | Any |
### Returns
`Promise`
Returns a promise. The promise is fulfilled when the client has entered the presence set, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Update the present member
`presence.update(data?: any): Promise`
Update the current member's data on the channel. This broadcasts an `update` event to all presence subscribers. The pre-requisites for `update()` are the same as for [`enter()`](#enter). If an attempt to `update()` is made before the client has entered the channel, the update is treated as an `enter`.
### Javascript
```
await channel.presence.update('new status');
```
### Parameters
The `update()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| data | Optional | The new data payload for the present member. May be `null`. | Any |
### Returns
`Promise`
Returns a promise. The promise is fulfilled when the update has been delivered, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Leave the presence set
`presence.leave(data?: any): Promise`
Leave the presence set for the channel. Optionally provide data to broadcast with the leave event. The client must already have [entered the presence set](#enter).
### Javascript
```
await channel.presence.leave();
```
### Parameters
The `leave()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| data | Optional | The data payload to broadcast with the leave event. | Any |
### Returns
`Promise`
Returns a promise. The promise is fulfilled when the client has left the presence set, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Get the presence set
`presence.get(params?: RealtimePresenceParams): Promise`
Retrieve the current members of the presence set for the channel. The returned array contains a [`PresenceMessage`](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md) object for each member, with metadata such as the member's `clientId`, `connectionId`, action, and any associated data.
The member set is retained in memory by the client, so this method typically returns immediately. However, by default it waits until the presence member set is synchronized, so if synchronization is not yet complete after the channel attaches, it waits until synchronization is complete.
When a channel is attached, the Ably service synchronizes the presence member set with the client. This typically completes in milliseconds, however a very large member set may take longer.
When a channel is `initialized` (i.e. no attempt to attach has yet been made), calling `get()` will implicitly attach the channel.
### Javascript
```
const members = await channel.presence.get();
console.log(`${members.length} members present`);
```
### Parameters
The `get()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| params | Optional | Filter and synchronization options for the query. | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| waitForSync | Optional | When `true`, `get()` returns the members once the presence set has been fully synchronized with the server. When `false`, the current presence set members are returned without waiting. Default: `true`. | Boolean |
| clientId | Optional | Filters the returned members by `clientId`. | String |
| connectionId | Optional | Filters the returned members by `connectionId`. | String |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with an array of [`PresenceMessage`](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md) objects representing the current members of the presence set, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Unsubscribe from presence events
`presence.unsubscribe(action: PresenceAction | PresenceAction[], listener: presenceMessageCallback): void`
Remove the listener for the specified `PresenceAction`.
`presence.unsubscribe(action: PresenceAction | PresenceAction[]): void`
Remove all listeners registered against the specified action(s).
`presence.unsubscribe(listener: presenceMessageCallback): void`
Remove the specified listener from all presence actions.
`presence.unsubscribe(): void`
Remove all listeners.
### Javascript
```
channel.presence.unsubscribe();
```
### Parameters
The `unsubscribe()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| action | Optional | The action(s) to unsubscribe from. | or `PresenceAction[]` |
| listener | Optional | The specific listener to remove. If omitted, all matching listeners are removed. | Function |
## Get presence history
`presence.history(params?: RealtimeHistoryParams): Promise>`
Get a [paginated](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#PaginatedResult) set of historical presence message events for the channel. If the [channel is configured to persist messages](https://ably.com/docs/storage-history/storage.md), the presence message history will typically be available for 24 - 72 hours. If not, presence message events are only retained in memory by the Ably service for two minutes.
### Javascript
```
const history = await channel.presence.history({ limit: 50 });
history.items.forEach((member) => {
console.log(member.action, member.clientId);
});
```
### Parameters
The `history()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| params | Optional | Query parameters as specified in the [presence history API documentation](https://ably.com/docs/storage-history/history.md#presence-history). | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| start | Optional | The time from which presence events are retrieved, as milliseconds since the Unix epoch. Default: the beginning of time. | Number |
| end | Optional | The time until which presence events are retrieved, as milliseconds since the Unix epoch. Default: current time. | Number |
| direction | Optional | The order of returned presence events. `'backwards'` orders from most recent to oldest; `'forwards'` orders from oldest to most recent. Default: `'backwards'`. | String |
| limit | Optional | An upper limit on the number of presence events returned. Default: 100. Maximum: 1000. | Number |
| untilAttach | Optional | When `true`, retrieves [continuous history](https://ably.com/docs/storage-history/history.md#continuous-history) up until the channel attachment point. Requires the channel to be attached and `direction` to be `'backwards'`. If the channel is not attached, or `direction` is `forwards`, this option results in an error. | Boolean |
### Returns
`Promise>`
Returns a promise. The promise is fulfilled with a [`PaginatedResult`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#PaginatedResult) containing an array of [`PresenceMessage`](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md) objects, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Enter the presence set on behalf of a client
`presence.enterClient(clientId: string, data?: any): Promise`
Enter the presence set on behalf of the given client ID. This is useful when a single client is acting on behalf of multiple clients, for example a server-side process managing presence for [multiple client IDs](https://ably.com/docs/presence-occupancy/presence.md#multiple-client-ids). Requires the client to be authenticated with a `clientId` matching the supplied value, or with a wildcard `clientId`. The wildcard requirement can be satisfied with an API key, or a token bound to a wildcard client ID.
### Javascript
```
await channel.presence.enterClient('user-123', 'status');
```
### Parameters
The `enterClient()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| clientId | Required | The client ID to enter the presence set on behalf of. | String |
| data | Optional | The data payload for the present member. | Any |
### Returns
`Promise`
Returns a promise. The promise is fulfilled when the client has been entered into the presence set, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Update a client's presence data
`presence.updateClient(clientId: string, data?: any): Promise`
Update the data for an existing present member on behalf of the given client ID. If the client is not already in the presence set, this is treated as an [`enterClient()`](#enter-client).
### Javascript
```
await channel.presence.updateClient('user-123', 'new status');
```
### Parameters
The `updateClient()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| clientId | Required | The client ID whose data is to be updated. | String |
| data | Optional | The new data payload. | Any |
### Returns
`Promise`
Returns a promise. The promise is fulfilled when the update has been delivered, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Leave the presence set on behalf of a client
`presence.leaveClient(clientId: string, data?: any): Promise`
Leave the presence set on behalf of the given client ID. Requires the same authentication conditions as [`enterClient()`](#enter-client).
### Javascript
```
await channel.presence.leaveClient('user-123');
```
### Parameters
The `leaveClient()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| clientId | Required | The client ID to remove from the presence set. | String |
| data | Optional | The data payload to broadcast with the leave event. | Any |
### Returns
`Promise`
Returns a promise. The promise is fulfilled when the client has left the presence set, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object.
## Related Topics
- [PresenceMessage](https://ably.com/docs/pub-sub/api/javascript/realtime/presence-message.md): API reference for the PresenceMessage type in the Ably Pub/Sub JavaScript Realtime SDK.
## Documentation Index
To discover additional Ably documentation:
1. Fetch [llms.txt](https://ably.com/llms.txt) for the canonical list of available pages.
2. Identify relevant URLs from that index.
3. Fetch target pages as needed.
Avoid using assumed or outdated documentation paths.