Retrieves reaction information for a specific client on a message.
Use this method when reaction summaries are clipped (too many reacting clients) and you need to check if a specific client has reacted. This is particularly useful for determining if the current user has reacted when they're not in the summary's client list. Note: This method uses the Ably Chat REST API and so does not require the room to be attached to be called.
The unique identifier of the message
OptionalclientId: stringThe client ID to check (defaults to current client)
Promise - That resolves to reaction data for the specified client. The promise rejects with:
import * as Ably from 'ably';
import { ChatClient } from '@ably/chat';
const chatClient: ChatClient; // existing ChatClient instance
const room = await chatClient.rooms.get('large-event');
const messageSerial = '01726585978590-001@abcdefghij:001';
try {
// Get reactions for the current client
const myReactions = await room.messages.reactions.clientReactions(messageSerial);
if (myReactions.unique?.['👍']) {
console.log('I have reacted with 👍');
}
if (myReactions.distinct?.['❤️']) {
console.log('I have reacted with ❤️');
}
if (myReactions.multiple?.['vote-option-a'] && chatClient.clientId) {
console.log(`I voted for option A: ${myReactions.multiple['vote-option-a'].clientIds[chatClient.clientId]} times`);
}
// Check reactions for a specific client
const specificClientReactions = await room.messages.reactions.clientReactions(
messageSerial,
'specific-client-id'
);
console.log('Specific client reactions:', specificClientReactions);
} catch (error) {
console.error('Failed to get client reactions:', error);
}
Deletes a previously sent reaction from a chat message.
The deletion behavior depends on the reaction type:
Note: This method uses the Ably Chat REST API and so does not require the room to be attached to be called.
The unique identifier of the message to remove the reaction from
Optionalparams: DeleteMessageReactionParamsOptional deletion parameters
Promise that resolves when the reaction has been deleted, or rejects with:
import * as Ably from 'ably';
import { ChatClient, MessageReactionType } from '@ably/chat';
const chatClient: ChatClient; // existing ChatClient instance
const room = await chatClient.rooms.get('team-chat');
const messageSerial = '01726585978590-001@abcdefghij:001';
// Delete a distinct reaction (specific emoji)
try {
await room.messages.reactions.delete(messageSerial, {
name: '👍',
type: MessageReactionType.Distinct
});
console.log('Thumbs up reaction removed');
} catch (error) {
console.error('Failed to delete reaction:', error);
}
// Delete a unique reaction (only one per user, name not needed)
await room.messages.reactions.delete(messageSerial, {
type: MessageReactionType.Unique
});
// Delete all instances of a multiple reaction
await room.messages.reactions.delete(messageSerial, {
name: 'option-b',
type: MessageReactionType.Multiple
});
Sends a reaction to a specific chat message.
Note:
The unique identifier of the message to react to.
The reaction parameters
Promise that resolves when the reaction has been sent, or rejects with:
import * as Ably from 'ably';
import { ChatClient, MessageReactionType } from '@ably/chat';
const chatClient: ChatClient; // existing ChatClient instance
const room = await chatClient.rooms.get('sports-chat');
const messageSerial = '01726585978590-001@abcdefghij:001';
// Send a simple reaction to a message
try {
await room.messages.reactions.send(messageSerial, {
name: '👍'
});
console.log('Reaction sent successfully');
} catch (error) {
console.error('Failed to send reaction:', error);
}
// Send a distinct type reaction (can react with multiple different emojis)
await room.messages.reactions.send(messageSerial, {
name: '❤️',
type: MessageReactionType.Distinct
});
// Send a multiple type reaction with count (for vote-style reactions)
await room.messages.reactions.send(messageSerial, {
name: 'option-a',
type: MessageReactionType.Multiple,
count: 3 // User votes 3 times for option-a
});
Subscribes to chat message reaction summary events.
Summary events provide aggregated reaction counts. Each summary event contains counts and client lists for all reaction types on a message.
Note:
clipped flag and use clientReactions for complete client information when needed.Callback invoked when reaction summaries are updated
Subscription object with an unsubscribe method
import * as Ably from 'ably';
import { ChatClient, MessageReactionSummaryEvent } from '@ably/chat';
const chatClient: ChatClient; // existing ChatClient instance
const room = await chatClient.rooms.get('product-reviews');
// Subscribe to reaction summaries
const subscription = room.messages.reactions.subscribe((event: MessageReactionSummaryEvent) => {
const { reactions } = event;
// Handle distinct reactions
if (reactions.distinct) {
Object.entries(reactions.distinct).forEach(([reaction, data]) => {
console.log(`${reaction}: ${data.total} reactions from ${data.clientIds.length} users`);
});
}
// Handle unique reactions
if (reactions.unique) {
Object.entries(reactions.unique).forEach(([reaction, data]) => {
console.log(`${reaction}: ${data.total} users reacted`);
});
}
// Handle multiple reactions
if (reactions.multiple) {
Object.entries(reactions.multiple).forEach(([reaction, data]) => {
console.log(`${reaction}: ${data.total} total votes`);
});
}
});
// Attach to the room to start receiving events
await room.attach();
// Later, unsubscribe when done
subscription.unsubscribe();
Subscribes to individual chat message reaction events.
Raw reaction events provide the individual updates for each reaction added or removed. This is most useful for analytics, but is not recommended for driving UI due to the high volume of events.
Note: Requires MessagesOptions.rawMessageReactions to be enabled in room options.
Callback invoked for each individual reaction event
Subscription object with an unsubscribe method
An Ably.ErrorInfo with ErrorCode.FeatureNotEnabledInRoom if raw message reactions are not enabled
import * as Ably from 'ably';
import { ChatClient, MessageReactionRawEvent, MessageReactionEventType } from '@ably/chat';
const chatClient: ChatClient; // existing ChatClient instance
// Enable raw reactions in room options
const room = await chatClient.rooms.get('live-stream', {
messages: {
rawMessageReactions: true
}
});
// Subscribe to individual reaction events
const subscription = room.messages.reactions.subscribeRaw((event: MessageReactionRawEvent) => {
const { type, reaction, timestamp } = event;
switch (type) {
case MessageReactionEventType.Create:
console.log(`${reaction.clientId} added ${reaction.name} to message ${reaction.messageSerial} at ${timestamp}`);
break;
case MessageReactionEventType.Delete:
console.log(`${reaction.clientId} removed ${reaction.name} from message ${reaction.messageSerial} at ${timestamp}`);
break;
}
// Handle multiple type reactions with counts
if (reaction.count !== undefined) {
console.log(`Reaction has count: ${reaction.count}`);
}
});
// Attach to the room to start receiving events
await room.attach();
// Later, unsubscribe when done
subscription.unsubscribe();
Send, delete, and subscribe to message reactions.