394 lines
12 KiB
Markdown
394 lines
12 KiB
Markdown
# FakeMessagePlatform 手工测试指南
|
||
|
||
> 基于 `docs/plans/2026-07-09-brainstorming-fake-message-platform.md` 和 `docs/qa/2026-07-09-test-plan-round5.md`
|
||
> 适用于开发者本地手工验证 FakeMessagePlatform 全链路消息流。
|
||
|
||
---
|
||
|
||
## 前置条件
|
||
|
||
1. PostgreSQL 16 + pgvector 运行在 `localhost:5444`,数据库 `gochat_dev` 已初始化
|
||
2. Redis 运行在 `localhost:6379`
|
||
3. Go 1.24+ 和 Node.js 20+ / pnpm 10+ 已安装
|
||
4. 仓库根目录执行过 `pnpm install`
|
||
5. 种子数据已加载(`admin@gochat.local / changeme` 账号存在)
|
||
|
||
---
|
||
|
||
## Step 1:启动三个服务
|
||
|
||
打开三个终端窗口:
|
||
|
||
```bash
|
||
# 终端 1:GoChat 后端 (:3000)
|
||
cd /home/yanghao05/Projects/gochat
|
||
export GOROOT=/usr/lib/go-1.24 && export PATH=$GOROOT/bin:/home/yanghao05/.local/node-v22.20.0-linux-x64/bin:$PATH
|
||
export GOMODCACHE=/home/yanghao05/go/pkg/mod
|
||
pnpm dev:backend
|
||
|
||
# 终端 2:前端 Vite (:3036)
|
||
cd /home/yanghao05/Projects/gochat
|
||
export PATH="/home/yanghao05/.local/node-v22.20.0-linux-x64/bin:$PATH"
|
||
cd frontend && npx vite --port 3036
|
||
|
||
# 终端 3:FakeMessagePlatform (:9100)
|
||
cd /home/yanghao05/Projects/gochat
|
||
export PATH="/home/yanghao05/.local/node-v22.20.0-linux-x64/bin:$PATH"
|
||
cd channels/fake && npx tsx src/index.ts
|
||
```
|
||
|
||
等待 10-15 秒,然后验证三个服务健康:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:3000/health # 预期: {"status":"ok",...}
|
||
curl -o /dev/null -w '%{http_code}' http://127.0.0.1:3036/ # 预期: 200
|
||
curl http://127.0.0.1:9100/health # 预期: {"status":"ok","service":"fake-message-platform"}
|
||
```
|
||
|
||
三个都通过才能继续。
|
||
|
||
---
|
||
|
||
## Step 2:通过前端 UI 创建 Fake 渠道 Inbox
|
||
|
||
1. 浏览器打开 `http://127.0.0.1:3036/app/login`
|
||
2. 登录:`admin@gochat.local` / `changeme`
|
||
3. 左侧栏点击「设置」展开子菜单
|
||
4. 点击「收件箱」
|
||
5. 点击「添加收件箱」
|
||
6. 在渠道选择页面找到「Fake 测试平台」卡片,点击
|
||
7. 填写表单:
|
||
- 频道名称:`Fake Test Inbox`
|
||
- 标识符 (Identifier):`fake_test_1`
|
||
- Webhook URL:`http://127.0.0.1:9100/receive`
|
||
- Token:`fake_test_token`
|
||
8. 点击「创建 Fake 频道」
|
||
9. 在 agent 分配页面添加 admin 到此 inbox
|
||
10. 返回收件箱列表,确认 "Fake Test Inbox" 出现在列表中
|
||
|
||
如果前端 UI 因浏览器问题不稳定,可以用 API 替代:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:3000/api/v1/accounts/1/inboxes \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-User-ID: 1" -H "X-Account-ID: 1" \
|
||
-d '{
|
||
"name": "Fake Test Inbox",
|
||
"channel": {
|
||
"type": "fake",
|
||
"identifier": "fake_test_1",
|
||
"webhook_url": "http://127.0.0.1:9100/receive",
|
||
"token": "fake_test_token"
|
||
}
|
||
}'
|
||
```
|
||
|
||
预期返回 JSON 中 `channel_type: "fake"`,`id: 2`(或更大)。
|
||
|
||
---
|
||
|
||
## Step 3:配置 FakeMessagePlatform 的 GoChat webhook URL
|
||
|
||
FakeMessagePlatform 需要知道 GoChat 的 webhook 端点和 token:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:9100/api/config \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"webhook_url":"http://127.0.0.1:3000/webhooks/fake/fake_test_1","token":"fake_test_token"}'
|
||
```
|
||
|
||
预期返回:`{"status":"ok"}`
|
||
|
||
> 如果启动 FakeMessagePlatform 时已经设置了环境变量 `GOCHAT_WEBHOOK_URL` 和 `GOCHAT_FAKE_TOKEN`,
|
||
> 则此步可跳过。但默认 URL 用的是 `fake_inbox_1`,需要改成你实际创建的 identifier。
|
||
|
||
---
|
||
|
||
## Step 4:连通性测试
|
||
|
||
发送一条测试消息,验证 FakeMessagePlatform → GoChat 的链路通畅:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:9100/api/send \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"inbox_identifier":"fake_test_1","sender_id":"smoke_test","sender_name":"连通性测试","content":"ping"}'
|
||
```
|
||
|
||
预期返回:
|
||
```json
|
||
{"status":"sent","message_id":"fake_msg_...","gochat_status":200}
|
||
```
|
||
|
||
检查 FakeMessagePlatform 状态:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:9100/api/status
|
||
```
|
||
|
||
预期 `total_sent >= 1`。
|
||
|
||
如果 `gochat_status` 不是 200,说明 webhook 未正确接收。检查:
|
||
- FakeMessagePlatform 的 webhook_url 是否指向正确的 identifier
|
||
- GoChat 后端日志是否出现 "Fake webhook received"(注意:后端 worker pool 日志很多,需要过滤查找)
|
||
|
||
---
|
||
|
||
## Step 5:入站消息 — 客户发消息 → GoChat 创建会话
|
||
|
||
模拟客户"测试客户A"发一条消息:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:9100/api/send \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001","sender_name":"测试客户A","content":"你好,我需要帮助"}'
|
||
```
|
||
|
||
验证:
|
||
1. 前端 Dashboard 应出现新会话(如果前端打开了的话)
|
||
2. 通过 API 确认会话和消息已创建:
|
||
|
||
```bash
|
||
# 查看最新会话(替换 ID 为实际的会话 ID)
|
||
curl -s "http://127.0.0.1:3000/api/v1/accounts/1/conversations/4" \
|
||
-H "X-User-ID: 1" -H "X-Account-ID: 1" | python3 -m json.tool | head -30
|
||
```
|
||
|
||
3. 或直接查数据库确认:
|
||
|
||
```bash
|
||
PGPASSWORD=xiha02 psql -h 127.0.0.1 -p 5444 -U postgres -d gochat_dev -c \
|
||
"SELECT id, content, sender_type, source_id FROM messages WHERE inbox_id=2 ORDER BY id DESC LIMIT 5"
|
||
```
|
||
|
||
预期:看到 content="你好,我需要帮助",sender_type="contact",source_id 以 "fake_msg_" 开头。
|
||
|
||
---
|
||
|
||
## Step 6:出站消息 — 客服回复 → FakeMessagePlatform 收到
|
||
|
||
模拟客服在会话中回复(替换 `4` 为实际的会话 ID):
|
||
|
||
```bash
|
||
curl -X POST "http://127.0.0.1:3000/api/v1/accounts/1/conversations/4/messages" \
|
||
-H "X-User-ID: 1" -H "X-Account-ID: 1" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"content":"您好,有什么可以帮您?","message_type":"outgoing","private":false}'
|
||
```
|
||
|
||
验证 FakeMessagePlatform 收到了出站消息:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:9100/api/messages?inbox_identifier=fake_test_1
|
||
```
|
||
|
||
预期返回的 `received` 数组中包含 content="您好,有什么可以帮您?",sender.type 为 "agent"。
|
||
|
||
这一步验证了完整的双向消息流:
|
||
```
|
||
客户消息 → FakeMsgPlatform → GoChat webhook → 创建会话/消息
|
||
客服回复 → GoChat API → FakeProvider.SendMessage → POST /receive → FakeMsgPlatform 存储
|
||
```
|
||
|
||
---
|
||
|
||
## Step 7:多客户并发会话
|
||
|
||
模拟两个不同客户同时发消息:
|
||
|
||
```bash
|
||
# 客户 B
|
||
curl -X POST http://127.0.0.1:9100/api/send \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"inbox_identifier":"fake_test_1","sender_id":"customer_002","sender_name":"测试客户B","content":"退款咨询"}'
|
||
|
||
# 客户 C
|
||
curl -X POST http://127.0.0.1:9100/api/send \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"inbox_identifier":"fake_test_1","sender_id":"customer_003","sender_name":"测试客户C","content":"技术支持"}'
|
||
```
|
||
|
||
验证创建了独立的会话:
|
||
|
||
```bash
|
||
PGPASSWORD=xiha02 psql -h 127.0.0.1 -p 5444 -U postgres -d gochat_dev -c \
|
||
"SELECT c.id, c.status, ct.name FROM conversations c JOIN contacts ct ON c.contact_id=ct.id WHERE c.inbox_id=2 ORDER BY c.id"
|
||
```
|
||
|
||
预期:每个 sender_id 对应一个独立的会话和联系人。
|
||
|
||
---
|
||
|
||
## Step 8:打字状态指示
|
||
|
||
模拟客户正在打字:
|
||
|
||
```bash
|
||
# 开始打字
|
||
curl -X POST http://127.0.0.1:9100/api/typing \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001","typing":true}'
|
||
|
||
# 停止打字
|
||
curl -X POST http://127.0.0.1:9100/api/typing \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001","typing":false}'
|
||
```
|
||
|
||
预期:两次请求都返回 `{"status":"sent","typing":true/false}`。
|
||
|
||
---
|
||
|
||
## Step 9:关闭聊天窗口
|
||
|
||
模拟客户关闭聊天窗口(发送 session.end 事件):
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:9100/api/close \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"inbox_identifier":"fake_test_1","sender_id":"customer_001"}'
|
||
```
|
||
|
||
验证 GoChat 创建了 "[session ended]" 系统消息:
|
||
|
||
```bash
|
||
PGPASSWORD=xiha02 psql -h 127.0.0.1 -p 5444 -U postgres -d gochat_dev -c \
|
||
"SELECT id, content, source_id FROM messages WHERE content='[session ended]' AND inbox_id=2"
|
||
```
|
||
|
||
预期:至少一条记录,source_id 以 "fake_close_" 开头。
|
||
|
||
---
|
||
|
||
## Step 10:消息附件
|
||
|
||
发送带图片附件的消息:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:9100/api/send \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"inbox_identifier":"fake_test_1",
|
||
"sender_id":"customer_001",
|
||
"sender_name":"测试客户A",
|
||
"content":"请看这张截图",
|
||
"content_type":"image",
|
||
"attachments":[{
|
||
"url":"http://example.com/screenshot.png",
|
||
"content_type":"image/png",
|
||
"filename":"screenshot.png",
|
||
"file_size":102400
|
||
}]
|
||
}'
|
||
```
|
||
|
||
验证消息以 image 类型创建:
|
||
|
||
```bash
|
||
PGPASSWORD=xiha02 psql -h 127.0.0.1 -p 5444 -U postgres -d gochat_dev -c \
|
||
"SELECT id, content_type, content_attributes FROM messages WHERE inbox_id=2 AND content_type='image' ORDER BY id DESC LIMIT 3"
|
||
```
|
||
|
||
预期:content_type 为 "image",content_attributes 中包含附件 URL。
|
||
|
||
---
|
||
|
||
## Step 11:客服上下线状态(FakeMessagePlatform 侧记录)
|
||
|
||
模拟客服上线和下线(这些是 FakeMessagePlatform 内存中记录的状态,供测试脚本查询):
|
||
|
||
```bash
|
||
# 客服上线
|
||
curl -X POST http://127.0.0.1:9100/api/agent/online \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"agent_id":"1","agent_name":"Admin"}'
|
||
|
||
# 查看状态
|
||
curl http://127.0.0.1:9100/api/status
|
||
# 预期:online_agents 中包含 agent_id="1"
|
||
|
||
# 客服下线
|
||
curl -X POST http://127.0.0.1:9100/api/agent/offline \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"agent_id":"1"}'
|
||
|
||
# 再次查看状态
|
||
curl http://127.0.0.1:9100/api/status
|
||
# 预期:online_agents 为空
|
||
```
|
||
|
||
---
|
||
|
||
## Step 12:重置状态(可选)
|
||
|
||
在每次测试前重置 FakeMessagePlatform 的内存状态:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:9100/api/reset
|
||
```
|
||
|
||
预期返回 `{"status":"ok"}`,之后 `/api/status` 显示所有计数为 0。
|
||
|
||
---
|
||
|
||
## 验证清单
|
||
|
||
- [ ] 三个服务全部启动且健康检查通过
|
||
- [ ] Fake Inbox 成功创建(channel_type=fake)
|
||
- [ ] FakeMessagePlatform webhook URL 已正确配置
|
||
- [ ] 连通性测试:发消息 → GoChat 返回 200
|
||
- [ ] 入站消息:客户发消息 → 创建 Contact + Conversation + Message
|
||
- [ ] 出站消息:客服回复 → FakeMessagePlatform /receive 收到
|
||
- [ ] 多客户并发:每个客户独立会话
|
||
- [ ] 打字状态:typing true/false 事件成功发送
|
||
- [ ] 会话关闭:"[session ended]" 消息创建
|
||
- [ ] 消息附件:image 类型消息正确创建
|
||
- [ ] 客服上下线:FakeMessagePlatform 状态正确记录
|
||
|
||
---
|
||
|
||
## 常见问题排查
|
||
|
||
### Q: FakeMessagePlatform 发消息返回 gochat_status 非 200
|
||
|
||
检查 FakeMessagePlatform 的 webhook URL:
|
||
```bash
|
||
curl http://127.0.0.1:9100/api/status
|
||
```
|
||
确认 webhook_url 指向 `http://127.0.0.1:3000/webhooks/fake/<你的identifier>`。
|
||
|
||
### Q: GoChat webhook 返回 200 但没有创建会话
|
||
|
||
FakeWebhookHandler 在出错时也返回 200(遵循 webhook 惯例)。检查后端日志:
|
||
```bash
|
||
# 在后端终端中查找 "Fake webhook" 相关日志
|
||
# 注意 worker pool 的 "record not found" 日志是正常噪音,不影响消息流
|
||
```
|
||
或直接查数据库确认消息是否已写入。
|
||
|
||
### Q: 客服回复没有到达 FakeMessagePlatform
|
||
|
||
确认 Fake Inbox 的 channel_config 中 webhook_url 指向 FakeMessagePlatform 的 /receive:
|
||
```bash
|
||
PGPASSWORD=xiha02 psql -h 127.0.0.1 -p 5444 -U postgres -d gochat_dev -c \
|
||
"SELECT channel_config FROM inboxes WHERE channel_type='fake'"
|
||
```
|
||
预期 webhook_url 为 `http://127.0.0.1:9100/receive`。
|
||
|
||
### Q: Meilisearch 连接失败
|
||
|
||
后端日志中可能出现 `meilisearch index document: ... connection refused`。这是因为 Meilisearch 未运行,搜索索引后台 job 会失败但**不影响消息收发**。如需完整搜索功能:
|
||
```bash
|
||
# 可选:启动 Meilisearch
|
||
cd /home/yanghao05/Projects/gochat/deploy/quickstart && docker compose up -d meilisearch
|
||
```
|
||
|
||
---
|
||
|
||
## 停止服务
|
||
|
||
测试完成后,在各终端按 Ctrl+C 停止服务。或批量停止:
|
||
|
||
```bash
|
||
kill $(lsof -t -i:3000 -i:3036 -i:9100) 2>/dev/null
|
||
```
|