10 Commits

Author SHA1 Message Date
OpenClaw Agent
b973bdaf47 refactor: 目录结构重构和清理 (v2.0.2)
新增目录:
- docs/legacy/ - 废弃文档归档
- scripts/ - 管理脚本和测试脚本
- build/ - 构建输出目录

文件移动:
- GO_REFACTOR_PROGRESS.md -> docs/legacy/
- OPTIMIZATION_REPORT.md -> docs/legacy/
- sms-receiver-go-ctl.sh -> scripts/
- test_api.sh -> scripts/

改进:
- 更新 .gitignore 忽略运行时文件
- 新增 CHANGELOG.md 独立变更日志
- 更新 README.md 目录结构说明
- 更新 Makefile 版本号到 v2.0.2
- 更新管理脚本路径引用

清理:
- 从仓库中移除二进制文件
- 从仓库中移除数据库文件
- 从仓库中移除日志文件
- 从仓库中移除配置文件
2026-02-12 12:19:05 +08:00
OpenClaw Agent
b29a7bbc63 docs(readme): 更新 v2.0.2 版本信息和更新日志
- 更新版本标签从 v2.0.0 到 v2.0.2
- 添加生产环境 Docker Compose 部署说明
- 新增 v2.0.2 详细更新日志
- 添加 Docker Hub 镜像标签说明
2026-02-12 11:47:27 +08:00
OpenClaw Agent
05a39bd495 feat(docker): 添加生产环境 Docker Compose 配置
- 使用预编译镜像 ouaone/sms-receiver-go:latest
- 自动数据卷挂载(data/ 和 logs/)
- 只读配置文件挂载
- 健康检查和资源限制配置
- 完整的使用说明文档
2026-02-12 11:13:39 +08:00
OpenClaw Agent
ebe9d61665 fix(docker): 复制 templates 和 static 目录到运行时镜像
- 修复容器启动时找不到模板文件导致崩溃的问题
- 添加 COPY 指令复制 templates/ 和 static/ 目录
- 验证容器可正常启动并通过健康检查
2026-02-12 00:59:46 +08:00
OpenClaw Agent
69814a3822 docs: 更新 README.md 添加 v2.0.1 变更日志 2026-02-08 23:15:44 +08:00
OpenClaw Agent
c01b3e82cf fix: v2.0.1 - 修复登录会话创建失败问题
🐛 Bug 修复:
- 修复 securecookie: the value is not valid 错误
- 回退密钥处理逻辑确保向后兼容
- 改进会话初始化错误处理

🔧 变更:
- 简化 auth.Init 函数
- 密钥不足时仅记录警告
- 更新版本号到 v2.0.1

 测试确认:
- 登录流程正常
- API v1 兼容
- Cookie 向后兼容
2026-02-08 23:09:41 +08:00
OpenClaw Agent
93e3911f43 feat: 添加 Docker Hub 镜像支持
- 更新 Dockerfile 使用 Go 1.24
- 优化镜像大小(14.8MB)
- 推送到 Docker Hub (ouaone/sms-receiver-go)
- 更新 README.md 添加 Docker Hub 使用说明
2026-02-08 19:48:17 +08:00
OpenClaw Agent
3ec9dac71e docs: 更新 README.md 添加版本信息说明 2026-02-08 19:21:08 +08:00
OpenClaw Agent
d34d1119dd feat: 编译时嵌入版本信息
- 添加版本显示功能 (--version 参数)
- 编译时注入 Version、BuildTime、GitCommit、GoVersion、BuildEnv
- 更新 Makefile 支持自动获取版本信息
- 添加 release-full 命令支持完整发布流程
- 启动时显示构建信息
2026-02-08 19:20:24 +08:00
OpenClaw Agent
28f2c2aec7 docs: 更新 README.md 到 v2.0.0
- 添加完整功能特性列表
- 新增 v2.0.0 更新日志
- 添加性能对比表
- 补充 Docker 部署说明
- 添加安全建议和管理脚本说明
- 优化文档结构
- 添加徽章和版本信息
2026-02-08 19:12:05 +08:00
23 changed files with 882 additions and 203 deletions

View File

@@ -1,46 +1,44 @@
# 构建/二进制文件 # Git
sms-receiver .git
sms-receiver-v2 .gitignore
*.exe .gitattributes
# 数据库文件 # IDE
*.db .idea
*.sqlite .vscode
*.sqlite3
# 日志文件
*.log
logs/
# 配置文件(敏感信息)
config.yaml
.env
# 临时文件
tmp/
temp/
*.tmp
# IDE 配置
.vscode/
.idea/
*.swp *.swp
*.swo *.swo
# 操作系统
.DS_Store
Thumbs.db
# Git
.git/
.gitignore
# 文档
README.md
DEVELOPMENT.md
*.md
# Docker # Docker
Dockerfile Dockerfile
docker-compose.yml docker-compose.yml
.dockerignore .dockerignore
# 文档
*.md
CHANGELOG.md
# 测试
*_test.go
testdata/
# 临时文件
*.tmp
tmp/
temp/
# 数据库
*.db
*.sqlite
*.sqlite3
# 日志
*.log
logs/
# 上传的二进制文件(如果有)
sms-receiver-v2*
# 开发相关
Makefile
tools/

27
.gitignore vendored
View File

@@ -7,9 +7,21 @@
*.log *.log
nohup.out nohup.out
# 二进制文件和备份(根目录)
sms-receiver
sms-receiver-new
sms-receiver-new.backup
sms-receiver-new.v2.0.0
sms-receiver-v2
# 配置文件(根目录)
config.yaml
# 临时文件 # 临时文件
tmp/ tmp/
*.tmp *.tmp
*.bak
*.backup
# Go 相关 # Go 相关
go.sum go.sum
@@ -21,6 +33,15 @@ go.sum
*.swo *.swo
*~ *~
# 备份文件 # 运行时目录
*.bak data/
*.backup logs/
build/
# 二进制目录(如果是旧的)
sms-receiver-go/
# Python 版本(不应该在 Go 项目中)
sms-receiver/
__pycache__/
*.pyc

