Ir al contenido

Conecta OpenClaw a Signal: guía de configuración rápida

Estado: integración CLI externa. El Gateway se comunica con signal-cli mediante HTTP JSON-RPC + SSE.

  • OpenClaw instalado en tu servidor (el flujo de Linux que verás abajo fue probado en Ubuntu 24).
  • signal-cli disponible en el host donde corre el Gateway.
  • Un número de teléfono que pueda recibir un SMS de verificación (para la ruta de registro por SMS).
  • Acceso al navegador para el captcha de Signal (signalcaptchas.org) durante el registro.
  1. Usa un número de Signal independiente para el bot (es lo más recomendable).
  2. Instala signal-cli (necesitarás Java si usas la versión JVM).
  3. Elige una ruta de configuración:
    • Ruta A (enlace QR): signal-cli link -n "OpenClaw" y escanéalo con Signal.
    • Ruta B (registro por SMS): registra un número dedicado con captcha y verificación por SMS.
  4. Configura OpenClaw y reinicia el Gateway.
  5. Envía un primer DM y aprueba el emparejamiento (openclaw pairing approve signal <CODE>).

Configuración mínima:

{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}

Referencia de campos:

CampoDescripción
accountNúmero de teléfono del bot en formato E.164 (+15551234567)
cliPathRuta a signal-cli (signal-cli si está en el PATH)
dmPolicyPolítica de acceso para DM (pairing es lo recomendado)
allowFromNúmeros de teléfono o valores uuid:<id> autorizados para enviar DM
  • Canal de Signal mediante signal-cli (no usa libsignal embebido).
  • Enrutamiento determinista: las respuestas siempre vuelven a Signal.
  • Los DM comparten la sesión principal del agente; los grupos están aislados (agent:<agentId>:signal:group:<groupId>).

Por defecto, Signal tiene permiso para escribir actualizaciones de configuración activadas por /config set|unset (requiere commands.config: true).

Desactívalo con:

{
channels: { signal: { configWrites: false } },
}

AI Setup Assistant

  • El Gateway se conecta a un Signal device (la cuenta de signal-cli).
  • Si ejecutas el bot en tu cuenta personal de Signal, ignorará tus propios mensajes (protección contra bucles).
  • Para el flujo de “le escribo al bot y me responde”, usa un número de bot independiente.

Opción de configuración A: vincular una cuenta de Signal existente (QR)

Sección titulada «Opción de configuración A: vincular una cuenta de Signal existente (QR)»
  1. Instala signal-cli (JVM o build nativo).
  2. Vincula una cuenta de bot:
    • signal-cli link -n "OpenClaw" y luego escanea el QR en Signal.
  3. Configura Signal e inicia el Gateway.

Ejemplo:

{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}

Soporte multi-cuenta: usa channels.signal.accounts con configuración por cuenta y un name opcional. Consulta gateway/configuration para ver el patrón compartido.

Opción de configuración B: registrar un número de bot dedicado (SMS, Linux)

Sección titulada «Opción de configuración B: registrar un número de bot dedicado (SMS, Linux)»

Usa esta opción cuando quieras un número de bot dedicado en lugar de vincular una cuenta de la app de Signal existente.

  1. Consigue un número que pueda recibir SMS (o verificación por voz para líneas fijas).
    • Usa un número de bot dedicado para evitar conflictos de cuenta o sesión.
  2. Instala signal-cli en el host del Gateway:
Ventana de terminal
VERSION=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/AsamK/signal-cli/releases/latest | sed -e 's/^.*\/v//')
curl -L -O "https://github.com/AsamK/signal-cli/releases/download/v${VERSION}/signal-cli-${VERSION}-Linux-native.tar.gz"
sudo tar xf "signal-cli-${VERSION}-Linux-native.tar.gz" -C /opt
sudo ln -sf /opt/signal-cli /usr/local/bin/
signal-cli --version

