Rooms & Participants
Create and manage Abrova Chat rooms, add participants, and control room lifecycle. Direct (1-to-1) and group rooms, idempotent findOrCreateRoom by external ID, push variables in metadata.
Create and manage chat rooms, add participants, and control room lifecycle.
Room Types
direct— 1-to-1 conversation between two participants.group— Multi-participant chat.
findOrCreateRoom is idempotent — call it every time a user opens a chat. If the room exists, participants are synced. If not, it's created.
Find or Create a Room#
Use findOrCreateRoom with your app's external ID. The call is idempotent: if a room already exists for that externalId, participants are synced and the existing room is returned.
Flutter
// Find or create room by external ID (idempotent — recommended)
final room = await client.findOrCreateRoom(
externalId: 'order-456', // Your app's unique ID
type: RoomType.direct,
participants: [
{'externalUserId': 'seller-1', 'displayName': 'TechShop', 'locale': 'en'},
{'externalUserId': 'buyer-2', 'displayName': 'Alice', 'locale': 'hy'},
],
metadata: {
'source': 'order',
'pushVariables': {'storeName': 'TechShop', 'orderNumber': 'ORD-456'},
'pushData': {'deepLink': 'myapp://orders/456'},
},
);iOS
// Find or create room by external ID (idempotent — recommended)
let room = try await client.findOrCreateRoom(
externalId: "order-456",
participants: [
["externalUserId": "seller-1", "displayName": "TechShop", "locale": "en"],
["externalUserId": "buyer-2", "displayName": "Alice", "locale": "hy"],
],
metadata: [
"source": "order",
"pushVariables": ["storeName": "TechShop", "orderNumber": "ORD-456"],
"pushData": ["deepLink": "myapp://orders/456"],
]
)Android
// Find or create room by external ID (idempotent — recommended)
val room = client.findOrCreateRoom(
externalId = "order-456",
participants = listOf(
mapOf("externalUserId" to "seller-1", "displayName" to "TechShop", "locale" to "en"),
mapOf("externalUserId" to "buyer-2", "displayName" to "Alice", "locale" to "hy"),
),
metadata = mapOf(
"source" to "order",
"pushVariables" to mapOf("storeName" to "TechShop", "orderNumber" to "ORD-456"),
"pushData" to mapOf("deepLink" to "myapp://orders/456"),
)
)React Native
// Find or create room by external ID (idempotent — recommended)
const room = await client.findOrCreateRoom(
'order-456',
[
{ externalUserId: 'seller-1', displayName: 'TechShop', locale: 'en' },
{ externalUserId: 'buyer-2', displayName: 'Alice', locale: 'hy' },
],
{
source: 'order',
pushVariables: { storeName: 'TechShop', orderNumber: 'ORD-456' },
pushData: { deepLink: 'myapp://orders/456' },
}
);Web
// Find or create room by external ID (idempotent — recommended)
const room = await client.findOrCreateRoom({
externalId: 'order-456',
type: 'direct',
participants: [
{ externalUserId: 'seller-1', displayName: 'TechShop', locale: 'en' },
{ externalUserId: 'buyer-2', displayName: 'Alice', locale: 'hy' },
],
metadata: {
source: 'order',
pushVariables: { storeName: 'TechShop', orderNumber: 'ORD-456' },
pushData: { deepLink: 'myapp://orders/456' },
},
});Node.js
// Find or create room by external ID (idempotent — recommended)
// @abrova/chat 0.2.0+ returns { room, created }
const { room, created } = await abrovaChat.rooms.findOrCreate({
externalId: 'order-456',
type: 'direct',
participants: [
{ externalUserId: 'seller-1', displayName: 'TechShop', locale: 'en' },
{ externalUserId: 'buyer-2', displayName: 'Alice', locale: 'hy' },
],
metadata: {
source: 'order',
pushVariables: { storeName: 'TechShop', orderNumber: 'ORD-456' },
pushData: { deepLink: 'myapp://orders/456' },
},
});REST API
# Find or create room (idempotent — recommended). Response: {"room": {...}, "created": true|false}
curl -X POST "https://chat.abrova.ir/api/v1/rooms/find-or-create" \
-H "X-API-Key: ab_live_your_api_key" \
-H "X-Server-Secret: $ABROVA_SERVER_SECRET" \
-H "Content-Type: application/json" \
-d '{
"externalId": "order-456",
"type": "direct",
"participants": [
{"externalUserId": "seller-1", "displayName": "TechShop", "locale": "en"},
{"externalUserId": "buyer-2", "displayName": "Alice", "locale": "hy"}
],
"metadata": {
"source": "order",
"pushVariables": {"storeName": "TechShop", "orderNumber": "ORD-456"},
"pushData": {"deepLink": "myapp://orders/456"}
}
}'Manage Rooms#
List, fetch, and modify rooms after creation. Subscribe to realtime updates when the user opens a chat.
Flutter
// List rooms for current user (each Room carries lastMessage and unreadCount)
final rooms = await client.listRooms();
// Get a specific room
final room = await client.getRoom('room-id');
// Add a participant
await client.addParticipant(
room.id,
externalUserId: 'support-3',
displayName: 'Support Agent',
role: ParticipantRole.admin,
);iOS
// List rooms for current user
let rooms = try await client.listRooms()
// Get a specific room
let room = try await client.getRoom("room-id")
// Subscribe to room events (realtime)
client.subscribeRoom(room.id)
// Unsubscribe when leaving the screen
client.unsubscribeRoom(room.id)Android
// List rooms for current user
val rooms = client.listRooms()
// Get a specific room
val room = client.getRoom("room-id")
// Subscribe to room events (realtime)
client.subscribeRoom(room.id)
// Unsubscribe when leaving the screen
client.unsubscribeRoom(room.id)React Native
// List rooms for current user
const rooms = await client.listRooms();
// Get a specific room
const room = await client.getRoom('room-id');
// Subscribe to room events (realtime)
client.subscribeToRoom(room.id);
// Unsubscribe when leaving the screen
client.unsubscribeFromRoom(room.id);Web
// List rooms for current user
const rooms = await client.listRooms();
// Get a specific room
const room = await client.getRoom('room-id');
// Subscribe to room events (realtime)
client.subscribeToRoom(room.id);
// Unsubscribe when leaving the screen
client.unsubscribeFromRoom(room.id);Node.js
// List rooms for a user
const rooms = await abrovaChat.rooms.list('buyer-2');
// Get a specific room
const roomById = await abrovaChat.rooms.get('room-id');
// Get room by external ID
const roomByExt = await abrovaChat.rooms.getByExternalId('order-456');
// Add a participant
await abrovaChat.rooms.addParticipant(room.id, {
externalUserId: 'support-3',
displayName: 'Support Agent',
role: 'admin',
});
// Get unread summary
const unread = await abrovaChat.rooms.getUnreadSummary('buyer-2');REST API
# List rooms for a user
curl -X GET "https://chat.abrova.ir/api/v1/rooms?userId=buyer-2" \
-H "X-API-Key: ab_live_your_api_key" -H "X-Server-Secret: $ABROVA_SERVER_SECRET"
# Add participant
curl -X POST "https://chat.abrova.ir/api/v1/rooms/{roomId}/participants" \
-H "X-API-Key: ab_live_your_api_key" \
-H "X-Server-Secret: $ABROVA_SERVER_SECRET" \
-H "Content-Type: application/json" \
-d '{"externalUserId": "support-3", "displayName": "Support Agent", "role": "admin"}'The metadata.pushVariables object is merged into push notification templates. For example, if your push template is "{{storeName}} sent you a message", the storeName value from pushVariables will be interpolated automatically. Use pushData to attach custom key-value pairs (like deep links) to the push payload.