Signal (signal-cli)

Trạng thái: tích hợp CLI bên ngoài. Gateway giao tiếp với signal-cli qua HTTP JSON-RPC + SSE.

Cài đặt nhanh (người mới)

  1. Dùng số Signal riêng cho bot (khuyên dùng).
  2. Cài đặt signal-cli (cần Java).
  3. Liên kết thiết bị bot và khởi động daemon:
    • signal-cli link -n "OpenClaw"
  4. Cấu hình OpenClaw và khởi động gateway.

Config tối thiểu:

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

Đây là gì

  • Channel Signal qua signal-cli (không phải libsignal nhúng).
  • Routing xác định: tin nhắn trả lời luôn quay về Signal.
  • DM dùng chung session chính của agent; nhóm được tách riêng (agent:<agentId>:signal:group:<groupId>).

Ghi config

Mặc định, Signal được phép ghi cập nhật config khi dùng lệnh /config set|unset (cần bật commands.config: true).

Tắt bằng cách:

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

Mô hình số điện thoại (quan trọng)

  • Gateway kết nối tới một thiết bị Signal (tài khoản signal-cli).
  • Nếu các bạn chạy bot trên tài khoản Signal cá nhân, nó sẽ bỏ qua tin nhắn của chính bạn (chống loop).
  • Để “mình nhắn tin cho bot và nó trả lời”, hãy dùng số bot riêng.

Cài đặt (đường nhanh)

  1. Cài đặt signal-cli (cần Java).
  2. Liên kết tài khoản bot:
    • signal-cli link -n "OpenClaw" rồi quét mã QR trong Signal.
  3. Cấu hình Signal và khởi động gateway.

Ví dụ:

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

Hỗ trợ nhiều tài khoản: dùng channels.signal.accounts với config riêng cho từng tài khoản và name tùy chọn. Xem gateway/configuration để biết pattern chung.

Chế độ daemon bên ngoài (httpUrl)

Nếu các bạn muốn tự quản lý signal-cli (JVM khởi động chậm, container init, hoặc CPU dùng chung), hãy chạy daemon riêng và trỏ OpenClaw vào đó:

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

Cách này bỏ qua auto-spawn và thời gian chờ khởi động trong OpenClaw. Nếu khởi động chậm khi auto-spawn, hãy đặt channels.signal.startupTimeoutMs.

Kiểm soát truy cập (DM + nhóm)

DM:

  • Mặc định: channels.signal.dmPolicy = "pairing".
  • Người gửi lạ sẽ nhận mã pairing; tin nhắn bị bỏ qua cho đến khi được duyệt (mã hết hạn sau 1 giờ).
  • Duyệt qua:
    • openclaw pairing list signal
    • openclaw pairing approve signal <CODE>
  • Pairing là cơ chế trao đổi token mặc định cho DM Signal. Chi tiết: Pairing
  • Người gửi chỉ có UUID (từ sourceUuid) được lưu dưới dạng uuid:<id> trong channels.signal.allowFrom.

Nhóm:

  • channels.signal.groupPolicy = open | allowlist | disabled.
  • channels.signal.groupAllowFrom kiểm soát ai có thể kích hoạt trong nhóm khi đặt allowlist.

Cách hoạt động

  • signal-cli chạy như daemon; gateway đọc sự kiện qua SSE.
  • Tin nhắn đến được chuẩn hóa thành channel envelope chung.
  • Tin trả lời luôn route về cùng số hoặc nhóm.

Media + giới hạn

  • Text gửi đi được chia nhỏ theo channels.signal.textChunkLimit (mặc định 4000).
  • Chia theo dòng mới (tùy chọn): đặt channels.signal.chunkMode="newline" để tách theo dòng trống (ranh giới đoạn văn) trước khi chia theo độ dài.
  • Hỗ trợ đính kèm (base64 lấy từ signal-cli).
  • Giới hạn media mặc định: channels.signal.mediaMaxMb (mặc định 8).
  • Dùng channels.signal.ignoreAttachments để bỏ qua tải media.
  • Context lịch sử nhóm dùng channels.signal.historyLimit (hoặc channels.signal.accounts.*.historyLimit), fallback về messages.groupChat.historyLimit. Đặt 0 để tắt (mặc định 50).

