
频道 = 你和 QwenPaw 在「哪里」对话:接钉钉就在钉钉里回,接 QQ 就在 QQ 里回。不熟悉这个词的话可以先看 项目介绍。
配置频道有两种方式:
控制台(推荐)— 在 控制台 的 Control → Channels 页面,点击频道卡片,在抽屉里启用并填写鉴权信息,保存即生效。
手动编辑
agent.json— 在智能体工作区的agent.json中(如~/.qwenpaw/workspaces/default/agent.json),将需要的频道设enabled: true并填好鉴权信息;保存后自动重载,无需重启。
下面按频道说明如何获取凭证并填写配置。
钉钉(推荐)
创建钉钉应用
视频操作流程:
图文操作流程:
打开 钉钉开发者后台
进入"应用开发→企业内部应用→钉钉应用→创建 应用"

在"应用能力→添加应用能力"中添加 「机器人」

配置机器人基础信息,设置消息接收模式为 Stream 模式(流式接收),点击发布


在"应用发布→版本管理与发布"中创建新版本,填写基础信息后保存


在"基础信息→凭证与基础信息"中获取:

Client ID(即 AppKey)
Client Secret(即 AppSecret)
(可选) 将服务器 IP 加入白名单 — 调用钉钉开放平台 API(如下载用户发送的图片和文件)时需要此配置。在应用设置中进入 "安全设置→服务器出口 IP",添加运行 QwenPaw 的机器的公网 IP。可在终端执行
curl ifconfig.me查看公网 IP。若未配置白名单,图片和文件下载将报Forbidden.AccessDenied.IpNotInWhiteList错误。
绑定应用
可以在console前端配置,或者修改智能体工作区的 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)。
方法1: 在console前端配置
从“控制→频道”找到DingTalk,点击后填入刚刚获取的Client ID和Client Secret

方法2: 修改 agent.json
在智能体工作区的 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)里找到 channels.dingtalk,填入对应信息:
"dingtalk": {
"enabled": true,
"bot_prefix": "[BOT]",
"client_id": "你的 Client ID",
"client_secret": "你的 Client Secret",
"filter_tool_messages": false}钉钉专属字段说明:
提示:
若希望隐藏工具执行详情,可设置
filter_tool_messages: true。AI Card 模式:将
message_type设为card,并填写card_template_id;card_template_key必须与钉钉模板变量名完全一致。群聊场景建议显式配置
robot_code;留空时 QwenPaw 会回退使用client_id。
保存后若服务已运行会自动重载;未运行则执行 qwenpaw app 启动。
找到创建的应用
视频操作流程:
图文操作流程:
点击钉钉【消息】栏的“搜索框”

搜索刚刚创建的 “机器人名称”,在【功能】下找到机器人

点击后进入对话框

注:可以在钉钉群中通过群设置→机器人→添加机器人将机器人添加到群聊。需要注意的是,从与机器人的单聊界面中创建群聊,会无法触发机器人的回复。
飞书
飞书频道通过 WebSocket 长连接 接收消息,无需公网 IP 或 webhook;发送走飞书开放平台 Open API。支持文本、图片、文件收发;群聊场景下会将 chat_id、message_id 放入请求消息的 metadata,便于下游去重与群上下文识别。
创建飞书应用并获取凭证
打开 飞书开放平台,创建企业自建应用


在「凭证与基础信息」中获取 App ID、App Secret

在
agent.json中填写上述 App ID 和 App Secret(见下方「填写 agent.json」),保存执行
qwenpaw app启动 QwenPaw 服务回到飞书开放平台,在「能力」中启用 机器人

选择「权限管理」中的「批量导入/导出权限」,将以下JSON代码复制进去
{
"scopes": {
"tenant": [
"aily:file:read",
"aily:file:write",
"aily:message:read",
"aily:message:write",
"corehr:file:download",
"im:chat",
"im:message",
"im:message.group_msg",
"im:message.p2p_msg:readonly",
"im:message.reactions:read",
"im:resource",
"contact:user.base:readonly"
],
"user": []
}}



在「事件与回调」中,点击「事件配置」,选择订阅方式为长连接(WebSocket) 模式(无需公网 IP)
注:操作顺序为先配置 App ID/Secret → 启动
qwenpaw app→ 再在开放平台配置长连接,如果此处仍显示错误,尝试先暂停 QwenPaw 服务并重新启动qwenpaw app。

选择「添加事件」,搜索接收消息,订阅接收消息 v2.0



在「事件与回调」中,点击「回调配置」,选择订阅方式为长连接(WebSocket) 模式(无需公网 IP)

选择「添加回调」,搜索卡片回传交互,订阅卡片回传交互



在「应用发布」的「版本管理与发布」中,创建版本,填写基础信息,保存并发布



