# 回调告警转短信服务 本项目是一个 Python 后端服务,用于接收 AI 视频分析平台的 HTTP 回调,并将关键告警信息转为阿里云短信发送给手机号列表。 ## 启动指令 pip install -r requirements.txt py -m uvicorn app.main:app --host 0.0.0.0 --port 2336 核心目标: 1. 接收并解析上游回调 JSON。 2. 生成短信模板变量 ACTION。 3. 查询 SQLite 中已启用手机号并群发。 4. 记录可追踪日志,返回标准化接口结果。 ## 1. 功能概览 服务提供两个接口: 1. GET /healthz:健康检查。 2. POST /callback:接收告警回调并触发短信逻辑。 POST /callback 的处理流程: 1. 解析 JSON(支持常见编码容错)。 2. 提取事件标识 event_id(优先 snowflake_id,其次 analysis_job_id)。 3. 脱敏写日志(图片 base64、密钥等敏感字段不落盘)。 4. 生成短信预览文本:发现有${ACTION}行为,请去摄像头查看。 5. 查询 SQLite 中 is_enabled=1 的手机号。 6. 根据 LOG_ONLY_NO_SMS 决定仅预览还是实际调用阿里云接口。 7. 返回统一结构:code、message、data。 ## 2. 环境准备 在项目根目录执行: ```bash pip install -r requirements.txt ``` 推荐 Python 3.11+。 ## 3. 配置说明 项目默认通过 .env 读取配置,主要参数如下: 1. ALIBABA_CLOUD_ACCESS_KEY_ID:阿里云 AK。 2. ALIBABA_CLOUD_ACCESS_KEY_SECRET:阿里云 SK。 3. ALIBABA_CLOUD_REGION_ID:区域,默认 cn-hangzhou。 4. ALIYUN_SMS_SIGN_NAME:已审核通过的短信签名。 5. ALIYUN_SMS_TEMPLATE_CODE:短信模板编码。 6. SMS_DB_PATH:SQLite 数据库路径,默认 data/sms_receivers.db。 7. SMS_DB_TABLE:手机号表名,默认 sms_receivers。 8. LOG_ONLY_NO_SMS:是否仅预览不实发。 LOG_ONLY_NO_SMS 取值建议: 1. true:联调阶段使用,不调用阿里云发送。 2. false:生产或实发测试使用,会真实发送短信。 ## 4. 手机号来源与优先级 服务启动时会自动创建手机号表(如果不存在): ```sql CREATE TABLE IF NOT EXISTS sms_receivers ( id INTEGER PRIMARY KEY AUTOINCREMENT, phone_number TEXT NOT NULL UNIQUE, is_enabled INTEGER NOT NULL DEFAULT 1, updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP ); ``` 接收方选择规则: 1. 仅使用 SQLite 中 is_enabled=1 的手机号。 这意味着你在服务运行期间修改数据库,下一次 callback 会立即生效,无需重启。 常用维护 SQL: ```sql INSERT INTO sms_receivers (phone_number, is_enabled) VALUES ('17394641215', 1); UPDATE sms_receivers SET is_enabled = 0, updated_at = CURRENT_TIMESTAMP WHERE phone_number = '17394641215'; DELETE FROM sms_receivers WHERE phone_number = '17394641215'; ``` ## 5. 启动服务 在项目根目录执行: ```bash py -m uvicorn app.main:app --host 0.0.0.0 --port 2336 ``` 启动成功后会看到: 1. sms_db_ready 2. Uvicorn running on http://0.0.0.0:2336 ## 6. 如何测试 ### 6.1 健康检查 ```bash curl http://127.0.0.1:2336/healthz ``` ### 6.2 回调测试 方式一:使用示例文件 test_callback_payload.json。 ```bash curl -X POST "http://127.0.0.1:2336/callback" \ -H "Content-Type: application/json; charset=utf-8" \ --data-binary "@test_callback_payload.json" ``` 方式二:直接发最小 JSON。 ```bash curl -X POST "http://127.0.0.1:2336/callback" \ -H "Content-Type: application/json" \ -d "{\"algorithm_name\":\"行人闯入\",\"snowflake_id\":\"demo-001\"}" ``` ## 7. 返回结构说明 接口始终返回统一结构: ```json { "code": 0, "message": "ok", "data": { "event_id": "1768287987212271616", "sms_preview": "发现有行人闯入行为,请去摄像头查看。", "sms_ok": true, "sms_skipped": false, "receiver_count": 1, "sms": { "code": "OK", "message": "OK", "request_id": "...", "biz_id": "..." }, "sms_error": "" } } ``` 字段含义: 1. sms_preview:短信文本语义预览。 2. sms_skipped:是否因为 LOG_ONLY_NO_SMS=true 而跳过实发。 3. sms_ok:阿里云返回码是否为 OK。 4. sms:阿里云网关返回详情。 5. sms_error:发送失败时的错误信息。 ## 8. 日志与排障 日志位置:logs/callback.log。 常见日志事件: 1. callback_received:收到回调。 2. sms_preview:短信预览与模板参数。 3. sms_receivers_loaded:当前收件人数。 4. sms_sent:已调用阿里云并返回结果。 5. sms_skipped:当前为仅预览模式。 6. sms_config_missing:缺少必要配置。 常见问题: 1. 看见中文乱码:多数是终端显示编码问题,先以接口 JSON 返回为准。 2. 未发送短信:检查 LOG_ONLY_NO_SMS 是否为 true。 3. receiver_count 为 0:检查 SQLite 是否有 is_enabled=1 的号码。 4. 阿里云报模板错误:确认签名、模板编码、模板变量 ACTION 与控制台一致。 ## 9. 安全建议 1. 不要把 AK/SK 提交到版本库。 2. 生产环境建议通过系统环境变量注入密钥。 3. 定期轮换 AK/SK,并限制 RAM 权限最小化。