# Sender 消息通知微服务


一个基于 Go 语言开发的高性能消息通知微服务，提供短信、邮件发送和验证码管理功能。采用 gRPC + HTTP Gateway 架构，支持多种服务商集成。

## ✨ 功能特性

### 📱 短信服务
- **多服务商支持**：阿里云短信、腾讯云短信
- **模板管理**：支持短信模板和参数替换
- **发送限制**：基于手机号的日发送量限制
- **黑名单过滤**：支持手机号黑名单机制
- **验证码生成**：自动生成和验证短信验证码

### 📧 邮件服务
- **SMTP支持**：支持标准SMTP协议发送邮件
- **模板引擎**：基于Go template的邮件模板系统
- **多服务商**：支持QQ邮箱、Gmail等主流邮箱服务
- **TLS加密**：支持TLS/SSL安全连接

### 🔐 验证码管理
- **自动生成**：支持4-10位数字验证码
- **Redis缓存**：验证码存储和过期管理
- **限流控制**：防止验证码频繁发送
- **验证接口**：提供验证码校验功能

### 🏗️ 微服务架构
- **gRPC服务**：高性能RPC通信
- **HTTP Gateway**：RESTful API支持
- **服务发现**：基于Etcd的服务注册发现
- **健康检查**：完整的健康检查机制

## 🚀 快速开始

### 环境要求

- Go 1.26.5
- Redis 6.0+
- PostgreSQL 12+
- Etcd 3.5+

### 安装依赖

```bash
# 克隆项目
git clone bsm/full/module/base/sender.git
cd sender

# 下载依赖
make deps
```

### 配置服务

1. **复制配置文件**：
```bash
cp etc/sender_dev.yaml etc/sender_local.yaml
```

2. **修改配置**：
```yaml
# etc/sender_local.yaml
Service:
  Name: sender
  Port: "12201"
  BindIP: "0.0.0.0"

# 数据库配置
Databases:
  Default:
    Driver: postgres
    Host: localhost
    Port: 5432
    Database: sender_db
    Username: postgres
    Password: your_password

# Redis配置
Cache:
  Redis:
    Host: localhost
    Port: 6379
    Password: your_redis_password
    Database: 0

# 短信服务配置
SMS:
  aliyun:
    Endpoint: "dysmsapi.aliyuncs.com"
    AccessKeyId: "your_access_key_id"
    AccessKeySecret: "your_access_key_secret"
    Region: "cn-hangzhou"

# 邮件服务配置
SMTP:
  qq:
    Endpoint: "smtp.qq.com"
    Port: 587
    Username: "your_email@qq.com"
    Password: "your_smtp_password"
    FromAddress: "your_email@qq.com"
    FromName: "系统通知"
```

### 运行服务

#### 方式一：直接运行
```bash
# 开发模式
make dev

# 生产模式
make build
make run
```

#### 方式二：Docker运行
```bash
# 构建镜像
make docker-build

# 使用docker-compose启动完整环境
make docker-compose-up
```

## 📖 API文档

### gRPC接口

#### 短信服务
```protobuf
service Sms {
  rpc Send(SmsSendRequest) returns (SmsReply);
  rpc Verify(SmsVerifyRequest) returns (SmsReply);
}
```

#### 邮件服务
```protobuf
service Mail {
  rpc Send(SendMailRequest) returns (SendMailReply);
}
```

### HTTP接口

服务启动后，可通过以下地址访问：

- **gRPC服务**：`localhost:12201`
- **HTTP Gateway**：`localhost:12202`
- **Swagger文档**：`http://localhost:12202/swagger/`

#### 发送短信示例
```bash
curl -X POST "http://localhost:12202/v1/sms/send" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "aliyun",
    "sign_name": "您的签名",
    "template_code": "SMS_123456789",
    "phone": "13800138000",
    "paramters": {
      "code": "123456"
    }
  }'
```

#### 发送邮件示例
```bash
curl -X POST "http://localhost:12202/v1/mail/send" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "qq",
    "template_key": "welcome",
    "to": "user@example.com",
    "paramters": {
      "username": "张三",
      "verification_code": "123456"
    }
  }'
```

## 🛠️ 开发指南

### 项目结构

```
sender/
├── cmd/                    # 应用程序入口
│   ├── main/              # 主服务入口
│   └── cli/               # 命令行工具
├── internal/              # 内部包
│   ├── config/            # 配置管理
│   ├── excode/            # 错误码定义
│   ├── impl/              # 依赖实现
│   ├── logic/             # 业务逻辑
│   │   ├── mail/          # 邮件服务
│   │   └── sms/           # 短信服务
│   ├── models/            # 数据模型
│   └── server/            # 服务器实现
├── pb/                    # protobuf生成代码
├── proto/                 # protobuf定义文件
├── etc/                   # 配置文件
├── test/                  # 测试文件
├── scripts/               # 脚本文件
└── swagger/               # API文档
```

