Cuộc Gọi Thoại (plugin)
Cuộc gọi thoại cho OpenClaw thông qua plugin. Hỗ trợ thông báo đi và hội thoại nhiều lượt với chính sách gọi đến. Các nhà cung cấp hiện tại:twilio(Programmable Voice + Media Streams)telnyx(Call Control v2)plivo(Voice API + XML transfer + GetInput speech)mock(dev/không mạng)
- Cài đặt plugin
- Khởi động lại Gateway
- Cấu hình dưới
plugins.entries.voice-call.config - Sử dụng
openclaw voicecall ...hoặc công cụvoice_call
Nơi chạy (local vs remote)
Plugin Cuộc Gọi Thoại chạy bên trong quá trình Gateway. Nếu sử dụng Gateway từ xa, cài đặt/cấu hình plugin trên máy chạy Gateway, sau đó khởi động lại Gateway để tải plugin.Cài đặt
Lựa chọn A: cài đặt từ npm (khuyến nghị)
Lựa chọn B: cài đặt từ thư mục local (dev, không sao chép)
Cấu hình
Đặt cấu hình dướiplugins.entries.voice-call.config:
- Twilio/Telnyx yêu cầu URL webhook có thể truy cập công khai.
- Plivo yêu cầu URL webhook có thể truy cập công khai.
mocklà nhà cung cấp dev local (không có cuộc gọi mạng).- Telnyx yêu cầu
telnyx.publicKey(hoặcTELNYX_PUBLIC_KEY) trừ khiskipSignatureVerificationlà true. skipSignatureVerificationchỉ dành cho thử nghiệm local.- Nếu sử dụng ngrok miễn phí, đặt
publicUrlthành URL ngrok chính xác; xác minh chữ ký luôn được thực thi. tunnel.allowNgrokFreeTierLoopbackBypass: truecho phép webhook Twilio với chữ ký không hợp lệ chỉ khitunnel.provider="ngrok"vàserve.bindlà loopback (ngrok local agent). Chỉ sử dụng cho dev local.- URL ngrok miễn phí có thể thay đổi hoặc thêm hành vi xen kẽ; nếu
publicUrlthay đổi, chữ ký Twilio sẽ thất bại. Đối với sản xuất, ưu tiên một tên miền ổn định hoặc Tailscale funnel. - Mặc định bảo mật streaming:
streaming.preStartTimeoutMsđóng các socket không bao giờ gửi một khungstarthợp lệ.streaming.maxPendingConnectionsgiới hạn tổng số socket chưa xác thực trước khi bắt đầu.streaming.maxPendingConnectionsPerIpgiới hạn socket chưa xác thực trước khi bắt đầu theo IP nguồn.streaming.maxConnectionsgiới hạn tổng số socket stream media mở (đang chờ + hoạt động).
Quản lý cuộc gọi cũ
Sử dụngstaleCallReaperSeconds để kết thúc các cuộc gọi không bao giờ nhận được webhook cuối cùng (ví dụ, các cuộc gọi chế độ thông báo không bao giờ hoàn thành). Mặc định là 0 (vô hiệu hóa).
Phạm vi khuyến nghị:
- Sản xuất:
120–300giây cho các luồng kiểu thông báo. - Giữ giá trị này cao hơn
maxDurationSecondsđể các cuộc gọi bình thường có thể hoàn thành. Một điểm khởi đầu tốt làmaxDurationSeconds + 30–60giây.
Bảo mật Webhook
Khi một proxy hoặc tunnel nằm trước Gateway, plugin sẽ tái tạo URL công khai để xác minh chữ ký. Các tùy chọn này kiểm soát các tiêu đề chuyển tiếp nào được tin cậy.webhookSecurity.allowedHosts cho phép danh sách các host từ tiêu đề chuyển tiếp.
webhookSecurity.trustForwardingHeaders tin tưởng các tiêu đề chuyển tiếp mà không cần danh sách cho phép.
webhookSecurity.trustedProxyIPs chỉ tin tưởng các tiêu đề chuyển tiếp khi IP từ xa của yêu cầu khớp với danh sách.
Bảo vệ phát lại webhook được kích hoạt cho Twilio và Plivo. Các yêu cầu webhook hợp lệ được phát lại sẽ được công nhận nhưng bỏ qua các tác động phụ.
Các lượt hội thoại Twilio bao gồm một token cho mỗi lượt trong các callback <Gather>, do đó các callback lời nói cũ/phát lại không thể thỏa mãn một lượt bản ghi chờ mới hơn.
Ví dụ với một host công khai ổn định:
TTS cho cuộc gọi
Cuộc Gọi Thoại sử dụng cấu hìnhmessages.tts cốt lõi để phát âm thanh trên các cuộc gọi. Bạn có thể ghi đè nó dưới cấu hình plugin với cùng hình dạng — nó sẽ hợp nhất sâu với messages.tts.
- Microsoft speech bị bỏ qua cho các cuộc gọi thoại (âm thanh điện thoại cần PCM; hiện tại Microsoft không cung cấp đầu ra PCM cho điện thoại).
- TTS cốt lõi được sử dụng khi streaming media Twilio được kích hoạt; nếu không, các cuộc gọi sẽ sử dụng giọng nói gốc của nhà cung cấp.
- Nếu một stream media Twilio đã hoạt động, Cuộc Gọi Thoại không quay lại TwiML
<Say>. Nếu TTS điện thoại không khả dụng trong trạng thái đó, yêu cầu phát lại sẽ thất bại thay vì trộn hai đường phát lại.
Nhiều ví dụ hơn
Chỉ sử dụng TTS cốt lõi (không ghi đè):Cuộc gọi đến
Chính sách gọi đến mặc định làdisabled. Để kích hoạt cuộc gọi đến, đặt:
inboundPolicy: "allowlist" là một màn hình ID người gọi có độ tin cậy thấp. Plugin chuẩn hóa giá trị From do nhà cung cấp cung cấp và so sánh nó với allowFrom. Xác minh webhook xác thực việc giao hàng của nhà cung cấp và tính toàn vẹn của tải trọng, nhưng không chứng minh quyền sở hữu số người gọi PSTN/VoIP. Xem allowFrom như là lọc ID người gọi, không phải là nhận dạng người gọi mạnh.
Phản hồi tự động sử dụng hệ thống agent. Điều chỉnh với:
responseModelresponseSystemPromptresponseTimeoutMs
Hợp đồng đầu ra nói
Đối với phản hồi tự động, Cuộc Gọi Thoại thêm một hợp đồng đầu ra nói nghiêm ngặt vào lời nhắc hệ thống:{"spoken":"..."}
- Bỏ qua các tải trọng được đánh dấu là nội dung lý luận/lỗi.
- Phân tích cú pháp JSON trực tiếp, JSON có khung, hoặc các khóa
"spoken"nội tuyến. - Quay lại văn bản thuần túy và loại bỏ các đoạn văn dẫn đầu có khả năng lập kế hoạch/meta.
Hành vi khởi động hội thoại
Đối với các cuộc gọiconversation đi, xử lý tin nhắn đầu tiên được liên kết với trạng thái phát lại trực tiếp:
- Hàng đợi ngắt lời và phản hồi tự động chỉ bị ngăn chặn trong khi lời chào ban đầu đang phát.
- Nếu phát lại ban đầu thất bại, cuộc gọi sẽ trở lại trạng thái
listeningvà tin nhắn ban đầu vẫn được xếp hàng để thử lại. - Phát lại ban đầu cho streaming Twilio bắt đầu khi kết nối stream mà không có độ trễ thêm.
Thời gian chờ ngắt kết nối stream Twilio
Khi một stream media Twilio ngắt kết nối, Cuộc Gọi Thoại chờ2000ms trước khi tự động kết thúc cuộc gọi:
- Nếu stream kết nối lại trong khoảng thời gian đó, tự động kết thúc sẽ bị hủy.
- Nếu không có stream nào được đăng ký lại sau thời gian chờ, cuộc gọi sẽ kết thúc để ngăn chặn các cuộc gọi hoạt động bị kẹt.
CLI
latency đọc calls.jsonl từ đường dẫn lưu trữ cuộc gọi thoại mặc định. Sử dụng --file <path> để chỉ định một nhật ký khác và --last <n> để giới hạn phân tích vào N bản ghi cuối cùng (mặc định 200). Đầu ra bao gồm p50/p90/p99 cho độ trễ lượt và thời gian chờ nghe.
Công cụ Agent
Tên công cụ:voice_call
Hành động:
initiate_call(message, to?, mode?)continue_call(callId, message)speak_to_user(callId, message)end_call(callId)get_status(callId)
skills/voice-call/SKILL.md.
Gateway RPC
voicecall.initiate(to?,message,mode?)voicecall.continue(callId,message)voicecall.speak(callId,message)voicecall.end(callId)voicecall.status(callId)