填写 agent.json
在智能体工作区的 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)中找到channels.feishu,只需填 App ID 和 App Secret(在开放平台「凭证与基础信息」里复制):
"feishu": {
"enabled": true,
"bot_prefix": "[BOT]",
"app_id": "cli_xxxxx",
"app_secret": "你的 App Secret",
"domain": "feishu"}飞书专属字段说明:
提示: 其他字段(encrypt_key、verification_token、media_dir)可选,WebSocket 模式可不填,有默认值。
依赖: pip install lark-oapi
如果你使用 SOCKS 代理联网,还需安装 python-socks(例如 pip install python-socks),否则可能报错:python-socks is required to use a SOCKS proxy。
注: App ID 和 App Secret 信息也可以在Console前端填写,但需重启 QwenPaw 服务,才能继续配置长链接的操作。
机器人权限建议
第6步中的json文件为应用配备了以下权限(应用身份、已开通),以保证收发消息与文件正常:
获取用户昵称(推荐):若希望会话和日志中显示用户昵称(如「张三#1d1a」)而非「unknown#1d1a」,需额外开通通讯录只读权限 以应用身份读取通讯录(
contact:user.base:readonly)。未开通时,飞书仅返回 open_id 等身份字段,不返回姓名,QwenPaw 无法解析昵称。开通后需重新发布/更新应用版本,权限生效后即可正常显示用户名称。
将机器人添加到常用
在工作台点击添加常用

搜索刚刚创建的机器人名称并添加

可以看到机器人已添加到常用中,双击可进入对话界面


iMessage(仅 macOS)
⚠️ iMessage 频道仅支持 macOS,依赖本地「信息」应用与 iMessage 数据库,无法在 Linux / Windows 上使用。
通过本地 iMessage 数据库轮询新消息并代为回复。
确保本地 「信息」(Messages) 已登录 Apple ID(系统设置里打开「信息」并登录)。
安装 imsg(用于访问 iMessage 数据库):
brew install steipete/tap/imsg
如果 Intel 芯片 Mac 用户通过上述方式无法安装成功,需要先克隆源码再编译
git clone https://github.com/steipete/imsg.gitcd imsg make buildsudo cp build/Release/imsg /usr/local/bin/cp ./bin/imsg /usr/local/bin/
为了使 iMessage 中的信息能被获取,需要 终端 (或你用来运行 QwenPaw 的 app) 和 消息 有 完全磁盘访问权限(系统设置 → 隐私与安全性 → 完全磁盘访问权限)。

填写 iMessage 数据库路径。默认路径为
~/Library/Messages/chat.db,若你改过系统路径,请填实际路径。有以下两种填写方案:进入 控制台 → 频道,点击 iMessage 卡片,将 Enable 开关打开,在 DB Path中填写上面的路径,点击 保存。

填写智能体工作区的
agent.json(如~/.qwenpaw/workspaces/default/agent.json):"imessage": { "enabled": true, "bot_prefix": "[BOT]", "db_path": "~/Library/Messages/chat.db", "poll_sec": 1.0}
iMessage 专属字段说明:
填写完成后,使用你的手机,给当前电脑登录的 iMessage 账号(与电脑Apple ID一致)发送任意一条消息,可以看到回复。

Discord
获取 Bot Token

新建应用(或选已有应用)

左侧进入 Bot,新建 Bot,复制 Token

下滑,给予 Bot “Message Content Intent” 和 “Send Messages” 的权限,并保存

在 OAuth2 → URL 生成器 里勾选
bot权限,给予 Bot “Send Messages” 的权限,生成邀请链接



在浏览器中访问该链接,会自动跳转到discord页面。将 Bot 拉进你的服务器


在服务器中可以看到 Bot已被拉入

绑定 Bot
可以在console前端配置,或者修改智能体工作区的 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)。
方法1: 在console前端配置
从“控制→频道”找到Discord,点击后填入刚刚获取的Bot Token

方法2: 修改 agent.json
在智能体工作区的 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)里找到 channels.discord,填入对应信息:
"discord": {
"enabled": true,
"bot_prefix": "[BOT]",
"bot_token": "你的 Bot Token",
"http_proxy": "",
"http_proxy_auth": ""}Discord 专属字段说明:
提示: 国内网络访问 Discord API 可能需代理。
获取 QQ 机器人凭证
打开 QQ 开放平台

创建 机器人应用,点击进入编辑页面


选择回调配置,首先在单聊事件中勾选C2C消息事件,再在群事件中勾选群消息事件AT事件,确认配置


选择沙箱配置中的消息列表配置项,点击添加成员,选择添加自己


在开发管理中获取AppID和AppSecret(即 ClientSecret),填入
agent.json,方式见下方填写 agent.json。在IP白名单中添加一个IP。提示: 如果使用魔搭创空间部署QwenPaw,QQ频道的IP白名单应填写:
47.92.200.108

在沙箱配置中,使用QQ扫码,将机器人添加到消息列表

填写 agent.json
在智能体工作区的 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)里找到 channels.qq,把上面两个值分别填进 app_id 和 client_secret:
"qq": {
"enabled": true,
"bot_prefix": "[BOT]",
"app_id": "你的 AppID",
"client_secret": "你的 AppSecret",
"markdown_enabled": false,
"max_reconnect_attempts": -1}QQ 专属字段说明:
注意: 这里填的是 AppID 和 AppSecret 两个字段,不是拼成一条 Token。
或者也可以在console前端填写:

