The client.chats service gives you full control over the iMessage conversations on your BlueBubbles Server. You can paginate through all chats, create new ones, add or remove participants, manage read state, send typing indicators, and delete or leave group chats. Many of these operations require the Private API to be enabled on your server.
List chats
Use list() to query chats from the server’s local iMessage database. Pass a request body to control pagination, sorting, and the related data you want returned.
import { BlueBubblesClient } from "bluebubbles-sdk";
const client = new BlueBubblesClient({
BASE: "http://your-server:1234",
PASSWORD: "your-server-password",
});
const response = await client.chats.list({
requestBody: {
limit: 25,
offset: 0,
with: ["lastMessage", "participants"],
sort: "lastmessage",
},
});
Query options
| Parameter | Type | Description |
|---|
limit | number | Max number of chats to return (default 1000) |
offset | number | Number of chats to skip — use for pagination (default 0) |
with | string[] | Related data to include. Options: participants, lastMessage, sms, archived, message.attributed-body, message.message-info-summary, message.payload-data |
sort | string | Sort order. Must be lastmessage. Requires lastMessage in with |
Paginate through all chats
const PAGE_SIZE = 50;
let offset = 0;
let allChats: any[] = [];
while (true) {
const response = await client.chats.list({
requestBody: {
limit: PAGE_SIZE,
offset,
with: ["lastMessage", "participants"],
sort: "lastmessage",
},
});
const chats = response.data ?? [];
allChats = allChats.concat(chats);
if (chats.length < PAGE_SIZE) break;
offset += PAGE_SIZE;
}
Fetch a single chat
Use get() to retrieve a specific chat by its GUID:
const chat = await client.chats.get({
chatGuid: "iMessage;+;+15551234567",
});
The GUID format for direct messages is iMessage;-;+15551234567 (note the -) or iMessage;+;+15551234567 for group chats. Use the GUIDs returned by list() to ensure you have the correct format.
Create a new chat
create() opens a new iMessage conversation with one or more participants. You can optionally send an opening message at the same time.
Creating chats requires the Private API. Requires BlueBubbles Server 0.3.0+.
// Direct message to one person
await client.chats.create({
requestBody: {
addresses: ["+15551234567"],
message: "Hey, I just set up BlueBubbles!",
},
});
// Group chat with multiple participants
await client.chats.create({
requestBody: {
addresses: ["+15551234567", "+15559876543", "friend@icloud.com"],
message: "Welcome to the group!",
},
});
Include country codes in phone numbers where possible. For US numbers, prefix with 1.
Add and remove participants
Add or remove participants from an existing group chat using addParticipantToChat() and removeParticipantFromChat().
Both methods require the Private API. Requires BlueBubbles Server 0.3.0+.
Add a participant
Remove a participant
await client.chats.addParticipantToChat({
chatGuid: "iMessage;+;chat-group-guid",
requestBody: {
address: "+15551234567",
},
});
await client.chats.removeParticipantFromChat({
chatGuid: "iMessage;+;chat-group-guid",
});
removeParticipantFromChat() takes only the chatGuid path parameter. The server determines which participant to remove based on the context of the request.
Mark a chat as read or unread
Mark as read
Mark as unread
markRead() marks a chat as read and dispatches a read event to other connected BlueBubbles clients.Requires Private API and BlueBubbles Server 1.1.0+.
await client.chats.markRead({
chatGuid: "iMessage;+;+15551234567",
});
markChatAsUnread() marks a chat as unread. The event is dispatched to all BlueBubbles clients, but the unread state is only reflected on other Apple devices when running macOS Ventura or later.Requires Private API, macOS Ventura, and BlueBubbles Server 1.4.0+.
await client.chats.markChatAsUnread({
chatGuid: "iMessage;+;+15551234567",
});
Send typing indicators
Show or hide the typing bubble in a conversation. Both methods require the Private API.
Typing indicators automatically stop when you send a message to the same chat. You don’t need to call stopSendTypingIndicator() after a successful sendText().
// Start typing
await client.chats.startSendTypingIndicator({
chatGuid: "iMessage;+;+15551234567",
});
// ... do some work, compose the message ...
// Stop typing manually if you decide not to send
await client.chats.stopSendTypingIndicator({
chatGuid: "iMessage;+;+15551234567",
});
Leave or delete a chat
Leave a group
Delete a chat
Use leaveChat() to remove yourself from a group conversation. This only works for group chats — calling it on a direct message chat returns an error.Requires the Private API.
await client.chats.leaveChat({
chatGuid: "iMessage;+;group-chat-guid",
});
deleteChat() removes a chat from the iMessage client on the macOS host. This change only applies to the server’s Mac — it does not affect other Apple devices signed into the same account.Requires the Private API. Requires BlueBubbles Server 1.3.0+.
Deleting a chat on the Mac is irreversible on that device. Other iCloud-connected devices retain the conversation.
await client.chats.deleteChat({
chatGuid: "iMessage;+;+15551234567",
});
Set or remove a group icon
Customize a group chat’s avatar using setGroupIcon(), or revert to the default with removeGroupIcon(). Both methods require the Private API.
Set an icon
Remove an icon
import { readFileSync } from "fs";
const formData = new FormData();
formData.append(
"icon",
new Blob([readFileSync("./team-photo.jpg")], { type: "image/jpeg" }),
"team-photo.jpg"
);
await client.chats.setGroupIcon({
chatGuid: "iMessage;+;group-chat-guid",
requestBody: formData,
});
await client.chats.removeGroupIcon({
chatGuid: "iMessage;+;group-chat-guid",
});