BlueBubbles (macOS REST)
Delivery: External prerequisite. Use BlueBubbles when you want the supported iMessage bridge in Fased. The gateway talks to the BlueBubbles macOS server over HTTP, receives inbound webhook events, and uses the normal Fased DM and group access model. Status: bundled channel bridge for iMessage on macOS. New iMessage deployments should start here. Use the olderimsg path only for established installs.
Overview
- Runs on macOS via the BlueBubbles helper app (bluebubbles.app).
- Recommended/tested: macOS Sequoia (15). macOS Tahoe (26) works, but edit is currently broken and group icon updates may report success without syncing.
- Fased talks to BlueBubbles through its REST API.
- Incoming messages arrive by webhook.
- Outgoing replies, typing indicators, read receipts, and tapbacks are REST calls.
- Attachments and stickers are ingested as inbound media when possible.
- Pairing and allowlists work like other Fased channels.
- Advanced features include edit, unsend, reply threading, message effects, and group management.
Quick start
You need one macOS host running the BlueBubbles server and one Fased gateway that can reach it over HTTP. In small setups they can be the same machine.- Install the BlueBubbles server on your Mac from bluebubbles.app/install.
- In the BlueBubbles config, enable the web API and set a password.
-
Open Agents, select the Agent, then use Agent > Channels >
BlueBubbles. Enter the server URL, password, and webhook path. Scripted
setups can use config:
-
Point BlueBubbles webhooks to your gateway:
- Start or restart the gateway if the UI asks for it; it will register the webhook handler and start pairing.
- Always set a webhook password.
- Fased rejects BlueBubbles webhook requests unless they include a password or
guid that matches
channels.bluebubbles.password, such as?password=<password>orx-password.
Keeping Messages.app alive (VM / headless setups)
Some macOS VM or always-on setups can leave Messages.app idle. Incoming events may stop until the app is opened again. A simple workaround is to poke Messages every 5 minutes with an AppleScript and LaunchAgent.1) Save the AppleScript
Save this as:~/Scripts/poke-messages.scpt
2) Install a LaunchAgent
Save this as:~/Library/LaunchAgents/com.user.poke-messages.plist
- This runs every 300 seconds and on login.
- The first run may trigger macOS Automation prompts
(
osascript-> Messages). Approve them in the same user session that runs the LaunchAgent.
Alternate setup paths
Normal browser setup is Agent > Channels > BlueBubbles. CLI onboarding can also prompt for the same fields when you prefer terminal setup:- Server URL (required): BlueBubbles server address, for example
http://192.168.1.100:1234 - Password (required): API password from BlueBubbles Server settings
- Webhook path (optional): Defaults to
/bluebubbles-webhook - DM policy: pairing, allowlist, open, or disabled
- Allow list: Phone numbers, emails, or chat targets
Access control (DMs + groups)
DMs:- Default:
channels.bluebubbles.dmPolicy = "pairing". - Unknown senders receive a pairing code. Messages wait for approval, and codes expire after 1 hour.
- Approve via:
fased pairing list bluebubblesfased pairing approve bluebubbles <CODE>
- Pairing is the default token exchange. Details: Pairing
channels.bluebubbles.groupPolicy = open | allowlist | disabled(default:allowlist).channels.bluebubbles.groupAllowFromcontrols who can trigger in groups whenallowlistis set.
Mention gating (groups)
BlueBubbles supports mention gating for group chats, matching iMessage/WhatsApp behavior:- Uses
agents.list[].groupChat.mentionPatternsormessages.groupChat.mentionPatternsto detect mentions. - When
requireMentionis enabled for a group, the agent only responds when mentioned. - Control commands from authorized senders bypass mention gating.
Command gating
- Control commands (e.g.,
/config,/model) require authorization. - Uses
allowFromandgroupAllowFromto determine command authorization. - Authorized senders can run control commands even without mentioning in groups.
Typing + read receipts
- Typing indicators: Fased sends typing start events before and during response generation. BlueBubbles clears typing automatically on send or timeout.
- Read receipts: controlled by
channels.bluebubbles.sendReadReceipts(default:true).
Advanced actions
BlueBubbles supports advanced message actions when enabled in config:- react: Add/remove tapback reactions (
messageId,emoji,remove) - edit: Edit a sent message (
messageId,text) - unsend: Unsend a message (
messageId) - reply: Reply to a specific message (
messageId,text,to) - sendWithEffect: Send with iMessage effect (
text,to,effectId) - renameGroup: Rename a group chat (
chatGuid,displayName) - setGroupIcon: Set a group chat’s icon/photo (
chatGuid,media). This can be flaky on macOS 26 Tahoe. - addParticipant: Add someone to a group (
chatGuid,address) - removeParticipant: Remove someone from a group (
chatGuid,address) - leaveGroup: Leave a group chat (
chatGuid) - sendAttachment: Send media/files (
to,buffer,filename,asVoice)- Voice memos: set
asVoice: truewith MP3 or CAF audio. BlueBubbles converts MP3 to CAF when sending voice memos.
- Voice memos: set
Message IDs (short vs full)
Fased may surface short message IDs (e.g.,1, 2) to save tokens.
MessageSid/ReplyToIdcan be short IDs.MessageSidFull/ReplyToIdFullcontain the provider full IDs.- Short IDs are in-memory; they can expire on restart or cache eviction.
- Actions accept short or full
messageId, but short IDs will error if no longer available.
- Templates:
{{MessageSidFull}},{{ReplyToIdFull}} - Context:
MessageSidFull/ReplyToIdFullin inbound payloads
Block streaming
Control whether responses are sent as a single message or streamed in blocks:Media + limits
- Inbound attachments are downloaded and stored in the media cache.
- Media cap via
channels.bluebubbles.mediaMaxMb(default: 8 MB). - Outbound text is chunked to
channels.bluebubbles.textChunkLimit(default: 4000 chars).
Configuration reference
Full configuration: Configuration Provider options:channels.bluebubbles.enabled: Enable/disable the channel.channels.bluebubbles.serverUrl: BlueBubbles REST API base URL.channels.bluebubbles.password: API password.channels.bluebubbles.webhookPath: Webhook endpoint path (default:/bluebubbles-webhook).channels.bluebubbles.dmPolicy:pairing | allowlist | open | disabled(default:pairing).channels.bluebubbles.allowFrom: DM allowlist using handles, emails, E.164 numbers,chat_id:*, orchat_guid:*.channels.bluebubbles.groupPolicy:open | allowlist | disabled(default:allowlist).channels.bluebubbles.groupAllowFrom: Group sender allowlist.channels.bluebubbles.groups: Per-group config (requireMention, etc.).channels.bluebubbles.sendReadReceipts: Send read receipts (default:true).channels.bluebubbles.blockStreaming: Enable block streaming (default:false; required for streaming replies).channels.bluebubbles.textChunkLimit: Outbound chunk size in chars (default: 4000).channels.bluebubbles.chunkMode:lengthornewline.newlinesplits on blank lines before length chunking.channels.bluebubbles.mediaMaxMb: Inbound media cap in MB (default: 8).channels.bluebubbles.mediaLocalRoots: Absolute local directories allowed for outbound local media paths. Local path sends require this allowlist. Per-account override:channels.bluebubbles.accounts.<accountId>.mediaLocalRoots.channels.bluebubbles.historyLimit: Max group messages for context (0 disables).channels.bluebubbles.dmHistoryLimit: DM history limit.channels.bluebubbles.actions: Enable/disable specific actions.channels.bluebubbles.accounts: Multi-account configuration.
agents.list[].groupChat.mentionPatterns(ormessages.groupChat.mentionPatterns).messages.responsePrefix.
Addressing / delivery targets
Preferchat_guid for stable routing:
chat_guid:iMessage;-;+15555550123(preferred for groups)chat_id:123chat_identifier:...- Direct handles:
+15555550123,[email protected]- If a direct handle has no existing DM chat, Fased creates one through
POST /api/v1/chat/new. This requires the BlueBubbles Private API.
- If a direct handle has no existing DM chat, Fased creates one through
Security
- Webhook requests are authenticated by comparing
guidorpasswordquery params or headers againstchannels.bluebubbles.password. - Keep the API password and webhook endpoint secret (treat them like credentials).
- If you proxy the gateway on the same host, require auth at the proxy and
configure
gateway.trustedProxies. See Gateway security. - Enable HTTPS + firewall rules on the BlueBubbles server if exposing it outside your LAN.
Troubleshooting
- If typing/read events stop working, check BlueBubbles webhook logs and verify
the gateway path matches
channels.bluebubbles.webhookPath. - Pairing codes expire after one hour; use
fased pairing list bluebubblesandfased pairing approve bluebubbles <code>. - Reactions require the BlueBubbles private API (
POST /api/v1/message/react); ensure the server version exposes it. - Edit/unsend require macOS 13+ and a compatible BlueBubbles server version. On macOS 26 Tahoe, edit is currently broken due to private API changes.
- Group icon updates can be flaky on macOS 26 Tahoe.
- Fased auto-hides known-broken actions based on the BlueBubbles server’s
macOS version. If edit still appears on macOS 26 Tahoe, disable it manually
with
channels.bluebubbles.actions.edit=false. - For status/health info:
fased status --allorfased status --deep.