The MessageReactions interface provides methods to send, delete, and subscribe to reactions on specific messages. Unlike room reactions, message reactions are persisted and associated with individual chat messages. Access it via room.messages.reactions.
1
const reactions = room.messages.reactions;Message reactions support three counting strategies:
- Unique: One reaction per client per message (like iMessage, WhatsApp)
- Distinct: One reaction of each type per client (like Slack)
- Multiple: Unlimited reactions including repeats (like Medium claps)
Send a reaction to a message
reactions.send(messageSerial: string, params: SendMessageReactionParams): Promise<void>Sends a reaction to a specific chat message. The reaction is persisted and contributes to the message's reaction summary.
This method uses the Ably Chat REST API and does not require the room to be attached.
1
2
3
await room.messages.reactions.send('message-serial-123', {
name: '👍'
});Parameters
The send() method takes the following parameters:
messageSerialrequiredStringparamsrequiredSendMessageReactionParamsReturns
Promise<void>
Returns a promise. The promise is fulfilled when the reaction has been sent, or rejected with an ErrorInfo object.
Delete a reaction from a message
reactions.delete(messageSerial: string, params?: DeleteMessageReactionParams): Promise<void>Removes a previously sent reaction from a chat message.
This method uses the Ably Chat REST API and does not require the room to be attached.
1
2
3
await room.messages.reactions.delete('message-serial-123', {
name: '👍'
});Parameters
The delete() method takes the following parameters:
messageSerialrequiredStringparamsoptionalDeleteMessageReactionParamsReturns
Promise<void>
Returns a promise. The promise is fulfilled when the reaction has been deleted, or rejected with an ErrorInfo object.
Subscribe to reaction summaries
reactions.subscribe(listener: MessageReactionListener): SubscriptionSubscribes to aggregated reaction count summaries for messages. Receives updates when the total reaction counts change on any message in the room.
The room must be attached to receive reaction summary events.
1
2
3
4
5
6
7
const { unsubscribe } = room.messages.reactions.subscribe((event) => {
console.log('Message:', event.messageSerial);
console.log('Reactions:', event.reactions);
});
// To stop receiving reaction summaries
unsubscribe();Parameters
The subscribe() method takes the following parameters:
listenerrequiredMessageReactionSummaryEventReturns
Subscription
Returns an object with the following methods:
Unsubscribe from reaction summaries
unsubscribe(): voidCall unsubscribe() to stop receiving reaction summary events.
Subscribe to individual reaction events
reactions.subscribeRaw(listener: MessageRawReactionListener): SubscriptionSubscribes to individual reaction events, receiving notifications each time a user adds or removes a reaction. This provides more granular updates than the summary subscription.
The room must be attached to receive raw reaction events. Raw message reactions must also be enabled when creating the room by setting rawMessageReactions: true in the MessagesOptions.
1
2
3
4
5
6
7
8
9
10
const { unsubscribe } = room.messages.reactions.subscribeRaw((event) => {
if (event.type === 'reaction.create') {
console.log(`${event.reaction.clientId} reacted with ${event.reaction.name}`);
} else if (event.type === 'reaction.delete') {
console.log(`${event.reaction.clientId} removed ${event.reaction.name}`);
}
});
// To stop receiving raw events
unsubscribe();Parameters
The subscribeRaw() method takes the following parameters:
listenerrequiredMessageReactionRawEventReturns
Subscription
Returns an object with the following methods:
Unsubscribe from raw reaction events
unsubscribe(): voidCall unsubscribe() to stop receiving raw reaction events.
Get reactions for a specific client
reactions.clientReactions(messageSerial: string, clientId?: string): Promise<MessageReactionSummary>Retrieves the reaction data for a specific client on a message. If no client ID is provided, returns reactions for the current user.
1
2
3
4
5
// Get current user's reactions on a message
const myReactions = await room.messages.reactions.clientReactions('message-serial-123');
// Get another user's reactions
const theirReactions = await room.messages.reactions.clientReactions('message-serial-123', 'user-456');Parameters
The clientReactions() method takes the following parameters:
messageSerialrequiredStringclientIdoptionalStringReturns
Promise<MessageReactionSummary>
Returns a promise. The promise is fulfilled with the reaction data for the specified client, or rejected with an ErrorInfo object.
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { MessageReactionType, MessageReactionRawEventType } from '@ably/chat';
const room = await chatClient.rooms.get('my-room', {
messages: { rawMessageReactions: true }
});
await room.attach();
// Subscribe to reaction summaries
const { unsubscribe: unsubscribeSummary } = room.messages.reactions.subscribe((event) => {
const { messageSerial, reactions } = event;
// Update UI with reaction counts
for (const [name, summary] of Object.entries(reactions.distinct)) {
console.log(`${name}: ${summary.total} reactions from ${summary.clientIds.length} clients`);
}
});
// Subscribe to individual reaction events for animations
const { unsubscribe: unsubscribeRaw } = room.messages.reactions.subscribeRaw((event) => {
if (event.type === MessageReactionRawEventType.Create) {
// Show reaction animation
showReactionAnimation(event.reaction.name, event.reaction.clientId);
}
});
// Send a distinct reaction (Slack-style)
await room.messages.reactions.send('message-serial-123', {
name: '👍',
type: MessageReactionType.Distinct
});
// Send multiple reactions (Medium-style claps)
await room.messages.reactions.send('message-serial-456', {
name: '👏',
type: MessageReactionType.Multiple,
count: 5
});
// Remove a reaction
await room.messages.reactions.delete('message-serial-123', {
name: '👍'
});
// Check what reactions I've sent on a message
const myReactions = await room.messages.reactions.clientReactions('message-serial-123');
console.log('My reactions:', myReactions);
// Clean up
unsubscribeSummary();
unsubscribeRaw();