# Messages
The `Messages` interface provides methods for sending, receiving, and managing chat messages in a room. Access it via `room.messages`.
#### Javascript
```
const messages = room.messages;
```
## Properties
The `Messages` interface has the following properties:
| Property | Description | Type |
| --- | --- | --- |
| reactions | Access to message reactions functionality for adding, removing, and subscribing to reactions on specific messages. | [MessageReactions](https://ably.com/docs/chat/api/javascript/message-reactions.md) |
## Subscribe to messages
`messages.subscribe(listener: MessageListener): MessageSubscriptionResponse`
Subscribe to chat message events in the room. This method allows you to listen for new messages and provides access to historical messages that occurred before the subscription was established.
The room must be [attached](https://ably.com/docs/chat/api/javascript/room.md#attach) for the listener to receive new message events.
### Javascript
```
const { unsubscribe, historyBeforeSubscribe } = messages.subscribe((event) => {
console.log('Received message:', event.message.text);
});
// Get messages sent before subscribing
const history = await historyBeforeSubscribe();
// To stop receiving messages
unsubscribe();
```
### Parameters
The `subscribe()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| listener | Required | A callback function invoked when chat message events occur. | |
| Parameter | Description | Type |
| --- | --- | --- |
| event | The message event that was received. | |
| Property | Description | Type |
| --- | --- | --- |
| type | The type of the message event. | |
| message | The message that was received. | [Message](https://ably.com/docs/chat/api/javascript/message.md) |
| Value | Description |
| --- | --- |
| Created | A new chat message was received. The value is `message.created`. |
| Updated | A chat message was updated. The value is `message.updated`. |
| Deleted | A chat message was deleted. The value is `message.deleted`. |
### Returns
`MessageSubscriptionResponse`
Returns an object with the following methods:
#### Unsubscribe from messages
`unsubscribe(): void`
Call `unsubscribe()` to stop listening for message events.
#### Get messages from before the subscription started
`historyBeforeSubscribe(params?: HistoryBeforeSubscribeParams): Promise>`
Get messages sent to the room from before the subscription was established.
##### Parameters
The `historyBeforeSubscribe()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| params | Optional | Query parameters to filter message retrieval. Messages are returned in order of most recent to oldest. | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| limit | Optional | Maximum number of messages to retrieve. Default: `100`. | Number |
| start | Optional | Start of the time window to query, as a Unix timestamp in milliseconds. | Number |
| end | Optional | End of the time window to query, as a Unix timestamp in milliseconds. | Number |
##### Returns
`Promise>`
Returns a promise. The promise is fulfilled with a [`PaginatedResult`](#PaginatedResult) containing an array of [Message](https://ably.com/docs/chat/api/javascript/message.md) objects, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object.
## Send a message
`messages.send(params: SendMessageParams): Promise`
Send a message to the chat room. The message will be delivered to all subscribers in real-time.
This method uses the Ably Chat REST API and does not require the room to be attached.
### Javascript
```
const message = await messages.send({
text: 'Hello, world!'
});
console.log('Message sent with serial:', message.serial);
```
### Parameters
The `send()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| params | Required | Message parameters containing the text and optional metadata/headers. | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| text | Required | The text content of the message. | String |
| metadata | Optional | Extra information attached to the message for features like animations or linking to external resources. | |
| headers | Optional | Additional information in Ably message extras, usable for features like livestream timestamping or message flagging. | |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with the sent [Message](https://ably.com/docs/chat/api/javascript/message.md) object, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object.
## Get message history
`messages.history(params: HistoryParams): Promise>`
Get messages that have been previously sent to the chat room. This method retrieves historical messages based on the provided query options, allowing you to paginate through message history, filter by time ranges, and control the order of results.
This method uses the Ably Chat REST API and does not require the room to be attached.
### Javascript
```
const history = await messages.history({
limit: 50,
orderBy: OrderBy.NewestFirst
});
console.log('Messages:', history.items);
// Get next page if available
if (history.hasNext()) {
const nextPage = await history.next();
}
```
### Parameters
The `history()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| params | Required | Query parameters to filter and control message retrieval. | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| limit | Optional | Maximum number of messages to retrieve. Default: `100`. | Number |
| orderBy | Optional | Order in which to return results: `'oldestFirst'` or `'newestFirst'`. Default: `'newestFirst'`. | |
| start | Optional | Start of the time window to query, as a Unix timestamp in milliseconds. | Number |
| end | Optional | End of the time window to query, as a Unix timestamp in milliseconds. | Number |
| Value | Description |
| --- | --- |
| OldestFirst | Return results starting with the oldest messages. The value is `oldestFirst`. |
| NewestFirst | Return results starting with the newest messages. The value is `newestFirst`. |
### Returns
`Promise>`
Returns a promise. The promise is fulfilled with a [`PaginatedResult`](#PaginatedResult) containing an array of [Message](https://ably.com/docs/chat/api/javascript/message.md) objects, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object.
## Get a specific message
`messages.get(serial: string): Promise`
Get a specific message by its unique serial identifier.
This method uses the Ably Chat REST API and does not require the room to be attached.
### Javascript
```
const message = await messages.get('01234567890@abcdefghij');
console.log('Message text:', message.text);
```
### Parameters
The `get()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| serial | Required | The unique serial identifier of the message to retrieve. | String |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with the [Message](https://ably.com/docs/chat/api/javascript/message.md) object matching the given serial, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object.
## Update a message
`messages.update(serial: string, updateParams: UpdateMessageParams, details?: OperationDetails): Promise`
Update a message in the chat room. This method modifies an existing message's content, metadata, or headers. The update creates a new version of the message while preserving the original serial identifier. Subscribers will receive an update event in real-time.
This method uses the Ably Chat REST API and does not require the room to be attached.
### Javascript
```
const updatedMessage = await messages.update(
message.serial,
{ text: 'Updated message text' },
{ description: 'Fixed typo' }
);
console.log('Message updated:', updatedMessage.version);
```
### Parameters
The `update()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| serial | Required | The unique identifier of the message to update. | String |
| updateParams | Required | The new message content and properties. | |
| details | Optional | Details to record about the update action. | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| text | Required | The new text content of the message. | String |
| metadata | Optional | New metadata for the message. | |
| headers | Optional | New headers for the message. | |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| description | Optional | A human-readable description of why the operation was performed. | String |
| metadata | Optional | Additional metadata about the operation. | |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with the updated [Message](https://ably.com/docs/chat/api/javascript/message.md) object, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object. The returned message will have its `action` property set to `updated`.
## Delete a message
`messages.delete(serial: string, details?: OperationDetails): Promise`
Delete a message in the chat room. This method performs a "soft delete" on a message, marking it as deleted rather than permanently removing it. The deleted message will still be visible in message history but will be flagged as deleted. Subscribers will receive a deletion event in real-time.
This method uses the Ably Chat REST API and does not require the room to be attached.
### Javascript
```
const deletedMessage = await messages.delete(
message.serial,
{ description: 'Removed inappropriate content' }
);
console.log('Message deleted:', deletedMessage.action);
```
### Parameters
The `delete()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| serial | Required | The unique identifier of the message to delete. | String |
| details | Optional | Details to record about the delete action. | |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with the deleted [Message](https://ably.com/docs/chat/api/javascript/message.md) object, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object. The returned message will have its `action` property set to `deleted`.
## PaginatedResult
A `PaginatedResult` represents a page of results from a paginated query such as [history()](#history) or [historyBeforeSubscribe()](#historyBeforeSubscribe).
### Properties
| Property | Description | Type |
| --- | --- | --- |
| items | The current page of results. | [`Message[]`](/docs/chat/api/javascript/message) |
### Check for more pages
`hasNext(): boolean`
Returns `true` if there are more pages available by calling `next()`.
### Check if last page
`isLast(): boolean`
Returns `true` if this is the last page of results.
### Get next page
`next(): Promise | null>`
Returns a promise. The promise is fulfilled with the next page of results, or `null` if there are no more pages, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object.
### Get first page
`first(): Promise>`
Returns a promise. The promise is fulfilled with the first page of results, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object.
### Get current page
`current(): Promise>`
Returns a promise. The promise is fulfilled with the current page of results, or rejected with an [`ErrorInfo`](https://ably.com/docs/chat/api/javascript/chat-client.md#errorinfo) object.
## Example
### Javascript
```
import { ChatMessageEventType, OrderBy } from '@ably/chat';
const room = await chatClient.rooms.get('my-room');
await room.attach();
// Subscribe to messages
const { unsubscribe, historyBeforeSubscribe } = room.messages.subscribe((event) => {
const msg = event.message;
switch (event.type) {
case ChatMessageEventType.Created:
console.log(`${msg.clientId}: ${msg.text}`);
break;
case ChatMessageEventType.Updated:
console.log(`Message updated: ${msg.text}`);
break;
case ChatMessageEventType.Deleted:
console.log(`Message deleted: ${msg.serial}`);
break;
}
});
// Get recent history
const history = await room.messages.history({ limit: 10 });
history.items.forEach(msg => {
console.log(`[History] ${msg.clientId}: ${msg.text}`);
});
// Send a message
const sent = await room.messages.send({ text: 'Hello everyone!' });
// Update the message
await room.messages.update(sent.serial, { text: 'Hello everyone! (edited)' });
// Clean up
unsubscribe();
```