87 lines
5.6 KiB
Markdown
87 lines
5.6 KiB
Markdown
**Push Server - 使用与变更说明**
|
||
|
||
简要说明
|
||
- 该文档记录对 `server/push-server.js` 的修改、运行所需的环境变量、表结构依赖、以及如何把 Supabase 的 cid 与通知通过 dCloud UNI‑PUSH 下发的端到端操作步骤。
|
||
|
||
变更要点(代码修改摘要)
|
||
- supaFetch: 默认仅发送 `apikey`;仅当 `SUPA_USE_BEARER=true` 或 `SUPA_KEY` 看起来像 JWT(包含两处 ".")时,才发送 `Authorization: Bearer`。避免把明文 service key 当作 JWT 发出导致 PostgREST 拒绝。
|
||
- 新增 endpoint `/api/v1/notifications`:将通知写入 `express_notifications`,根据 `aud` 与 `recipient_id` 查询 `push_devices`,再发送推送(proxy 或 mock),并写回通知状态。
|
||
- 新增 uni-push adapter `sendToUniPush(targets, notification, payload)`:当设置了 `UNI_PUSH_URL` 时,`/api/v1/push/send` 与 `/api/v1/notifications` 会调用该适配器优先发送到 UNI‑PUSH;否则若设置了 `PUSH_PROXY_URL` 则转发到该 URL。
|
||
|
||
新增/修改的接口(简要)
|
||
- GET `/health` — 健康检查。
|
||
- POST `/api/v1/push/register` — 注册/更新设备;会写本地 `server/data/push_devices.json`,并尝试 upsert 到 Supabase `push_devices` 表(如果配置了 SUPA_URL + SERVICE_ROLE_KEY)。
|
||
- POST `/api/v1/push/unregister` — 注销设备(本地并尝试同步 Supabase)。
|
||
- GET `/api/v1/push/devices` — 列出设备(优先从 Supabase 获取)。
|
||
- POST `/api/v1/push/send` — 直接按 `cids` 或 `user_id` 发送推送;若 `UNI_PUSH_URL` 存在使用 adapter,否则若 `PUSH_PROXY_URL` 存在转发,默认 mock 返回。
|
||
- POST `/api/v1/notifications` — 将通知写入 `express_notifications` 并基于 `aud`/`recipient_id` 拉取 `push_devices` 发推送,成功/失败状态写回 `express_notifications.status_code`。
|
||
|
||
依赖的数据库表(必须存在)
|
||
- `public.push_devices`:用于存储设备 cid、user_id/merchant_id、is_active 等(见仓库迁移脚本 `20260224_add_push_devices_and_notifications.sql`)。
|
||
- `public.express_notifications`:用于保存通知记录与状态(见迁移脚本)。
|
||
|
||
关键环境变量(示例与说明)
|
||
- SUPA_URL — Supabase REST(PostgREST)地址(内部建议 `http://rest:3000`)。
|
||
- SERVICE_ROLE_KEY 或 SUPA_KEY — 用作 `apikey` 向 PostgREST 请求(不要把明文放到 Authorization 除非该值确为 JWT)。
|
||
- SUPA_USE_BEARER — (可选) 若为 `true` 则强制发送 Authorization: Bearer <SUPA_KEY>。
|
||
- UNI_PUSH_URL — (可选) 若设置则使用内置 `sendToUniPush` adapter 直接调用 dCloud uni-push 接口。
|
||
- UNI_PUSH_APPID / UNI_PUSH_SECRET — adapter 用于构造或鉴权(按你现有 uni-push 接口调整)。
|
||
- PUSH_PROXY_URL / PUSH_PROXY_TOKEN — 若不使用 adapter,可把此设置为你现有的推送代理 URL 与 token,后端会将 {targets, notification, payload} 转发过去。
|
||
- PUSH_PROXY_URL 优先级低于 UNI_PUSH_URL:若 UNI_PUSH_URL 存在,优先使用本地 adapter。
|
||
|
||
运行与测试(本地示例)
|
||
1) 安装依赖并启动:
|
||
```bash
|
||
cd server
|
||
npm install express body-parser cors node-fetch
|
||
SUPA_URL='http://rest:3000' SERVICE_ROLE_KEY='PASTE_SERVICE_ROLE_KEY' node push-server.js
|
||
```
|
||
|
||
2) 健康检查:
|
||
```bash
|
||
curl http://localhost:7301/health
|
||
# 返回 {"ok":true}
|
||
```
|
||
|
||
3) 注册设备(后端会写本地并尝试写 Supabase):
|
||
```bash
|
||
curl -X POST http://localhost:7301/api/v1/push/register \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"cid":"test-cid-1","user_id":"<USER_UUID>","platform":"android"}'
|
||
```
|
||
|
||
4) 按 user 发通知(写入 express_notifications 并触发推送):
|
||
```bash
|
||
curl -X POST http://localhost:7301/api/v1/notifications \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"aud":"user","recipient_id":"<USER_UUID>","notification":{"title":"测试","body":"uni-push 测试"}}'
|
||
```
|
||
|
||
5) 直接按 cid 发(跳过 DB):
|
||
```bash
|
||
curl -X POST http://localhost:7301/api/v1/push/send \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"cids":["test-cid-1"],"notification":{"title":"hi","body":"msg"}}'
|
||
```
|
||
|
||
UNI‑PUSH 集成注意事项
|
||
- adapter 当前构造 body 使用 `cidList` 与 `message:{title,content,payload}`。请根据你已经验证成功的 uni-push curl 请求体调整字段名与鉴权 header(可使用 `UNI_PUSH_APPID`、`UNI_PUSH_SECRET`、或 `PUSH_PROXY_TOKEN`)。
|
||
- 建议:把你成功的 uni-push curl 发给我,我可以把 adapter 的 body/header 精确改成一致格式。
|
||
|
||
故障与排查要点
|
||
- 如果 Supabase 报 401 或 PGRST301:不要把明文 service key 作为 Bearer;使用 `apikey` header,或生成并使用与 `PGRST_JWT_SECRET` 匹配的 JWT。可通过 `docker inspect` 检查容器 env 中的 `PGRST_JWT_SECRET`。
|
||
- 如果 `/rest/v1/push_devices` 返回 404:确认表名在 `public` schema 中并加载,或调整请求前缀。
|
||
- 查看 push-server 控制台输出中的 `supaFetch` warn 和 proxy 响应体以获取具体错误信息。
|
||
|
||
后续建议(可选实现)
|
||
- 将 `express_notifications` 增加 `attempts`、`error`、`sent_at` 字段以支持重试与错误记录;可实现后台 worker 或 pg_notify+listener 做可靠投递与重试。
|
||
- 为 `/api/v1/push/send` 与 `/api/v1/notifications` 添加管理员鉴权(例如 `PUSH_ADMIN_KEY`)以限制谁能发送通知。
|
||
|
||
文件位置
|
||
- 文档:[server/PUSH_SERVER_README.md](server/PUSH_SERVER_README.md)
|
||
- 代码:[server/push-server.js](server/push-server.js)
|
||
|
||
如果需要,我可以:
|
||
- 把 adapter 的请求体精确匹配你现有成功的 uni-push curl(请把 curl 发来);或
|
||
- 为通知添加重试/记录字段并实现简单重试机制。
|