docs/announcements/bluebubbles-imessage.md
OpenClaw no longer ships the BlueBubbles channel. iMessage support runs through the bundled imessage plugin: the Gateway spawns imsg as a child process, locally or through an SSH wrapper, and talks JSON-RPC over stdin/stdout. No server, no webhook, no port.
If your config still contains channels.bluebubbles, migrate it to channels.imessage. The legacy /channels/bluebubbles docs URL redirects to Coming from BlueBubbles, which has the full config translation table and cutover checklist.
imsg on the Mac where Messages.app is signed in.imsg surfaces and macOS permissions.imsg launch, which requires SIP disabled.channels.imessage.cliPath at an SSH wrapper that runs imsg on the signed-in Mac.Install and verify imsg on the Messages Mac:
brew install steipete/tap/imsg
imsg --version
imsg chats --limit 3
imsg rpc --help
Grant Full Disk Access and Automation permissions to the process context that runs imsg and OpenClaw.
Translate the old config:
{
channels: {
imessage: {
enabled: true,
cliPath: "/opt/homebrew/bin/imsg",
dmPolicy: "pairing",
allowFrom: ["+15555550123"],
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"*": { requireMention: true },
},
includeAttachments: true,
},
},
}
Restart the gateway and verify:
openclaw channels status --probe
Test DMs, groups, attachments, and any private API actions you depend on before deleting your old BlueBubbles server.
channels.bluebubbles.serverUrl and channels.bluebubbles.password have no iMessage equivalent; there is no server to reach or authenticate.allowFrom, groupAllowFrom, groups, includeAttachments, attachmentRoots, mediaMaxMb, textChunkLimit, and actions.* keep their meaning under channels.imessage.channels.imessage.includeAttachments is still off by default. Set it explicitly if you expect inbound photos, voice memos, videos, or files to reach the agent.groupPolicy: "allowlist", copy the old groups block, including any "*" wildcard entry. Group sender allowlists and the group registry are separate gates; a groups block with entries but no matching chat_id (or no "*") drops the message at runtime, and an empty groups block logs a startup warning even though sender filtering still lets messages through.match.channel: "bluebubbles" must change to "imessage".allowFrom entries keep working, but conversation history under BlueBubbles session keys does not carry over.