用户要求:推送密钥必须是可选项(自部署后端不能写死推送方式),且要支持 多厂商配置式接入 —— 每个用户各自部署服务器、自己选厂商、自己配凭证。 所以落地成: · internal/push:通道抽象 + 工厂表(RegisterType),加厂商不改配置层与端点形状; HMS 只是第一个实现(internal/push/hms.go) · 配置在 PUSH_CONFIG(默认 <AGENTMAIL_DATA_DIR>/push.json),一项一个厂商, 凭证走文件(app_secret_file / files.*,建议 600);环境变量只是可选覆盖 · 没配 = 整条推送路径连一次查库都不发生(shouldDispatch 早退); 单项配错(未知类型/密钥读不到/enabled:false)只跳过那一条,不影响启动 · push_tokens 表带 provider 维度 + 三个 /me/devices/push-token 端点; 没配推送时端点照存并回 enabled:false(登记成功 != 服务端开了推送) · notify.Recipients 末尾异步挂钩:收件人名单直接用 SSE 那份 seen(两条通道 共用同一份"谁该收到"的判据);失败只记日志,绝不拖住收信 HMS 的形状是拿真凭证打线上接口问出来的(v1 + message.token[] + testMessage; payload/target 形状 v1 不认、v2 要服务账号 JWT)。未上架应用必须 test_message=true, 单批 ≤10 token(MaxTokensPerRequest 声明)、每日 1000 条兜底(项目级额度)。 实测:App ID + App Secret 能换到 access_token(3600s);形状被线上服务接受。 判据:repo 6 条 + push 12 条 + handler 3 组,全部做过**变异验证** —— 过程中抓出两条假判据(异步分发与 t.Cleanup 赛跑而假绿;密钥文件优先级没被覆盖) 并补掉。Go 全量测试与 go vet 干净。 ★ 未验:端到端真机送达(需要真机 token + 客户端按 com.jianf.agentmail 重编并签名, 签名指纹还要在 AGC 登记)—— 从未真正发出过一条能到达设备的推送。 详见 docs/HMS-PUSH-PLAN.md 的「实现状态」一节。
68 lines
2.6 KiB
JSON
68 lines
2.6 KiB
JSON
{
|
||
"_说明": [
|
||
"AgentMail 推送通道配置(可选)。默认路径 <AGENTMAIL_DATA_DIR>/push.json,",
|
||
"也可用环境变量 PUSH_CONFIG 指向别处。文件不存在 = 没配推送 —— 那是正常状态,",
|
||
"服务端一切照常(SSE 仍是在线客户端的收信主通道)。",
|
||
"",
|
||
"设计要点:",
|
||
" · 多厂商:providers 是一张表,一项一个厂商(type)。同一实例可以同时接多个厂商。",
|
||
" · 配置式:加新厂商 = 服务端加一个 Factory 实现 + 一行 RegisterType,用户只改这个文件。",
|
||
" · 凭证是配置项:密钥走文件(app_secret_file 或 files.*),文件权限建议 600;",
|
||
" 不喜欢文件也可以内联 app_secret(方便临时验证,但不推荐)。",
|
||
" · 谁部署谁配:每个用户自己部署服务端、自己选厂商、自己填凭证。",
|
||
"",
|
||
"改完这个文件需要重启 gateway 生效:systemctl restart agentmail-gateway",
|
||
"(重启会打断正在跑的 worker,挑空闲时做。)"
|
||
],
|
||
|
||
"providers": [
|
||
{
|
||
"_说明": "华为 HMS Push(鸿蒙设备)。未上架应用必须 test_message=true,否则收不到。",
|
||
"type": "hms",
|
||
"name": "hms",
|
||
"enabled": true,
|
||
|
||
"app_id": "6917616450599975320",
|
||
|
||
"app_secret_file": "/etc/agentmail/hms-app-secret",
|
||
|
||
"client_config_file": "/etc/agentmail/agconnect-services.json",
|
||
|
||
"test_message": true,
|
||
|
||
"daily_limit": 1000
|
||
},
|
||
|
||
{
|
||
"_说明": [
|
||
"同一厂商接多套凭证的写法:显式给 name 区分,客户端按名字登记 token。",
|
||
"(例如同一个服务端要同时推给两个华为应用)"
|
||
],
|
||
"type": "hms",
|
||
"name": "hms-second-app",
|
||
"enabled": false,
|
||
"app_id": "0000000000000000000",
|
||
"files": {
|
||
"app_secret": "/etc/agentmail/hms-second-app.secret"
|
||
},
|
||
"test_message": true
|
||
},
|
||
|
||
{
|
||
"_说明": [
|
||
"其它厂商(Web Push / 小米 / 荣耀 …):",
|
||
"服务端需要先有该厂商的 Factory 实现(internal/push 里 RegisterType),",
|
||
"否则这一项会在启动日志里被标记为「不支持的类型,已跳过」,其余条目照常启用。",
|
||
"厂商私有的密钥类文件统一放 files 表里(键名由那个厂商的实现定义)。"
|
||
],
|
||
"type": "webpush",
|
||
"name": "webpush",
|
||
"enabled": false,
|
||
"files": {
|
||
"vapid_public_key": "/etc/agentmail/vapid.pub",
|
||
"vapid_private_key": "/etc/agentmail/vapid.pem"
|
||
}
|
||
}
|
||
]
|
||
}
|