38
CHANGELOG-v2.0.1.md Normal file
View File

@@ -0,0 +1,38 @@
# v2.0.1 - 2026-02-08
## 🐛 Bug 修复
### 关键修复
-**修复登录会话创建失败问题**
- 问题: `securecookie: the value is not valid`
- 原因: 新版本的 hex 解码逻辑与旧版本生成的 Cookie 不兼容
- 解决: 回退密钥处理逻辑以确保向后兼容性
### 其他改进
- 改进会话初始化: 密钥长度不足时只记录警告,不中断服务
- 增强 API 兼容性: 完美支持 `/api/v1/*``/api/*` 路由
## 🔧 变更文件
- `auth/auth.go`: 简化密钥处理,恢复旧版本兼容性
- `main.go`: 改进会话初始化错误处理
- `Makefile`: 更新版本号为 v2.0.1
- `config.yaml`: 更新版本号为 2.0.1
## 🔄 升级说明
从 v2.0.0 升级到 v2.0.1:
1. **无需特殊操作**: 直接替换二进制文件即可
2. **Cookie 兼容**: 与现有 Cookie 完全兼容,无需清除
3. **配置兼容**: 配置文件无需修改
## ⚠️ 注意事项
- 配置文件中的密钥将直接使用,不再尝试 hex 解码
- 如果密钥过短(<16字节启动时会记录警告但不会失败
## 📦 下载
- 二进制文件: https://gitea.king.nyc.mn/openclaw/SmsReceiver-go/releases/tag/v2.0.1
- Docker 镜像: `ouaone/sms-receiver-go:v2.0.1`

103
CHANGELOG.md Normal file
View File

@@ -0,0 +1,103 @@
# CHANGELOG.md
所有重要的变更都会记录在此文件中。
## [v2.0.2] - 2026-02-12
### 🐛 Bug 修复
- ✅ 修复容器启动时找不到模板文件导致崩溃的问题
- ✅ 修复 Dockerfile 缺少 `templates/``static/` 目录复制
### 📦 Docker 改进
- ✅ 完善多阶段构建,正确复制运行时所需文件
- ✅ 新增 `docker-compose.production.yml` 生产环境配置
- ✅ 预编译镜像推送到 Docker Hub (ouaone/sms-receiver-go:v2.0.2)
- ✅ 验证容器可正常启动并通过健康检查
### 📂 目录结构重构
- ✅ 新增 `docs/legacy/` 目录,归档废弃文档
- ✅ 新增 `scripts/` 目录,存放管理脚本和测试脚本
- ✅ 新增 `build/` 目录,用于构建输出
- ✅ 移动 `sms-receiver-go-ctl.sh``scripts/`
- ✅ 移动 `test_api.sh``scripts/`
- ✅ 移动 `GO_REFACTOR_PROGRESS.md``docs/legacy/`
- ✅ 移动 `OPTIMIZATION_REPORT.md``docs/legacy/`
### 🔧 Git 仓库清理
- ✅ 从仓库中移除二进制文件sms-receiver*, sms_*.db, *.log
- ✅ 从仓库中移除配置文件 `config.yaml`
- ✅ 更新 `.gitignore` 忽略运行时生成文件
- ✅ 从仓库中移除 Python 版本目录 `sms-receiver/`
### 📚 文档
- ✅ 更新 `README.md` 版本标签从 v2.0.0 到 v2.0.2
- ✅ 更新 `README.md` 镜像拉取说明
- ✅ 新增 `CHANGELOG.md` 独立变更日志文件
- ✅ 添加 Docker Hub 镜像标签说明
### 🔧 兼容性
- ✅ 与 v2.0.1 功能完全兼容
- ✅ 数据库无需迁移
- ✅ 配置文件格式无变更
- ✅ 更新管理脚本路径(`scripts/sms-receiver-go-ctl.sh`
---
## [v2.0.1] - 2026-02-08
### 🐛 Bug 修复
- ✅ 修复登录会话创建失败问题(`securecookie: the value is not valid`
- ✅ 回退密钥处理逻辑确保向后兼容性
- ✅ 改进会话初始化错误处理
### 🔧 兼容性
- ✅ 与 v2.0.0 Cookie 完全兼容,无需清除
- ✅ 支持 `/api/v1/*``/api/*` 路由
- ✅ 密钥长度不足时仅记录警告
---
## [v2.0.0] - 2026-02-08
### 🔴 高优先级 (6项)
- ✅ 数据库事务支持 (确保消息和日志一致性)
- ✅ SQL 注入修复 (参数化查询)
- ✅ 配置验证启动时自动检查
- ✅ 会话密钥强化 (长度验证)
- ✅ 签名验证增强 (详细记录验证过程)
- ✅ 密码哈希支持 (bcrypt)
### 🟡 中优先级 (15项)
- ✅ 连接池配置 (MaxOpenConns, MaxIdleConns)
- ✅ 查询优化 (范围查询, 索引)
- ✅ 健康检查增强 (/health 端点)
- ✅ API 版本控制 (/api/v1/*)
- ✅ 认证中间件 (RequireAuth, RequireAPIAuth)
- ✅ 定时任务优化 (robfig/cron)
- ✅ 配置文件示例 (config.example.yaml)
- ✅ 常量定义 (config/constants.go)
- ✅ 开发文档 (DEVELOPMENT.md)
### 🟢 低优先级 (9项)
- ✅ Docker 支持 (Dockerfile, docker-compose.yml)
- ✅ Makefile 构建脚本
- ✅ 优化报告 (OPTIMIZATION_REPORT.md)
- ✅ 密码哈希工具 (tools/password_hash.go)
- ✅ 单元测试架构准备
### 📦 文件变更
- 新增文件: 14 个
- 代码行数: +1523 / -101
---
## [v1.0.0] - 2026-02-08
### 🎉 初始版本发布
- ✅ 完整功能实现
- ✅ 对齐 Python 版本所有核心特性
- ✅ 独立数据库 (sms_receiver_go.db)
- ✅ 完整的 API 接口 (POST /api/receive, GET /api/messages, GET /api/statistics)
- ✅ Web 管理界面 (短信列表、详情、统计、日志)
- ✅ 签名验证 (HMAC-SHA256)
- ✅ 时区转换 (Asia/Shanghai)

View File

@@ -1,13 +1,13 @@
# 构建阶段 # 构建阶段 - 使用多阶段构建减小镜像体积
FROM golang:1.21-alpine AS builder FROM golang:1.24-alpine AS builder
# 安装构建依赖 # 安装构建依赖
RUN apk add --no-cache git gcc musl-dev RUN apk add --no-cache git gcc musl-dev sqlite-dev
# 设置工作目录 # 设置工作目录
WORKDIR /app WORKDIR /app
# 复制 go.mod 和 go.sum # 复制依赖文件
COPY go.mod go.sum ./ COPY go.mod go.sum ./
# 下载依赖 # 下载依赖
@@ -16,34 +16,48 @@ RUN go mod download
# 复制源代码 # 复制源代码
COPY . . COPY . .
# 编译 # 编译 - 嵌入版本信息
RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -ldflags="-w -s" -o sms-receiver main.go ARG VERSION=v2.0.0
ARG BUILD_TIME=unknown
ARG GIT_COMMIT=unknown
# 运行阶段 RUN CGO_ENABLED=1 GOOS=linux go build \
FROM alpine:latest -ldflags="-X 'main.Version=${VERSION}' -X 'main.BuildTime=${BUILD_TIME}' -X 'main.GitCommit=${GIT_COMMIT}' -X 'main.BuildEnv=docker' -w -s" \
-a -installsuffix cgo \
-o sms-receiver main.go
# 安装运行时依赖 # 运行阶段 - 使用最小化 Alpine 镜像
RUN apk --no-cache add ca-certificates sqlite tzdata FROM alpine:3.19
# 设置时区(可选) # 仅安装必需的运行时依赖
RUN apk --no-cache add \
ca-certificates \
tzdata \
sqlite-libs
# 设置时区
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai
# 创建非 root 用户 # 创建非 root 用户(安全最佳实践)
RUN addgroup -g 1000 appuser && \ RUN addgroup -g 1000 appuser && \
adduser -D -u 1000 -G appuser appuser adduser -D -u 1000 -G appuser appuser
# 设置工作目录 # 设置工作目录
WORKDIR /app WORKDIR /app
# 从构建阶段复制二进制文件 # 从构建阶段复制二进制文件和配置示例
COPY --from=builder /app/sms-receiver . COPY --from=builder /app/sms-receiver .
COPY --from=builder /app/config.example.yaml config.yaml COPY --from=builder /app/config.example.yaml config.yaml
# 创建数据目录 # 复制运行时需要的目录(模板和静态资源)
RUN mkdir -p /app/data && \ COPY --from=builder /app/templates ./templates
COPY --from=builder /app/static ./static
# 创建数据目录并设置权限
RUN mkdir -p /app/data /app/logs && \
chown -R appuser:appuser /app chown -R appuser:appuser /app
# 切换用户 # 切换到非 root 用户
USER appuser USER appuser
# 暴露端口 # 暴露端口

View File

@@ -1,9 +1,16 @@
.PHONY: all build clean run test docker-build docker-run install-dev help .PHONY: all build clean run test docker-build docker-run install-dev help release
# 应用名称 # 应用名称
APP_NAME := sms-receiver-v2 APP_NAME := sms-receiver-v2
MAIN_FILE := main.go MAIN_FILE := main.go
# 版本信息
VERSION := v2.0.2
BUILD_TIME := $(shell date +%Y-%m-%d\ %H:%M:%S)
GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
GO_VERSION := $(shell go version | awk '{print $$3}')
BUILD_ENV := prod
# Go 配置 # Go 配置
GO := go GO := go
GOFMT := gofmt GOFMT := gofmt
@@ -12,7 +19,7 @@ GOTEST := go test
# 构建配置 # 构建配置
BUILD_DIR := ./build BUILD_DIR := ./build
LDFLAGS := -ldflags="-w -s" LDFLAGS := -ldflags="-X 'main.Version=$(VERSION)' -X 'main.BuildTime=$(BUILD_TIME)' -X 'main.GitCommit=$(GIT_COMMIT)' -X 'main.GoVersion=$(GO_VERSION)' -X 'main.BuildEnv=$(BUILD_ENV)' -w -s"
# Docker 配置 # Docker 配置
DOCKER_IMAGE := sms-receiver-go DOCKER_IMAGE := sms-receiver-go
@@ -110,3 +117,52 @@ init:
else \ else \
echo "config.yaml 已存在"; \ echo "config.yaml 已存在"; \
fi fi
## release: 发布版本(创建 tag、推送到远程、上传二进制文件
release: clean build
@echo "正在发布版本: $(VERSION)"
@if [ -z "$(VERSION)" ]; then \
echo "错误: 请指定 VERSION例如: make release VERSION=v2.0.0"; \
exit 1; \
fi
@git tag -a $(VERSION) -m "Release $(VERSION)" || echo "Tag 已存在,继续..."
@git push origin $(VERSION) || echo "Tag 已推送"
@echo "请在 Gitea 上手动上传二进制文件到 Release: $(VERSION)"
@echo "或者使用: make release-upload VERSION=$(VERSION)"
## release-upload: 上传二进制文件到 Gitea Release
release-upload:
@echo "上传二进制文件到 Gitea Release: $(VERSION)"
@if [ ! -f $(APP_NAME) ]; then \
echo "错误: 找不到编译文件 $(APP_NAME),请先运行 make build"; \
exit 1; \
fi
@if [ -z "$(GITEA_TOKEN)" ]; then \
echo "错误: 请设置环境变量 GITEA_TOKEN"; \
echo "用法: make release-upload VERSION=v2.0.0 GITEA_TOKEN=your_token"; \
exit 1; \
fi
@echo "正在上传 $(APP_NAME) 到 Gitea..."
@curl -X POST \
-H "Authorization: token $(GITEA_TOKEN)" \
-F "attachment=@$(APP_NAME)" \
"https://gitea.king.nyc.mn/api/v1/repos/openclaw/SmsReceiver-go/releases/$(VERSION)/assets" \
2>&1 | grep -E "(name|size|browser_download_url)" || echo "上传完成"
@echo "✅ 上传完成!"
## release-full: 完整发布流程编译、tag、推送、上传
release-full: clean build
@echo "完整发布流程: $(VERSION)"
@if [ -z "$(VERSION)" ] || [ -z "$(GITEA_TOKEN)" ]; then \
echo "用法: make release-full VERSION=v2.0.0 GITEA_TOKEN=your_token"; \
exit 1; \
fi
@echo "1. 创建并推送 Git tag..."
@git tag -a $(VERSION) -m "Release $(VERSION)"
@git push origin $(VERSION)
@echo "2. 上传二进制文件到 Gitea Release..."
@curl -X POST \
-H "Authorization: token $(GITEA_TOKEN)" \
-F "attachment=@$(APP_NAME)" \
"https://gitea.king.nyc.mn/api/v1/repos/openclaw/SmsReceiver-go/releases/$(VERSION)/assets"
@echo "✅ 发布完成!访问: https://gitea.king.nyc.mn/openclaw/SmsReceiver-go/releases/tag/$(VERSION)"

476
README.md
View File

@@ -1,11 +1,16 @@
# SmsReceiver-go # SmsReceiver-go
短信转发接收端 Go 版本 - 基于 Flask 版本的完整重写 > 短信转发接收端 Go 版本 - 基于 Flask 版本的完整重写,生产级优化
## 功能特性 [![Go Version](https://img.shields.io/badge/Go-1.21+-00ADD8?style=flat&logo=go)](https://golang.org/)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Version](https://img.shields.io/badge/Version-2.0.2-blue.svg)](https://gitea.king.nyc.mn/openclaw/SmsReceiver-go/releases/tag/v2.0.2)
## ✨ 功能特性
### 核心功能
- ✅ 短信接收 API (支持 TranspondSms Android APP) - ✅ 短信接收 API (支持 TranspondSms Android APP)
- ✅ 登录验证与会话管理 - ✅ 登录验证与会话管理(支持密码哈希)
- ✅ 短信列表展示(分页、搜索、筛选) - ✅ 短信列表展示(分页、搜索、筛选)
- ✅ 统计信息(总数、今日、本周、签名验证) - ✅ 统计信息(总数、今日、本周、签名验证)
- ✅ 接收日志查看 - ✅ 接收日志查看
@@ -14,152 +19,491 @@
- ✅ 签名验证HMAC-SHA256 - ✅ 签名验证HMAC-SHA256
- ✅ 多 Token 管理 - ✅ 多 Token 管理
## 技术栈 ### v2.0.0 新增特性
- 🔐 **密码哈希支持**: 使用 bcrypt 存储密码,提升安全性
- 🔄 **数据库事务**: 消息和日志原子性存储,确保数据一致性
- 🔍 **参数化查询**: 修复潜在 SQL 注入风险
-**配置验证**: 启动时自动检查配置完整性
- 🏥 **增强健康检查**: `/health` 端点返回详细状态信息
- 📦 **API 版本控制**: 支持 `/api/v1/*` 和旧版 API
- 🛡️ **认证中间件**: 代码复用和权限控制
-**Cron 定时任务**: 使用 `robfig/cron` 替代 sleep
- 💾 **连接池优化**: 数据库连接池配置
- 🚀 **Docker 支持**: Dockerfile + docker-compose.yml
- 📝 **Makefile**: 便捷构建命令
- 📚 **完整文档**: 开发文档 + 优化报告
## 🛠 技术栈
- **Web 框架**: Gorilla Mux - **Web 框架**: Gorilla Mux
- **数据库**: SQLite3 (mattn/go-sqlite3) - **数据库**: SQLite3 (mattn/go-sqlite3)
- **模板引擎**: Go html/template - **模板引擎**: Go html/template
- **认证**: Cookie-based session - **认证**: Cookie-based session (gorilla/sessions)
- **语言**: Go 1.23+ - **密码哈希**: bcrypt (golang.org/x/crypto/bcrypt)
- **定时任务**: robfig/cron
- **配置管理**: Viper
- **语言**: Go 1.21+
## 项目结构 ## 📁 项目结构
``` ```
SmsReceiver-go/ SmsReceiver-go/
├── main.go # 入口文件 ├── main.go # 入口文件
├── config.yaml # 配置文件 ├── go.mod / go.sum # Go 依赖管理
├── GO_REFACTOR_PROGRESS.md # 重构进度文档 ├── Makefile # 构建脚本
├── config.example.yaml # 配置示例
├── .gitignore # Git 忽略规则
├── .dockerignore # Docker 忽略规则
├── Dockerfile # Docker 镜像
├── docker-compose.yml # 开发环境 Docker Compose
├── docker-compose.production.yml # 生产环境 Docker Compose
├── README.md # 项目说明
├── CHANGELOG.md # 变更日志
├── DEVELOPMENT.md # 开发文档
├── docs/ # 文档目录
│ └── legacy/ # 废弃文档归档
│ ├── GO_REFACTOR_PROGRESS.md
│ └── OPTIMIZATION_REPORT.md
├── scripts/ # 脚本目录
│ ├── sms-receiver-go-ctl.sh # 服务管理脚本
│ └── test_api.sh # API 测试脚本
├── auth/ # 认证模块 ├── auth/ # 认证模块
│ └── password.go # 密码验证bcrypt
├── config/ # 配置加载 ├── config/ # 配置加载
│ └── constants.go # 常量定义
├── database/ # 数据库操作 ├── database/ # 数据库操作
├── handlers/ # HTTP 处理器 ├── handlers/ # HTTP 处理器
│ ├── middleware.go # 认证中间件
│ └── health.go # 健康检查
├── models/ # 数据模型 ├── models/ # 数据模型
├── sign/ # 签名验证 ├── sign/ # 签名验证
├── static/ # 静态资源 ├── static/ # 静态资源
── templates/ # HTML 模板 ── templates/ # HTML 模板
└── tools/ # 工具脚本
└── password_hash.go # 密码哈希生成
``` ```
## 快速开始 **运行时生成(不在仓库中)**:
- `config.yaml` - 配置文件(需从 config.example.yaml 创建)
- `sms_receiver_go.db` - SQLite 数据库
- `sms_receiver.log` - 运行日志
- `data/` - 数据目录
- `logs/` - 日志目录
- `build/` - 构建输出目录
- `sms-receiver-v2` - 编译后的二进制文件
### 使用预编译二进制(推荐) ## 🚀 快速开始
仓库已包含编译好的二进制文件 `sms-receiver-new`: ### 方式 1: 使用预编译二进制(推荐)
从 [Release](https://gitea.king.nyc.mn/openclaw/SmsReceiver-go/releases) 下载对应平台的二进制文件:
```bash ```bash
chmod +x sms-receiver-new # 赋予执行权限
./sms-receiver-new chmod +x sms-receiver-v2
# 查看版本信息
./sms-receiver-v2 --version
# 运行
./sms-receiver-v2
``` ```
### 从源码编译 版本输出示例:
```
SmsReceiver-go v2.0.0
Version: v2.0.0
Build Env: prod
Build Time: 2026-02-08 19:18:33
Git Commit: 28f2c2a
Go Version: go1.24.4
Repository: https://gitea.king.nyc.mn/openclaw/SmsReceiver-go
```
### 方式 2: 使用 Makefile
```bash
# 初始化配置
make init
# 编译
make build
# 运行
make run
```
### 方式 3: Docker 部署
**使用 Docker Hub 镜像(推荐)**:
```bash
# 拉取镜像
docker pull ouaone/sms-receiver-go:latest
# 运行容器
docker run -d \
--name sms-receiver-go \
-p 28001:28001 \
-v $(pwd)/config.yaml:/app/config.yaml:ro \
-v $(pwd)/data:/app/data \
--restart unless-stopped \
ouaone/sms-receiver-go:latest
```
**从源码构建**:
```bash
# 构建镜像
make docker-build
# 运行容器
make docker-run
# 查看日志
make docker-logs
```
或使用 docker-compose:
```bash
docker-compose up -d
```
**使用生产环境 Docker Compose推荐**:
```bash
# 复制配置文件
cp config.example.yaml config.yaml
# 启动服务
docker compose -f docker-compose.production.yml up -d
# 查看日志
docker compose -f docker-compose.production.yml logs -f
# 停止服务
docker compose -f docker-compose.production.yml down
```
**Docker Hub**: https://hub.docker.com/r/ouaone/sms-receiver-go
**可用镜像标签**:
- `ouaone/sms-receiver-go:latest` - 最新版本(推荐)
- `ouaone/sms-receiver-go:v2.0.2` - v2.0.2 稳定版本
- `ouaone/sms-receiver-go:v2.0.1` - v2.0.1 版本
- `ouaone/sms-receiver-go:v2.0.0` - v2.0.0 版本
### 方式 4: 从源码编译
```bash ```bash
go build -o sms-receiver main.go go build -o sms-receiver main.go
``` ```
### 配置 ## ⚙️ 配置
编辑 `config.yaml`: 初始化配置:
```bash
make init
```
或手动创建 `config.yaml`:
```yaml ```yaml
app:
name: "SmsReceiver-go"
version: "2.0.0"
server: server:
host: "0.0.0.0" host: "127.0.0.1" # 监听地址
port: 28001 port: 28001 # 监听端口
debug: false # 调试模式
security: security:
enabled: true enabled: true # 启用登录验证
username: "admin" username: "admin" # 管理员用户名
password: "admin123" password: "admin123" # 管理员密码(明文)
# password_hash: "$2a$12$..." # 推荐:使用 bcrypt 哈希
session_lifetime: 3600 # 会话有效期(秒)
secret_key: "your-secret-key-at-least-16-characters" # 会话加密密钥
sign_verify: true # 启用签名验证
sign_max_age: 300000 # 签名有效期(毫秒)
database: database:
path: "sms_receiver_go.db" path: "sms_receiver_go.db" # SQLite 数据库文件
timezone: "Asia/Shanghai" # 时区
sms:
max_messages: 0 # 最大保存消息数0=不限制)
auto_cleanup: false # 自动清理旧消息
cleanup_days: 90 # 保留天数
api_tokens: api_tokens:
- name: "默认配置" - name: "default"
token: "default_token" token: "default_token"
secret: "" secret: "" # secret 为空时不验证签名
enabled: true enabled: true
``` ```
### 运行 ### 生成密码哈希(推荐)
```bash ```bash
./sms-receiver go run tools/password_hash.go your_password
# 或使用 Makefile
make password
``` ```
服务将运行在 `http://0.0.0.0:28001` 将输出的哈希值配置到 `security.password_hash` 字段。
### 访问 ## 🌐 访问服务
- 短信列表: http://localhost:28001/ 服务启动后访问:
- 首页(短信列表): http://localhost:28001/
- 统计信息: http://localhost:28001/statistics - 统计信息: http://localhost:28001/statistics
- 接收日志: http://localhost:28001/logs - 接收日志: http://localhost:28001/logs
- 健康检查: http://localhost:28001/health
默认登录账号: 默认登录:
- 用户名: `admin` - 用户名: `admin`
- 密码: `admin123` - 密码: `admin123`(或你设置的密码)
## API 接口 ## 📡 API 接口
### 接收短信 ### 1. 接收短信
```bash ```
POST /api/receive POST /api/receive 或 POST /api/v1/receive
Content-Type: multipart/form-data Content-Type: multipart/form-data
from=10086&content=测试短信&timestamp=1234567890&sign=xxx&token=your_token
``` ```
### 获取消息列表 **参数**:
- `from` (必需): 发送方号码
- `content` (必需): 短信内容
- `timestamp`: 短信时间戳(毫秒级,可选)
- `sign`: 签名值(根据配置验证)
- `token`: API Token用于签名验证
- `device`: 设备信息(可选)
- `sim`: SIM 信息(可选)
```bash **响应**:
GET /api/messages?page=1&limit=20&from=&search= ```json
{
"success": true,
"message": "短信已接收",
"message_id": 123
}
``` ```
需要登录认证 ### 2. 获取消息列表
### 获取统计信息 ```
GET /api/messages 或 GET /api/v1/messages?page=1&limit=20&from=&search=
```bash
GET /api/statistics
``` ```
需要登录认证 **参数**:
- `page`: 页码从1开始
- `limit`: 每页数量最大100
- `from`: 发送方号码筛选
- `search`: 内容或号码搜索
## 数据库 **响应**:
```json
{
"success": true,
"data": [...],
"total": 100,
"page": 1,
"limit": 20
}
```
独立使用 `sms_receiver_go.db`,包含以下表: 需要登录认证。
- `sms_messages`: 短信存储 ### 3. 获取统计信息
- `receive_logs`: 接收日志
- `sqlite_sequence`: 自增序列
## 与 Python 版本对比 ```
GET /api/statistics 或 GET /api/v1/statistics
```
| 特性 | Python 版本 | Go 版本 | **响应**:
|------|------------|---------| ```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"
}
```
## 🗄️ 数据库
**独立数据库**: `sms_receiver_go.db`
### 表结构
**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 | 创建时间 |
## 📊 性能对比
### 与 Python 版本对比
| 特性 | Python 版本 | Go 版本 (v2.0.0) |
|------|------------|------------------|
| 运行方式 | Python 解释器 | 编译二进制 | | 运行方式 | Python 解释器 | 编译二进制 |
| 部署大小 | ~50KB (源码) | ~18MB (二进制, 已包含) | | 部署大小 | ~50KB (源码) | ~6MB (二进制) |
| 启动速度 | ~100ms | ~10ms | | 启动速度 | ~100ms | ~10ms |
| 内存占用 | ~30MB | ~15MB | | 内存占用 | ~30MB | ~15MB |
| 并发处理 | GIL 限制 | 原生协程 | | 并发处理 | GIL 限制 | 原生协程 |
| 数据库 | `sms_receiver.db` | `sms_receiver_go.db` | | 数据库 | `sms_receiver.db` | `sms_receiver_go.db` |
| 密码存储 | 明文 | bcrypt 哈希 |
| 事务支持 | ❌ | ✅ |
| Docker 支持 | ❌ | ✅ |
## 重要说明 ### 优化指标
- **代码质量**: ✅ 30 项优化建议全部完成
- **安全性**: ✅ 事务、哈希、验证全面强化
- **性能**: ✅ 连接池、索引、查询优化
- **可维护性**: ✅ 完整文档、常量、中间件
- **部署便利**: ✅ Makefile、Docker、Systemd
## 🔧 管理脚本
### 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 stop sms-receiver-go # 停止
systemctl restart sms-receiver-go # 重启
systemctl status sms-receiver-go # 状态
```
### 控制脚本
使用 `scripts/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 # 实时查看日志
```
## 📚 文档
- [变更日志](CHANGELOG.md) - 版本更新记录
- [开发文档](DEVELOPMENT.md) - 详细的开发指南和 API 文档
- [优化报告](docs/legacy/OPTIMIZATION_REPORT.md) - v2.0.0 优化详情归档
## 🔒 安全建议
1. **使用强密码**: 至少12位包含大小写字母、数字和特殊符号
2. **使用密码哈希**: 运行 `tools/password_hash.go` 生成 bcrypt 哈希
3. **配置签名验证**: 启用 `sign_verify` 并为 token 配置 secret
4. **限制访问**: 通过防火墙或反向代理限制访问
5. **定期备份**: 定期备份数据库文件
6. **更新依赖**: 定期运行 `go get -u ./...`
## ⚠️ 重要说明
- 本版本与 Python 版本使用**独立的数据库文件** - 本版本与 Python 版本使用**独立的数据库文件**
- 数据不互通,属于完全独立的实现 - 数据不互通,属于完全独立的实现
- 功能已对齐 Python 版本所有核心特性 - 功能已对齐 Python 版本所有核心特性
- 修复了模板渲染类型兼容性问题 - API 同时支持 `/api/*``/api/v1/*`,完全兼容
## License ## 📜 许可证
MIT License MIT License
## 更新日志 ## 🤝 贡献
### v1.0.0 (2026-02-08) 欢迎提交 Issue 和 Pull Request
## 📦 下载
- [Gitea 仓库](https://gitea.king.nyc.mn/openclaw/SmsReceiver-go)
- [Releases](https://gitea.king.nyc.mn/openclaw/SmsReceiver-go/releases)
## 📝 更新日志
详细的版本更新记录请查看 [CHANGELOG.md](CHANGELOG.md)
- ✅ 初始版本发布
- ✅ 完整功能实现
- ✅ 修复模板类型兼容性问题
- ✅ 对齐 Python 版本功能

View File

@@ -1,8 +1,6 @@
package auth package auth
import ( import (
"encoding/hex"
"fmt"
"log" "log"
"net/http" "net/http"
"time" "time"
@@ -23,39 +21,14 @@ const (
) )
// Init 初始化会话存储 // Init 初始化会话存储
func Init(secretKey string) error { func Init(secretKey string) {
if secretKey == "" { store = sessions.NewCookieStore([]byte(secretKey))
return fmt.Errorf("安全密钥不能为空")
}
// 支持 hex 格式的密钥
key := []byte(secretKey)
if len(key) > 64 && len(secretKey) >= 64 { // 可能是 hex 格式 32 字节
if decodedKey, err := hex.DecodeString(secretKey); err == nil {
key = decodedKey
log.Printf("使用 hex 解码密钥")
} else {
log.Printf("hex 解码失败,使用原始密钥: %v", err)
}
}
// 检查密钥长度至少16字节
if len(key) < 16 {
return fmt.Errorf("安全密钥长度不足至少需要16字节当前: %d 字节)", len(key))
}
store = sessions.NewCookieStore(key)
store.Options = &sessions.Options{ store.Options = &sessions.Options{
Path: "/", Path: "/",
MaxAge: 86400 * 7, // 7天 MaxAge: 86400 * 7, // 7天
HttpOnly: true, HttpOnly: true,
// 不设置 SameSite让浏览器使用默认值Lax在同站上下文中工作正常
// SameSite: http.SameSiteNoneMode,
// Secure: true,
} }
log.Printf("会话存储初始化完成,密钥长度: %d 字节", len(key)) log.Printf("会话存储初始化完成,密钥长度: %d 字节", len(secretKey))
return nil
} }
// GetStore 获取会话存储 // GetStore 获取会话存储

View File

@@ -1,34 +0,0 @@
# SMS Receiver Go - 配置文件
app:
name: "短信转发接收端"
version: "1.0.0"
server:
host: "0.0.0.0"
port: 28001
debug: true
security:
enabled: true
username: "admin"
password: "admin123"
session_lifetime: 3600
secret_key: "1e81b5f9e5a695eba01e996b14871db8899b08e111cf8252df8aa4c91d1c7144"
sign_verify: true
sign_max_age: 3600000
sms:
max_messages: 10000
auto_cleanup: true
cleanup_days: 30
database:
path: "sms_receiver_go.db"
timezone: "Asia/Shanghai"
api_tokens:
- name: "默认配置"
token: "default_token"
secret: ""
enabled: true

View File

@@ -0,0 +1,97 @@
# SmsReceiver-go 生产环境 Docker Compose 配置
# 使用预编译好的 Docker 镜像,无需本地编译
#
# 快速启动:
# 1. 复制配置文件cp config.example.yaml config.yaml
# 2. 根据需要修改 config.yaml数据库路径、API Token 等)
# 3. 启动服务docker compose -f docker-compose.production.yml up -d
#
# 访问地址http://localhost:28001
# 默认账号admin / admin123
services:
sms-receiver:
# 使用 Docker Hub 上的预编译镜像
image: ouaone/sms-receiver-go:latest
# 或指定版本image: ouaone/sms-receiver-go:v2.0.2
container_name: sms-receiver-go
# 自动重启策略
restart: unless-stopped
# 端口映射
ports:
- "28001:28001"
# 数据卷挂载
volumes:
# 数据库目录(容器内 /app/data
- ./data:/app/data
# 日志目录(容器内 /app/logs
- ./logs:/app/logs
# 配置文件(只读挂载)
- ./config.yaml:/app/config.yaml:ro
# 环境变量
environment:
- TZ=Asia/Shanghai
# 健康检查
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:28001/health"]
interval: 30s # 每 30 秒检查一次
timeout: 3s # 超时时间 3 秒
retries: 3 # 失败 3 次后标记为不健康
start_period: 5s # 容器启动后 5 秒开始检查
# 网络
networks:
- sms-network
# 资源限制(可选)
deploy:
resources:
limits:
cpus: '0.5'
memory: 128M
reservations:
cpus: '0.1'
memory: 32M
networks:
sms-network:
driver: bridge
# 使用说明:
#
# 1. 首次使用前,创建配置文件:
# cp config.example.yaml config.yaml
#
# 2. 编辑 config.yaml 配置:
# - data_path: /app/data (数据库名称,无需修改)
# - admin_password: admin123 (修改为强密码,或使用 password_hash
# - api_tokens: 添加你的 TranspondSms APP 的 Token 配置
#
# 3. 启动服务:
# docker compose -f docker-compose.production.yml up -d
#
# 4. 查看日志:
# docker compose -f docker-compose.production.yml logs -f
#
# 5. 停止服务:
# docker compose -f docker-compose.production.yml down
#
# 6. 更新镜像:
# docker compose -f docker-compose.production.yml pull
# docker compose -f docker-compose.production.yml up -d
#
# 目录结构示例:
# SmsReceiver-go/
# ├── docker-compose.production.yml (本文件)
# ├── config.yaml (配置文件,需自行创建)
# ├── config.example.yaml (配置示例)
# ├── data/ (自动创建,存放数据库)
# └── logs/ (自动创建,存放日志)

1
docs/.gitkeep Normal file
View File

@@ -0,0 +1 @@
# 废弃文档归档

1
docs/legacy/.gitkeep Normal file
View File

@@ -0,0 +1 @@
# 空目录

59
main.go
View File

@@ -2,6 +2,7 @@ package main
import ( import (
"flag" "flag"
"fmt"
"log" "log"
"net/http" "net/http"
"os" "os"
@@ -18,10 +19,61 @@ import (
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
) )
// 编译时注入的版本信息
var (
Version = "dev" // 版本号
BuildTime = "unknown" // 构建时间
GitCommit = "unknown" // Git commit hash
GoVersion = "unknown" // Go 版本
BuildEnv = "dev" // 构建环境dev/prod
)
func printVersion() {
fmt.Printf("SmsReceiver-go %s\n", Version)
fmt.Printf(" Version: %s\n", Version)
fmt.Printf(" Build Env: %s\n", BuildEnv)
fmt.Printf(" Build Time: %s\n", BuildTime)
fmt.Printf(" Git Commit: %s\n", GitCommit)
fmt.Printf(" Go Version: %s\n", GoVersion)
fmt.Printf(" Repository: https://gitea.king.nyc.mn/openclaw/SmsReceiver-go\n")
}
func main() { func main() {
// 检查是否请求版本信息(需要在 flag.Parse 之前)
for _, arg := range os.Args[1:] {
if arg == "--version" || arg == "-v" {
printVersion()
os.Exit(0)
} else if arg == "--help" || arg == "-h" {
fmt.Println("SmsReceiver-go - 短信转发接收端 Go 版本")
fmt.Println()
fmt.Println("Usage:")
fmt.Println(" sms-receiver-v2 [options]")
fmt.Println()
fmt.Println("Options:")
flag.PrintDefaults()
fmt.Println()
fmt.Println("Additional Options:")
fmt.Println(" -v, --version 显示版本信息")
fmt.Println(" -h, --help 显示帮助信息")
os.Exit(0)
}
}
// 记录启动时间 // 记录启动时间
startTime := time.Now() startTime := time.Now()
// 打印启动信息
log.Printf("========================================")
log.Printf("SmsReceiver-go v%s (%s)", Version, BuildEnv)
log.Printf("========================================")
log.Printf("Version: %s", Version)
log.Printf("Build Env: %s", BuildEnv)
log.Printf("Build Time: %s", BuildTime)
log.Printf("Git Commit: %s", GitCommit)
log.Printf("Go Version: %s", GoVersion)
log.Printf("========================================")
// 命令行参数 // 命令行参数
configPath := flag.String("config", "config.yaml", "配置文件路径") configPath := flag.String("config", "config.yaml", "配置文件路径")
templatesPath := flag.String("templates", "templates", "模板目录路径") templatesPath := flag.String("templates", "templates", "模板目录路径")
@@ -41,8 +93,11 @@ func main() {
defer database.Close() defer database.Close()
// 初始化会话存储 // 初始化会话存储
if err := auth.Init(cfg.Security.SecretKey); err != nil { auth.Init(cfg.Security.SecretKey)
log.Fatalf("初始化会话存储失败: %v", err)
// 验证密钥配置
if len(cfg.Security.SecretKey) < 16 {
log.Printf("警告: 安全密钥长度不足建议至少16字节当前: %d 字节)", len(cfg.Security.SecretKey))
} }
// 初始化模板 // 初始化模板

1
scripts/.gitkeep Normal file
View File

@@ -0,0 +1 @@
# 脚本目录

View File

@@ -2,8 +2,11 @@
# SMS Receiver Go - 管理脚本 # SMS Receiver Go - 管理脚本
SERVICE_NAME="sms-receiver-go" SERVICE_NAME="sms-receiver-go"
BINARY_PATH="/root/.openclaw/workspace/SmsReceiver-go/sms-receiver-new" # 脚本所在目录的父目录(项目根目录)
LOG_PATH="/root/.openclaw/workspace/SmsReceiver-go/sms_receiver.log" SCRIPT_DIR=$(cd "$(dirname "$0")/.." && pwd)
BINARY_NAME="sms-receiver-v2"
BINARY_PATH="$SCRIPT_DIR/$BINARY_NAME"
LOG_PATH="$SCRIPT_DIR/sms_receiver.log"
case "$1" in case "$1" in
start) start)
@@ -28,11 +31,19 @@ case "$1" in
;; ;;
log) log)
echo "SMS Receiver Go 日志 (最近 50 行):" echo "SMS Receiver Go 日志 (最近 50 行):"
tail -n 50 $LOG_PATH if [ -f "$LOG_PATH" ]; then
tail -n 50 "$LOG_PATH"
else
echo "日志文件不存在: $LOG_PATH"
fi
;; ;;
logtail) logtail)
echo "实时监控 SMS Receiver Go 日志 (Ctrl+C 退出):" echo "实时监控 SMS Receiver Go 日志 (Ctrl+C 退出):"
tail -f $LOG_PATH if [ -f "$LOG_PATH" ]; then
tail -f "$LOG_PATH"
else
echo "日志文件不存在: $LOG_PATH"
fi
;; ;;
enable) enable)
echo "设置 SMS Receiver Go 开机自启..." echo "设置 SMS Receiver Go 开机自启..."

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.