5.6 KiB
5.6 KiB
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 到 Supabasepush_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 — (可选) 若设置则使用内置
sendToUniPushadapter 直接调用 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。
运行与测试(本地示例)
- 安装依赖并启动:
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
- 健康检查:
curl http://localhost:7301/health
# 返回 {"ok":true}
- 注册设备(后端会写本地并尝试写 Supabase):
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"}'
- 按 user 发通知(写入 express_notifications 并触发推送):
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 测试"}}'
- 直接按 cid 发(跳过 DB):
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;使用
apikeyheader,或生成并使用与PGRST_JWT_SECRET匹配的 JWT。可通过docker inspect检查容器 env 中的PGRST_JWT_SECRET。 - 如果
/rest/v1/push_devices返回 404:确认表名在publicschema 中并加载,或调整请求前缀。 - 查看 push-server 控制台输出中的
supaFetchwarn 和 proxy 响应体以获取具体错误信息。
后续建议(可选实现)
- 将
express_notifications增加attempts、error、sent_at字段以支持重试与错误记录;可实现后台 worker 或 pg_notify+listener 做可靠投递与重试。 - 为
/api/v1/push/send与/api/v1/notifications添加管理员鉴权(例如PUSH_ADMIN_KEY)以限制谁能发送通知。
文件位置
如果需要,我可以:
- 把 adapter 的请求体精确匹配你现有成功的 uni-push curl(请把 curl 发来);或
- 为通知添加重试/记录字段并实现简单重试机制。