# SmsReceiver-go 开发文档 ## 项目概述 SmsReceiver-go 是一个用 Go 语言重构的短信接收服务,完全复现 Python 版本功能。 ### 核心特性 - ✅ 基于 Go + SQLite 的轻量级短信接收服务 - ✅ 支持签名验证(HMAC-SHA256) - ✅ 登录认证保护所有页面 - ✅ Web 管理界面(短信列表、详情、日志、统计) - ✅ 支持多 API Token 配置 - ✅ 时区自动转换 - ✅ 自动清理旧消息(支持 cron 定时任务) ## 技术栈 - **Web 框架**: Gorilla Mux - **模板引擎**: html/template - **数据库**: SQLite3 - **认证**: gorilla/sessions - **定时任务**: robfig/cron - **配置管理**: viper ## 项目结构 ``` SmsReceiver-go/ ├── main.go # 入口文件 ├── config.yaml # 配置文件 ├── sms-receiver-v2 # 编译后的二进制文件 ├── sms_receiver_go.db # 独立数据库 ├── auth/ # 认证模块 │ ├── auth.go # 认证逻辑 │ └── password.go # 密码验证 ├── config/ # 配置模块 │ ├── config.go # 配置加载 │ └── constants.go # 常量定义 ├── database/ # 数据库模块 │ └── database.go # 数据库操作 ├── handlers/ # HTTP 处理器 │ ├── handlers.go # 主处理函数 │ ├── middleware.go # 中间件 │ └── health.go # 健康检查 ├── models/ # 数据模型 │ └── message.go # 数据结构定义 ├── sign/ # 签名验证 │ └── sign.go # HMAC-SHA256 签名 ├── static/ # 静态资源 ├── templates/ # HTML 模板 └── tools/ # 工具脚本 └── password_hash.go # 密码哈希生成工具 ``` ## 数据库设计 ### sms_messages 表 存储接收到的短信消息: | 字段 | 类型 | 说明 | |------|------|------| | id | INTEGER | 主键,自增 | | from_number | TEXT | 发送方号码 | | content | TEXT | 短信内容 | | timestamp | INTEGER | 短信时间戳(毫秒级) | | device_info | TEXT | 设备信息(可选) | | sim_info | TEXT | SIM 信息(可选) | | sign_verified | INTEGER | 签名验证结果(0/1) | | ip_address | TEXT | 客户端 IP | | created_at | TIMESTAMP | 创建时间 | ### receive_logs 表 存储短信接收日志: | 字段 | 类型 | 说明 | |------|------|------| | id | INTEGER | 主键,自增 | | from_number | TEXT | 发送方号码 | | content | TEXT | 短信内容 | | timestamp | INTEGER | 短信时间戳(毫秒级) | | sign | TEXT | 签名值(可选) | | sign_valid | INTEGER | 签名验证结果(0/1) | | ip_address | TEXT | 客户端 IP | | status | TEXT | 状态(success/error) | | error_message | TEXT | 错误信息(可选) | | created_at | TIMESTAMP | 创建时间 | ## API 接口 ### 1. 接收短信 **请求**: `POST /api/receive` **参数**: - `from` (必需): 发送方号码 - `content` (必需): 短信内容 - `timestamp`: 短信时间戳(毫秒级,可选,默认当前时间) - `sign`: 签名值(可选,根据配置验证) - `token`: API Token(可选,用于签名验证) - `device`: 设备信息(可选) - `sim`: SIM 信息(可选) **响应**: ```json { "success": true, "message": "短信已接收", "message_id": 123 } ``` ### 2. 获取消息列表 **请求**: `GET /api/messages?page=1&limit=20&from=...&search=...` **参数**: - `page`: 页码(从1开始) - `limit`: 每页数量(最大100) - `from`: 发送方号码筛选 - `search`: 内容或号码搜索 **响应**: ```json { "success": true, "data": [ { "id": 123, "from_number": "+8613800138000", "content": "短信内容", "timestamp": 1704567890123, "timestamp_str": "2024-01-07 12:34:50" } ], "total": 100, "page": 1, "limit": 20 } ``` ### 3. 获取统计信息 **请求**: `GET /api/statistics` **响应**: ```json { "success": true, "data": { "total": 100, "today": 10, "week": 50, "verified": 80, "unverified": 20 } } ``` ### 4. 健康检查 **请求**: `GET /health` **响应**: ```json { "status": "ok", "app_name": "SmsReceiver-go", "version": "2.0.0", "database": "ok", "total_messages": 100, "uptime": "1h23m45s" } ``` ## 部署指南 ### 1. 编译 ```bash cd /root/.openclaw/workspace/SmsReceiver-go go build -o sms-receiver-v2 main.go ``` ### 2. 配置 ```bash # 复制配置示例 cp config.example.yaml config.yaml # 编辑配置 vim config.yaml ``` ### 3. 生成密码哈希(可选) ```bash # 生成 bcrypt 哈希(推荐) go run tools/password_hash.go your_password # 将输出复制到 config.yaml 的 security.password_hash ``` ### 4. 运行 ```bash # 直接运行 ./sms-receiver-v2 # 或指定配置文件 ./sms-receiver-v2 -config /path/to/config.yaml ``` ### 5. Systemd 服务 创建 `/etc/systemd/system/sms-receiver-go.service`: ```ini [Unit] Description=SmsReceiver-go SMS Service After=network.target [Service] Type=simple User=root WorkingDirectory=/root/.openclaw/workspace/SmsReceiver-go ExecStart=/root/.openclaw/workspace/SmsReceiver-go/sms-receiver-v2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target ``` 管理服务: ```bash systemctl daemon-reload systemctl enable sms-receiver-go systemctl start sms-receiver-go systemctl status sms-receiver-go ``` ## 管理脚本 `sms-receiver-go-ctl.sh` 提供便捷的管理命令: ```bash ./sms-receiver-go-ctl.sh start # 启动服务 ./sms-receiver-go-ctl.sh stop # 停止服务 ./sms-receiver-go-ctl.sh restart # 重启服务 ./sms-receiver-go-ctl.sh status # 查看状态 ./sms-receiver-go-ctl.sh log # 查看日志 ./sms-receiver-go-ctl.sh logtail # 实时查看日志 ``` ## 开发说明 ### 时间戳说明 - `timestamp` 字段:毫秒级时间戳(uint64) - `created_at` 字段:SQLite TIMESTAMP(秒级精度) - 模板中显示使用 `timestamp` 字段(更准确) ### 会话管理 - 使用 `gorilla/sessions` 管理会话 - 会话默认有效期 1 小时(可配置) - 密钥至少 16 字节 ### 签名验证 签名生成规则(HMAC-SHA256): ``` stringToSign = timestamp + "\n" + secret signature = base64(hmac_sha256(stringToSign, secret)) ``` Go 实现示例: ```go stringToSign := strconv.FormatInt(timestamp, 10) + "\n" + secret hmacCode := hmac.New(sha256.New, []byte(secret)) hmacCode.Write([]byte(stringToSign)) signBytes := hmacCode.Sum(nil) signBase64 := base64.StdEncoding.EncodeToString(signBytes) sign := url.QueryEscape(signBase64) ``` ### 数据库事务 接收短信时使用事务确保数据一致性: - 同时插入消息和日志 - 任一失败则整体回滚 ### 查询优化 - 使用索引优化查询速度 - 统计查询使用范围查询而非函数调用 - 定期优化数据库:`VACUUM ANALYZE` ## 常见问题 ### 1. 统计数据不显示? 检查数据库查询是否正确,重点关注时间范围计算逻辑。 ### 2. 签名验证失败? - 检查 token 配置是否正确 - 验证时间戳是否在有效期内 - 确认签名生成算法与服务器一致 ### 3. 数据库连接失败? - 检查数据库文件路径是否正确 - 确认文件权限(读写权限) - 检查磁盘空间 ### 4. 如何清空所有数据? ```bash # 停止服务 systemctl stop sms-receiver-go # 删除数据库 rm sms_receiver_go.db # 重启服务(会自动重建数据库) systemctl start sms-receiver-go ``` ## 安全建议 1. **使用强密码**:建议至少12位,包含大小写字母、数字和特殊符号 2. **使用密码哈希**:运行 `tools/password_hash.go` 生成 bcrypt 哈希 3. **配置签名验证**:启用 `sign_verify` 并为每个 token 配置 secret 4. **限制访问**:通过防火墙或反向代理限制访问 5. **定期备份**:定期备份数据库文件 `sms_receiver_go.db` 6. **更新依赖**:定期更新 go 依赖包:`go get -u ./...` ## 许可证 MIT License