BlueBubbles (REST macOS)

Statut : plugin integre qui communique avec le serveur macOS BlueBubbles via HTTP. Recommande pour l’integration iMessage grace a son API plus riche et sa configuration plus simple que le canal legacy imsg.

Presentation

  • Fonctionne sur macOS via l’application BlueBubbles (bluebubbles.app).
  • Recommande/teste : macOS Sequoia (15). macOS Tahoe (26) fonctionne ; la modification est actuellement cassee sur Tahoe, et les mises a jour d’icone de groupe peuvent signaler un succes sans se synchroniser.
  • OpenClaw communique via son API REST (GET /api/v1/ping, POST /message/text, POST /chat/:id/*).
  • Les messages entrants arrivent par webhooks ; les reponses sortantes, indicateurs de saisie, accuses de lecture et tapbacks sont des appels REST.
  • Les pieces jointes et stickers sont ingeres comme medias entrants (et presentes a l’agent lorsque c’est possible).
  • L’appairage et la liste d’autorisation fonctionnent comme pour les autres canaux (/channels/pairing etc.) avec channels.bluebubbles.allowFrom + codes d’appairage.
  • Les reactions sont exposees comme evenements systeme, tout comme sur Slack/Telegram, afin que les agents puissent les « mentionner » avant de repondre.
  • Fonctionnalites avancees : modification, annulation, fils de reponse, effets de message, gestion de groupe.

Demarrage rapide

  1. Installez le serveur BlueBubbles sur votre Mac (suivez les instructions sur bluebubbles.app/install).

  2. Dans la configuration BlueBubbles, activez l’API web et definissez un mot de passe.

  3. Lancez openclaw onboard et selectionnez BlueBubbles, ou configurez manuellement :

    {
      channels: {
        bluebubbles: {
          enabled: true,
          serverUrl: "http://192.168.1.100:1234",
          password: "example-password",
          webhookPath: "/bluebubbles-webhook",
        },
      },
    }
  4. Dirigez les webhooks BlueBubbles vers votre gateway (exemple : https://your-gateway-host:3000/bluebubbles-webhook?password=<password>).

  5. Demarrez la gateway ; elle enregistrera le gestionnaire de webhook et lancera l’appairage.

Note de securite :

  • Definissez toujours un mot de passe webhook.
  • L’authentification webhook est obligatoire. OpenClaw rejette les requetes webhook BlueBubbles qui ne contiennent pas un mot de passe/guid correspondant a channels.bluebubbles.password (par exemple ?password=<password> ou x-password), quelle que soit la topologie loopback/proxy.
  • L’authentification par mot de passe est verifiee avant la lecture/analyse complete du corps du webhook.

Maintenir Messages.app actif (configurations VM / headless)

Certaines configurations VM macOS ou toujours actives peuvent voir Messages.app passer en mode « inactif » (les evenements entrants s’arretent tant que l’application n’est pas ouverte/mise au premier plan). Une solution simple consiste a solliciter Messages toutes les 5 minutes via un AppleScript + LaunchAgent.

1) Enregistrer l’AppleScript

Enregistrez ceci sous :

  • ~/Scripts/poke-messages.scpt

Exemple de script (non interactif ; ne vole pas le focus) :

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) Installer un LaunchAgent

Enregistrez ceci sous :

  • ~/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>

Remarques :

  • Ceci s’execute toutes les 300 secondes et a la connexion.
  • La premiere execution peut declencher des invites macOS Automation (osascript → Messages). Approuvez-les dans la session utilisateur qui execute le LaunchAgent.

Chargez-le :

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

Onboarding

BlueBubbles est disponible dans l’assistant de configuration interactif :

openclaw onboard

L’assistant demande :

  • URL du serveur (obligatoire) : adresse du serveur BlueBubbles (par ex. http://192.168.1.100:1234)
  • Mot de passe (obligatoire) : mot de passe API depuis les parametres du serveur BlueBubbles
  • Chemin webhook (optionnel) : par defaut /bluebubbles-webhook
  • Politique DM : appairage, liste d’autorisation, ouvert ou desactive
  • Liste d’autorisation : numeros de telephone, e-mails ou cibles de conversation

Vous pouvez aussi ajouter BlueBubbles via la CLI :

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

Controle d’acces (DMs + groupes)

DMs :

  • Par defaut : channels.bluebubbles.dmPolicy = "pairing".
  • Les expediteurs inconnus recoivent un code d’appairage ; les messages sont ignores jusqu’a approbation (les codes expirent apres 1 heure).
  • Approuvez via :
    • openclaw pairing list bluebubbles
    • openclaw pairing approve bluebubbles <CODE>
  • L’appairage est l’echange de jetons par defaut. Details : Appairage

Groupes :

  • channels.bluebubbles.groupPolicy = open | allowlist | disabled (par defaut : allowlist).
  • channels.bluebubbles.groupAllowFrom controle qui peut declencher le bot dans les groupes lorsque allowlist est defini.

Filtrage par mention (groupes)

BlueBubbles prend en charge le filtrage par mention pour les conversations de groupe, comme sur iMessage/WhatsApp :

  • Utilise agents.list[].groupChat.mentionPatterns (ou messages.groupChat.mentionPatterns) pour detecter les mentions.
  • Lorsque requireMention est active pour un groupe, l’agent ne repond que s’il est mentionne.
  • Les commandes de controle provenant d’expediteurs autorises contournent le filtrage par mention.

Configuration par groupe :

{
  channels: {
    bluebubbles: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15555550123"],
      groups: {
        "*": { requireMention: true }, // par defaut pour tous les groupes
        "iMessage;-;chat123": { requireMention: false }, // exception pour un groupe specifique
      },
    },
  },
}

Filtrage des commandes

  • Les commandes de controle (par ex. /config, /model) necessitent une autorisation.
  • Utilise allowFrom et groupAllowFrom pour determiner l’autorisation des commandes.
  • Les expediteurs autorises peuvent executer des commandes de controle meme sans mentionner le bot dans les groupes.

Indicateurs de saisie + accuses de lecture

  • Indicateurs de saisie : envoyes automatiquement avant et pendant la generation de reponse.
  • Accuses de lecture : controles par channels.bluebubbles.sendReadReceipts (par defaut : true).
  • Indicateurs de saisie : OpenClaw envoie des evenements de debut de saisie ; BlueBubbles efface automatiquement la saisie a l’envoi ou apres un delai (l’arret manuel via DELETE n’est pas fiable).
{
  channels: {
    bluebubbles: {
      sendReadReceipts: false, // desactiver les accuses de lecture
    },
  },
}

Actions avancees

BlueBubbles prend en charge des actions avancees sur les messages lorsqu’elles sont activees dans la configuration :

{
  channels: {
    bluebubbles: {
      actions: {
        reactions: true, // tapbacks (par defaut : true)
        edit: true, // modifier les messages envoyes (macOS 13+, casse sur macOS 26 Tahoe)
        unsend: true, // annuler des messages (macOS 13+)
        reply: true, // fils de reponse par GUID de message
        sendWithEffect: true, // effets de message (slam, loud, etc.)
        renameGroup: true, // renommer les conversations de groupe
        setGroupIcon: true, // definir l'icone/photo du groupe (instable sur macOS 26 Tahoe)
        addParticipant: true, // ajouter des participants aux groupes
        removeParticipant: true, // retirer des participants des groupes
        leaveGroup: true, // quitter les conversations de groupe
        sendAttachment: true, // envoyer des pieces jointes/medias
      },
    },
  },
}

Actions disponibles :

  • react : ajouter/supprimer des reactions tapback (messageId, emoji, remove)
  • edit : modifier un message envoye (messageId, text)
  • unsend : annuler un message (messageId)
  • reply : repondre a un message specifique (messageId, text, to)
  • sendWithEffect : envoyer avec un effet iMessage (text, to, effectId)
  • renameGroup : renommer une conversation de groupe (chatGuid, displayName)
  • setGroupIcon : definir l’icone/photo d’un groupe (chatGuid, media) — instable sur macOS 26 Tahoe (l’API peut retourner un succes sans que l’icone ne se synchronise).
  • addParticipant : ajouter quelqu’un a un groupe (chatGuid, address)
  • removeParticipant : retirer quelqu’un d’un groupe (chatGuid, address)
  • leaveGroup : quitter une conversation de groupe (chatGuid)
  • sendAttachment : envoyer des medias/fichiers (to, buffer, filename, asVoice)
    • Memos vocaux : definissez asVoice: true avec un audio MP3 ou CAF pour envoyer un message vocal iMessage. BlueBubbles convertit le MP3 en CAF lors de l’envoi de memos vocaux.

Identifiants de message (courts vs complets)

OpenClaw peut afficher des identifiants de message courts (par ex. 1, 2) pour economiser des tokens.

  • MessageSid / ReplyToId peuvent etre des identifiants courts.
  • MessageSidFull / ReplyToIdFull contiennent les identifiants complets du fournisseur.
  • Les identifiants courts sont en memoire ; ils peuvent expirer au redemarrage ou a l’eviction du cache.
  • Les actions acceptent un messageId court ou complet, mais les identifiants courts provoqueront une erreur s’ils ne sont plus disponibles.

Utilisez les identifiants complets pour les automatisations et le stockage durables :

  • Templates : {{MessageSidFull}}, {{ReplyToIdFull}}
  • Contexte : MessageSidFull / ReplyToIdFull dans les payloads entrants

Voir Configuration pour les variables de template.

Streaming par blocs

Controle si les reponses sont envoyees en un seul message ou diffusees par blocs :

{
  channels: {
    bluebubbles: {
      blockStreaming: true, // activer le streaming par blocs (desactive par defaut)
    },
  },
}

Medias + limites

  • Les pieces jointes entrantes sont telechargees et stockees dans le cache media.
  • Limite media via channels.bluebubbles.mediaMaxMb pour les medias entrants et sortants (par defaut : 8 Mo).
  • Le texte sortant est decoupe selon channels.bluebubbles.textChunkLimit (par defaut : 4000 caracteres).

Reference de configuration

Configuration complete : Configuration

Options du fournisseur :

  • channels.bluebubbles.enabled : activer/desactiver le canal.
  • channels.bluebubbles.serverUrl : URL de base de l’API REST BlueBubbles.
  • channels.bluebubbles.password : mot de passe API.
  • channels.bluebubbles.webhookPath : chemin du point de terminaison webhook (par defaut : /bluebubbles-webhook).
  • channels.bluebubbles.dmPolicy : pairing | allowlist | open | disabled (par defaut : pairing).
  • channels.bluebubbles.allowFrom : liste d’autorisation DM (identifiants, e-mails, numeros E.164, chat_id:*, chat_guid:*).
  • channels.bluebubbles.groupPolicy : open | allowlist | disabled (par defaut : allowlist).
  • channels.bluebubbles.groupAllowFrom : liste d’autorisation des expediteurs de groupe.
  • channels.bluebubbles.groups : configuration par groupe (requireMention, etc.).
  • channels.bluebubbles.sendReadReceipts : envoyer les accuses de lecture (par defaut : true).
  • channels.bluebubbles.blockStreaming : activer le streaming par blocs (par defaut : false ; necessaire pour les reponses en streaming).
  • channels.bluebubbles.textChunkLimit : taille des morceaux sortants en caracteres (par defaut : 4000).
  • channels.bluebubbles.chunkMode : length (par defaut) decoupe uniquement au-dela de textChunkLimit ; newline decoupe aux lignes vides (limites de paragraphes) avant le decoupage par longueur.
  • channels.bluebubbles.mediaMaxMb : limite media entrant/sortant en Mo (par defaut : 8).
  • channels.bluebubbles.mediaLocalRoots : liste explicite de repertoires locaux absolus autorises pour les chemins de medias locaux sortants. Les envois par chemin local sont refuses par defaut sauf si cette option est configuree. Remplacement par compte : channels.bluebubbles.accounts.<accountId>.mediaLocalRoots.
  • channels.bluebubbles.historyLimit : nombre maximal de messages de groupe pour le contexte (0 desactive).
  • channels.bluebubbles.dmHistoryLimit : limite d’historique DM.
  • channels.bluebubbles.actions : activer/desactiver des actions specifiques.
  • channels.bluebubbles.accounts : configuration multi-comptes.

Options globales associees :

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

Adressage / cibles de livraison

Preferez chat_guid pour un routage stable :

  • chat_guid:iMessage;-;+15555550123 (prefere pour les groupes)
  • chat_id:123
  • chat_identifier:...
  • Identifiants directs : +15555550123, [email protected]
    • Si un identifiant direct n’a pas de conversation DM existante, OpenClaw en creera une via POST /api/v1/chat/new. Cela necessite l’activation de l’API privee BlueBubbles.

Securite

  • Les requetes webhook sont authentifiees en comparant les parametres/en-tetes de requete guid/password avec channels.bluebubbles.password. Les requetes provenant de localhost sont egalement acceptees.
  • Gardez le mot de passe API et le point de terminaison webhook secrets (traitez-les comme des identifiants).
  • La confiance localhost signifie qu’un reverse proxy sur le meme hote peut contourner involontairement le mot de passe. Si vous placez un proxy devant la gateway, exigez l’authentification au niveau du proxy et configurez gateway.trustedProxies. Voir Securite de la gateway.
  • Activez HTTPS + regles de pare-feu sur le serveur BlueBubbles si vous l’exposez en dehors de votre reseau local.

Depannage

  • Si les evenements de saisie/lecture cessent de fonctionner, verifiez les journaux webhook BlueBubbles et assurez-vous que le chemin de la gateway correspond a channels.bluebubbles.webhookPath.
  • Les codes d’appairage expirent apres une heure ; utilisez openclaw pairing list bluebubbles et openclaw pairing approve bluebubbles <code>.
  • Les reactions necessitent l’API privee BlueBubbles (POST /api/v1/message/react) ; assurez-vous que la version du serveur l’expose.
  • La modification/annulation necessite macOS 13+ et une version compatible du serveur BlueBubbles. Sur macOS 26 (Tahoe), la modification est actuellement cassee en raison de changements dans l’API privee.
  • Les mises a jour d’icone de groupe peuvent etre instables sur macOS 26 (Tahoe) : l’API peut retourner un succes sans que la nouvelle icone ne se synchronise.
  • OpenClaw masque automatiquement les actions connues comme defaillantes en fonction de la version macOS du serveur BlueBubbles. Si la modification apparait encore sur macOS 26 (Tahoe), desactivez-la manuellement avec channels.bluebubbles.actions.edit=false.
  • Pour les informations de statut/sante : openclaw status --all ou openclaw status --deep.

Pour une reference generale sur le flux de travail des canaux, consultez Canaux et le guide Plugins.