Uni‑Push2 云函数化指南

概述
- 后台实现概览：
  - `webhook-receiver`（pages/mall/delivery/webhook-server）：接收第三方/Mock Webhook，验签并写入 `platform_express_tracking_events`（原始留痕 `platform_express_event_raw`）。
  - `notify_queue`（或触发器）：新事件入队，作为消息生成的可靠中间件。
  - `notify-worker.js`：消费 `notify_queue`，为每个收件人生成/upsert 到 `express_notifications`（含 `message_id`/`dedupe_key`、`event_text_safe` 等）。
  - `push-server.js`：提供设备管理 API（`push/register` 等）并作为推送消费者（轮询 `express_notifications`），对每个目标 `cid` POST 到配置的 `CLOUD_FUNC_URL`（云函数），或在非云函数模式下调用推送通道。
  - 云函数（Uni‑Push2）：实际负责把推送请求转为厂商推送（uni-push2 / 小米 / 华为 等），并返回调用结果；云函数应做鉴权、日志与重试上报。

云函数化的目标
- 把设备下发逻辑从后端移到可托管的云函数，降低后端对第三方 SDK 的依赖，便于横向扩展与运维隔离。

云函数实现要点（示例流程）
1) 接收：`push-server` 对每个 `cid` 发起 POST 到 `CLOUD_FUNC_URL`，body 包含：`token, push_clientid, title, content, payload`。
2) 云函数处理：
   - 兼容各云厂商：若 `event.body` 为字符串，先 JSON.parse；兼容 `event` 直接对象场景。
   - 鉴权：校验 `event.token` 与环境变量 `PUSH_TOKEN`。
   - 校验：要求 `push_clientid` 存在，否则返回 4xx。
   - 调用 uni-push2：用云端可用的 SDK 或 HTTP 接口下发推送（参见示例代码）。
   - 返回统一响应：HTTP 2xx + JSON { errCode:0, errMsg:'success' } 表示成功。

云函数示例（Node.js，需按云平台调整）

```javascript
// index.js
const fetch = require('node-fetch'); // 如果云平台不提供 fetch
module.exports.main = async (event, context) => {
  let input = event || {};
  if (typeof input.body === 'string') {
    try { input = JSON.parse(input.body); } catch (e) { /* ignore */ }
  }

  const { token, push_clientid, title, content, payload } = input;
  if (process.env.PUSH_TOKEN && token !== process.env.PUSH_TOKEN) {
    return { errCode:401, errMsg:'unauthorized' };
  }
  if (!push_clientid) return { errCode:400, errMsg:'push_clientid required' };

  // TODO: 替换为你云函数环境支持的 uni-push2 调用
  // 示例：调用一个第三方/自托管的推送服务 API
  const uniPushUrl = process.env.UNI_PUSH_API_URL; // 可选：如果使用自建转发层
  const body = {
    appid: process.env.UNI_PUSH_APPID,
    clientid: push_clientid,
    title, content, payload
  };

  try {
    // 如果你在云函数中安装了 uni-push2 SDK，请在此调用 SDK
    // 下面为通用 fetch 示例（替换为真实厂商 API）
    const r = await fetch(uniPushUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    });
    const txt = await r.text();
    if (!r.ok) return { errCode: 500, errMsg: 'push-failed', detail: txt };
    return { errCode:0, errMsg:'success', data: txt };
  } catch (e) {
    return { errCode:500, errMsg:'exception', detail: e && e.message };
  }
};
```

依赖与打包
- 两种方式：
  1) 使用仓库已有的 `server/tools/deploy-cloudfunc.js` 自动打包并上传（推荐）：
     - 在 `server` 目录安装依赖：`npm install archiver node-fetch form-data`（如脚本需要）。
     - 配置环境变量 `CLOUD_UPLOAD_URL`、`CLOUD_UPLOAD_TOKEN`（按脚本要求），运行：
       ```powershell
       cd server
       node tools/deploy-cloudfunc.js --upload
       ```
     - 脚本会把 `uniCloud-alipay/cloudfunctions/testUnipush2` 打包为 ZIP 并上传。
  2) 手工打包上传：将云函数目录打包为 zip，使用云厂商控制台或 API 上传并发布。

必备环境变量（运行时）
- `PUSH_TOKEN`：云函数鉴权 token（与 `push-server` 中传出的 token 一致）。
- `UNI_PUSH_APPID` / `UNI_PUSH_SECRET`（如厂商需要）。
- `UNI_PUSH_API_URL`：可选；当云函数以 HTTP 方式调用第三方推送代理时使用。

测试方法
- 本地快速测试（若云函数开放公网可访问）：
```bash
curl -X POST https://your-cloudfunc.example/handle \
  -H "Content-Type: application/json" \
  -d '{"token":"<PUSH_TOKEN>","push_clientid":"CID_TEST","title":"测试","content":"hello","payload":{}}'
```
- PowerShell 注意 UTF-8 编码，避免中文变成问号：
```powershell
$json = '{"token":"<PUSH_TOKEN>","push_clientid":"CID_TEST","title":"测试","content":"内容"}'
$bytes = [System.Text.Encoding]::UTF8.GetBytes($json)
Invoke-RestMethod -Uri 'https://your-cloudfunc.example/handle' -Method POST -ContentType 'application/json; charset=utf-8' -Body $bytes
```

运维与监控建议
- 日志：云函数应把每次调用的 request/response 摘要记录到云日志（包括 `push_clientid`、status、耗时、ret code），便于排查。不要在日志中输出完整敏感 payload。 
- 重试：`push-server` consumer 应实现指数退避的重试；云函数若返回非 2xx，被视为失败并重试。云函数内部也应对推送通道失败做重试或将错误上报。
- 鉴权与安全：`PUSH_TOKEN` 放在云函数的环境变量中并由 `push-server` 透传；上传/部署脚本的 `CLOUD_UPLOAD_TOKEN` 等密钥使用 CI Secrets。

常见坑
- Cloud 函数平台把请求体放在 `event.body`（字符串）——必须解析。示例代码已处理此场景。
- PowerShell 发送 JSON 时编码问题，导致中文变问号——请用 UTF-8 bytes 或 `curl.exe`。
- 若云函数调用 uni-push SDK，需要在函数包中包含对应 SDK 并在打包时一并上传。

参考文件
- push-server 实现：server/push-server.js
- notify-worker：server/notify-worker.js
- 云函数目录（示例）：uniCloud-alipay/cloudfunctions/testUnipush2
- 自动部署脚本：server/tools/deploy-cloudfunc.js


---
作者：自动生成文档（可手动微调）
日期：2026-03-11
