Files
go-sip/cmd/saas-server/README.md
T

133 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SaaS Server:最小外呼测试工具
使用 Fiber/v3,代替浏览器操作:提供 Dispatcher 所需配置,手动向测试队列发送一条外呼,查看回执和最终结果。
**不修改 Dispatcher/Agent,不绕过它们的业务检查。启动不自动发消息。仅支持专用 `saas-mock-*` vhost,不能和真实 SaaS 共用反馈队列。** 本工具不授权真实拨号或真实 AI/OSS 调用。
## 启动
```sh
go build -o /tmp/saas-server ./cmd/saas-server
/tmp/saas-server --config /absolute/path/server.json
```
`server.json` 示例(全部为占位,须换成已批准的测试配置):
```json
{
"listen": "0.0.0.0:8089",
"dispatcher_id": "c046b893-8628-4589-ae50-619d049248a6",
"dispatcher_secret": "TEST_DISPATCHER_SECRET",
"broker_url": "amqp://TEST_USER:TEST_PASSWORD@127.0.0.1:5672/saas-mock-example",
"snapshots": "snapshots",
"feedback_dir": "feedback",
"tls_cert": "dispatcher-test.crt",
"tls_key": "dispatcher-test.key"
}
```
- 相对路径以 `server.json` 所在目录为基准。
- `listen` 省略时为 `0.0.0.0:8089`。
- TLS 两项可同时省略,服务改为 HTTP;需要遵循现有 Dispatcher 客户端的连接要求,不能为测试放松客户端校验。
- 启动文件和各快照必须是私有普通文件(如 `0600`)。反馈目录独立且私有(如 `0700`),不能与输入配置目录交叠。
- MQ 用户必须能够在这个专用 vhost 声明、绑定和使用现行拓扑。已有拓扑不匹配或已有独占反馈消费者时明确失败;不会清队列或自动恢复连接。
快照目录:
```text
snapshots/
sip.json
providers.json
quota.json
tasks/
<task_id>.json
```
JSON 内容直接采用 [`../../contracts/schema/`](../../contracts/schema/README.md) 的现行配置响应格式,不使用旧 ENV 替代。所有资源必须属于启动文件中的 Dispatcher;首期仅一个租户,任务文件名与 task_id 一致。任务列表由详情生成,不另建列表文件。
AI 连接、模型、音色、参数、SIP 线路、额度和时段来自这些文件;合同示例只是结构参考,不保证线路具备执行参数,也不是拨号授权。
另行启动使用这套测试配置及专用 MQ 的 Dispatcher/Agent;本工具不启动、停止、重启或修改现有服务。五类正式配置接口校验现有 `X-DISPATCHER-id` 和 `X-DISPATCHER-SECRET-KEY` 请求头。
## 手动发送一条外呼
以下命令以本地 HTTP 为例;启用 TLS 时改用 HTTPS 并使用测试 CA 的 `--cacert`,不要关闭证书校验。
```sh
BASE=http://127.0.0.1:8089
# 任务、号码必须是本次获准的测试数据;123456 只是占位。
curl --fail-with-body "$BASE/test/calls" \
-H 'Content-Type: application/json' \
-d '{"event_id":"test-numberID-001","task_id":"1","callee":"123456"}'
```
`event_id` 由调用者明确指定,原样保留。相同身份、相同请求在本次进程中不再发送;同身份不同内容报错。重启会清除发送记录,**不要通过重启、换 ID 或重复调用补拨**;Dispatcher 的既有重复消息规则不变。
响应中的 `status`:
| 值 | 含义 |
| --- | --- |
| `confirmed` | 队列已确认,不表示已拨号或已接通 |
| `unroutable` | 消息被队列退回,没有对应路由 |
| `rejected` | 队列明确拒绝 |
| `not_sent` | 发送前失败 |
| `unknown` | 是否发送成功不确定;禁止自动重发 |
非 `confirmed` 返回 HTTP 503,并保留本次状态。输入错误返回 HTTP 400。工具没有自动重试、批量、定时或换线功能。
## 查询和校验反馈
```sh
curl --fail-with-body --get "$BASE/test/events" \
--data-urlencode 'event_id=test-numberID-001'
```
返回本次进程内的 `requests` 与 `feedback`。派发回执和最终结果分别记录;`validation` 为 `valid` 或 `invalid`,错误原因会明确显示。等待不到反馈不等于通话失败,只有拒绝的未发起请求不一定有通话最终结果。
查询只返回身份、状态、结果及校验摘要,不显示完整对话/音频等正文。收到的原消息保存在独立反馈目录的随机 `feedback-*.json` 文件中,文件保存并同步成功后才 ACK。保存失败停止消费并退出,不丢弃消息。重复或错误消息也保留证据,冲突不覆盖原记录。
**重启后不恢复历史查询;旧反馈文件仍保留,供人工检查。本工具不会回写配置,也不会保存内存修改。**
## 内存修改配置
使用完整配置响应,不使用 PATCH 或字段合并:
```sh
curl --fail-with-body -X PUT "$BASE/test/config/sip" \
-H 'Content-Type: application/json' --data-binary @/path/candidate-sip.json
curl --fail-with-body -X PUT "$BASE/test/config/providers" \
-H 'Content-Type: application/json' --data-binary @/path/candidate-providers.json
curl --fail-with-body -X PUT "$BASE/test/config/quota" \
-H 'Content-Type: application/json' --data-binary @/path/candidate-quota.json
curl --fail-with-body -X PUT "$BASE/test/config/tasks/1" \
-H 'Content-Type: application/json' --data-binary @/path/candidate-task.json
```
校验成功后整体替换内存,失败不改变当前值。只能修改已加载资源,不能增删任务或更换租户/Dispatcher 身份。重启重新加载原文件。
修改配置不会自动通知 Dispatcher,需要显式操作:
```sh
# action 只支持 start、resume、edit;每条指令使用明确的源 event_id。
curl --fail-with-body "$BASE/test/task-controls" \
-H 'Content-Type: application/json' \
-d '{"event_id":"test-edit-001","task_id":"1","action":"edit","reason":"test configuration change"}'
# change_type 按现行合同:enabled、disabled、removed、created;revision 为正整数。
curl --fail-with-body "$BASE/test/sip-refresh" \
-H 'Content-Type: application/json' \
-d '{"event_id":"test-sip-001","trunk_id":"trunk-mock","change_type":"enabled","revision":8}'
```
任务/额度按现行 start/resume/edit 流程读取,edit 不解除暂停、不恢复已停止任务。SIP 通知触发现行加载流程;已经发出的通话不改变快照。AI providers 只在 Dispatcher 启动读取,修改后须另行安排重启;本工具不重启服务。
## 本地验证
```sh
go test -race ./cmd/saas-server
# 需 Docker 和已存在的 rabbitmq:4.1-management-alpine 镜像,不自动拉取。
bash cmd/saas-server/check-integration.sh
```
集成脚本只创建并清理自己的临时 RabbitMQ 容器,运行 Fiber HTTPS → RabbitMQ → 未修改的 Dispatcher → Mock Agent mTLS → 回执/最终结果测试。使用临时配置、数据库和合成音频,不拨号,不访问真实 AI/OSS。通过不代表真实服务或通话验收。