Typing + read receipts

  • Typing indicators: OpenClaw gửi tín hiệu typing qua signal-cli sendTyping và làm mới chúng trong khi đang trả lời.
  • Read receipts: khi channels.signal.sendReadReceipts là true, OpenClaw chuyển tiếp read receipts cho DM được phép.
  • Signal-cli không hiển thị read receipts cho nhóm.

Reactions (message tool)

  • Dùng message action=react với channel=signal.
  • Targets: E.164 hoặc UUID của người gửi (dùng uuid:<id> từ output pairing; UUID trần cũng được).
  • messageId là timestamp Signal của tin nhắn các bạn muốn react.
  • Reaction nhóm cần targetAuthor hoặc targetAuthorUuid.

Ví dụ:

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=✅

Config:

  • channels.signal.actions.reactions: bật/tắt reaction actions (mặc định true).
  • channels.signal.reactionLevel: off | ack | minimal | extensive.
    • off/ack tắt agent reactions (message tool react sẽ báo lỗi).
    • minimal/extensive bật agent reactions và đặt mức hướng dẫn.
  • Override theo tài khoản: channels.signal.accounts.<id>.actions.reactions, channels.signal.accounts.<id>.reactionLevel.

Delivery targets (CLI/cron)

  • DM: signal:+15551234567 (hoặc E.164 trần).
  • UUID DM: uuid:<id> (hoặc UUID trần).
  • Nhóm: signal:group:<groupId>.
  • Usernames: username:<name> (nếu tài khoản Signal của bạn hỗ trợ).

Tham khảo cấu hình (Signal)

Cấu hình đầy đủ: Configuration

Tùy chọn provider:

  • channels.signal.enabled: bật/tắt khởi động channel.
  • channels.signal.account: E.164 cho tài khoản bot.
  • channels.signal.cliPath: đường dẫn tới signal-cli.
  • channels.signal.httpUrl: URL daemon đầy đủ (ghi đè host/port).
  • channels.signal.httpHost, channels.signal.httpPort: daemon bind (mặc định 127.0.0.1:8080).
  • channels.signal.autoStart: tự động spawn daemon (mặc định true nếu không đặt httpUrl).
  • channels.signal.startupTimeoutMs: timeout chờ khởi động tính bằng ms (tối đa 120000).
  • channels.signal.receiveMode: on-start | manual.
  • channels.signal.ignoreAttachments: bỏ qua tải đính kèm.
  • channels.signal.ignoreStories: bỏ qua stories từ daemon.
  • channels.signal.sendReadReceipts: chuyển tiếp read receipts.
  • channels.signal.dmPolicy: pairing | allowlist | open | disabled (mặc định: pairing).
  • channels.signal.allowFrom: allowlist DM (E.164 hoặc uuid:<id>). open cần "*". Signal không có username; dùng phone/UUID ids.
  • channels.signal.groupPolicy: open | allowlist | disabled (mặc định: allowlist).
  • channels.signal.groupAllowFrom: allowlist người gửi nhóm.
  • channels.signal.historyLimit: số tin nhắn nhóm tối đa để đưa vào context (0 để tắt).
  • channels.signal.dmHistoryLimit: giới hạn lịch sử DM theo lượt người dùng. Override theo người dùng: channels.signal.dms["<phone_or_uuid>"].historyLimit.
  • channels.signal.textChunkLimit: kích thước chunk gửi đi (ký tự).
  • channels.signal.chunkMode: length (mặc định) hoặc newline để tách theo dòng trống (ranh giới đoạn văn) trước khi chia theo độ dài.
  • channels.signal.mediaMaxMb: giới hạn media gửi/nhận (MB).

Tùy chọn global liên quan:

  • agents.list[].groupChat.mentionPatterns (Signal không hỗ trợ mention gốc).
  • messages.groupChat.mentionPatterns (fallback global).
  • messages.responsePrefix.