OneBot v11(NapCat / QQ 完整协议)
OneBot 渠道通过反向 WebSocket 将 QwenPaw 连接到 NapCat、go-cqhttp、Lagrange 或其他任何兼容 OneBot v11 的实现。
与内置 QQ 渠道(使用官方 QQ Bot API,功能受限)不同,OneBot v11 提供完整 QQ 协议支持:个人号、群聊无需 @、富媒体消息等。
工作原理
QwenPaw 启动一个 WebSocket 服务器,OneBot 实现(如 NapCat)作为客户端连接过来:
NapCat ──反向 WS──▶ QwenPaw (:6199/ws)
配置 NapCat
通过 Docker 运行 NapCat:
docker run -d \ --name napcat \ -e ACCOUNT=<你的QQ号> \ -p 6099:6099 \ mlikiowa/napcat-docker:latest
打开 NapCat WebUI
http://localhost:6099,用 QQ 扫码登录。进入 网络配置 → 新建 → WebSocket 客户端(反向 WS):
URL:
ws://<qwenpaw地址>:6199/wsAccess Token:与 QwenPaw 配置中的
access_token保持一致(可选)
填写 agent.json
"onebot": {
"enabled": true,
"ws_host": "0.0.0.0",
"ws_port": 6199,
"access_token": "",
"share_session_in_group": false}OneBot 专属字段说明:
Docker Compose 提示: QwenPaw 和 NapCat 一起用 Docker Compose 部署时,NapCat 的反向 WS 地址填
ws://qwenpaw:6199/ws(使用服务名)。
多模态支持:
提示: 语音和视频在渠道层已正确接收,但需要配置 QwenPaw 的转写服务(
transcription_provider_type)才能让 LLM 理解内容。未配置时语音消息显示为占位符。
企业微信
创建新企业
个人使用者可以访问企业微信官网注册账号,创建新企业,成为企业管理员。

填写企业信息与管理员信息,并绑定微信账号

注册成功之后即可登陆企业微信开始使用。
若已经有企业微信账号或是企业普通员工,可以直接在当前企业创建API模式机器人。
创建机器人
可在工作台点击智能机器人-创建机器人,选择API模式创建-通过长链接配置



获取Bot ID和Secret

绑定bot
可以在Console或是智能体工作区的 agent.json 填写Bot ID和Secret绑定bot
方法一在console填写

方法二在 agent.json 填写(如 ~/.qwenpaw/workspaces/default/agent.json)
找到wecom,填写对应信息:
"wecom": {
"enabled": true,
"bot_prefix": "[BOT]",
"dm_policy": "open",
"group_policy": "open",
"bot_id": "your bot_id",
"secret": "your secret",
"media_dir": "~/.qwenpaw/media",
"max_reconnect_attempts": -1}企业微信专属字段说明:
在企业微信开始与机器人聊天

微信个人(iLink)
微信 iLink Bot 频道允许通过个人微信账号运行 AI 机器人,无需企业资质,使用官方 iLink Bot HTTP API 协议。
注意:微信个人 Bot(iLink 协议)目前仍处于内测阶段,需申请接入资格后方可使用。
工作原理
登录方式:首次使用时扫描二维码授权,Token 自动持久化到本地文件(默认
~/.qwenpaw/wechat_bot_token),后续启动无需重复扫码。消息接收:通过 HTTP 长轮询(
getupdates)持续拉取新消息,支持文本、图片、语音(ASR 转录)和文件。消息发送:通过
sendmessage接口回复用户,当前仅支持文本(iLink API 限制)。
扫码登录(推荐通过 Console)
在 QwenPaw Web Console 中进入 设置 → 通道 → 微信个人(iLink)。
点击 获取登录二维码,等待二维码显示。
用手机微信扫描二维码并确认授权。
扫码成功后,Bot Token 会自动填入表单,点击 保存 即可。
在配置文件中填写
也可直接在智能体工作区的 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)中配置:
"wechat": {
"enabled": true,
"bot_prefix": "[BOT]",
"bot_token": "your_bot_token",
"bot_token_file": "~/.qwenpaw/wechat_bot_token",
"base_url": "",
"media_dir": "~/.qwenpaw/media",
"dm_policy": "open",
"group_policy": "open"}微信个人专属字段说明:
环境变量方式
也可通过环境变量配置:
WECHAT_CHANNEL_ENABLED=1 WECHAT_BOT_TOKEN=your_bot_token WECHAT_BOT_TOKEN_FILE=~/.qwenpaw/wechat_bot_token WECHAT_MEDIA_DIR=~/.qwenpaw/media WECHAT_DM_POLICY=open WECHAT_GROUP_POLICY=open
Telegram
获取 Telegram 机器人凭证
打开 Telegram 并搜索
@BotFather添加 Bot(注意需要是官方 @BotFather,有蓝色认证标识)。打开与 @BotFather 的聊天,根据对话中的指引创建新机器人

在对话框中创建 bot_name,复制 bot_token

绑定 Bot
可以在console前端配置,或者修改智能体的 agent.json。
方法1: 在console前端配置
从"控制→频道"找到Telegram,点击后填入刚刚获取的Bot Token

