Viniendo de BlueBubbles
El complemento imessage incluido ahora alcanza la misma superficie de API privada que BlueBubbles (react, edit, unsend, reply, sendWithEffect, gestión de grupos, archivos adjuntos) al controlar steipete/imsg a través de JSON-RPC. Si ya ejecutas una Mac con imsg instalado, puedes dejar de usar el servidor de BlueBubbles y dejar que el complemento hable directamente con Messages.app.
Se eliminó el soporte de BlueBubbles. OpenClaw admite iMessage solo a través de imsg. Esta guía es para migrar configuraciones antiguas de channels.bluebubbles a channels.imessage; no hay otra ruta de migración admitida.
Lista de verificación de migración
Sección titulada «Lista de verificación de migración»Use esta lista de verificación cuando ya conozca su configuración anterior de BlueBubbles y desee la ruta más segura y corta:
- Verifique
imsgdirectamente en la Mac que ejecuta Messages.app (imsg chats,imsg history,imsg sendyimsg rpc --help). - Copie las claves de comportamiento de
channels.bluebubblesachannels.imessage:dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups,includeAttachments,attachmentRoots,mediaMaxMb,textChunkLimit,coalesceSameSenderDmsyactions. - Elimine las claves de transporte que ya no existen:
serverUrl,password, URL de webhook y la configuración del servidor BlueBubbles. - Si la puerta de enlace (Gateway) no se está ejecutando en la Mac de Messages, configure
channels.imessage.cliPathen un contenedor SSH y configureremoteHostpara la recuperación remota de archivos adjuntos. - Con la puerta de enlace detenida, habilite
channels.imessagey luego ejecuteopenclaw channels status --probe --channel imessage. - Pruebe un mensaje directo (DM), un grupo permitido, archivos adjuntos si están habilitados y cada acción de API privada que espere que use el agente.
- Elimine el servidor de BlueBubbles y la configuración antigua de
channels.bluebubblesdespués de verificar la ruta de iMessage.
Cuándo tiene sentido esta migración
Sección titulada «Cuándo tiene sentido esta migración»- Ya estás ejecutando
imsgen el mismo Mac (o uno accesible por SSH) donde Messages.app tiene la sesión iniciada. - Quieres tener una pieza móvil menos — ningún servidor BlueBubbles separado, ningún endpoint REST que autenticar, ninguna tubería de webhooks. Un único binario CLI en lugar de un servidor + aplicación cliente + asistente.
- Estás en una compilación de macOS /
imsgcompatible donde el sondeo de la API privada informaavailable: true.
Lo que hace imsg
Sección titulada «Lo que hace imsg»imsg es una CLI local de macOS para Messages. OpenClaw inicia imsg rpc como un proceso hijo y se comunica a través de JSON-RPC usando stdin/stdout. No hay servidor HTTP, URL de webhook, demonio en segundo plano, agente de lanzamiento (launch agent) o puerto que exponer.
- Las lecturas provienen de
~/Library/Messages/chat.dbusando un manejador SQLite de solo lectura. - Los mensajes entrantes en vivo provienen de
imsg watch/watch.subscribe, que sigue los eventos del sistema de archivoschat.dbcon un respaldo de sondeo (polling). - Los envíos utilizan la automatización de Messages.app para envíos de texto normal y archivos.
- Las acciones avanzadas usan
imsg launchpara inyectar el asistenteimsgen Messages.app. Eso es lo que desbloquea las confirmaciones de lectura, indicadores de escritura, envíos enriquecidos, editar, no enviar, respuestas en hilos, reacciones y gestión de grupos. - Las compilaciones de Linux pueden inspeccionar una
chat.dbcopiada, pero no pueden enviar, vigilar la base de datos del Mac en vivo o controlar Messages.app. Para OpenClaw iMessage, ejecutaimsgen el Mac con la sesión iniciada o a través de un envoltorio (wrapper) SSH a ese Mac.
Antes de empezar
Sección titulada «Antes de empezar»-
Instala
imsgen el Mac que ejecuta Messages.app:Ventana de terminal brew install steipete/tap/imsgimsg --versionimsg chats --limit 3Si
imsg chatsfalla conunable to open database file, salida vacía oauthorization denied, concede Acceso total al disco (Full Disk Access) a la terminal, editor, proceso Node, servicio Gateway o proceso padre SSH que iniciaimsg, y luego vuelve a abrir ese proceso padre. -
Verifica las superficies de lectura, vigilancia, envío y RPC antes de cambiar la configuración de OpenClaw:
Ventana de terminal imsg chats --limit 10 --json | jq -simsg history --chat-id 42 --limit 10 --attachments --json | jq -simsg watch --chat-id 42 --reactions --jsonimsg send --chat-id 42 --text "OpenClaw imsg test"imsg rpc --helpReemplaza
42con un ID de chat real deimsg chats. El envío requiere permiso de Automatización para Messages.app. Si OpenClaw se ejecutará a través de SSH, ejecute estos comandos a través del mismo contenedor SSH o contexto de usuario que OpenClaw usará. Si las lecturas/sondeos funcionan pero los envíos fallan con AppleEvents-1743, verifique si Automatización se instaló en/usr/libexec/sshd-keygen-wrapper; consulte Los envíos del contenedor SSH fallan con AppleEvents -1743. -
Habilite el puente de API privada cuando necesite acciones avanzadas:
Ventana de terminal imsg launchimsg status --jsonimsg launchrequiere que SIP esté deshabilitado. El envío básico, el historial y la vigilancia funcionan sinimsg launch; las acciones avanzadas no. -
Después de agregar una configuración
channels.imessagehabilitada, verifique el puente a través de OpenClaw:Ventana de terminal openclaw channels status --probeDeseas
imessage.privateApi.available: true. Si informafalse, solucione eso primero; consulte Detección de capacidades.channels status --probesolo sondea cuentas configuradas y habilitadas. -
Haga una instantánea de su configuración:
Ventana de terminal cp ~/.openclaw/openclaw.json5 ~/.openclaw/openclaw.json5.bak
Traducción de configuración
Sección titulada «Traducción de configuración»iMessage y BlueBubbles comparten mucha configuración a nivel de canal. Las claves que cambian son principalmente de transporte (servidor REST vs CLI local). Las claves de comportamiento (dmPolicy, groupPolicy, allowFrom, etc.) mantienen el mismo significado.
| BlueBubbles | iMessage incluido | Notas |
|---|---|---|
channels.bluebubbles.enabled | channels.imessage.enabled | Misma semántica. |
channels.bluebubbles.serverUrl | (eliminado) | Sin servidor REST: el complemento inicia imsg rpc a través de stdio. |
channels.bluebubbles.password | (eliminado) | No se requiere autenticación de webhook. |
| (implícito) | channels.imessage.cliPath | Ruta a imsg (por defecto imsg); use un script contenedor para SSH. |
| (implícito) | channels.imessage.dbPath | Invalidación opcional de Messages.app chat.db; detectada automáticamente si se omite. |
| (implícito) | channels.imessage.remoteHost | host o user@host — solo se necesita cuando cliPath es un contenedor SSH y desea descargas de archivos adjuntos SCP. |
channels.bluebubbles.dmPolicy | channels.imessage.dmPolicy | Mismos valores (pairing / allowlist / open / disabled). |
channels.bluebubbles.allowFrom | channels.imessage.allowFrom | Los aprobaciones de emparejamiento se transfieren por identificador, no por token. |
channels.bluebubbles.groupPolicy | channels.imessage.groupPolicy | Mismos valores (allowlist / open / disabled). |
channels.bluebubbles.groupAllowFrom | channels.imessage.groupAllowFrom | Igual. |
channels.bluebubbles.groups | channels.imessage.groups | Copie esto textualmente, incluyendo cualquier entrada comodín groups: { "*": { ... } }. Los valores requireMention, tools y toolsBySender por grupo se transfieren. Con groupPolicy: "allowlist", un bloque groups vacío o ausente descarta silenciosamente cada mensaje de grupo; consulte a continuación “Trampa de registro de grupos”. |
channels.bluebubbles.sendReadReceipts | channels.imessage.sendReadReceipts | Por defecto true. Con el complemento incluido, esto solo se activa cuando el sondeo de la API privada está activo. |
channels.bluebubbles.includeAttachments | channels.imessage.includeAttachments | Misma forma, mismo desactivado por defecto. Si tenía archivos adjuntos fluyendo en BlueBubbles, debe restablecer esto explícitamente en el bloque iMessage; no se transfiere implícitamente, y las fotos/multimedios entrantes se descartarán silenciosamente sin ninguna línea de registro Inbound message hasta que lo haga. |
channels.bluebubbles.attachmentRoots | channels.imessage.attachmentRoots | Raíces locales; mismas reglas de comodín. |
| (N/A) | channels.imessage.remoteAttachmentRoots | Solo se usa cuando remoteHost está configurado para obtenciones por SCP. |
channels.bluebubbles.mediaMaxMb | channels.imessage.mediaMaxMb | Predeterminado 16 MB en iMessage (el predeterminado de BlueBubbles era 8 MB). Establécelo explícitamente si deseas mantener el límite más bajo. |
channels.bluebubbles.textChunkLimit | channels.imessage.textChunkLimit | Predeterminado 4000 en ambos. |
channels.bluebubbles.coalesceSameSenderDms | channels.imessage.coalesceSameSenderDms | Misma participación opcional. Solo MD — los chats de grupo mantienen el envío instantáneo por mensaje en ambos canales. Amplía el antirrebote de entrada predeterminado a 2500 ms cuando se habilita sin un messages.inbound.byChannel.imessage explícito. Consulte Documentación de iMessage § Coalescing split-send DMs. |
channels.bluebubbles.enrichGroupParticipantsFromContacts | (N/A) | iMessage ya lee los nombres para mostrar del remitente de chat.db. |
channels.bluebubbles.actions.* | channels.imessage.actions.* | Interruptores por acción: reactions, edit, unsend, reply, sendWithEffect, renameGroup, setGroupIcon, addParticipant, removeParticipant, leaveGroup, sendAttachment. |
Las configuraciones multicuenta (channels.bluebubbles.accounts.*) se traducen uno a uno a channels.imessage.accounts.*.
Peligro del registro de grupos
Sección titulada «Peligro del registro de grupos»El complemento iMessage integrado ejecuta dos puertas de lista de permitidos de grupos separadas una tras otra. Ambas deben pasar para que un mensaje de grupo llegue al agente:
- Lista blanca de remitente/destino de chat (
channels.imessage.groupAllowFrom) — verificada porisAllowedIMessageSender. Coincide con los mensajes entrantes por el identificador del remitente,chat_guid,chat_identifierochat_id. Misma forma que BlueBubbles. - Registro de grupos (
channels.imessage.groups) — verificado porresolveChannelGroupPolicydeinbound-processing.ts:199. CongroupPolicy: "allowlist", este filtro requiere:- una entrada comodín
groups: { "*": { ... } }(estableceallowAll = true), o - una entrada explícita por
chat_idbajogroups.
- una entrada comodín
Si se pasa la puerta 1 pero falla la puerta 2, el mensaje se descarta. El complemento emite dos señales de nivel warn para que esto ya no sea silencioso en el nivel de registro predeterminado:
- Una
warnde inicio único por cuenta cuandogroupPolicy: "allowlist"está establecido perochannels.imessage.groupsestá vacío (sin comodín"*", sin entradas porchat_id) — se activa antes de que aterrice cualquier mensaje. - Una
warnúnica porchat_idla primera vez que se descarta un grupo específico en tiempo de ejecución, nombrando el chat_id y la clave exacta para agregar agroupspara permitirlo.
Los MDs siguen funcionando porque toman una ruta de código diferente.
Este es el modo de fallo de migración más común de BlueBubbles a iMessage integrado: los operadores copian groupAllowFrom y groupPolicy pero omiten el bloque groups, porque el groups: { "*": { "requireMention": true } } de BlueBubbles parece una configuración de mención no relacionada. En realidad, es fundamental para la puerta del registro.
La configuración mínima para mantener fluyendo los mensajes grupales después de groupPolicy: "allowlist":
{ channels: { imessage: { groupPolicy: "allowlist", groupAllowFrom: ["+15555550123", "chat_guid:any;-;..."], groups: { "*": { requireMention: true }, }, }, },}requireMention: true bajo * es inofensivo cuando no se han configurado patrones de mención: el tiempo de ejecución establece canDetectMention = false y cortocircuita la caída de la mención en inbound-processing.ts:512. Con patrones de mención configurados (agents.list[].groupChat.mentionPatterns), funciona como se espera.
Si la puerta de enlace registra imessage: dropping group message from chat_id=<id> o la línea de inicio imessage: groupPolicy="allowlist" but channels.imessage.groups is empty, la puerta 2 está descartando — agregue el bloque groups.
Paso a paso
Sección titulada «Paso a paso»-
Añada un bloque iMessage junto al bloque BlueBubbles existente. Manténgalo deshabilitado mientras el Gateway siga enrutando el tráfico de BlueBubbles:
{channels: {bluebubbles: {enabled: true,// ... existing config ...},imessage: {enabled: false,cliPath: "/opt/homebrew/bin/imsg",dmPolicy: "pairing",allowFrom: ["+15555550123"], // copy from bluebubbles.allowFromgroupPolicy: "allowlist",groupAllowFrom: [], // copy from bluebubbles.groupAllowFromgroups: { "*": { requireMention: true } }, // copy from bluebubbles.groups — silently drops groups if missing, see "Group registry footgun" aboveactions: {reactions: true,edit: true,unsend: true,reply: true,sendWithEffect: true,sendAttachment: true,},},},} -
Probar antes de que importe el tráfico — detenga el Gateway, habilite temporalmente el bloque iMessage y confirme que iMessage reporta estado saludable desde la CLI:
Ventana de terminal openclaw gateway stop# edit config: channels.imessage.enabled = trueopenclaw channels status --probe --channel imessage # expect imessage.privateApi.available: truechannels status --probesolo sondea cuentas configuradas y habilitadas. No reinicie la puerta de enlace con BlueBubbles e iMessage habilitados a menos que intencionalmente desee que ambos monitores de canal se estén ejecutando. Si no va a realizar el cambio de inmediato, vuelva a establecerchannels.imessage.enabledenfalseantes de reiniciar la puerta de enlace. Use los comandos directos deimsgen Antes de comenzar para validar la Mac antes de habilitar el tráfico de OpenClaw. -
Realiza la transición. Una vez que la cuenta de iMessage habilitada informe que está sana, elimina la configuración de BlueBubbles y mantén iMessage habilitado:
{channels: {imessage: { enabled: true /* ... */ },},}Reinicia el gateway. El tráfico entrante de iMessage ahora fluye a través del complemento incluido.
-
Verifica los MD. Envía un mensaje directo al agente; confirma que la respuesta llegue.
-
Verifica los grupos por separado. Los MD y los grupos toman diferentes rutas de código — el éxito de los MD no prueba que los grupos se estén enrutando. Envía un mensaje al agente en un chat de grupo vinculado y confirma que la respuesta llegue. Si el grupo se queda en silencio (sin respuesta del agente, sin error), verifica el registro de la puerta de enlace en busca de
imessage: dropping group message from chat_id=<id>o la línea deimessage: groupPolicy="allowlist" but channels.imessage.groups is emptyal inicio — ambos se disparan en el nivel de registro predeterminado. Si aparece alguno, tu bloquegroupsfalta o está vacío — consulta “Peligro del registro de grupos” más arriba. -
Verifica la superficie de acciones — desde un MD vinculado, pide al agente que reaccione, edite, desaplique, responda, envíe una foto y (en un grupo) cambie el nombre del grupo / añada o elimine un participante. Cada acción debería aparecer de forma nativa en Messages.app. Si alguna lanza “iMessage
<action>requiere el puente de la API privada de imsg”, ejecutaimsg launchde nuevo y actualizachannels status --probe. -
Elimina el servidor y la configuración de BlueBubbles una vez verificados los MD, grupos y acciones de iMessage. OpenClaw no usará
channels.bluebubbles.
Paridad de acciones de un vistazo
Sección titulada «Paridad de acciones de un vistazo»| Acción | BlueBubbles heredado | iMessage incluido |
|---|---|---|
| Enviar texto / respaldo SMS | ✅ | ✅ |
| Enviar multimedia (foto, video, archivo, voz) | ✅ | ✅ |
Respuesta en hilo (reply_to_guid) | ✅ | ✅ (cierra #51892) |
Tapback (react) | ✅ | ✅ |
| Editar / anular envío (destinatarios macOS 13+) | ✅ | ✅ |
| Enviar con efecto de pantalla | ✅ | ✅ (cierra parte de #9394) |
| Texto enriquecido negrita / cursiva / subrayado / tachado | ✅ | ✅ (formato typed-run vía attributedBody) |
| Cambiar nombre de grupo / establecer icono de grupo | ✅ | ✅ |
| Añadir / eliminar participante, salir del grupo | ✅ | ✅ |
| Confirmaciones de lectura e indicador de escritura | ✅ | ✅ (condicionado a la sonda de API privada) |
| Agrupación de MD del mismo remitente | ✅ | ✅ (solo MD; activación opcional mediante channels.imessage.coalesceSameSenderDms) |
| Puesta al día de mensajes entrantes recibidos mientras la puerta de enlace está caída | ✅ (repetición de webhook + obtención de historial) | ✅ (activación opcional mediante channels.imessage.catchup.enabled; cierra #78649) |
La puesta al día de iMessage ya está disponible como función opcional en el complemento incluido. Al iniciar la puerta de enlace, si channels.imessage.catchup.enabled es true, la puerta de enlace ejecuta una pasada chats.list + messages.history por chat contra el mismo cliente JSON-RPC que usa imsg watch, reproduce cada fila entrante perdida a través de la ruta de envío en vivo (listas de permitidos, política de grupos, antirrebote, caché de eco) y persiste un cursor por cuenta para que los inicios posteriores continúen donde se quedaron. Consulta Ponerse al día después del tiempo de inactividad de la puerta de enlace para ajustes.
Emparejamiento, sesiones y enlaces ACP
Sección titulada «Emparejamiento, sesiones y enlaces ACP»- Las aprobaciones de emparejamiento se transfieren por identificador. No necesitas volver a aprobar a los remitentes conocidos:
channels.imessage.allowFromreconoce las mismas cadenas+15555550123/[email protected]que usaba BlueBubbles. - Las sesiones permanecen limitadas por agente + chat. Los MDs se colapsan en la sesión principal del agente bajo el
session.dmScope=mainpredeterminado; las sesiones de grupo permanecen aisladas porchat_id. Las claves de sesión difieren (agent:<id>:imessage:group:<chat_id>frente al equivalente de BlueBubbles); el historial de conversación antiguo bajo las claves de sesión de BlueBubbles no se traslada a las sesiones de iMessage. - Los enlaces ACP que hacen referencia a
match.channel: "bluebubbles"deben actualizarse a"imessage". Las formasmatch.peer.id(chat_id:,chat_guid:,chat_identifier:, identificador simple) son idénticas.
Sin canal de reversión
Sección titulada «Sin canal de reversión»No hay un tiempo de ejecución de BlueBubbles compatible al que volver a cambiar. Si falla la verificación de iMessage, establece channels.imessage.enabled: false, reinicia el Gateway, soluciona el bloqueador de imsg y vuelve a intentar la transición.
La caché de respuestas reside en el estado del complemento SQLite. openclaw doctor --fix importa y archiva el sidecar antiguo de imessage/reply-cache.jsonl cuando está presente.
Relacionado
Sección titulada «Relacionado»- Eliminación de BlueBubbles y la ruta iMessage de imsg — breve anuncio y resumen para operadores.
- iMessage — referencia completa del canal iMessage, incluyendo la configuración de
imsg launchy la detección de capacidades. /channels/bluebubbles— URL heredada que redirige a esta guía de migración.- Emparejamiento — autenticación de MD y flujo de emparejamiento.
- Enrutamiento de canales — cómo el gateway elige un canal para las respuestas salientes.