# Room reactions Users can send reactions to the entire chat room to show their sentiment as to what is happening. For example, agreeing with the content in a livestream using a thumbs up, or sending a heart when their team scores in a sports game. Room reactions are ephemeral and not stored or aggregated by Ably. The intention being that they show the overall sentiment of a room at a point in time. ## Subscribe to room reactions Subscribe to room reactions by registering a listener. Use the [`reactions.subscribe()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.RoomReactions.html#subscribe)[`reactions.subscribe()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/roomreactions/subscribe%28%29-64gdf)[`reactions.subscribe()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-room-reactions/subscribe.html) method in a room to receive reactions: Use the [`reactions.asFlow()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/as-flow.html) to receive new room reactions: Subscribe to room reactions with the [`useRoomReactions`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.useRoomReactions.html) hook. Supply an optional listener to receive the room reactions. ```javascript const {unsubscribe} = room.reactions.subscribe((event) => { const reaction = event.reaction; console.log(`Received a reaction from ${reaction.clientId} with name ${reaction.name}, and metadata ${reaction.metadata}`); }); ``` ```react import React from 'react'; import { useRoomReactions } from '@ably/chat/react'; const MyComponent = () => { useRoomReactions({ listener: (reactionEvent) => { console.log('Received reaction: ', reactionEvent.reaction); }, }); return
Room Reactions Component
; }; ``` ```swift let reactionSubscription = room.reactions.subscribe() for await event in reactionSubscription { print("Received a reaction of name \(event.reaction.name), and metadata \(event.reaction.metadata)") } ``` ```kotlin val subscription = room.reactions.subscribe { event: RoomReactionEvent -> println("Received a reaction of name ${event.reaction.name} with metadata ${event.reaction.metadata}") } ``` ```jetpack import androidx.compose.runtime.* import com.ably.chat.Room import com.ably.chat.RoomReactionEvent @Composable fun RoomReactionsComponent(room: Room) { LaunchedEffect(room) { room.reactions.asFlow().collect { event: RoomReactionEvent -> println("Received a reaction of name ${event.reaction.name} with metadata ${event.reaction.metadata}") } } } ```
### Room reaction event structure The following are the properties of a room reaction event: | Property | Description | Type | | -------- | ----------- | ---- | | `type` | The type of reaction event. | `String` | | `reaction` | The reaction data. | `Object` | | `reaction.name` | The name of the reaction, for example a 'like' or a heart emoji. | `String` | | `reaction.headers` | Optional headers for adding additional information to a reaction. | `Object` | | `reaction.metadata` | Optional metadata about the reaction, such as an animation or effect. This information is not read by Ably. | `Object` | | `reaction.createdAt` | The time the reaction was sent. | `Date` | | `reaction.clientId` | The client identifier of the user that sent the reaction. | `String` | | `reaction.isSelf` | Will be `true` for the user that sent the reaction. | `Boolean` | ### Unsubscribe from room reactions Use the `unsubscribe()` function returned in the `subscribe()` response to remove a room reaction listener: Jetpack Compose automatically handles lifecycle and cleanup when using `LaunchedEffect` with `asFlow`. You don't need to handle removing listeners, as this is done automatically by the SDK. When you unmount the component that is using the `useRoomReactions` hook, it will automatically handle unsubscribing any associated listeners registered for room reactions. ```javascript // Initial subscription const {unsubscribe} = room.reactions.subscribe((event) => { console.log(`Received a reaction of type ${event.reaction.name}, and metadata ${event.reaction.metadata}`); }); // To remove the listener unsubscribe(); ``` ```kotlin // Initial subscription val (unsubscribe) = room.reactions.subscribe { event -> println("Received a reaction of type ${event.reaction.name}, and metadata ${event.reaction.metadata}") } // To remove the listener unsubscribe() ``` ## Send a room reaction Use the [`reactions.send()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.RoomReactions.html#send)[`reactions.send()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/roomreactions/send%28withparams%3A%29)[`reactions.send()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-room-reactions/send.html) method to send a room-level reaction. The most common way of using this method is to trigger it whenever a user clicks an emoji button in a room: Use the [`sendRoomReaction()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-react.UseRoomReactionsResponse.html#sendroomreaction) method available from the response of the `useRoomReactions` hook to emit an event when a user reacts, for example when they click an emoji button: ```javascript await room.reactions.send({name: "like"}); await room.reactions.send({name: "heart", metadata: {"effect": "fireworks"}}); ``` ```react import { useRoomReactions } from '@ably/chat/react'; const MyComponent = () => { const { sendRoomReaction } = useRoomReactions(); const sendLike = () => { sendRoomReaction({ name: 'like' }); }; return (
); }; ``` ```swift try await room.reactions.send(params: .init(name: "like")) try await room.reactions.send(params: .init(name: "heart", metadata: ["effect": "fireworks"])) ``` ```kotlin room.reactions.send(name = "like") // import com.ably.chat.json.* room.reactions.send(name = "heart", metadata = jsonObject { put("effect", "fireworks") }) ``` ```jetpack import androidx.compose.material.* import androidx.compose.runtime.* import com.ably.chat.Room import com.ably.chat.json.* import kotlinx.coroutines.launch @Composable fun SendReactionComponent(room: Room) { val coroutineScope = rememberCoroutineScope() Button(onClick = { coroutineScope.launch { room.reactions.send(name = "like") } }) { Text("Send Like") } Button(onClick = { coroutineScope.launch { room.reactions.send( name = "heart", metadata = jsonObject { put("effect", "fireworks") } ) } }) { Text("Send Heart with Effect") } } ```