BlueBubbles
Conecta iMessage via BlueBubbles macOS Server (REST): enviar/recibir, estado de escritura, reacciones y acciones avanzadas.
Estado: plugin integrado que se comunica con BlueBubbles macOS Server via HTTP. Como la API es más rica y la configuración más fluida, BlueBubbles es la integración de iMessage recomendada (preferida sobre el canal legacy imsg).
Resumen
- Ejecuta en macOS: la app auxiliar BlueBubbles (bluebubbles.app).
- Recomendado/probado: macOS Sequoia (15). macOS Tahoe (26) funciona, pero la edición de mensajes está actualmente rota en Tahoe, y las actualizaciones de íconos de grupo pueden reportar éxito pero no sincronizar.
- OpenClaw usa la API REST (ej. GET /api/v1/ping, POST /message/text, POST /chat/:id/*).
- Los mensajes entrantes llegan vía webhook; las respuestas salientes, escritura, confirmaciones de lectura y tapbacks se hacen vía llamadas REST.
- Adjuntos y stickers entran al pipeline de medios entrantes (expuestos al agente cuando sea posible).
- Emparejamiento/lista permitida funciona como otros canales (/start/pairing): channels.bluebubbles.allowFrom + código de emparejamiento.
- Las reacciones se inyectan como eventos del sistema (como Slack/Telegram), así que el agente puede mencionarlas antes de responder.
- Capacidades avanzadas: editar, deshacer envío, responder a mensaje, efectos de mensaje y gestión de grupos.
Inicio Rápido
1. Instala BlueBubbles Server en tu Mac (sigue bluebubbles.app/install).
2. Habilita la Web API en configuración de BlueBubbles y establece una contraseña.
3. Ejecuta openclaw onboard y elige BlueBubbles, o configúralo manualmente:
{
channels: {
bluebubbles: {
enabled: true,
serverUrl: "http://192.168.1.100:1234",
password: "example-password",
webhookPath: "/bluebubbles-webhook",
},
},
}4. Apunta el webhook de BlueBubbles a tu Gateway (ejemplo: https://tu-gateway-host:3000/bluebubbles-webhook?password=<contraseña>).
5. Inicia el Gateway; registra el manejador de webhook y comienza el flujo de emparejamiento.
Incorporación
BlueBubbles soporta un asistente interactivo:
openclaw onboard
El asistente preguntará:
- URL del Servidor (requerido): dirección del servidor BlueBubbles (ej. http://192.168.1.100:1234)
- Contraseña (requerido): contraseña API desde configuración de BlueBubbles Server
- Ruta del webhook (opcional): por defecto /bluebubbles-webhook
- Política DM: emparejamiento, lista permitida, abierto o deshabilitado
- Lista permitida: números de teléfono, emails o objetivos de chat
También puedes agregarlo vía CLI:
openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>
Control de Acceso (DM + grupos)
DMs:
- Por defecto: channels.bluebubbles.dmPolicy = "pairing".
- Remitentes desconocidos reciben un código de emparejamiento; los mensajes se ignoran hasta ser aprobados (los códigos expiran después de 1 hora).
- Aprobar vía:
- openclaw pairing list bluebubbles
- openclaw pairing approve bluebubbles <CÓDIGO>
- El emparejamiento es el intercambio de token por defecto. Detalles: /start/pairing
Grupos:
- channels.bluebubbles.groupPolicy = open | allowlist | disabled (por defecto allowlist).
- Cuando es allowlist, channels.bluebubbles.groupAllowFrom controla quién puede activar el agente en grupos.
Gating de mención (grupos)
El gating de mención de grupo BlueBubbles coincide con el comportamiento de iMessage/WhatsApp:
- Las menciones se detectan vía agents.list[].groupChat.mentionPatterns (o messages.groupChat.mentionPatterns).
- Cuando el requireMention de un grupo está habilitado, el agente solo responde cuando se le menciona.
- Los remitentes de comandos de control confiables pueden omitir el gating de mención.
Configuración por grupo:
{
channels: {
bluebubbles: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"*": { requireMention: true },
"iMessage;-;chat123": { requireMention: false },
},
},
},
}Gating de comandos
- Los comandos de control (ej. /config, /model) requieren autorización.
- La autorización se determina por allowFrom y groupAllowFrom.
- Los remitentes autorizados pueden ejecutar comandos de control en grupos sin @mención.
Estado de escritura + confirmaciones de lectura
- Estado de escritura: enviado automáticamente antes y durante la generación de respuesta.
- Confirmaciones de lectura: controladas por channels.bluebubbles.sendReadReceipts (por defecto true).
- El estado de escritura es limpiado por BlueBubbles después del envío o timeout (detención manual vía DELETE no es confiable).
{
channels: {
bluebubbles: {
sendReadReceipts: false
},
},
}Acciones avanzadas
Cuando está habilitado, BlueBubbles soporta acciones avanzadas de mensaje:
{
channels: {
bluebubbles: {
actions: {
reactions: true,
edit: true,
unsend: true,
reply: true,
sendWithEffect: true,
renameGroup: true,
setGroupIcon: true,
addParticipant: true,
removeParticipant: true,
leaveGroup: true,
sendAttachment: true,
},
},
},
}Lista de acciones:
- react: agregar/eliminar tapback (messageId, emoji, remove)
- edit: editar un mensaje enviado (messageId, text) (macOS 13+; actualmente roto en macOS 26 Tahoe)
- unsend: deshacer envío de mensaje (messageId) (macOS 13+)
- reply: responder a un mensaje específico (messageId, text, to)
- sendWithEffect: enviar con efectos iMessage (text, to, effectId)
- renameGroup: renombrar un grupo (chatGuid, displayName)
- setGroupIcon: establecer ícono de grupo (chatGuid, media) (puede reportar éxito pero no sincronizar en macOS 26 Tahoe)
- addParticipant: agregar un participante (chatGuid, address)
- removeParticipant: eliminar un participante (chatGuid, address)
- leaveGroup: salir de un grupo (chatGuid)
- sendAttachment: enviar medios/adjuntos (to, buffer, filename, asVoice)
- Nota de voz: establece asVoice: true y proporciona audio MP3 o CAF para enviar una nota de voz iMessage. BlueBubbles convierte MP3 a CAF para notas de voz.
IDs de mensaje (corto vs completo)
Para ahorrar tokens, OpenClaw puede exponer un "id de mensaje corto" en contexto (ej. 1, 2).
- MessageSid / ReplyToId pueden ser un ID corto.
- MessageSidFull / ReplyToIdFull son IDs completos del proveedor.
- Los IDs cortos son un caché en memoria; se vuelven inválidos después de reinicios o expulsión.
- Las acciones aceptan tanto messageId corto como completo, pero darán error si un ID corto ya no está disponible.
Para automatización/almacenamiento de larga duración, usa IDs completos:
- Plantillas: <code>'{'{MessageSidFull}'}'</code>, <code>'{'{ReplyToIdFull}'}'</code>
- Contexto: MessageSidFull / ReplyToIdFull en payloads entrantes
Ver /gateway/configuration para variables de plantilla.
Bloquear streaming
Controla si las respuestas se envían en una sola pieza o se transmiten en bloques:
{
channels: {
bluebubbles: {
blockStreaming: true
},
},
}Medios y límites
- Los adjuntos entrantes se descargan y almacenan en el caché de medios.
- Límite: channels.bluebubbles.mediaMaxMb (por defecto 8 MB).
- El texto saliente se fragmenta por channels.bluebubbles.textChunkLimit (por defecto 4000 caracteres).
Referencia de configuración
Config completa: /gateway/configuration
Opciones del proveedor:
- channels.bluebubbles.enabled
- channels.bluebubbles.serverUrl
- channels.bluebubbles.password
- channels.bluebubbles.webhookPath (default /bluebubbles-webhook)
- channels.bluebubbles.dmPolicy: pairing | allowlist | open | disabled (default pairing)
- channels.bluebubbles.allowFrom: DM allowlist (handles, emails, E.164, chat_id:*, chat_guid:*)
- channels.bluebubbles.groupPolicy: open | allowlist | disabled (default allowlist)
- channels.bluebubbles.groupAllowFrom
- channels.bluebubbles.groups (per-group overrides like requireMention)
- channels.bluebubbles.sendReadReceipts (default true)
- channels.bluebubbles.blockStreaming (default true)
- channels.bluebubbles.textChunkLimit (default 4000)
- channels.bluebubbles.chunkMode: length (default) / newline
- channels.bluebubbles.mediaMaxMb (default 8)
- channels.bluebubbles.historyLimit (group context message limit; disable with 0)
- channels.bluebubbles.dmHistoryLimit
- channels.bluebubbles.actions
- channels.bluebubbles.accounts
Opciones globales relacionadas:
- agents.list[].groupChat.mentionPatterns (or messages.groupChat.mentionPatterns)
- messages.responsePrefix
Direcciones y objetivos
Para enrutamiento estable, prefiere chat_guid:
- chat_guid:iMessage;-;+15555550123 (preferido para chats grupales)
- chat_id:123
- chat_identifier:...
- Handles directos: +15555550123, [email protected]
- Si no existe un chat DM para un handle, OpenClaw crea uno via POST /api/v1/chat/new (requiere BlueBubbles Private API).
Seguridad
- Las solicitudes de webhook se autentican comparando guid/password en query params o headers con channels.bluebubbles.password; las solicitudes de localhost también son aceptadas.
- Trata la contraseña de API y el endpoint de webhook como credenciales (no las filtres).
- Confiar en localhost significa que un proxy inverso en el mismo host puede evitar contraseñas involuntariamente. Si usas proxy del Gateway, aplica auth en la capa del proxy y configura gateway.trustedProxies. Ver Seguridad del Gateway.
- Si expones el servidor BlueBubbles fuera de tu LAN, habilita HTTPS y configura reglas de firewall.
Solución de problemas
- Eventos de typing/read dejaron de funcionar: revisa los logs de webhook de BlueBubbles y confirma que la ruta del Gateway coincide con channels.bluebubbles.webhookPath.
- Los códigos de emparejamiento expiran después de 1 hora: openclaw pairing list bluebubbles / openclaw pairing approve bluebubbles <code>.
- Las reacciones requieren la Private API de BlueBubbles (POST /api/v1/message/react); confirma que tu versión del servidor la expone.
- edit/unsend requieren macOS 13+ y un servidor BlueBubbles compatible; en macOS 26 (Tahoe), edit está actualmente no disponible debido a cambios en la Private API.
- Las actualizaciones de icono de grupo pueden ser inestables en macOS 26 (Tahoe): la API puede devolver éxito pero el icono no se sincroniza.
- OpenClaw oculta automáticamente acciones conocidas por no estar disponibles para tu versión de macOS. Si todavía ves edit en macOS 26 (Tahoe), deshabilítalo manualmente: channels.bluebubbles.actions.edit=false.
- Estado/salud: openclaw status --all o openclaw status --deep.
Para un resumen de cómo funcionan los canales, ver Canales y Plugins.