Signal (signal-cli)
Estado: integración con CLI externa. El Gateway se comunica consignal-cli mediante HTTP JSON-RPC + SSE.
Requisitos previos
- OpenClaw instalado en tu servidor (el flujo de Linux a continuación se probó en Ubuntu 24).
signal-clidisponible en el host donde se ejecuta el gateway.- Un número de teléfono que pueda recibir un SMS de verificación (para la ruta de registro por SMS).
- Acceso a un navegador para el captcha de Signal (
signalcaptchas.org) durante el registro.
Configuración rápida (principiante)
- Usa un número de Signal independiente para el bot (recomendado).
- Instala
signal-cli(se requiere Java si usas la compilación JVM). - Elige una ruta de configuración:
- Ruta A (vinculación por QR):
signal-cli link -n "OpenClaw"y escanea con Signal. - Ruta B (registro por SMS): registra un número dedicado con captcha + verificación por SMS.
- Ruta A (vinculación por QR):
- Configura OpenClaw y reinicia el gateway.
- Envía un primer mensaje directo y aprueba el pairing (
openclaw pairing approve signal <CODE>).
| Field | Descripción |
|---|---|
account | Número de teléfono del bot en formato E.164 (+15551234567) |
cliPath | Ruta a signal-cli (signal-cli si está en PATH) |
dmPolicy | Política de acceso a mensajes directos (pairing recomendado) |
allowFrom | Números de teléfono o valores uuid:<id> con permiso para mensajes directos |
Qué es
- Canal de Signal mediante
signal-cli(nolibsignalintegrado). - Enrutamiento determinista: las respuestas siempre vuelven a Signal.
- Los mensajes directos comparten la sesión principal del agente; los grupos están aislados (
agent:<agentId>:signal:group:<groupId>).
Escrituras de configuración
De forma predeterminada, Signal puede escribir actualizaciones de configuración activadas por/config set|unset (requiere commands.config: true).
Desactívalo con:
El modelo de números (importante)
- El gateway se conecta a un dispositivo de Signal (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 caso “le escribo al bot y me responde”, usa un número de bot independiente.
Ruta de configuración A: vincular una cuenta de Signal existente (QR)
- Instala
signal-cli(compilación JVM o nativa). - Vincula una cuenta de bot:
signal-cli link -n "OpenClaw"y luego escanea el QR en Signal.
- Configura Signal e inicia el gateway.
channels.signal.accounts con configuración por cuenta y name opcional. Consulta gateway/configuration para ver el patrón compartido.
Ruta de configuración B: registrar un número de bot dedicado (SMS, Linux)
Usa esta opción si quieres un número de bot dedicado en lugar de vincular una cuenta existente de la app de Signal.- Obtén 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/sesión.
- Instala
signal-clien el host del gateway:
signal-cli-${VERSION}.tar.gz), instala primero JRE 25+.
Mantén signal-cli actualizado; upstream indica que las versiones antiguas pueden dejar de funcionar a medida que cambian las API del servidor de Signal.
- Registra y verifica el número:
- Abre
https://signalcaptchas.org/registration/generate.html. - Completa el captcha y copia el destino del enlace
signalcaptcha://...de “Open Signal”. - Ejecuta desde la misma IP externa que la sesión del navegador cuando sea posible.
- Ejecuta el registro de nuevo inmediatamente (los tokens de captcha caducan rápido):
- Configura OpenClaw, reinicia el gateway y verifica el canal:
- Empareja el remitente de tus mensajes directos:
- 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 “Unknown contact”.
signal-cli puede desautenticar la sesión principal de la app de Signal para ese número. Prefiere un número de bot dedicado, o usa el modo de vinculación por QR si necesitas conservar tu configuración actual de la app del teléfono.
Referencias de upstream:
signal-cliREADME: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)
Modo de daemon externo (httpUrl)
Si quieres gestionarsignal-cli tú mismo (arranques en frío lentos de JVM, inicialización de contenedor o CPU compartidas), ejecuta el daemon por separado y apunta OpenClaw hacia él:
channels.signal.startupTimeoutMs.
Control de acceso (mensajes directos + grupos)
Mensajes directos:- Predeterminado:
channels.signal.dmPolicy = "pairing". - Los remitentes desconocidos reciben un código de pairing; los mensajes se ignoran hasta su aprobación (los códigos caducan después de 1 hora).
- Aprobar mediante:
openclaw pairing list signalopenclaw pairing approve signal <CODE>
- El pairing es el intercambio de tokens predeterminado para los mensajes directos de Signal. Detalles: Pairing
- Los remitentes solo con UUID (de
sourceUuid) se almacenan comouuid:<id>enchannels.signal.allowFrom.
channels.signal.groupPolicy = open | allowlist | disabled.channels.signal.groupAllowFromcontrola quién puede activar acciones en grupos cuandoallowlistestá configurado.channels.signal.groups["<group-id>" | "*"]puede sobrescribir el comportamiento del grupo conrequireMention,toolsytoolsBySender.- Usa
channels.signal.accounts.<id>.groupspara sobrescrituras por cuenta en configuraciones con varias cuentas. - Nota de tiempo de ejecución: si
channels.signalfalta por completo, el tiempo de ejecución usagroupPolicy="allowlist"como respaldo para las comprobaciones de grupos (incluso sichannels.defaults.groupPolicyestá configurado).
Cómo funciona (comportamiento)
signal-clise ejecuta como daemon; el gateway lee eventos mediante SSE.- Los mensajes entrantes se normalizan en el sobre compartido del canal.
- Las respuestas siempre se enrutan de vuelta al mismo número o grupo.
Medios + límites
- El texto saliente se fragmenta según
channels.signal.textChunkLimit(predeterminado 4000). - Fragmentación opcional por líneas nuevas: configura
channels.signal.chunkMode="newline"para dividir en líneas en blanco (límites de párrafo) antes de fragmentar por longitud. - Se admiten adjuntos (base64 obtenido desde
signal-cli). - Límite de medios predeterminado:
channels.signal.mediaMaxMb(predeterminado 8). - Usa
channels.signal.ignoreAttachmentspara omitir la descarga de medios. - El contexto del historial de grupos usa
channels.signal.historyLimit(ochannels.signal.accounts.*.historyLimit), con respaldo enmessages.groupChat.historyLimit. Establece0para desactivar (predeterminado 50).
Indicadores de escritura + confirmaciones de lectura
- Indicadores de escritura: OpenClaw envía señales de escritura mediante
signal-cli sendTypingy las actualiza mientras se está generando una respuesta. - Confirmaciones de lectura: cuando
channels.signal.sendReadReceiptsestrue, OpenClaw reenvía las confirmaciones de lectura para los mensajes directos permitidos. - Signal-cli no expone confirmaciones de lectura para grupos.
Reacciones (herramienta de mensajes)
- Usa
message action=reactconchannel=signal. - Destinos: E.164 del remitente o UUID (usa
uuid:<id>desde la salida de pairing; el UUID sin prefijo también funciona). messageIdes la marca de tiempo de Signal del mensaje al que estás reaccionando.- Las reacciones en grupos requieren
targetAuthorotargetAuthorUuid.
channels.signal.actions.reactions: habilitar/deshabilitar acciones de reacción (predeterminado true).channels.signal.reactionLevel:off | ack | minimal | extensive.off/ackdeshabilita las reacciones del agente (la herramienta de mensajesreactdevolverá un error).minimal/extensivehabilita las reacciones del agente y establece el nivel de guía.
- Sobrescrituras por cuenta:
channels.signal.accounts.<id>.actions.reactions,channels.signal.accounts.<id>.reactionLevel.
Destinos de entrega (CLI/cron)
- Mensajes directos:
signal:+15551234567(o E.164 sin formato adicional). - Mensajes directos por UUID:
uuid:<id>(o UUID sin prefijo). - Grupos:
signal:group:<groupId>. - Nombres de usuario:
username:<name>(si tu cuenta de Signal lo admite).
Solución de problemas
Ejecuta primero esta secuencia:- El daemon es accesible pero no hay respuestas: verifica la configuración de la cuenta/daemon (
httpUrl,account) y el modo de recepción. - Se ignoran los mensajes directos: el remitente está pendiente de aprobación de pairing.
- Se ignoran los mensajes de grupo: el control por remitente/mención del grupo bloquea la entrega.
- Errores de validación de configuración después de editar: ejecuta
openclaw doctor --fix. - Signal no aparece en el diagnóstico: confirma
channels.signal.enabled: true.
Notas de seguridad
signal-clialmacena las claves 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"salvo que quieras explícitamente un acceso más amplio a los mensajes directos. - La verificación por SMS solo se necesita para flujos de registro o recuperación, pero perder el control del número/cuenta puede complicar el nuevo registro.
Referencia de configuración (Signal)
Configuración completa: Configuration Opciones del proveedor:channels.signal.enabled: habilitar/deshabilitar el inicio del canal.channels.signal.account: E.164 para la cuenta del bot.channels.signal.cliPath: ruta asignal-cli.channels.signal.httpUrl: URL completa del daemon (sobrescribe host/puerto).channels.signal.httpHost,channels.signal.httpPort: enlace del daemon (predeterminado 127.0.0.1:8080).channels.signal.autoStart: iniciar automáticamente el daemon (predeterminado true sihttpUrlno está configurado).channels.signal.startupTimeoutMs: tiempo de espera de arranque en ms (límite 120000).channels.signal.receiveMode:on-start | manual.channels.signal.ignoreAttachments: omitir descargas de adjuntos.channels.signal.ignoreStories: ignorar historias del daemon.channels.signal.sendReadReceipts: reenviar confirmaciones de lectura.channels.signal.dmPolicy:pairing | allowlist | open | disabled(predeterminado: pairing).channels.signal.allowFrom: allowlist de mensajes directos (E.164 ouuid:<id>).openrequiere"*". Signal no tiene nombres de usuario; usa identificadores de teléfono/UUID.channels.signal.groupPolicy:open | allowlist | disabled(predeterminado: allowlist).channels.signal.groupAllowFrom: allowlist de remitentes de grupo.channels.signal.groups: sobrescrituras por grupo indexadas por ID de grupo de Signal (o"*"). Campos admitidos:requireMention,tools,toolsBySender.channels.signal.accounts.<id>.groups: versión por cuenta dechannels.signal.groupspara configuraciones con varias cuentas.channels.signal.historyLimit: máximo de mensajes de grupo que se incluyen como contexto (0 desactiva).channels.signal.dmHistoryLimit: límite del historial de mensajes directos en turnos de usuario. Sobrescrituras por usuario:channels.signal.dms["<phone_or_uuid>"].historyLimit.channels.signal.textChunkLimit: tamaño de fragmento saliente (caracteres).channels.signal.chunkMode:length(predeterminado) onewlinepara dividir en líneas en blanco (límites de párrafo) antes de fragmentar por longitud.channels.signal.mediaMaxMb: límite de medios entrantes/salientes (MB).
agents.list[].groupChat.mentionPatterns(Signal no admite menciones nativas).messages.groupChat.mentionPatterns(respaldo global).messages.responsePrefix.
Relacionado
- Channels Overview — todos los canales compatibles
- Pairing — autenticación de mensajes directos y flujo de pairing
- Groups — comportamiento de chats grupales y control por menciones
- Channel Routing — enrutamiento de sesiones para mensajes
- Security — modelo de acceso y endurecimiento