Si usas el build de JVM (signal-cli-${VERSION}.tar.gz), instala primero JRE 25+. Mantén signal-cli actualizado; las notas del proyecto original indican que las versiones antiguas pueden dejar de funcionar si las API del servidor de Signal cambian.

  1. Registra y verifica el número:
Ventana de terminal
signal-cli -a +<BOT_PHONE_NUMBER> register

Si se requiere captcha:

  1. Abre https://signalcaptchas.org/registration/generate.html.
  2. Completa el captcha, copia el enlace signalcaptcha://... desde “Open Signal”.
  3. Ejecuta el comando desde la misma IP externa que la sesión del navegador cuando sea posible.
  4. Ejecuta el registro de nuevo inmediatamente (los tokens de captcha caducan rápido):
Ventana de terminal
signal-cli -a +<BOT_PHONE_NUMBER> register --captcha '<SIGNALCAPTCHA_URL>'
signal-cli -a +<BOT_PHONE_NUMBER> verify <VERIFICATION_CODE>
  1. Configura OpenClaw, reinicia el Gateway y verifica el canal:
Ventana de terminal
# If you run the gateway as a user systemd service:
systemctl --user restart openclaw-gateway
# Then verify:
openclaw doctor
openclaw channels status --probe
  1. Vincula tu remitente de DM:
    • Envía cualquier mensaje al número del bot.
    • Aprueba el código en el servidor: openclaw pairing approve signal <PAIRING_CODE>.
    • Guarda el número del bot como contacto en tu teléfono para evitar el aviso de “Contacto desconocido”.

Importante: registrar una cuenta de número de teléfono con signal-cli puede desautenticar la sesión principal de la app Signal para ese número. Es mejor usar un número de bot dedicado o usar el modo de vinculación por QR si necesitas mantener tu configuración actual en la app del teléfono.

Referencias externas:

  • README de signal-cli: https://github.com/AsamK/signal-cli
  • Flujo de captcha: https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha
  • Flujo de vinculación: https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)

Si quieres gestionar signal-cli por tu cuenta (por inicios en frío lentos de JVM, inicialización de contenedores o CPUs compartidas), ejecuta el daemon por separado y apunta OpenClaw hacia él:

{
channels: {
signal: {
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
},
},
}

Esto omite el auto-spawn y la espera de inicio dentro de OpenClaw. Para inicios lentos al usar auto-spawn, configura channels.signal.startupTimeoutMs.

Para los DMs:

  • Por defecto: channels.signal.dmPolicy = "pairing".
  • Si recibes mensajes de remitentes desconocidos, se generará un código de vinculación; los mensajes se ignorarán hasta que los apruebes (los códigos caducan tras 1 hora).
  • Puedes aprobarlos con estos comandos:
    • openclaw pairing list signal
    • openclaw pairing approve signal <CODE>
  • El emparejamiento es el intercambio de tokens estándar para los DMs de Signal. Tienes todos los detalles en: Pairing
  • Los remitentes que solo tienen UUID (provenientes de sourceUuid) se guardan como uuid:<id> en la configuración channels.signal.allowFrom.

