@openclaw/signal). Gateway giao tiếp với signal-cli qua HTTP: daemon gốc (JSON-RPC + SSE) hoặc container bbernhard/signal-cli-rest-api (REST + WebSocket). OpenClaw không nhúng libsignal.
Mô hình số điện thoại (hãy đọc phần này trước)
- Gateway kết nối với một thiết bị Signal: tài khoản
signal-cli. - Chạy bot trên tài khoản Signal cá nhân của bạn khiến bot bỏ qua tin nhắn của chính bạn (bảo vệ chống vòng lặp).
- Để “tôi nhắn tin cho bot và bot trả lời”, hãy dùng một số điện thoại riêng cho bot.
Cài đặt
openclaw plugins install clawhub:@openclaw/signal hoặc npm:@openclaw/signal. plugins install đăng ký và bật Plugin; không cần bước enable riêng. Xem Plugin để biết các quy tắc cài đặt chung.
Thiết lập nhanh
1
Chọn một số điện thoại
Dùng một số Signal riêng cho bot (khuyến nghị).
2
Cài đặt Plugin
3
Chạy quy trình thiết lập có hướng dẫn
signal-cli có nằm trên PATH hay không và nếu thiếu sẽ đề nghị cài đặt: tải bản dựng GraalVM gốc chính thức trên Linux x86-64 hoặc cài đặt qua Homebrew trên macOS và các kiến trúc khác. Sau đó, trình hướng dẫn yêu cầu số điện thoại của bot và đường dẫn signal-cli.Đối với thiết lập không tương tác, openclaw channels add --channel signal cũng chấp nhận --signal-number <e164> cho số điện thoại của bot, cùng với --http-host <host> và --http-port <port> cho điểm cuối daemon Signal (mặc định là 127.0.0.1:8080).4
Liên kết hoặc đăng ký tài khoản
- Liên kết bằng mã QR (nhanh nhất):
signal-cli link -n "OpenClaw", sau đó quét bằng Signal. Xem Lộ trình A. - Đăng ký bằng SMS: số điện thoại riêng với captcha + xác minh qua SMS. Xem Lộ trình B.
5
Xác minh và ghép đôi
openclaw pairing approve signal <CODE>.
Hỗ trợ nhiều tài khoản: dùng
channels.signal.accounts với cấu hình cho từng tài khoản và name tùy chọn. Xem Kênh nhiều tài khoản để biết mẫu dùng chung.
Chức năng
- Định tuyến tất định: câu trả lời luôn được gửi lại qua Signal.
- Tin nhắn trực tiếp dùng chung phiên chính của tác nhân; các nhóm được cô lập (
agent:<agentId>:signal:group:<groupId>). - Theo mặc định, Signal có thể ghi các bản cập nhật cấu hình do
/config set|unsetkích hoạt (yêu cầucommands.config: true). Tắt bằngchannels.signal.configWrites: false.
Lộ trình thiết lập A: liên kết tài khoản Signal hiện có (QR)
- Cài đặt
signal-cli(bản dựng JVM hoặc gốc), hoặc đểopenclaw channels addcài đặt thay bạn. - Liên kết tài khoản bot:
signal-cli link -n "OpenClaw", sau đó quét mã QR trong Signal. - Cấu hình Signal và khởi động Gateway.
Lộ trình thiết lập B: đăng ký số điện thoại riêng cho bot (SMS, Linux)
Dùng cách này cho số điện thoại riêng của bot thay vì liên kết một tài khoản ứng dụng Signal hiện có. Quy trình dưới đây đã được kiểm thử trên Ubuntu 24.- Chuẩn bị một số điện thoại có thể nhận SMS (hoặc xác minh bằng cuộc gọi thoại đối với điện thoại cố định). Số điện thoại riêng cho bot giúp tránh xung đột tài khoản/phiên.
- Cài đặt
signal-clitrên máy chủ Gateway:
signal-cli-${VERSION}.tar.gz), hãy cài đặt JRE trước. Luôn cập nhật signal-cli; tài liệu thượng nguồn lưu ý rằng các bản phát hành cũ có thể ngừng hoạt động khi API máy chủ Signal thay đổi.
- Đăng ký và xác minh số điện thoại:
- Mở
https://signalcaptchas.org/registration/generate.html. - Hoàn thành captcha, sao chép đích của liên kết
signalcaptcha://...từ “Open Signal”. - Khi có thể, hãy chạy từ cùng địa chỉ IP bên ngoài với phiên trình duyệt (token captcha hết hạn nhanh).
- Đăng ký và xác minh ngay lập tức:
- Cấu hình OpenClaw, khởi động lại Gateway và xác minh kênh:
- Ghép đôi người gửi tin nhắn trực tiếp:
- Gửi bất kỳ tin nhắn nào đến số điện thoại của bot.
- Phê duyệt trên máy chủ:
openclaw pairing approve signal <PAIRING_CODE>. - Lưu số điện thoại của bot làm liên hệ trên điện thoại để tránh “Unknown contact”.
- README của
signal-cli:https://github.com/AsamK/signal-cli - Quy trình captcha:
https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha - Quy trình liên kết:
https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)
Chế độ daemon bên ngoài (httpUrl)
Để tự quản lýsignal-cli (khởi động nguội JVM chậm, khởi tạo container, CPU dùng chung), hãy chạy daemon riêng và trỏ OpenClaw đến daemon đó:
channels.signal.startupTimeoutMs.
Chế độ container (bbernhard/signal-cli-rest-api)
Thay vì chạysignal-cli theo cách gốc, hãy dùng container Docker bbernhard/signal-cli-rest-api, bao bọc signal-cli phía sau giao diện REST + WebSocket.
Yêu cầu:
- Container phải chạy với
MODE=json-rpcđể nhận tin nhắn theo thời gian thực. - Đăng ký hoặc liên kết tài khoản Signal của bạn bên trong container trước khi kết nối OpenClaw.
docker-compose.yml:
apiMode kiểm soát giao thức OpenClaw sử dụng:
Khi
apiMode là "auto", OpenClaw lưu chế độ đã phát hiện vào bộ nhớ đệm trong 30 giây cho mỗi URL daemon để tránh thăm dò lặp lại (chế độ gốc được ưu tiên khi cả hai phương thức truyền tải đều hoạt động tốt). Chế độ nhận của container chỉ được chọn để truyền luồng sau khi /v1/receive/{account} nâng cấp lên WebSocket, việc này yêu cầu MODE=json-rpc.
Chế độ container hỗ trợ các thao tác Signal giống như chế độ gốc khi container cung cấp các API tương ứng: gửi, nhận, tệp đính kèm, chỉ báo đang nhập, biên nhận đã đọc/đã xem, phản ứng, nhóm và văn bản có định dạng. OpenClaw chuyển đổi các lệnh gọi RPC Signal gốc thành payload REST của container, bao gồm ID nhóm group.{base64(internal_id)} và text_mode: "styled" cho văn bản có định dạng.
Lưu ý vận hành:
- Dùng
autoStart: falsevới chế độ container; OpenClaw không nên tạo daemon gốc khiapiMode: "container"được chọn. - Dùng
MODE=json-rpcđể nhận.MODE=normalcó thể khiến/v1/aboutcó vẻ hoạt động tốt, nhưng/v1/receive/{account}sẽ không nâng cấp lên WebSocket, vì vậy OpenClaw sẽ không chọn truyền luồng nhận của container trong chế độauto. - Đặt
apiMode: "container"khihttpUrltrỏ đến API REST bbernhard,"native"khi nó trỏ đến JSON-RPC/SSEsignal-cligốc và"auto"khi cách triển khai có thể thay đổi. - Việc tải xuống tệp đính kèm trong container tuân theo cùng giới hạn số byte phương tiện như chế độ gốc. Các phản hồi quá lớn sẽ bị từ chối trước khi được đệm hoàn toàn khi máy chủ gửi
Content-Length, hoặc trong khi truyền luồng ở các trường hợp khác.
Kiểm soát truy cập (tin nhắn trực tiếp + nhóm)
Tin nhắn trực tiếp:- Mặc định:
channels.signal.dmPolicy = "pairing". - Người gửi không xác định nhận được mã ghép đôi; tin nhắn bị bỏ qua cho đến khi được phê duyệt (mã hết hạn sau 1 giờ).
- Phê duyệt qua
openclaw pairing list signalvàopenclaw pairing approve signal <CODE>. - Ghép đôi là cơ chế trao đổi token mặc định cho tin nhắn trực tiếp Signal. Chi tiết: Ghép đôi
- Người gửi chỉ có UUID (từ
sourceUuid) được lưu dưới dạnguuid:<id>trongchannels.signal.allowFrom.
channels.signal.groupPolicy = open | allowlist | disabled.channels.signal.groupAllowFromkiểm soát những nhóm hoặc người gửi nào có thể kích hoạt câu trả lời trong nhóm khiallowlistđược đặt; mục nhập có thể là ID nhóm Signal (thô,group:<id>hoặcsignal:group:<id>), số điện thoại người gửi, giá trịuuid:<id>hoặc*.channels.signal.groups["<group-id>" | "*"]có thể ghi đè hành vi nhóm bằngrequireMention,toolsvàtoolsBySender.- Dùng
channels.signal.accounts.<id>.groupsđể ghi đè theo từng tài khoản trong thiết lập nhiều tài khoản. - Việc thêm một nhóm Signal vào danh sách cho phép thông qua
groupAllowFromkhông tự động tắt cơ chế yêu cầu đề cập. Một mụcchannels.signal.groups["<group-id>"]được cấu hình cụ thể sẽ xử lý mọi tin nhắn nhóm trừ khirequireMention=trueđược đặt. - Với
requireMention=true, các lượt @đề cập gốc của Signal được đối chiếu từ siêu dữ liệu đề cập có cấu trúc với số điện thoại hoặcaccountUuidcủa tài khoản bot. CácmentionPatternsđã cấu hình vẫn là phương án dự phòng bằng văn bản thuần túy. - Lưu ý khi chạy: nếu hoàn toàn thiếu
channels.signal, thời gian chạy sẽ dự phòng sanggroupPolicy="allowlist"để kiểm tra nhóm (ngay cả khichannels.defaults.groupPolicyđược đặt).
Cách hoạt động (hành vi)
- Chế độ gốc:
signal-clichạy dưới dạng daemon; Gateway đọc các sự kiện qua SSE. - Chế độ vùng chứa: Gateway gửi qua REST API và nhận qua WebSocket.
- Tin nhắn đến được chuẩn hóa thành phong bì kênh dùng chung.
- Phản hồi luôn được định tuyến trở lại cùng số hoặc nhóm.
- Phản hồi cho tin nhắn đến bao gồm siêu dữ liệu trích dẫn Signal gốc khi backend chấp nhận dấu thời gian và tác giả của tin nhắn đến; nếu siêu dữ liệu trích dẫn bị thiếu hoặc bị từ chối, OpenClaw sẽ gửi phản hồi dưới dạng tin nhắn thông thường.
- Cấu hình việc sử dụng trích dẫn gốc bằng
channels.signal.replyToMode = off | first | all | batched, hoặcchannels.signal.replyToModeByChatType.direct/groupđể ghi đè theo từng loại cuộc trò chuyện. Các giá trị cấp tài khoản trongchannels.signal.accounts.<id>được ưu tiên.
Phương tiện + giới hạn
- Văn bản gửi đi được chia thành các đoạn theo
channels.signal.textChunkLimit(mặc định 4000). - Tùy chọn chia đoạn theo dòng mới: đặt
channels.signal.streaming.chunkMode="newline"để chia tại các dòng trống (ranh giới đoạn văn) trước khi chia theo độ dài. - Có hỗ trợ tệp đính kèm (base64 được truy xuất từ
signal-cli). - Tệp đính kèm ghi chú thoại sử dụng tên tệp
signal-clilàm phương án MIME dự phòng khi thiếucontentType, để tính năng phiên âm vẫn có thể phân loại các bản ghi nhớ thoại AAC. - Giới hạn phương tiện mặc định:
channels.signal.mediaMaxMb(mặc định 8). - Dùng
channels.signal.ignoreAttachmentsđể bỏ qua việc tải phương tiện xuống. - Ngữ cảnh lịch sử nhóm sử dụng
channels.signal.historyLimit(hoặcchannels.signal.accounts.*.historyLimit), dự phòng vềmessages.groupChat.historyLimit. Đặt0để tắt (mặc định 50).
Chỉ báo nhập + xác nhận đã đọc
- Chỉ báo đang nhập: OpenClaw gửi tín hiệu đang nhập qua
signal-cli sendTypingvà làm mới chúng trong khi đang tạo phản hồi. - Xác nhận đã đọc: khi
channels.signal.sendReadReceiptslà true, OpenClaw chuyển tiếp xác nhận đã đọc cho các DM được cho phép. signal-clikhông cung cấp xác nhận đã đọc cho nhóm.
Phản ứng trạng thái vòng đời
Đặtmessages.statusReactions.enabled: true để Signal hiển thị vòng đời phản ứng dùng chung gồm đang xếp hàng/đang suy nghĩ/công cụ/Compaction/hoàn tất/lỗi trên các lượt đến. Signal sử dụng dấu thời gian của tin nhắn đến làm mục tiêu phản ứng; phản ứng nhóm được gửi với ID nhóm Signal cùng người gửi ban đầu làm tác giả mục tiêu.
Phản ứng trạng thái cũng yêu cầu một phản ứng xác nhận và messages.ackReactionScope tương ứng (direct, group-all, group-mentions, hoặc all). Đặt channels.signal.reactionLevel: "off" để tắt phản ứng trạng thái Signal.
messages.removeAckAfterReply: true xóa phản ứng trạng thái cuối cùng sau thời gian giữ đã cấu hình. Nếu không, Signal khôi phục phản ứng xác nhận ban đầu sau trạng thái hoàn tất/lỗi cuối cùng.
Phản ứng (công cụ tin nhắn)
Dùngmessage action=react với channel=signal.
- Mục tiêu: E.164 hoặc UUID của người gửi (dùng
uuid:<id>từ đầu ra ghép nối; UUID thuần cũng hoạt động). messageIdlà dấu thời gian Signal của tin nhắn mà bạn đang phản ứng.- Phản ứng nhóm yêu cầu
targetAuthorhoặctargetAuthorUuid.
channels.signal.actions.reactions: bật/tắt hành động phản ứng (mặc định true).channels.signal.reactionLevel:off | ack | minimal | extensive(mặc địnhminimal).off/acktắt phản ứng của tác tử (công cụ tin nhắnreactbáo lỗi).minimal/extensivebật phản ứng của tác tử và đặt mức hướng dẫn.
- Ghi đè theo từng tài khoản:
channels.signal.accounts.<id>.actions.reactions,channels.signal.accounts.<id>.reactionLevel.
Phản ứng phê duyệt
Lời nhắc phê duyệt lệnh thực thi và Plugin của Signal sử dụng các khối định tuyến cấp cao nhấtapprovals.exec và approvals.plugin. Signal không có khối channels.signal.execApprovals.
👍phê duyệt một lần.👎từ chối.- Dùng
/approve <id> allow-alwayskhi yêu cầu cung cấp tùy chọn phê duyệt lâu dài.
channels.signal.allowFrom, channels.signal.defaultTo, hoặc các trường cấp tài khoản tương ứng. Lời nhắc phê duyệt lệnh thực thi trực tiếp trong cùng cuộc trò chuyện vẫn có thể ẩn phương án dự phòng cục bộ /approve bị trùng lặp mà không cần chỉ định rõ người phê duyệt; phê duyệt nhóm không có người phê duyệt vẫn hiển thị phương án dự phòng cục bộ.
Phản ứng cho câu hỏi
Đối với lời nhắcask_user có một câu hỏi không bí mật, chọn một đáp án và từ một đến bốn tùy chọn, Signal hiển thị 1️⃣ đến 4️⃣ bên cạnh nhãn tùy chọn. Hãy phản ứng với lời nhắc đã gửi bằng số tương ứng để trả lời. OpenClaw xác minh rằng phản ứng nhắm đến tin nhắn do bot tạo, sau đó ánh xạ số đó sang tùy chọn chuẩn thông qua Gateway. Các lượt nhấn cũ hoặc trùng lặp bị bỏ qua. Lời nhắc có nhiều câu hỏi, chọn nhiều đáp án và văn bản tự do vẫn chỉ có thể trả lời bằng văn bản; các quy tắc chấp nhận DM/nhóm Signal thông thường sẽ cấp quyền cho người gửi.
Mục tiêu gửi (CLI/cron)
- DM:
signal:+15551234567(hoặc E.164 thuần). - DM UUID:
uuid:<id>(hoặc UUID thuần). - Nhóm:
signal:group:<groupId>. - Tên người dùng:
username:<name>(nếu tài khoản Signal của bạn hỗ trợ).
Bí danh
Cấu hình bí danh làm tên ổn định cho các mục tiêu Signal thường xuyên sử dụng. Bí danh chỉ là cấu hình phía OpenClaw; chúng không tạo hoặc chỉnh sửa danh bạ Signal.openclaw directory peers list --channel signal và openclaw directory groups list --channel signal liệt kê các bí danh đã cấu hình. Thư mục Signal dựa trên cấu hình; nó không truy vấn trực tiếp danh bạ Signal hoặc sửa đổi tài khoản Signal.
Khắc phục sự cố
Trước tiên, chạy chuỗi kiểm tra này:- Có thể truy cập daemon nhưng không có phản hồi: xác minh cài đặt tài khoản/daemon (
httpUrl,account) và chế độ nhận. - DM bị bỏ qua: người gửi đang chờ phê duyệt ghép nối.
- Tin nhắn nhóm bị bỏ qua: cổng kiểm soát người gửi/đề cập của nhóm chặn việc gửi.
- Lỗi xác thực cấu hình sau khi chỉnh sửa: chạy
openclaw doctor --fix. - Không có Signal trong thông tin chẩn đoán: xác nhận
channels.signal.enabled: true.
Lưu ý bảo mật
signal-clilưu khóa tài khoản cục bộ (thường là~/.local/share/signal-cli/data/).- Sao lưu trạng thái tài khoản Signal trước khi di chuyển hoặc dựng lại máy chủ.
- Giữ nguyên
channels.signal.dmPolicy: "pairing"trừ khi bạn chủ ý muốn cấp quyền truy cập DM rộng hơn. - Xác minh SMS chỉ cần thiết cho quy trình đăng ký hoặc khôi phục, nhưng việc mất quyền kiểm soát số/tài khoản có thể khiến quá trình đăng ký lại trở nên phức tạp.
Tham chiếu cấu hình (Signal)
Cấu hình đầy đủ: Cấu hình Tùy chọn nhà cung cấp:channels.signal.enabled: bật/tắt khởi động kênh.channels.signal.apiMode:auto | native | container(mặc định: tự động). Xem Chế độ vùng chứa.channels.signal.account: E.164 cho tài khoản bot.channels.signal.accountUuid: UUID tùy chọn của tài khoản bot để phát hiện @mention gốc và bảo vệ khỏi vòng lặp.channels.signal.cliPath: đường dẫn đếnsignal-cli.channels.signal.configPath: thư mụcsignal-cli --configtùy chọn.channels.signal.httpUrl: URL đầy đủ của daemon (ghi đè máy chủ/cổng).channels.signal.httpHost,channels.signal.httpPort: địa chỉ liên kết của daemon (mặc định127.0.0.1:8080).channels.signal.autoStart: tự động khởi chạy daemon (mặc định là true nếu chưa đặthttpUrl).channels.signal.startupTimeoutMs: thời gian chờ khởi động tính bằng mili giây (tối thiểu 1000, tối đa 120000; mặc định 30000).channels.signal.receiveMode:on-start | manual.channels.signal.ignoreAttachments: bỏ qua việc tải xuống tệp đính kèm.channels.signal.ignoreStories: bỏ qua các tin từ daemon.channels.signal.sendReadReceipts: chuyển tiếp xác nhận đã đọc.channels.signal.dmPolicy:pairing | allowlist | open | disabled(mặc định: ghép nối).channels.signal.allowFrom: danh sách cho phép DM (E.164 hoặcuuid:<id>).openyêu cầu"*". Signal không có tên người dùng; hãy dùng ID điện thoại/UUID.channels.signal.aliases: bí danh phía OpenClaw cho các đích gửi DM hoặc nhóm.channels.signal.groupPolicy:open | allowlist | disabled(mặc định: danh sách cho phép).channels.signal.groupAllowFrom: danh sách cho phép của nhóm; chấp nhận ID nhóm Signal (dạng thô,group:<id>hoặcsignal:group:<id>), số E.164 của người gửi hoặc các giá trịuuid:<id>.channels.signal.groups: các giá trị ghi đè theo nhóm, được lập khóa bằng ID nhóm Signal (hoặc"*"). Các trường được hỗ trợ:requireMention,tools,toolsBySender.channels.signal.accounts.<id>.groups: phiên bản theo tài khoản củachannels.signal.groupsdành cho cấu hình nhiều tài khoản.channels.signal.accounts.<id>.aliases: bí danh theo tài khoản, được hợp nhất với các bí danh cấp cao nhất.channels.signal.replyToMode: chế độ trích dẫn trả lời gốc,off | first | all | batched(mặc định:all).channels.signal.replyToModeByChatType.direct,channels.signal.replyToModeByChatType.group: các giá trị ghi đè trích dẫn trả lời gốc theo loại cuộc trò chuyện.channels.signal.accounts.<id>.replyToMode,channels.signal.accounts.<id>.replyToModeByChatType.direct,channels.signal.accounts.<id>.replyToModeByChatType.group: các giá trị ghi đè trích dẫn trả lời theo tài khoản.channels.signal.historyLimit: số tin nhắn nhóm tối đa cần đưa vào làm ngữ cảnh (0 để tắt).channels.signal.dmHistoryLimit: giới hạn lịch sử DM tính theo lượt của người dùng. Giá trị ghi đè theo người dùng:channels.signal.dms["<phone_or_uuid>"].historyLimit.channels.signal.textChunkLimit: kích thước phân đoạn gửi đi tính theo ký tự (mặc định 4000).channels.signal.streaming.chunkMode:length(mặc định) hoặcnewlineđể tách tại các dòng trống (ranh giới đoạn văn) trước khi phân đoạn theo độ dài.channels.signal.mediaMaxMb: giới hạn phương tiện đầu vào/đầu ra tính bằng MB (mặc định 8).channels.signal.reactionLevel:off | ack | minimal | extensive(mặc địnhminimal). Xem Cảm xúc.channels.signal.reactionNotifications:off | own | all | allowlist(mặc địnhown) - thời điểm tác nhân được thông báo về cảm xúc đến từ người khác.channels.signal.reactionAllowlist: những người gửi có cảm xúc sẽ thông báo cho tác nhân khireactionNotifications: "allowlist".channels.signal.streaming.block.enabled,channels.signal.streaming.block.coalesce: các chế độ điều khiển truyền phát theo khối được dùng chung giữa các kênh. Xem Truyền phát.
agents.list[].groupChat.mentionPatterns(phương án dự phòng văn bản thuần túy; @mention gốc của Signal được phát hiện từ siêu dữ liệu có cấu trúc khi danh tính tài khoản bot được cấu hình).messages.groupChat.mentionPatterns(phương án dự phòng toàn cục).messages.responsePrefix.
Liên quan
- Tổng quan về kênh - tất cả các kênh được hỗ trợ
- Ghép nối - xác thực DM và luồng ghép nối
- Nhóm - hành vi trò chuyện nhóm và kiểm soát bằng lượt đề cập
- Định tuyến kênh - định tuyến phiên cho tin nhắn
- Bảo mật - mô hình truy cập và gia cố bảo mật