# PresenceMessage
A `PresenceMessage` represents an individual presence event sent to or received from Ably. Presence messages are delivered through a channel's [`presence.subscribe()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md#subscribe) method, or retrieved via [`presence.get()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md#get) and [`presence.history()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md#history).
#### Javascript
```
await channel.presence.subscribe((presenceMessage) => {
console.log(presenceMessage.action, presenceMessage.clientId);
});
```
## Properties
The `PresenceMessage` type has the following properties:
| Property | Description | Type |
| --- | --- | --- |
| action | The type of [presence action](https://ably.com/docs/presence-occupancy/presence.md#trigger-events) this message represents. | |
| clientId | The client ID of the publisher of this presence message. | String |
| connectionId | The connection ID of the publisher of this presence message. | String |
| data | The presence data payload, if provided. | String, JSON Object, or Buffer |
| encoding | This will typically be empty as all presence messages received from Ably are automatically decoded client-side using this value. However, if the encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload. | String |
| extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for `extras` are the [`push`](https://ably.com/docs/push/publish.md#sub-channels), [`ref`](https://ably.com/docs/messages.md) and [`privileged`](https://ably.com/docs/platform/integrations/skip-integrations.md) objects. | JSON Object |
| id | A unique ID assigned to each `PresenceMessage` by Ably. | String |
| timestamp | Timestamp when the presence message was first received by Ably, as milliseconds since the epoch. | Integer |
| 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. |
## Create a PresenceMessage from an encoded object
`PresenceMessage.fromEncoded(JsonObject: any, channelOptions?: ChannelOptions): Promise`
A static factory method to create a `PresenceMessage` from a deserialized `PresenceMessage`-like object encoded using Ably's wire protocol. The returned promise resolves with the decoded presence message.
### Javascript
```
const presenceMessage = await Ably.Realtime.PresenceMessage.fromEncoded(encodedMsg);
```
### Parameters
The `PresenceMessage.fromEncoded()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| JsonObject | Required | A `PresenceMessage`-like deserialized object. | Any |
| channelOptions | Optional | If you have an encrypted channel, use this to allow the SDK to decrypt the data. | [ChannelOptions](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md#get) |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with a `PresenceMessage` object decoded from the supplied object, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object if the object cannot be decoded.
## Create an array of PresenceMessages from encoded objects
`PresenceMessage.fromEncodedArray(JsonArray: any[], channelOptions?: ChannelOptions): Promise`
A static factory method to create an array of `PresenceMessage` objects from an array of deserialized `PresenceMessage`-like objects encoded using Ably's wire protocol. The returned promise resolves with the decoded presence messages.
### Javascript
```
const presenceMessages = await Ably.Realtime.PresenceMessage.fromEncodedArray(encodedMsgs);
```
### Parameters
The `PresenceMessage.fromEncodedArray()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| JsonArray | Required | An array of `PresenceMessage`-like deserialized objects. | `Any[]` |
| channelOptions | Optional | If you have an encrypted channel, use this to allow the SDK to decrypt the data. | [ChannelOptions](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md#get) |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with an array of `PresenceMessage` objects decoded from the supplied array, or rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object if the array cannot be decoded.
## Create a PresenceMessage from values
`PresenceMessage.fromValues(values: Partial>): PresenceMessage`
A static factory method that initialises a `PresenceMessage` from a `PresenceMessage`-like object. Only the `clientId`, `data`, and `extras` fields are used.
### Javascript
```
const presenceMessage = Ably.Realtime.PresenceMessage.fromValues({
clientId: 'user-123',
data: { status: 'available' }
});
```
### Parameters
The `PresenceMessage.fromValues()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| values | Required | A `PresenceMessage`-like object to initialise from. Only the `clientId`, `data`, and `extras` fields are accepted. | Object |
### Returns
`PresenceMessage`
Returns a `PresenceMessage` object initialised from the supplied values.
## Related Topics
- [RealtimePresence](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-presence.md): API reference for the Presence (RealtimePresence) interface 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.