Para los grupos:

  • channels.signal.groupPolicy = open | allowlist | disabled.
  • channels.signal.groupAllowFrom controla quién puede activar el bot en los grupos cuando usas el modo allowlist.
  • Puedes usar channels.signal.groups["<group-id>" | "*"] para sobrescribir el comportamiento del grupo con requireMention, tools, toolsBySender y otros parámetros específicos.
  • Utiliza channels.signal.accounts.<id>.groups para aplicar configuraciones específicas por cuenta si manejas un entorno multi-cuenta.
  • Nota sobre el runtime: si falta la sección channels.signal por completo, el sistema utiliza por defecto groupPolicy="allowlist" para las comprobaciones de grupo, incluso si has definido channels.defaults.groupPolicy.
  • signal-cli se ejecuta como un daemon y el Gateway lee los eventos mediante SSE.
  • Los mensajes entrantes se normalizan dentro del sobre del canal compartido.
  • Las respuestas siempre se envían de vuelta al mismo número o grupo de origen.
  • El texto saliente se divide en fragmentos según el límite definido en channels.signal.textChunkLimit (4000 por defecto).
  • División opcional por saltos de línea: configura channels.signal.chunkMode="newline" para separar el contenido en líneas en blanco (límites de párrafo) antes de aplicar la división por longitud.
  • Soportamos archivos adjuntos, los cuales se obtienen en formato base64 desde signal-cli.
  • El límite de tamaño para archivos multimedia es channels.signal.mediaMaxMb (8 MB por defecto).
  • Puedes usar channels.signal.ignoreAttachments si prefieres omitir la descarga de archivos multimedia.
  • El contexto del historial en grupos utiliza channels.signal.historyLimit (o channels.signal.accounts.*.historyLimit), recurriendo a messages.groupChat.historyLimit si no se especifica. Configúralo en 0 para desactivarlo (el valor por defecto es 50).

Indicadores de escritura + confirmaciones de lectura

Sección titulada «Indicadores de escritura + confirmaciones de lectura»
  • Indicadores de escritura: OpenClaw envía señales de escritura mediante signal-cli sendTyping y las actualiza mientras se está procesando una respuesta.
  • Confirmaciones de lectura: cuando channels.signal.sendReadReceipts es true, OpenClaw reenvía las confirmaciones de lectura para los DMs permitidos.
  • Ten en cuenta que signal-cli no muestra las confirmaciones de lectura en los grupos.

Para enviar una reacción, usa message action=react con channel=signal. Es la forma más directa de interactuar con un mensaje sin generar ruido innecesario.

  • Destinatarios: E.164 del remitente o UUID (usa uuid:<id> del output de pairing; el UUID solo también funciona).
  • messageId: Es el timestamp de Signal del mensaje al que estás reaccionando.
  • Las reacciones en grupos requieren obligatoriamente targetAuthor o targetAuthorUuid.
  • Te recomiendo verificar siempre el messageId para asegurar que la reacción llegue al mensaje correcto.
message action=react channel=signal target=uuid:123e4567-e89b-12d3-a456-426614174000 messageId=1737630212345 emoji=🔥
message action=react channel=signal target=+15551234567 messageId=1737630212345 emoji=🔥 remove=true
message action=react channel=signal target=signal:group:<groupId> targetAuthor=uuid:<sender-uuid> messageId=1737630212345 emoji=✅

Configuración:

  • channels.signal.actions.reactions: activa o desactiva las acciones de reacción (por defecto es true).
  • channels.signal.reactionLevel: define el comportamiento mediante los niveles off | ack | minimal | extensive.
  • Los niveles off o ack desactivan las reacciones del agente, por lo que la herramienta react devolverá un error.
  • Los niveles minimal o extensive activan las reacciones y establecen qué tan detallada será la guía.

Si necesitas una configuración más granular, puedes usar los overrides por cuenta en channels.signal.accounts.<id>.actions.reactions y channels.signal.accounts.<id>.reactionLevel.

Cuando configures envíos automáticos o uses la CLI, tienes varias opciones para definir a dónde llegará el mensaje:

  • DMs: signal:+15551234567 (o simplemente el formato E.164).
  • DMs por UUID: uuid:<id> (o el UUID solo).
  • Grupos: signal:group:<groupId>.
  • Usernames: username:<name> (siempre que tu cuenta de Signal soporte esta función).

Primero, sigue estos pasos en orden:

Ventana de terminal
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe

Luego, si es necesario, confirma el estado de vinculación de los DM:

Ventana de terminal
openclaw pairing list signal