### 开发命令

```bash
# 查看所有可用命令
make help

# 生成protobuf代码
make proto

# 运行测试
make test

# 代码检查
make lint

# 格式化代码
make fmt

# 构建所有平台版本
make build-all

# 运行完整构建流程
make all
```

### 添加新的短信服务商

1. **在配置中添加服务商配置**：
```yaml
SMS:
  new_provider:
    Endpoint: "api.newprovider.com"
    AccessKeyId: "your_key"
    AccessKeySecret: "your_secret"
    Region: "us-east-1"
```

2. **在 `internal/logic/sms/send.go` 中添加处理逻辑**：
```go
case "new_provider":
    if impl.Provider.NewProvider == nil {
        return nil, excode.ErrProviderIsNil
    }
    result, err = NewProviderSender(in, smsCode)
```

3. **实现具体的发送函数**：
```go
func NewProviderSender(args *pb.SmsSendRequest, code string) (map[string]any, error) {
    // 实现新服务商的发送逻辑
}
```

### 添加新的邮件服务商

1. **在配置中添加SMTP配置**：
```yaml
SMTP:
  gmail:
    Endpoint: "smtp.gmail.com"
    Port: 587
    Username: "your_email@gmail.com"
    Password: "your_app_password"
    FromAddress: "your_email@gmail.com"
    FromName: "系统通知"
```

2. **在 `internal/logic/mail/send.go` 中添加处理逻辑**：
```go
case "gmail":
    err = GmailSender(cfg, tmpl, in.GetTo(), tplRecord.Subjet, in.GetParamters())
```

3. **实现具体的发送函数**：
```go
func GmailSender(cfg *config.SmtpConf, tmpl *template.Template, to string, subject string, args map[string]string) error {
    // 实现Gmail的发送逻辑
}
```

## 🧪 测试

### 运行测试

```bash
# 运行所有测试
make test

# 运行邮件测试
make test-mail

# 运行短信测试
make test-sms

# 生成测试覆盖率报告
make test-coverage
```

### 测试环境

项目提供了完整的Docker测试环境：

```bash
# 启动测试环境（包含Mailhog用于邮件测试）
docker-compose --profile development up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f sender-service
```

## 📦 部署

### Docker部署

```bash
# 构建生产镜像
make docker-build

# 使用docker-compose部署
make docker-compose-up

# 停止服务
make docker-compose-down
```

### 生产环境配置

1. **环境变量设置**：
```bash
export SERVICE_ENV=prod
export POSTGRES_PASSWORD=your_strong_password
export REDIS_PASSWORD=your_redis_password
```

2. **配置文件**：
使用 `etc/sender_prod.yaml` 作为生产环境配置

3. **健康检查**：
```bash
# 检查服务健康状态
curl http://localhost:12202/health
```

## 🔧 配置说明

### 主要配置项

| 配置项 | 说明 | 默认值 |
|--------|------|--------|
| `Service.Port` | 服务端口 | 12201 |
| `Service.BindIP` | 绑定IP | 0.0.0.0 |
| `Code.Length` | 验证码长度 | 6 |
| `Code.Expire` | 验证码过期时间(秒) | 300 |
| `Code.MaxSentLimit` | 每日最大发送次数 | 10 |

### 环境变量

| 环境变量 | 说明 | 示例 |
|----------|------|------|
| `SERVICE_ENV` | 服务环境 | dev/test/prod |
| `POSTGRES_PASSWORD` | 数据库密码 | your_password |
| `REDIS_PASSWORD` | Redis密码 | your_redis_password |

## 📊 监控和日志

### 健康检查

- **HTTP健康检查**：`GET /health`
- **gRPC健康检查**：使用gRPC健康检查协议

### 日志管理

- 日志文件位置：`/app/logs/`
- 支持结构化日志输出
- 集成ELK日志收集（可选）

### 性能监控

- 支持APM监控集成
- 提供Prometheus指标导出
- 支持分布式链路追踪

## 🤝 贡献指南

1. Fork 本仓库
2. 创建特性分支：`git checkout -b feature/new-feature`
3. 提交更改：`git commit -am 'Add new feature'`
4. 推送分支：`git push origin feature/new-feature`
5. 提交Pull Request

### 代码规范

- 遵循Go官方代码规范
- 使用 `gofmt` 格式化代码
- 运行 `make lint` 进行代码检查
- 确保测试覆盖率 > 80%

## 📄 许可证

本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。

## 📞 支持

如有问题或建议，请通过以下方式联系：

- 提交 [Issue](https://bsm/full/module/base/sender/issues)
- 发送邮件至：david.yan@qq.com
- 查看 [Wiki](https://bsm/full/module/base/sender/wiki) 获取更多文档

---

**注意**：本项目为企业内部使用，请确保在生产环境中正确配置安全参数。