BlueBubbles (macOS REST)

Status: plugin incluso que se comunica com o servidor BlueBubbles no macOS via HTTP. Recomendado para integração com iMessage devido à sua API mais completa e configuração mais simples em comparação com o canal legacy imsg.

Visão geral

  • Roda no macOS via o app auxiliar BlueBubbles (bluebubbles.app).
  • Recomendado/testado: macOS Sequoia (15). macOS Tahoe (26) funciona; a edição está quebrada no Tahoe, e atualizações de ícone de grupo podem reportar sucesso mas não sincronizar.
  • O OpenClaw se comunica com ele através da API REST (GET /api/v1/ping, POST /message/text, POST /chat/:id/*).
  • Mensagens recebidas chegam via webhooks; respostas enviadas, indicadores de digitação, confirmações de leitura e tapbacks são chamadas REST.
  • Anexos e stickers são processados como mídia de entrada (e exibidos ao agente quando possível).
  • O pareamento/lista de permitidos funciona da mesma forma que em outros canais (/channels/pairing, etc.) com channels.bluebubbles.allowFrom + códigos de pareamento.
  • As reações são apresentadas como eventos do sistema, assim como no Slack/Telegram, para que os agentes possam “mencioná-las” antes de responder.
  • Recursos avançados: edição, cancelamento de envio, threads de resposta, efeitos de mensagem, gerenciamento de grupos.

Início rápido

  1. Instale o servidor BlueBubbles no seu Mac (siga as instruções em bluebubbles.app/install).

  2. Na configuração do BlueBubbles, ative a API web e defina uma senha.

  3. Execute openclaw onboard e selecione BlueBubbles, ou configure manualmente:

    {
      channels: {
        bluebubbles: {
          enabled: true,
          serverUrl: "http://192.168.1.100:1234",
          password: "example-password",
          webhookPath: "/bluebubbles-webhook",
        },
      },
    }
  4. Aponte os webhooks do BlueBubbles para seu gateway (exemplo: https://your-gateway-host:3000/bluebubbles-webhook?password=<password>).

  5. Inicie o gateway; ele registrará o handler do webhook e iniciará o pareamento.

Nota de segurança:

  • Sempre defina uma senha para o webhook.
  • A autenticação do webhook é sempre obrigatória. O OpenClaw rejeita requisições de webhook do BlueBubbles a menos que incluam um password/guid que corresponda a channels.bluebubbles.password (por exemplo ?password=<password> ou x-password), independentemente da topologia loopback/proxy.
  • A autenticação por senha é verificada antes de ler/analisar os corpos completos do webhook.

Manter o Messages.app ativo (VM / setups headless)

Algumas configurações de macOS em VM ou sempre ligadas podem fazer com que o Messages.app entre em modo “ocioso” (os eventos de entrada param até que o app seja aberto/colocado em primeiro plano). Uma solução simples é ativar o Messages a cada 5 minutos usando um AppleScript + LaunchAgent.

1) Salve o AppleScript

Salve como:

  • ~/Scripts/poke-messages.scpt

Script de exemplo (não interativo; não rouba o foco):

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) Instale um LaunchAgent

Salve como:

  • ~/Library/LaunchAgents/com.user.poke-messages.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>com.user.poke-messages</string>

    <key>ProgramArguments</key>
    <array>
      <string>/bin/bash</string>
      <string>-lc</string>
      <string>/usr/bin/osascript &quot;$HOME/Scripts/poke-messages.scpt&quot;</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>StartInterval</key>
    <integer>300</integer>

    <key>StandardOutPath</key>
    <string>/tmp/poke-messages.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/poke-messages.err</string>
  </dict>
</plist>

Notas:

  • Executa a cada 300 segundos e no login.
  • A primeira execução pode disparar prompts de Automação do macOS (osascript → Messages). Aprove-os na mesma sessão de usuário que roda o LaunchAgent.

Carregue:

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

Onboarding

O BlueBubbles está disponível no assistente de configuração interativo:

openclaw onboard

O assistente solicita:

  • URL do servidor (obrigatório): endereço do servidor BlueBubbles (ex.: http://192.168.1.100:1234)
  • Senha (obrigatória): senha da API nas configurações do servidor BlueBubbles
  • Caminho do webhook (opcional): padrão /bluebubbles-webhook
  • Política de DMs: pareamento, lista de permitidos, aberta ou desativada
  • Lista de permitidos: números de telefone, e-mails ou alvos de chat

Você também pode adicionar o BlueBubbles via CLI:

openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>

Controle de acesso (DMs + grupos)

DMs:

  • Padrão: channels.bluebubbles.dmPolicy = "pairing".
  • Remetentes desconhecidos recebem um código de pareamento; mensagens são ignoradas até a aprovação (códigos expiram após 1 hora).
  • Aprove via:
    • openclaw pairing list bluebubbles
    • openclaw pairing approve bluebubbles <CODE>
  • O pareamento é a troca de tokens padrão. Detalhes: Pareamento

Grupos:

  • channels.bluebubbles.groupPolicy = open | allowlist | disabled (padrão: allowlist).
  • channels.bluebubbles.groupAllowFrom controla quem pode acionar o bot em grupos quando allowlist está definido.

Controle por menção (grupos)

O BlueBubbles suporta controle por menção em chats de grupo, seguindo o comportamento do iMessage/WhatsApp:

  • Usa agents.list[].groupChat.mentionPatterns (ou messages.groupChat.mentionPatterns) para detectar menções.
  • Quando requireMention está ativado para um grupo, o agente só responde quando mencionado.
  • Comandos de controle de remetentes autorizados ignoram o controle por menção.

Configuração por grupo:

{
  channels: {
    bluebubbles: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15555550123"],
      groups: {
        "*": { requireMention: true }, // padrão para todos os grupos
        "iMessage;-;chat123": { requireMention: false }, // exceção para grupo específico
      },
    },
  },
}

Controle de comandos

  • Comandos de controle (ex.: /config, /model) requerem autorização.
  • Usam allowFrom e groupAllowFrom para determinar a autorização de comandos.
  • Remetentes autorizados podem executar comandos de controle sem mencionar o bot em grupos.

Indicadores de digitação + confirmações de leitura

  • Indicadores de digitação: enviados automaticamente antes e durante a geração de respostas.
  • Confirmações de leitura: controladas por channels.bluebubbles.sendReadReceipts (padrão: true).
  • Indicadores de digitação: o OpenClaw envia eventos de início de digitação; o BlueBubbles limpa a digitação automaticamente ao enviar ou por timeout (a parada manual via DELETE não é confiável).
{
  channels: {
    bluebubbles: {
      sendReadReceipts: false, // desativar confirmações de leitura
    },
  },
}

Ações avançadas

O BlueBubbles suporta ações avançadas de mensagens quando ativadas na configuração:

{
  channels: {
    bluebubbles: {
      actions: {
        reactions: true, // tapbacks (padrão: true)
        edit: true, // editar mensagens enviadas (macOS 13+, quebrado no macOS 26 Tahoe)
        unsend: true, // cancelar envio de mensagens (macOS 13+)
        reply: true, // threads de resposta por GUID da mensagem
        sendWithEffect: true, // efeitos de mensagem (slam, loud, etc.)
        renameGroup: true, // renomear chats de grupo
        setGroupIcon: true, // definir ícone/foto do chat de grupo (instável no macOS 26 Tahoe)
        addParticipant: true, // adicionar participantes a grupos
        removeParticipant: true, // remover participantes de grupos
        leaveGroup: true, // sair de chats de grupo
        sendAttachment: true, // enviar anexos/mídia
      },
    },
  },
}

Ações disponíveis:

  • react: adicionar/remover reações tapback (messageId, emoji, remove)
  • edit: editar uma mensagem enviada (messageId, text)
  • unsend: cancelar o envio de uma mensagem (messageId)
  • reply: responder a uma mensagem específica (messageId, text, to)
  • sendWithEffect: enviar com efeito iMessage (text, to, effectId)
  • renameGroup: renomear um chat de grupo (chatGuid, displayName)
  • setGroupIcon: definir o ícone/foto de um chat de grupo (chatGuid, media) — instável no macOS 26 Tahoe (a API pode retornar sucesso mas o ícone não sincroniza).
  • addParticipant: adicionar alguém a um grupo (chatGuid, address)
  • removeParticipant: remover alguém de um grupo (chatGuid, address)
  • leaveGroup: sair de um chat de grupo (chatGuid)
  • sendAttachment: enviar mídia/arquivos (to, buffer, filename, asVoice)
    • Notas de voz: defina asVoice: true com áudio MP3 ou CAF para enviar como mensagem de voz do iMessage. O BlueBubbles converte MP3 para CAF ao enviar notas de voz.

IDs de mensagens (curtos vs completos)

O OpenClaw pode exibir IDs de mensagens curtos (ex.: 1, 2) para economizar tokens.

  • MessageSid / ReplyToId podem ser IDs curtos.
  • MessageSidFull / ReplyToIdFull contêm os IDs completos do provedor.
  • IDs curtos ficam em memória; podem expirar ao reiniciar ou na remoção do cache.
  • As ações aceitam messageId curto ou completo, mas IDs curtos darão erro se não estiverem mais disponíveis.

Use IDs completos para automações e armazenamento duráveis:

  • Templates: {{MessageSidFull}}, {{ReplyToIdFull}}
  • Contexto: MessageSidFull / ReplyToIdFull nos payloads de entrada

Consulte Configuração para as variáveis de template.

Streaming em blocos

Controle se as respostas são enviadas como uma única mensagem ou transmitidas em blocos:

{
  channels: {
    bluebubbles: {
      blockStreaming: true, // ativar streaming em blocos (desativado por padrão)
    },
  },
}

Mídia + limites

  • Anexos recebidos são baixados e armazenados no cache de mídia.
  • Limite de mídia via channels.bluebubbles.mediaMaxMb para mídia de entrada e saída (padrão: 8 MB).
  • O texto de saída é fragmentado conforme channels.bluebubbles.textChunkLimit (padrão: 4000 caracteres).

Referência de configuração

Configuração completa: Configuração

Opções do provedor:

  • channels.bluebubbles.enabled: ativar/desativar o canal.
  • channels.bluebubbles.serverUrl: URL base da API REST do BlueBubbles.
  • channels.bluebubbles.password: senha da API.
  • channels.bluebubbles.webhookPath: caminho do endpoint do webhook (padrão: /bluebubbles-webhook).
  • channels.bluebubbles.dmPolicy: pairing | allowlist | open | disabled (padrão: pairing).
  • channels.bluebubbles.allowFrom: lista de permitidos para DMs (handles, e-mails, números E.164, chat_id:*, chat_guid:*).
  • channels.bluebubbles.groupPolicy: open | allowlist | disabled (padrão: allowlist).
  • channels.bluebubbles.groupAllowFrom: lista de permitidos de remetentes em grupos.
  • channels.bluebubbles.groups: configuração por grupo (requireMention, etc.).
  • channels.bluebubbles.sendReadReceipts: enviar confirmações de leitura (padrão: true).
  • channels.bluebubbles.blockStreaming: ativar streaming em blocos (padrão: false; necessário para respostas em streaming).
  • channels.bluebubbles.textChunkLimit: tamanho do fragmento de saída em caracteres (padrão: 4000).
  • channels.bluebubbles.chunkMode: length (padrão) divide apenas ao exceder textChunkLimit; newline divide em linhas em branco (limites de parágrafo) antes da divisão por comprimento.
  • channels.bluebubbles.mediaMaxMb: limite de mídia de entrada/saída em MB (padrão: 8).
  • channels.bluebubbles.mediaLocalRoots: lista explícita de diretórios locais absolutos permitidos para caminhos de mídia local de saída. Envios de caminhos locais são negados por padrão a menos que configurado. Exceção por conta: channels.bluebubbles.accounts.<accountId>.mediaLocalRoots.
  • channels.bluebubbles.historyLimit: máximo de mensagens de grupo para contexto (0 desativa).
  • channels.bluebubbles.dmHistoryLimit: limite de histórico de DMs.
  • channels.bluebubbles.actions: ativar/desativar ações específicas.
  • channels.bluebubbles.accounts: configuração multiconta.

Opções globais relacionadas:

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

Endereçamento / alvos de entrega

Prefira chat_guid para roteamento estável:

  • chat_guid:iMessage;-;+15555550123 (preferido para grupos)
  • chat_id:123
  • chat_identifier:...
  • Handles diretos: +15555550123, [email protected]
    • Se um handle direto não tiver um chat de DM existente, o OpenClaw criará um via POST /api/v1/chat/new. Isso requer que a API privada do BlueBubbles esteja habilitada.

Segurança

  • As requisições de webhook são autenticadas comparando os parâmetros de query ou headers guid/password com channels.bluebubbles.password. Requisições de localhost também são aceitas.
  • Mantenha a senha da API e o endpoint do webhook em segredo (trate-os como credenciais).
  • A confiança em localhost significa que um proxy reverso no mesmo host pode inadvertidamente ignorar a senha. Se você usar proxy no gateway, exija autenticação no proxy e configure gateway.trustedProxies. Veja Segurança do gateway.
  • Ative HTTPS + regras de firewall no servidor BlueBubbles se expô-lo fora da sua rede local.

Solução de problemas

  • Se os eventos de digitação/leitura pararem de funcionar, verifique os logs de webhook do BlueBubbles e confirme que o caminho do gateway corresponde a channels.bluebubbles.webhookPath.
  • Códigos de pareamento expiram após uma hora; use openclaw pairing list bluebubbles e openclaw pairing approve bluebubbles <code>.
  • As reações requerem a API privada do BlueBubbles (POST /api/v1/message/react); certifique-se de que a versão do servidor a exponha.
  • Editar/cancelar envio requer macOS 13+ e uma versão compatível do servidor BlueBubbles. No macOS 26 (Tahoe), a edição está quebrada devido a mudanças na API privada.
  • Atualizações de ícone de grupo podem ser instáveis no macOS 26 (Tahoe): a API pode retornar sucesso mas o novo ícone não sincroniza.
  • O OpenClaw oculta automaticamente ações que sabidamente não funcionam com base na versão do macOS do servidor BlueBubbles. Se a edição ainda aparecer no macOS 26 (Tahoe), desative-a manualmente com channels.bluebubbles.actions.edit=false.
  • Para informações de status/saúde: openclaw status --all ou openclaw status --deep.

Para uma referência geral do fluxo de trabalho de canais, consulte Canais e o guia de Plugins.