Fallos comunes:

  • El daemon responde pero no hay réplicas: verifica la configuración de la cuenta y del daemon (httpUrl, account) y el modo de recepción.
  • Los DM se ignoran: el remitente tiene pendiente la aprobación de vinculación.
  • Los mensajes de grupo se ignoran: el remitente del grupo o el filtrado de menciones bloquean la entrega.
  • Errores de validación de configuración tras editar: ejecuta openclaw doctor --fix.
  • Signal no aparece en los diagnósticos: confirma que channels.signal.enabled: true.

Comprobaciones adicionales:

Ventana de terminal
openclaw pairing list signal
pgrep -af signal-cli
grep -i "signal" "/tmp/openclaw/openclaw-$(date +%Y-%m-%d).log" | tail -20

Para el flujo de triaje: /channels/troubleshooting.

  • signal-cli almacena las llaves de la cuenta localmente (normalmente en ~/.local/share/signal-cli/data/).
  • Haz una copia de seguridad del estado de la cuenta de Signal antes de migrar o reconstruir el servidor.
  • Mantén channels.signal.dmPolicy: "pairing" a menos que quieras explícitamente un acceso a DM más amplio.
  • La verificación por SMS solo es necesaria para el registro o flujos de recuperación, pero perder el control del número o la cuenta puede complicar el nuevo registro.

Configuración completa: Configuration

Opciones del proveedor:

  • channels.signal.enabled: activa o desactiva el inicio del canal.
  • channels.signal.account: E.164 para la cuenta del bot.
  • channels.signal.cliPath: ruta hacia signal-cli.
  • channels.signal.httpUrl: URL completa del daemon (sobrescribe host/puerto).
  • channels.signal.httpHost, channels.signal.httpPort: bind del daemon (por defecto 127.0.0.1:8080).
  • channels.signal.autoStart: inicia automáticamente el daemon (por defecto true si httpUrl no está definido).
  • channels.signal.startupTimeoutMs: tiempo de espera de inicio en ms (máximo 120000).
  • channels.signal.receiveMode: on-start | manual.
  • channels.signal.ignoreAttachments: omite la descarga de archivos adjuntos.
  • channels.signal.ignoreStories: ignora las historias del daemon.
  • channels.signal.sendReadReceipts: reenvía confirmaciones de lectura.
  • channels.signal.dmPolicy: pairing | allowlist | open | disabled (por defecto: pairing).
  • channels.signal.allowFrom: lista de permitidos para DM (E.164 o uuid:<id>). open requiere "*". Signal no utiliza nombres de usuario; usa IDs de teléfono o UUID.
  • channels.signal.groupPolicy: open | allowlist | disabled (por defecto: allowlist).
  • channels.signal.groupAllowFrom: lista de remitentes permitidos para grupos.
  • channels.signal.groups: sobrescrituras por grupo identificadas por el ID de grupo de Signal (o "*"). Campos soportados: requireMention, tools, toolsBySender.
  • channels.signal.accounts.<id>.groups: versión por cuenta de channels.signal.groups para configuraciones multi-cuenta.
  • channels.signal.historyLimit: máximo de mensajes de grupo para incluir como contexto (0 lo desactiva).
  • channels.signal.dmHistoryLimit: límite de historial de DM en turnos de usuario. Sobrescrituras por usuario: channels.signal.dms["<phone_or_uuid>"].historyLimit.
  • channels.signal.textChunkLimit: tamaño de fragmento de salida (caracteres).
  • channels.signal.chunkMode: length (por defecto) o newline para dividir en líneas en blanco (límites de párrafo) antes de fragmentar por longitud.
  • channels.signal.mediaMaxMb: límite de archivos multimedia entrantes/salientes (MB).

Opciones globales relacionadas:

  • agents.list[].groupChat.mentionPatterns (Signal no soporta menciones nativas).
  • messages.groupChat.mentionPatterns (fallback global).
  • messages.responsePrefix.

AI Setup Assistant

OpenClaw

OpenClaw Expert

Sigues atascado?

Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.