Ir al contenido

BlueBubbles

Estado: complemento incluido que se comunica con el servidor macOS de BlueBubbles a través de HTTP. Recomendado para la integración de iMessage debido a su API más rica y una configuración más fácil en comparación con el canal imsg heredado.

  • Se ejecuta en macOS a través de la aplicación auxiliar BlueBubbles (bluebubbles.app).
  • Recomendado/probado: macOS Sequoia (15). macOS Tahoe (26) funciona; la edición actualmente está rota en Tahoe, y las actualizaciones de iconos de grupo pueden informar éxito pero no sincronizarse.
  • OpenClaw se comunica con él a través de su API REST (GET /api/v1/ping, POST /message/text, POST /chat/:id/*).
  • Los mensajes entrantes llegan a través de webhooks; las respuestas salientes, indicadores de escritura, confirmaciones de lectura y reacciones (tapbacks) son llamadas REST.
  • Los archivos adjuntos y las pegatinas se ingieren como medios entrantes (y se muestran al agente cuando es posible).
  • Las respuestas de TTS automáticas que sintetizan audio MP3 o CAF se entregan como burbujas de memo de voz de iMessage en lugar de archivos adjuntos simples.
  • El emparejamiento/lista blanca funciona de la misma manera que otros canales (/channels/pairing etc.) con channels.bluebubbles.allowFrom + códigos de emparejamiento.
  • Las reacciones se muestran como eventos del sistema, al igual que en Slack/Telegram, para que los agentes puedan “mencionarlas” antes de responder.
  • Funciones avanzadas: editar, no enviar, hilos de respuesta, efectos de mensaje, gestión de grupos.
  1. Instalar BlueBubbles

    Instala el servidor BlueBubbles en tu Mac (sigue las instrucciones en bluebubbles.app/install).

  2. Habilitar la API web

    En la configuración de BlueBubbles, habilite la API web y establezca una contraseña.

  3. Configurar OpenClaw

    Ejecute openclaw onboard y seleccione BlueBubbles, o configure manualmente:

    {
    channels: {
    bluebubbles: {
    enabled: true,
    serverUrl: "http://192.168.1.100:1234",
    password: "example-password",
    webhookPath: "/bluebubbles-webhook",
    },
    },
    }
  4. Apuntar webhooks a la puerta de enlace

    Apunte los webhooks de BlueBubbles a su puerta de enlace (ejemplo: `https://your-gateway-host:3000/bluebubbles-webhook?password=

    `).

  5. Iniciar la puerta de enlace

    Inicie la puerta de enlace; esta registrará el controlador de webhooks y comenzará el emparejamiento.

Mantener Mensajes.app activo (configuraciones de VM / sin cabeza)

Sección titulada «Mantener Mensajes.app activo (configuraciones de VM / sin cabeza)»

Algunas configuraciones de macOS VM / siempre activas pueden terminar con Mensajes.app pasando a “inactivo” (los eventos entrantes se detienen hasta que la aplicación se abre/pone en primer plano). Una solución sencilla es hacer un toque a Messages cada 5 minutos usando un AppleScript + LaunchAgent.

  1. Guardar el AppleScript

    Guárdelo como ~/Scripts/poke-messages.scpt:

    try
    tell application "Messages"
    if not running then
    launch
    end if
    -- Touch the scripting interface to keep the process responsive.
    set _chatCount to (count of chats)
    end tell
    on error
    -- Ignore transient failures (first-run prompts, locked session, etc).
    end try
  2. Instalar un LaunchAgent

    Guárdelo como ~/Library/LaunchAgents/com.user.poke-messages.plist:

    Label

    com.user.poke-messages

    ProgramArguments

    /bin/bash

    -lc

    /usr/bin/osascript “$HOME/Scripts/poke-messages.scpt”

    RunAtLoad

    StartInterval

    300

    StandardOutPath

    /tmp/poke-messages.log

    StandardErrorPath

    /tmp/poke-messages.err

    Esto se ejecuta **cada 300 segundos** y **al iniciar sesión**. La primera ejecución puede activar las indicaciones de **Automatización** de macOS (`osascript` → Messages). Apruébelas en la misma sesión de usuario que ejecuta el LaunchAgent.
  3. Cargarlo

    Ventana de terminal
    launchctl unload ~/Library/LaunchAgents/com.user.poke-messages.plist 2>/dev/null || true
    launchctl load ~/Library/LaunchAgents/com.user.poke-messages.plist

BlueBubbles está disponible en la incorporación interactiva:

openclaw onboard

El asistente solicita:

Dirección del servidor de BlueBubbles (p. ej., `http://192.168.1.100:1234`). Contraseña de API de la configuración del servidor BlueBubbles. Ruta del endpoint del webhook. `pairing`, `allowlist`, `open` o `disabled`. Números de teléfono, correos electrónicos o destinos de chat.

También puedes añadir BlueBubbles a través de la CLI:

openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>
  • Predeterminado: channels.bluebubbles.dmPolicy = "pairing".
  • Los remitentes desconocidos reciben un código de emparejamiento; los mensajes se ignoran hasta que se aprueban (los códigos caducan después de 1 hora).
  • Aprobar vía:
    • openclaw pairing list bluebubbles
    • `openclaw pairing approve bluebubbles

` - El emparejamiento es el intercambio de token predeterminado. Detalles: Emparejamiento

Enriquecimiento de nombres de contactos (macOS, opcional)

Sección titulada «Enriquecimiento de nombres de contactos (macOS, opcional)»

Los webhooks de grupo de BlueBubbles a menudo solo incluyen las direcciones brutas de los participantes. Si deseas que el contexto GroupMembers muestre los nombres de los contactos locales en su lugar, puedes optar por el enriquecimiento local de Contactos en macOS:

  • channels.bluebubbles.enrichGroupParticipantsFromContacts = true habilita la búsqueda. Predeterminado: false.
  • Las búsquedas se ejecutan solo después de que el acceso al grupo, la autorización de comandos y el filtrado de menciones hayan permitido el paso del mensaje.
  • Solo se enriquecen los participantes telefónicos sin nombre.
  • Los números de teléfono brutos se mantienen como alternativa cuando no se encuentra ninguna coincidencia local.
{
channels: {
bluebubbles: {
enrichGroupParticipantsFromContacts: true,
},
},
}

BlueBubbles admite el filtrado de menciones para los chats grupales, coincidiendo con el comportamiento de iMessage/WhatsApp:

  • Usa agents.list[].groupChat.mentionPatterns (o messages.groupChat.mentionPatterns) para detectar menciones.
  • Cuando requireMention está habilitado para un grupo, el agente solo responde cuando se le menciona.
  • Los comandos de control de remitentes autorizados omiten el filtrado de menciones.

Configuración por grupo:

{
channels: {
bluebubbles: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"*": { requireMention: true }, // default for all groups
"iMessage;-;chat123": { requireMention: false }, // override for specific group
},
},
},
}
  • Los comandos de control (por ejemplo, /config, /model) requieren autorización.
  • Usa allowFrom y groupAllowFrom para determinar la autorización del comando.
  • Los remitentes autorizados pueden ejecutar comandos de control incluso sin mencionar en grupos.

Cada entrada bajo channels.bluebubbles.groups.* acepta una cadena systemPrompt opcional. El valor se inyecta en el prompt del sistema del agente en cada turno que maneja un mensaje en ese grupo, por lo que puedes establecer reglas de comportamiento o persona por grupo sin editar los prompts del agente:

{
channels: {
bluebubbles: {
groups: {
"iMessage;-;chat123": {
systemPrompt: "Keep responses under 3 sentences. Mirror the group's casual tone.",
},
},
},
},
}

La clave coincide con lo que BlueBubbles reporte como chatGuid / chatIdentifier / numérico chatId para el grupo, y una entrada comodín "*" proporciona un valor predeterminado para cada grupo sin una coincidencia exacta (el mismo patrón usado por requireMention y las políticas de herramientas por grupo). Las coincidencias exactas siempre ganan sobre el comodín. Los MDs ignoran este campo; usa la personalización de prompt a nivel de agente o de cuenta en su lugar.

Ejemplo práctico: respuestas en hilo y reacciones de tapback (API privada)

Sección titulada «Ejemplo práctico: respuestas en hilo y reacciones de tapback (API privada)»

Con la API privada de BlueBubbles habilitada, los mensajes entrantes llegan con ID de mensajes cortos (por ejemplo [[reply_to:5]]) y el agente puede llamar a action=reply para responder en hilo a un mensaje específico o action=react para enviar una tapback. Un systemPrompt por grupo es una forma confiable de mantener al agente eligiendo la herramienta correcta:

{
channels: {
bluebubbles: {
groups: {
"iMessage;+;chat-family": {
systemPrompt: "When replying in this group, always call action=reply with the [[reply_to:N]] messageId from context so your response threads under the triggering message. Never send a new unlinked message. For short acknowledgements ('ok', 'got it', 'on it'), use action=react with an appropriate tapback emoji (❤️, 👍, 😂, ‼️, ❓) instead of sending a text reply.",
},
},
},
},
}

Las reacciones Tapback y las respuestas en hilos requieren la API privada de BlueBubbles; consulta Acciones avanzadas e IDs de mensajes para conocer la mecánica subyacente.

Los chats de BlueBubbles pueden convertirse en espacios de trabajo de ACP duraderos sin cambiar la capa de transporte.

Flujo rápido del operador:

  • Ejecute /acp spawn codex --bind here dentro del MD o del chat de grupo permitido.
  • Los mensajes futuros en esa misma conversación de BlueBubbles se enrutan a la sesión de ACP generada.
  • /new y /reset restablecen la misma sesión de ACP vinculada en su lugar.
  • /acp close cierra la sesión de ACP y elimina el vínculo.

También se admiten vínculos persistentes configurados a través de entradas bindings[] de nivel superior con type: "acp" y match.channel: "bluebubbles".

match.peer.id puede usar cualquier forma de destino de BlueBubbles admitida:

  • identificador de MD normalizado, como +15555550123 o [email protected]
  • chat_id:<id>
  • chat_guid:<guid>
  • chat_identifier:<identifier>

Para vínculos de grupo estables, prefiera chat_id:* o chat_identifier:*.

Ejemplo:

{
agents: {
list: [
{
id: "codex",
runtime: {
type: "acp",
acp: { agent: "codex", backend: "acpx", mode: "persistent" },
},
},
],
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "bluebubbles",
accountId: "default",
peer: { kind: "dm", id: "+15555550123" },
},
acp: { label: "codex-imessage" },
},
],
}

Consulta Agentes ACP para conocer el comportamiento de enlace ACP compartido.

Indicadores de escritura + confirmaciones de lectura

Sección titulada «Indicadores de escritura + confirmaciones de lectura»
  • Indicadores de escritura: Se envían automáticamente antes y durante la generación de la respuesta.
  • Confirmaciones de lectura: Controladas por channels.bluebubbles.sendReadReceipts (predeterminado: true).
  • Indicadores de escritura: OpenClaw envía eventos de inicio de escritura; BlueBubbles borra la escritura automáticamente al enviar o al tiempo de espera (la detención manual mediante DELETE no es confiable).
{
channels: {
bluebubbles: {
sendReadReceipts: false, // disable read receipts
},
},
}

BlueBubbles admite acciones de mensajes avanzadas cuando se habilitan en la configuración:

{
channels: {
bluebubbles: {
actions: {
reactions: true, // tapbacks (default: true)
edit: true, // edit sent messages (macOS 13+, broken on macOS 26 Tahoe)
unsend: true, // unsend messages (macOS 13+)
reply: true, // reply threading by message GUID
sendWithEffect: true, // message effects (slam, loud, etc.)
renameGroup: true, // rename group chats
setGroupIcon: true, // set group chat icon/photo (flaky on macOS 26 Tahoe)
addParticipant: true, // add participants to groups
removeParticipant: true, // remove participants from groups
leaveGroup: true, // leave group chats
sendAttachment: true, // send attachments/media
},
},
},
}
Acciones disponibles
  • react: Añadir/eliminar reacciones de tapback (messageId, emoji, remove). El conjunto nativo de tapbacks de iMessage es love, like, dislike, laugh, emphasize y question. Cuando un agente elige un emoji fuera de ese conjunto (por ejemplo 👀), la herramienta de reacción recurre a love para que el tapback aún se renderice en lugar de fallar toda la solicitud. Las reacciones de confirmación configuradas aún se validan estrictamente y dan error en valores desconocidos.
  • edit: Editar un mensaje enviado (messageId, text).
  • unsend: Enviar al olvido un mensaje (messageId).
  • reply: Responder a un mensaje específico (messageId, text, to).
  • sendWithEffect: Enviar con efecto de iMessage (text, to, effectId).
  • renameGroup: Cambiar el nombre de un chat de grupo (chatGuid, displayName).
  • setGroupIcon: Establecer el icono/foto de un chat de grupo (chatGuid, media) — inestable en macOS 26 Tahoe (la API puede devolver éxito pero el icono no se sincroniza).
  • addParticipant: Añadir a alguien a un grupo (chatGuid, address).
  • removeParticipant: Eliminar a alguien de un grupo (chatGuid, address).
  • leaveGroup: Salir de un chat de grupo (chatGuid).
  • upload-file: Enviar medios/archivos (to, buffer, filename, asVoice).
    • Notas de voz: configure asVoice: true con audio MP3 o CAF para enviar como un mensaje de voz de iMessage. BlueBubbles convierte MP3 → CAF al enviar notas de voz.
  • Alias heredado: sendAttachment aún funciona, pero upload-file es el nombre de acción canónico.

OpenClaw puede mostrar IDs de mensajes cortos (por ejemplo, 1, 2) para guardar tokens.

  • MessageSid / ReplyToId pueden ser IDs cortos.
  • MessageSidFull / ReplyToIdFull contienen los IDs completos del proveedor.
  • Los IDs cortos están en memoria; pueden expirar al reiniciar o por la eliminación de la caché.
  • Las acciones aceptan IDs cortos o completos messageId, pero los IDs cortos darán error si ya no están disponibles.

Use IDs completos para automatizaciones y almacenamiento duraderos:

  • Plantillas: {{MessageSidFull}}, {{ReplyToIdFull}}
  • Contexto: MessageSidFull / ReplyToIdFull en las cargas útiles entrantes

Consulte Configuración para las variables de plantilla.

Fusión de MDs enviados por partes (comando + URL en una sola composición)

Sección titulada «Fusión de MDs enviados por partes (comando + URL en una sola composición)»

Cuando un usuario escribe un comando y una URL juntos en iMessage (por ejemplo, Dump https://example.com/article), Apple divide el envío en dos entregas de webhook separadas:

  1. Un mensaje de texto ("Dump").
  2. Un globo de vista previa de URL ("https://...") con imágenes de vista previa OG como archivos adjuntos.

Los dos webhooks llegan a OpenClaw con una diferencia de ~0,8-2,0 s en la mayoría de las configuraciones. Sin la fusión, el agente recibe el comando solo en el turno 1, responde (a menudo “envíame la URL”) y solo ve la URL en el turno 2, momento en el cual el contexto del comando ya se ha perdido.

channels.bluebubbles.coalesceSameSenderDms activa la fusión de webhooks consecutivos del mismo remitente en un solo turno de agente para un MD. Los chats de grupo siguen clasificándose por mensaje para que se preserve la estructura de turnos de múltiples usuarios.

Habilite cuando:

  • Implemente habilidades que esperen command + payload en un solo mensaje (volcado, pegar, guardar, cola, etc.).
  • Sus usuarios peguen URL, imágenes o contenido largo junto con comandos.
  • Pueda aceptar la latencia adicional de turno de MD (ver abajo).

Deje deshabilitado cuando:

  • Necesite una latencia mínima de comando para activadores de MD de una sola palabra.
  • Todos sus flujos sean comandos de un solo tiro sin seguimientos de carga útil.
Usuario componeApple entregaIndicador desactivado (predeterminado)Indicador activado + ventana de 2500 ms
Dump https://example.com (un envío)2 webhooks a ~1 s de diferenciaDos turnos del agente: “Dump” solo, luego la URLUn turno: texto fusionado Dump https://example.com
Save this 📎image.jpg caption (archivo adjunto + texto)2 webhooksDos turnosUn turno: texto + imagen
/status (comando independiente)1 webhookDespacho instantáneoEsperar hasta la ventana y luego despachar
URL pegada sola1 webhookDespacho instantáneoDespacho instantáneo (solo una entrada en el cubo)
Texto + URL enviados como dos mensajes separados deliberados, a unos minutos de diferencia2 webhooks fuera de la ventanaDos turnosDos turnos (la ventana caduca entre ellos)
Inundación rápida (>10 MD pequeños dentro de la ventana)N webhooksN turnosUn turno, salida limitada (primero + último, se aplican límites de texto/archivos adjuntos)

Solución de problemas de la fusión de envíos divididos

Sección titulada «Solución de problemas de la fusión de envíos divididos»

Si el indicador está activado y los envíos divididos siguen llegando como dos turnos, verifique cada capa:

Configuración realmente cargada
grep coalesceSameSenderDms ~/.openclaw/openclaw.json

Luego openclaw gateway restart — el indicador se lee en la creación del registro de debouncer.

Ventana de debouncer lo suficientemente ancha para tu configuración

Mira el registro del servidor BlueBubbles en ~/Library/Logs/bluebubbles-server/main.log:

grep -E "Dispatching event to webhook" main.log | tail -20

Mide la brecha entre el envío de texto estilo "Dump" y el envío "https://..."; Attachments: que sigue. Aumenta messages.inbound.byChannel.bluebubbles para cubrir cómodamente esa brecha.

Marcas de tiempo de JSONL de sesión ≠ llegada del webhook

Las marcas de tiempo de los eventos de sesión (`~/.openclaw/agents/

/sessions/*.jsonl) reflejan cuándo la puerta de enlace entrega un mensaje al agente, **no** cuándo llegó el webhook. Un mensaje en cola segundo etiquetado como [Queued messages while agent was busy]` significa que el primer turno aún se estaba ejecutando cuando llegó el segundo webhook — el cubo de fusión ya se había vaciado. Ajusta la ventana según el registro del servidor BB, no el registro de sesión.

Presión de memoria ralentizando el envío de respuestas

En máquinas más pequeñas (8 GB), los turnos del agente pueden tardar lo suficiente como para que el cubo de fusión se vacíe antes de que se complete la respuesta, y la URL llegue como un segundo turno en cola. Verifica memory_pressure y ps -o rss -p $(pgrep openclaw-gateway); si la puerta de enlace supera los ~500 MB de RSS y el compresor está activo, cierra otros procesos pesados o cambia a un host más grande.

Los envíos de cita de respuesta son una ruta diferente

Si el usuario tocó Dump como una respuesta a un globo de URL existente (iMessage muestra una insignia “1 Reply” en el globo de Dump), la URL vive en replyToBody, no en un segundo webhook. La fusión no se aplica — eso es un asunto de habilidad/prompt, no un asunto de debouncer.

Controla si las respuestas se envían como un único mensaje o se transmiten en bloques:

{
channels: {
bluebubbles: {
blockStreaming: true, // enable block streaming (off by default)
},
},
}
  • Los archivos adjuntos entrantes se descargan y almacenan en la caché de medios.
  • Límite de medios a través de channels.bluebubbles.mediaMaxMb para medios entrantes y salientes (predeterminado: 8 MB).
  • El texto saliente se divide en channels.bluebubbles.textChunkLimit (predeterminado: 4000 caracteres).

Configuración completa: Configuración

Conexión y webhook
  • channels.bluebubbles.enabled: Habilitar/deshabilitar el canal.
  • channels.bluebubbles.serverUrl: URL base de la API REST de BlueBubbles.
  • channels.bluebubbles.password: Contraseña de la API.
  • channels.bluebubbles.webhookPath: Ruta del endpoint del webhook (predeterminado: /bluebubbles-webhook).
Política de acceso
  • channels.bluebubbles.dmPolicy: pairing | allowlist | open | disabled (predeterminado: pairing).
  • channels.bluebubbles.allowFrom: Lista de permitidos de MD (identificadores, correos electrónicos, números E.164, chat_id:*, chat_guid:*).
  • channels.bluebubbles.groupPolicy: open | allowlist | disabled (predeterminado: allowlist).
  • channels.bluebubbles.groupAllowFrom: Lista de permitidos de remitentes de grupo.
  • channels.bluebubbles.enrichGroupParticipantsFromContacts: En macOS, opcionalmente enriquece a los participantes del grupo sin nombre desde los Contactos locales después de pasar el filtrado. Predeterminado: false.
  • channels.bluebubbles.groups: Configuración por grupo (requireMention, etc.).
Entrega y fragmentación
  • channels.bluebubbles.sendReadReceipts: Enviar confirmaciones de lectura (predeterminado: true).
  • channels.bluebubbles.blockStreaming: Habilitar transmisión por bloques (predeterminado: false; necesario para respuestas en streaming).
  • channels.bluebubbles.textChunkLimit: Tamaño de fragmento de salida en caracteres (predeterminado: 4000).
  • channels.bluebubbles.sendTimeoutMs: Tiempo de espera por solicitud en ms para el envío de texto de salida a través de /api/v1/message/text (predeterminado: 30000). Aumente en configuraciones de macOS 26 donde los envíos de iMessage de la API privada pueden detenerse durante 60+ segundos dentro del framework de iMessage; por ejemplo 45000 o 60000. Las sondas, búsquedas de chat, reacciones, ediciones y verificaciones de salud mantienen actualmente el valor predeterminado más corto de 10 s; se planea ampliar la cobertura a reacciones y ediciones como seguimiento. Anulación por cuenta: `channels.bluebubbles.accounts.

.sendTimeoutMs. - channels.bluebubbles.chunkMode: length(predeterminado) divide solo cuando excedetextChunkLimit; newline` divide en líneas en blanco (límites de párrafo) antes de la fragmentación por longitud.

Medios e historial
  • channels.bluebubbles.mediaMaxMb: Límite de medios entrantes/salientes en MB (predeterminado: 8).
  • channels.bluebubbles.mediaLocalRoots: Lista de permitidos explícita de directorios locales absolutos permitidos para rutas de medios locales salientes. Los envíos de rutas locales se deniegan de forma predeterminada a menos que esto esté configurado. Anulación por cuenta: `channels.bluebubbles.accounts.

.mediaLocalRoots. - channels.bluebubbles.coalesceSameSenderDms: Fusionar webhooks consecutivos de MD del mismo remitente en una turno del agente para que el envío dividido de texto+URL de Apple llegue como un solo mensaje (predeterminado: false). Consulte [Coalescing split-send DMs](#coalescing-split-send-dms-command--url-in-one-composition) para ver escenarios, ajuste de ventana y compensaciones. Amplía la ventana de antirrebote entrante predeterminada de 500 ms a 2500 ms cuando se habilita sin un messages.inbound.byChannel.bluebubblesexplícito. -channels.bluebubbles.historyLimit: Máximo de mensajes grupales para el contexto (0 deshabilita). - channels.bluebubbles.dmHistoryLimit: Límite de historial de MD. - channels.bluebubbles.replyContextApiFallback: Cuando llega una respuesta entrante sin replyToBody/replyToSendery se produce un error en la caché en memoria del contexto de respuesta, obtenga el mensaje original de la API HTTP de BlueBubbles como una alternativa de mejor esfuerzo (predeterminado:false). Útil para implementaciones de múltiples instancias que comparten una cuenta de BlueBubbles, después de reiniciar el proceso o después de la expulsión de caché TTL/LRU de larga duración. La obtención está protegida contra SSRF por la misma política que todas las demás solicitudes de cliente de BlueBubbles, nunca genera excepciones y rellena la caché para que las respuestas posteriores se amortícen. Anulación por cuenta: channels.bluebubbles.accounts.

.replyContextApiFallback`. Una configuración a nivel de canal se propaga a las cuentas que omiten el indicador.

Acciones y cuentas
  • channels.bluebubbles.actions: Habilitar/deshabilitar acciones específicas.
  • channels.bluebubbles.accounts: Configuración multicuenta.

Opciones globales relacionadas:

  • agents.list[].groupChat.mentionPatterns (o messages.groupChat.mentionPatterns).
  • messages.responsePrefix.

Prefiera chat_guid para un enrutamiento estable:

  • chat_guid:iMessage;-;+15555550123 (preferido para grupos)
  • chat_id:123
  • chat_identifier:...
  • Identificadores directos: +15555550123, [email protected]
    • Si un identificador directo no tiene un chat MD existente, OpenClaw creará uno a través de POST /api/v1/chat/new. Esto requiere que la API privada de BlueBubbles esté habilitada.

Cuando el mismo identificador tiene un chat de iMessage y un chat de SMS en el Mac (por ejemplo, un número de teléfono que está registrado en iMessage pero que también ha recibido respuestas alternativas de burbuja verde), OpenClaw prefiere el chat de iMessage y nunca degrada silenciosamente a SMS. Para forzar el chat por SMS, use un prefijo de destino sms: explícito (por ejemplo, sms:+15555550123). Los identificadores sin un chat de iMessage coincidente todavía se envían a través del chat que BlueBubbles reporte.

  • Las solicitudes de webhook se autentican comparando los parámetros de consulta o encabezados guid/password contra channels.bluebubbles.password.
  • Mantenga la contraseña de la API y el punto final del webhook en secreto (trátelos como credenciales).
  • No hay ninguna omisión de localhost para la autenticación de webhook de BlueBubbles. Si proxy el tráfico de webhook, mantenga la contraseña de BlueBubbles en la solicitud de extremo a extremo. gateway.trustedProxies no reemplaza channels.bluebubbles.password aquí. Consulte Seguridad de la puerta de enlace.
  • Habilite HTTPS + reglas de firewall en el servidor BlueBubbles si lo expone fuera de su LAN.
  • Si los eventos de escritura/lectura dejan de funcionar, verifique los registros de webhook de BlueBubbles y asegúrese de que la ruta de la puerta de enlace coincida con channels.bluebubbles.webhookPath.
  • Los códigos de emparejamiento caducan después de una hora; use openclaw pairing list bluebubbles y openclaw pairing approve bluebubbles <code>.
  • Las reacciones requieren la API privada de BlueBubbles (POST /api/v1/message/react); asegúrese de que la versión del servidor la exponga.
  • Las funciones de editar/no enviar requieren macOS 13+ y una versión compatible del servidor BlueBubbles. En macOS 26 (Tahoe), la edición está actualmente rota debido a cambios en la API privada.
  • Las actualizaciones del icono del grupo pueden ser inestables en macOS 26 (Tahoe): la API puede devolver éxito pero el nuevo icono no se sincroniza.
  • OpenClaw oculta automáticamente las acciones que se sabe que están rotas basándose en la versión de macOS del servidor de BlueBubbles. Si la edición todavía aparece en macOS 26 (Tahoe), desactívela manualmente con channels.bluebubbles.actions.edit=false.
  • coalesceSameSenderDms habilitado pero los envíos divididos (por ejemplo, Dump + URL) todavía llegan como dos turnos: consulte la lista de verificación de solución de problemas de combinación de envíos divididos — las causas comunes son una ventana de debounce demasiado ajustada, marcas de tiempo de registro de sesión mal leídas como la llegada del webhook, o un envío de cita de respuesta (que usa replyToBody, no un segundo webhook).
  • Para información de estado/salud: openclaw status --all o openclaw status --deep.

Para obtener una referencia general del flujo de trabajo del canal, consulte Channels y la guía Plugins.

  • Channel Routing — enrutamiento de sesión para mensajes
  • Channels Overview — todos los canales compatibles
  • Groups — comportamiento del chat de grupo y control de menciones
  • Pairing — autenticación de MD y flujo de vinculación
  • Security — modelo de acceso y endurecimiento