2026-05-18 11:10:52 +08:00

4.6 KiB
Raw Blame History

Why

当前 SmsReceive 已经具备短信验证码接收、解析、存储和本地诊断能力。新需求是在收到字符串内容后,把它发送到服务器。用户已经给出 Python 参考实现,目标服务器实际是飞书机器人 webhook构造 interactive markdown 卡片,使用 timestamp + "\n" + secret 生成 HmacSHA256 + Base64 签名,然后 POST 到 https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id}

这次变更的重点不是重新设计服务端协议,而是把 Python 中已经验证过的请求协议等价迁移到 Android并与当前短信接收链路解耦。Android 侧应提供一个可测试、可诊断、可复用的发送模块,后续可以由 SmsReceiver、手动测试按钮或其它业务入口调用。

What Changes

  • 新增飞书 webhook 推送规格,覆盖:
    • 签名算法:保持与 Python generate_sign(secret, timestamp) 完全一致。
    • 请求体:保持 msg_type=interactive,卡片元素为 markdown content。
    • URLhttps://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id}
    • 网络请求Android 侧使用 OkHttp 作为首选实现,避免为了一个简单 POST 引入 Retrofit 接口层。
    • 线程模型:所有网络请求必须在后台线程执行,不能阻塞 BroadcastReceiver.onReceive 或主线程。
    • 结果判断HTTP 200 且响应 JSON code == 0 才视为成功。
    • 失败诊断区分签名失败、参数缺失、HTTP 非 200、响应 JSON 异常、飞书业务错误码、网络异常和超时。
  • 新增轻量配置入口:
    • webhook_idsecret 不写死在代码中。
    • 实际配置从 /sdcard/Android/data/{applicationId}/config/feishu.json 读取,便于动态调试。
    • 如果 feishu.json 不存在,则生成默认模板 /sdcard/Android/data/{applicationId}/config/def_config_feishu.json
  • 后续实现可接入当前短信结果:
    • 成功解析验证码后,可以把验证码摘要、来源、时间和发送方掩码作为 markdown 内容推送。
    • 按调试需求推送完整短信原文,便于确认服务端收到的内容与本机短信一致。

Capabilities

New Capabilities

  • feishu-webhook-push: 定义 Android 侧飞书机器人 webhook 推送能力,包括签名、请求体、网络执行、响应解析、错误诊断和隐私边界。

Modified Capabilities

  • sms-code-capture: 后续实现可以在验证码解析成功后触发推送,但短信捕获本身不依赖网络成功。
  • sms-receiver-delivery-diagnostics: 后续诊断应区分“短信接收/解析成功”和“远端推送成功/失败”,避免把网络失败误判为短信接收失败。

Impact

  • 预期后续会修改:
    • app/build.gradle:新增 OkHttp 依赖,必要时新增 JSON 解析依赖或使用 org.json
    • app/src/main/AndroidManifest.xml:新增 android.permission.INTERNET
    • app/src/main/java/com/smsreceive/app/:新增飞书推送相关 Java 类,例如 FeishuWebhookClientFeishuWebhookConfigStoreFeishuWebhookPushResult
    • MainActivity:新增 JSON 配置路径展示、配置输入、测试发送和最近推送结果展示。
    • SmsReceiver 或统一结果处理层:在验证码解析成功后触发异步推送。
  • 推荐技术选择:
    • 网络库OkHttp。
    • JSON 构造/解析:优先使用 Android 自带 org.json,降低依赖数量。
    • 签名:javax.crypto.Mac + SecretKeySpec + android.util.Base64.NO_WRAP
    • 异步执行:小型 ExecutorService 或现有轻量后台执行器,不引入协程/RxJava。
  • 隐私影响:
    • 默认推送验证码摘要、来源、发送方掩码、时间和短信原文。
    • 不在 logcat 打印 secret、sign、完整 webhook URL 或完整短信正文。

Validation

  • OpenSpec 文档结构完整,包含 proposal.mddesign.mdtasks.md 和 capability spec。
  • 方案必须能解释以下问题:
    • Python 签名算法如何在 Android 中等价实现。
    • 为什么首选 OkHttp 而不是 Retrofit。
    • 为什么网络请求不能直接在 BroadcastReceiver.onReceive 内同步执行。
    • 如何判断推送成功,以及失败时如何诊断。
    • 哪些短信内容可以上传,哪些默认不上传。
  • 后续代码完成后:
    • 签名单元测试使用固定 secrettimestamp 对比 Python 算法输出。
    • 请求体构造测试验证 JSON 字段与 Python 参考实现一致。
    • 响应解析测试覆盖 code == 0、业务错误码、非 JSON 响应。
    • 不要求本轮编译;代码完成后通知用户即可。
  • 每次 commit 或 push 前必须检查 diff避免引入非预期 EOF newline 变化。