方法2: 修改 agent.json
在智能体工作区的 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)里找到 channels.telegram,填入对应信息:
"telegram": {
"enabled": true,
"bot_prefix": "[BOT]",
"bot_token": "你的 Bot Token",
"http_proxy": "",
"http_proxy_auth": ""}Telegram 专属字段说明:
提示: 国内网络访问 Telegram API 可能需代理。
备注
可使用本页顶部介绍的通用访问控制字段(dm_policy、group_policy、allow_from、deny_message、require_mention)控制谁可以与机器人交互。仍建议不要将 bot username 暴露到公共环境中。
建议在 @BotFather 设置:
/setprivacy -> ENABLED # 设置bot回复权限 /setjoingroups -> DISABLED # 拦截Group邀请
Mattermost
Mattermost 频道通过 WebSocket 实时监听事件,并使用 REST API 发送回复。支持私聊和群聊场景,在群聊中基于 Thread(盖楼) 划分会话上下文。
获取凭证并配置
在 Mattermost 中创建 Bot 账号 (System Console → Integrations → Bot Accounts)。
给予机器人必要的权限(如
Post all),并获取 Access Token。在控制台或智能体工作区的
agent.json(如~/.qwenpaw/workspaces/default/agent.json)中配置 URL 和 Token。
配置示例:
"mattermost": {
"enabled": true,
"bot_prefix": "[BOT]",
"url": "https://mattermost.example.com",
"bot_token": "your_access_token",
"show_typing": true,
"thread_follow_without_mention": false,
"dm_policy": "open",
"group_policy": "open"}Mattermost 专属字段说明:
提示:Mattermost 的
session_id在私聊中固定为mattermost_dm:{mm_channel_id},在群聊中按 Thread ID 隔离回话。仅在 Session 首次触发时会自动拉取最近的历史记录作为上下文补全。
MQTT
介绍
当前仅支持了文本和JSON格式消息。
JSON消息格式
{
"text": "...",
"redirect_client_id": "..."
}基础配置
主题
简单订阅和推送
模糊匹配订阅和自动推送
模糊订阅全server/+/up主题,根据客户端的client_id自动推送到对应的主题,例如客户端向
/server/client_a/up推送QwenPaw处理完后,将会向/client/client_b/down推送消息。重定向主题推送
发送消息为JSON格式,订阅主题为
server/client_a/up,推送主题为client/client_a/down{ "text": "讲个笑话,直接回复文本即可。", "redirect_client_id": "client_b"}消息会根据redirect_client_id属性,推送至
client/client_b/down,从而实现跨主题推送。在物联网场景,可以做到以QwenPaw为核心,根据个人需求,多设备间自主推送消息。
Matrix
Matrix 频道通过 matrix-nio 库将 QwenPaw 接入任意 Matrix 服务器,支持私聊和群聊房间中的文本消息收发。
创建机器人账号并获取 Access Token
在任意 Matrix 服务器上注册机器人账号(例如 matrix.org,可在 app.element.io 注册)。
获取机器人的 Access Token,最简便的方式是通过 Element:
也可以直接调用 Matrix Client-Server API:
curl -X POST "https://matrix.org/_matrix/client/v3/login" \ -H "Content-Type: application/json" \ -d '{"type":"m.login.password","user":"@yourbot:matrix.org","password":"yourpassword"}'响应中的
access_token即为所需 Token。以机器人账号登录 app.element.io
前往 设置 → 帮助与关于 → 高级 → Access Token
复制 Token(以
syt_...开头)记录机器人的 User ID(格式:
@用户名:服务器,例如@mybot:matrix.org)和 Homeserver URL(例如https://matrix.org)。
配置频道
方式一: 在 Console 中配置
前往 控制 → 频道,点击 Matrix,启用后填写:
Homeserver URL — 例如
https://matrix.orgUser ID — 例如
@mybot:matrix.orgAccess Token — 上面复制的 Token(以密码框形式显示)
方式二: 编辑智能体工作区的 agent.json
在 agent.json(如 ~/.qwenpaw/workspaces/default/agent.json)中找到 channels.matrix:
"matrix": {
"enabled": true,
"bot_prefix": "[BOT]",
"homeserver": "https://matrix.org",
"user_id": "@mybot:matrix.org",
"access_token": "syt_..."}Matrix 专属字段说明:
保存后,若 QwenPaw 已在运行,频道会自动重载。
开始聊天
从任意 Matrix 客户端(如 Element)邀请机器人进入房间或发起私聊。机器人会监听其已加入的所有房间中的消息。
注意事项
Matrix 频道当前仅支持文本消息(不支持图片/文件附件)。
机器人只能接收已加入房间的消息,发消息前请先邀请机器人进入对应房间。
如使用自建服务器,将
homeserver设置为你的服务器地址(例如https://matrix.example.com)。
小艺(XiaoYi)
小艺通道通过 A2A (Agent-to-Agent) 协议 基于 WebSocket 连接华为小艺平台。
获取凭证并配置
在小艺开放平台创建Agent。
获取 AK (Access Key)、SK (Secret Key) 和 Agent ID。
在控制台或智能体工作区的
agent.json中配置。
配置示例:
"xiaoyi": {
"enabled": true,
"bot_prefix": "[BOT]",
"ak": "your_access_key",
"sk": "your_secret_key",
"agent_id": "your_agent_id",
"ws_url": "wss://hag.cloud.huawei.com/openclaw/v1/ws/link"}小艺专属字段说明:
支持的文件类型
图片:JPEG, JPG, PNG, BMP, WEBP
文件:PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, TXT
注:小艺平台限制,不支持视频和音频文件。
Voice
Voice 频道通过 Twilio ConversationRelay 实现电话语音交互,支持语音转文本(STT)、文本转语音(TTS),让用户可以直接拨打电话与 QwenPaw 对话。
前置要求
Twilio 账号:从 Twilio 官网 注册账号并获取凭证
Cloudflare Tunnel(或其他内网穿透方案):将本地 QwenPaw 服务暴露到公网,供 Twilio 回调使用
创建 Twilio 账号并获取凭证
访问 Twilio Console,注册账号
在 Dashboard 中获取:
Account SID(账号标识)
Auth Token(认证令牌)
购买电话号码:
前往 Phone Numbers → Buy a Number
选择支持语音通话的号码
记录 Phone Number(如
+1234567890)和 Phone Number SID
配置 Cloudflare Tunnel
Twilio 需要通过公网回调 QwenPaw 的 Webhook 接口,因此需要将本地服务暴露到公网。
安装 Cloudflare Tunnel 客户端:
# macOSbrew install cloudflare/cloudflare/cloudflared# Linuxwget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflaredsudo chmod +x /usr/local/bin/cloudflared
启动隧道,将本地 8088 端口暴露到公网:
cloudflared tunnel --url http://localhost:8088
终端会输出一个公网 URL,例如:
https://abc-def-ghi.trycloudflare.com
配置 Voice 频道
方式一: 在 Console 中配置
前往 控制 → 频道,点击 Voice,启用后填写:
Twilio Account SID:从 Twilio Dashboard 获取
Twilio Auth Token:从 Twilio Dashboard 获取
Phone Number:购买的电话号码(如
+1234567890)Phone Number SID:电话号码的 SID
高级选项:
TTS Provider:文本转语音提供商(默认
google)TTS Voice:语音模型(默认
en-US-Journey-D)STT Provider:语音转文本提供商(默认
deepgram)Language:语言代码(默认
en-US)Welcome Greeting:欢迎语(用户接通电话后的第一句话)
方式二: 手动编辑 agent.json
{
"channels": {
"voice": {
"enabled": true,
"twilio_account_sid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxx",
"twilio_auth_token": "your_auth_token",
"phone_number": "+1234567890",
"phone_number_sid": "PNxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tts_provider": "google",
"tts_voice": "en-US-Journey-D",
"stt_provider": "deepgram",
"language": "en-US",
"welcome_greeting": "Hi! This is QwenPaw. How can I help you?"
}
}}配置 Twilio Webhook
在 Twilio Console 中配置电话号码的 Webhook:
前往 Phone Numbers → Manage → Active Numbers
点击你的电话号码
在 Voice Configuration 部分:
A Call Comes In:选择 Webhook
URL:填入
https://your-cloudflare-url.trycloudflare.com/api/voice/callbackHTTP Method:选择 POST
保存配置
使用方式
配置完成后,直接拨打你购买的 Twilio 电话号码,即可与 QwenPaw 进行语音对话:
拨打电话
听到欢迎语后开始说话
QwenPaw 将语音转文本,调用 Agent 处理
将 Agent 的回复转为语音播放给用户
Voice 频道专属字段说明:
注意:Voice 频道需要持续的网络连接和内网穿透工具运行。建议在生产环境使用稳定的内网穿透方案(如 Cloudflare Tunnel、ngrok 付费版等)。
SIP
SIP 频道让你可以通过标准 SIP 电话或软电话(如 Linphone、MicroSIP、IP 座机)与 QwenPaw 进行语音对话。完全在本地网络或私有基础设施上运行,无需云账号或公网 URL。
提供两种后端模式:
快速体验:Dev 模式(3 分钟,零外部依赖)
最快的体验方式。QwenPaw 会自动启动内置 SIP 注册服务器,无需 Asterisk、FreeSWITCH 或任何外部服务。
安装:
pip install "qwenpaw[sip]"
启动 QwenPaw 并在控制台中配置:
qwenpaw init --defaults qwenpaw app
打开 http://127.0.0.1:8088/ → 设置 → 模型:配置模型提供商和 API Key。然后进入 控制 → 频道 → SIP:启用,填入 DashScope API Key,点击 保存。其他字段全部留空即可 — sip_server 留空时 QwenPaw 自动启动内置注册服务器,STT/TTS 默认使用 aliyun,语音模型自动选择默认音色。
QwenPaw 会自动重启 SIP 频道,终端中会看到:
[SIP] Built-in SIP registrar started on 0.0.0.0:5060 [SIP] Quickstart: register your softphone to <你的IP>:5060 [SIP] Dial 'sip:agent@<你的IP>:5060' to talk with QwenPaw!
打开 Linphone(或任意 SIP 软电话)并配置:
你会听到欢迎语,然后说话 — QwenPaw 会回复!
也可以用 pjsua(命令行,使用系统麦克风/扬声器)
pjsua --local-port=5062 \ --bound-addr=127.0.0.1 \ --no-tcp \ --id='sip:caller@127.0.0.1:5062' \ --registrar='sip:127.0.0.1:5060' \ --realm='*' --username=caller --password=pass
注册成功后按
m发起呼叫,输入sip:agent@127.0.0.1:5060,即可通过麦克风对话。按h挂断。进入 Preferences → SIP Accounts → Add
Username:任意名称(如
caller)SIP Domain:
127.0.0.1(使用 IP 地址,不要用localhost,避免 IPv6 问题)Transport:UDP
无需密码 — 内置注册服务器接受所有注册
拨号:
sip:agent@127.0.0.1:5060
注意:内置注册服务器仅供快速试用。生产环境请参见下方生产部署。
快速体验:LiveKit 模式浏览器测试(3 分钟,无需 SIP 电话)
你可以直接用浏览器通过 WebRTC 测试完整的 LiveKit 音频管线,无需 SIP Trunk、Docker 或 Redis。
注册 LiveKit Cloud(有免费额度),创建项目。在 Settings → Project 中获取项目 URL,在 Settings → API keys 中获取 API Key 和 API Secret。
安装、启动 QwenPaw 并在控制台中配置:
pip install "qwenpaw[sip,sip-livekit]"qwenpaw init --defaults qwenpaw app
打开 http://127.0.0.1:8088/ → 设置 → 模型:配置模型提供商和 API Key。然后进入 控制 → 频道 → SIP:启用,SIP 模式选 Production (LiveKit),填写以下 4 个字段:
LiveKit URL(如
wss://<your-project>.livekit.cloud)LiveKit API Key
LiveKit API Secret
DashScope API Key
其他字段全部留空即可,点击 保存。
终端中会看到:Connected to room: sip-inbound, waiting...
生成 Token 并通过 LiveKit Meet 加入房间:
# 安装 LiveKit CLI(一次性)brew install livekit-cli# 生成 Tokenlk token create \ --api-key <your-api-key> \ --api-secret <your-api-secret> \ --join --room sip-inbound \ --identity test-user
打开 meet.livekit.io → 点击底部 "Custom"
输入你的 LiveKit Cloud URL(如
wss://<your-project>.livekit.cloud)粘贴生成的 Token 并点击 Connect
允许麦克风权限,然后说话 — QwenPaw 会回复!
注意:浏览器测试与真实 SIP 电话走的是完全相同的音频管线(流式 STT、24kHz TTS、语音打断),是 LiveKit 模式的完整验证。
生产部署
生产环境下使用真实电话号码和运营商级可靠性,可选择以下方案:
Dev 模式 + 外部 SIP 服务器:
使用 Asterisk、FreeSWITCH 或任意 SIP PBX 作为注册服务器。将 sip_server 设为 PBX 地址,QwenPaw 注册为 SIP 分机,由 PBX 路由来电。
LiveKit 模式 + SIP Trunk:
需要 PSTN 连接(真实电话号码)时,部署 LiveKit Server + LiveKit SIP,配合 SIP Trunk 提供商(如 Twilio、Telnyx、Vonage)。参见 LiveKit SIP 文档。
Dev 模式配置
Dev 模式使用 pyVoIP — 一个纯 Python SIP 库。
方式一: 在控制台中配置
进入 控制 → 频道,点击 SIP,选择 Dev (pyVoIP) 模式。sip_server 留空使用内置注册服务器,或填写外部 SIP 服务器地址。点击 保存。
方式二: 编辑 agent 工作区 agent.json
{
"channels": {
"sip": {
"enabled": true,
"sip_mode": "dev",
"sip_server": "",
"stt_provider": "aliyun",
"tts_provider": "aliyun",
"tts_voice": "longxiaochun",
"language": "zh-CN",
"welcome_greeting": "你好,我是QwenPaw"
}
}}sip_server 留空时,QwenPaw 自动在 5060 端口启动内置 SIP 注册服务器,agent 自动注册。设置 sip_server(如 "192.168.1.100:5060")时,QwenPaw 注册到该外部服务器。
LiveKit 模式配置
生产模式将 SIP/RTP 委托给 LiveKit SIP Server,处理 NAT 穿透、抖动缓冲和编解码协商。QwenPaw 作为 AI 参与者加入 LiveKit 房间。
安装扩展:
pip install "qwenpaw[sip,sip-livekit]"
在控制台或
agent.json中配置 SIP 频道:
{
"channels": {
"sip": {
"enabled": true,
"sip_mode": "livekit",
"livekit_url": "wss://<your-project>.livekit.cloud",
"livekit_api_key": "your-api-key",
"livekit_api_secret": "your-api-secret",
"stt_provider": "aliyun",
"tts_provider": "aliyun",
"tts_voice": "longxiaochun",
"language": "zh-CN",
"welcome_greeting": "你好,我是QwenPaw"
}
}}
livekit_url:LiveKit Cloud 使用wss://<project>.livekit.cloud,自建 LiveKit Server 使用ws://<host>:<port>。
启动 QwenPaw。如需 SIP 电话呼入,还需部署 LiveKit 基础设施并配置 SIP Trunk 和 Dispatch Rule(参见 LiveKit SIP 文档)。浏览器测试请参见上方快速体验。
使用方式
配置完成后,从 SIP 电话或浏览器发起通话:
电话接通,听到欢迎语
开始说话 — QwenPaw 通过流式 STT 将语音转为文本
Agent 处理消息并生成回复
回复通过 TTS 转为语音播放给你
自然地继续对话 — 完全支持多轮对话
支持语音打断:在 Agent 说话时直接开口即可打断
SIP 频道专属字段说明
附录
配置总览
所有频道均支持本页顶部「通用字段」中介绍的访问控制字段(dm_policy、group_policy、allow_from、deny_message、require_mention)。
各频道字段与完整结构见上文表格及 配置与工作目录。
通用字段说明
所有频道都支持以下通用字段:
多模态消息支持
不同频道对「文本 / 图片 / 视频 / 音频 / 文件」的接收(用户发给机器人)与发送(机器人回复用户)支持程度如下。 「✓」= 已支持;「🚧」= 施工中(可实现但尚未实现);「✗」= 不支持(该频道本身无法支持)。
说明:
钉钉:接收支持富文本与单文件(downloadCode),发送通过会话 webhook 支持图片 / 语音 / 视频 / 文件。
飞书:WebSocket 长连接收消息,Open API 发送;支持文本 / 图片 / 文件收发;群聊时在消息 metadata 中带
feishu_chat_id、feishu_message_id便于下游去重与群上下文。Discord:接收时附件会解析为图片 / 视频 / 音频 / 文件并传入 Agent;回复时真实附件发送为 🚧 施工中,当前仅以链接形式附在文本中。
iMessage:基于本地 imsg + 数据库轮询,仅支持文本收发;平台/实现限制,无法支持附件(✗)。
QQ:接收侧附件解析为多模态、发送侧真实媒体均为 🚧 施工中,当前仅文本 + 链接形式。
Telegram:接收时附件会解析为文件并传入,可在telegram对话界面以对应格式打开(图片 / 语音 / 视频 / 文件)
企业微信:WebSocket 长连接接收,markdown/template_card 发送;支持接收和发送文本、图片、语音、视频和文件。
微信个人(iLink):HTTP 长轮询接收,支持文本、图片(AES-128-ECB 解密)、语音(ASR 转录文字)、文件和视频;发送支持文本、图片、文件和视频;音频文件(如 MP3)因 iLink API 限制暂不支持。
Matrix:接收图片 / 视频 / 音频 / 文件(通过
mxc://媒体 URL);发送时将文件上传至服务器后以原生 Matrix 媒体消息(m.image、m.video、m.audio、m.file)发出。小艺:支持接收文本、图片(JPEG/PNG/BMP/WEBP)和文件(PDF/DOC/DOCX/PPT/PPTX/XLS/XLSX/TXT);平台限制不支持视频和音频。
Voice:纯语音通话频道,接收用户语音并转为文本,Agent 回复转为语音播放;不支持其他格式。
通过 HTTP 修改配置
服务运行时可读写频道配置,修改会写回 agent.json 并自动生效:
GET /config/channels— 获取全部频道PUT /config/channels— 整体覆盖GET /config/channels/{channel_name}— 获取单个(如dingtalk、imessage)PUT /config/channels/{channel_name}— 更新单个
扩展渠道
如需接入新平台(如企业微信、Slack 等),可基于 BaseChannel 实现子类,无需改核心源码。
数据流与队列
ChannelManager 为每个启用队列的 channel 维护一个队列;收到消息时 channel 调用
self._enqueue(payload)(由 manager 启动时注入),manager 在消费循环中再调用channel.consume_one(payload)。基类已实现 默认
consume_one:把 payload 转成AgentRequest、跑_process、对每条完成消息调用send_message_content、错误时调用_on_consume_error。多数渠道只需实现「入口→请求」和「回复→出口」,不必重写consume_one。
子类必须实现
基类提供的通用能力
消费流程:
_payload_to_request(payload→AgentRequest)、get_to_handle_from_request(解析发送目标,默认user_id)、get_on_reply_sent_args(回调参数)、_before_consume_process(处理前钩子,如保存 receive_id)、_on_consume_error(错误时发送,默认send_content_parts)、可选refresh_webhook_or_token(空实现,子类需刷新 token 时覆盖)。辅助:
resolve_session_id、build_agent_request_from_user_content、_message_to_content_parts、send_message_content、send_content_parts、to_handle_from_target。
需要不同消费逻辑时(如控制台打印、钉钉合并去抖)再覆盖 consume_one;需要不同发送目标或回调参数时覆盖 get_to_handle_from_request / get_on_reply_sent_args。
示例:最简渠道(仅文本)
只处理文本、使用 manager 队列时,不必实现 consume_one,基类默认即可:
# my_channel.pyfrom agentscope_runtime.engine.schemas.agent_schemas import TextContent, ContentTypefrom qwenpaw.app.channels.base import BaseChannelfrom qwenpaw.app.channels.schema import ChannelTypeclass MyChannel(BaseChannel):
channel: ChannelType = "my_channel"
def __init__(self, process, enabled=True, bot_prefix="", **kwargs): super().__init__(process, on_reply_sent=kwargs.get("on_reply_sent")) self.enabled = enabled self.bot_prefix = bot_prefix @classmethod
def from_config(cls, process, config, on_reply_sent=None, show_tool_details=True): return cls(process=process, enabled=getattr(config, "enabled", True),
bot_prefix=getattr(config, "bot_prefix", ""), on_reply_sent=on_reply_sent) @classmethod
def from_env(cls, process, on_reply_sent=None): return cls(process=process, on_reply_sent=on_reply_sent) def build_agent_request_from_native(self, native_payload):
payload = native_payload if isinstance(native_payload, dict) else {}
channel_id = payload.get("channel_id") or self.channel
sender_id = payload.get("sender_id") or ""
meta = payload.get("meta") or {}
session_id = self.resolve_session_id(sender_id, meta)
text = payload.get("text", "")
content_parts = [TextContent(type=ContentType.TEXT, text=text)]
request = self.build_agent_request_from_user_content(
channel_id=channel_id, sender_id=sender_id, session_id=session_id,
content_parts=content_parts, channel_meta=meta,
)
request.channel_meta = meta return request async def start(self): pass
async def stop(self): pass
async def send(self, to_handle, text, meta=None): # 调用你的 HTTP API 等发送
pass收到消息时组一个 native 字典并入队(_enqueue 由 manager 注入):
native = { "channel_id": "my_channel", "sender_id": "user_123", "text": "你好", "meta": {},
}self._enqueue(native)示例:多模态(文本 + 图片/视频/音频/文件)
在 build_agent_request_from_native 里把附件解析成 runtime 的 content,再调用 build_agent_request_from_user_content:
from agentscope_runtime.engine.schemas.agent_schemas import (
TextContent, ImageContent, VideoContent, AudioContent, FileContent, ContentType,
)def build_agent_request_from_native(self, native_payload):
payload = native_payload if isinstance(native_payload, dict) else {}
channel_id = payload.get("channel_id") or self.channel
sender_id = payload.get("sender_id") or ""
meta = payload.get("meta") or {}
session_id = self.resolve_session_id(sender_id, meta)
content_parts = [] if payload.get("text"):
content_parts.append(TextContent(type=ContentType.TEXT, text=payload["text"])) for att in payload.get("attachments") or []:
t = (att.get("type") or "file").lower()
url = att.get("url") or ""
if not url: continue
if t == "image":
content_parts.append(ImageContent(type=ContentType.IMAGE, image_url=url)) elif t == "video":
content_parts.append(VideoContent(type=ContentType.VIDEO, video_url=url)) elif t == "audio":
content_parts.append(AudioContent(type=ContentType.AUDIO, data=url)) else:
content_parts.append(FileContent(type=ContentType.FILE, file_url=url)) if not content_parts:
content_parts = [TextContent(type=ContentType.TEXT, text="")]
request = self.build_agent_request_from_user_content(
channel_id=channel_id, sender_id=sender_id, session_id=session_id,
content_parts=content_parts, channel_meta=meta,
)
request.channel_meta = meta return request自定义渠道目录与 CLI
目录:工作目录下的
custom_channels/(默认~/.qwenpaw/custom_channels/)用于存放自定义渠道模块。Manager 启动时会扫描该目录下的.py文件与包(含__init__.py的子目录),加载其中的BaseChannel子类,并按类的channel属性注册。安装:
qwenpaw channels install <key>会在custom_channels/下生成名为<key>.py的模板文件,可直接编辑实现;也可用--path <本地路径>或--url <URL>从本地/网络复制渠道模块。qwenpaw channels add <key>等价于安装后并写入 config 默认项,且可加--path/--url。删除:
qwenpaw channels remove <key>会从custom_channels/中删除该渠道模块(仅支持自定义渠道,内置渠道不可删);加--no-keep-config(默认)会同时从config.json的channels中移除对应 key。Config:
ChannelConfig使用extra="allow",config.json的channels下可写任意 key;自定义渠道的配置会保存在 extra 中。配置方式与内置一致:qwenpaw channels config交互式配置,或直接编辑 config。
HTTP 路由注册
对于需要 Webhook 回调的渠道(如微信、Slack、LINE 等),可以通过在模块中导出 register_app_routes 可调用对象来注册自定义 HTTP 路由,无需修改 QwenPaw 核心源码。
QwenPaw 启动时会扫描 custom_channels/ 下的模块,发现 register_app_routes 后将其与 FastAPI app 实例一起调用,渠道即可注册所需的任何路由。
路由前缀规则:
接口说明 — register_app_routes(app)
参数:
app— FastAPI 应用实例返回:None
作用域:注册路由、中间件、或 startup/shutdown 事件
错误隔离:单个渠道注册失败不影响其他渠道
最简示例 — Echo 频道:
<workspace>/ └── custom_channels/ └── my_echo/ └── __init__.py
# custom_channels/my_echo/__init__.pyfrom qwenpaw.app.channels.base import BaseChannelclass MyEchoChannel(BaseChannel): """最简单的回声频道。"""
def __init__(self, **kwargs): super().__init__(**kwargs) async def _listen(self): pass # 通过 HTTP 回调接收消息
async def _send(self, target, content, **kwargs): self.logger.info(f"Would send to {target}: {content}")def register_app_routes(app): """注册该频道的 HTTP 路由。""" @app.post("/api/my-echo/callback")
async def echo_callback(request): """Webhook 入口。"""
body = await request.json() from qwenpaw.app.channels.base import TextContent
channel = MyEchoChannel()
channel.enqueue_user_message(
user_id=body.get("user_id", "anonymous"),
session_id=body.get("session_id", "default"),
content=[TextContent(type="text", text=body.get("text", ""))],
) return {"status": "ok"}配置 agent.json:
{
"channels": {
"my_echo": {
"enabled": true
}
}}启动后测试:
curl -X POST http://localhost:8088/api/my-echo/callback \
-H "Content-Type: application/json" \
-d '{"user_id": "test", "session_id": "test", "text": "Hello!"}'实际案例:微信 ClawBot 集成(PR #2140、Issue #2043)通过此机制注册 /api/wechat/callback 路由,使用腾讯官方 SDK 处理消息投递。
