# 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
