371 lines
8.7 KiB
Markdown
371 lines
8.7 KiB
Markdown
# 短信工具文档
|
||
|
||
## 概述
|
||
|
||
短信工具提供了阿里云短信发送功能,使用Go标准库实现,无需第三方依赖。
|
||
|
||
## 功能特性
|
||
|
||
- 支持阿里云短信服务
|
||
- 支持发送原始请求(完全由外部控制请求参数)
|
||
- 支持模板短信发送
|
||
- 支持批量发送
|
||
- 自动签名计算
|
||
- 使用配置工具统一管理配置
|
||
|
||
## 使用方法
|
||
|
||
### 1. 创建短信发送器
|
||
|
||
```go
|
||
import (
|
||
"git.toowon.com/jimmy/go-commom/config"
|
||
"git.toowon.com/jimmy/go-commom/sms"
|
||
)
|
||
|
||
// 从配置加载
|
||
cfg, err := config.LoadFromFile("./config.json")
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
smsConfig := cfg.GetSMS()
|
||
if smsConfig == nil {
|
||
log.Fatal("SMS config is nil")
|
||
}
|
||
|
||
// 创建短信发送器
|
||
smsClient, err := sms.NewSMS(smsConfig)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
```
|
||
|
||
### 2. 发送原始请求(推荐,最灵活)
|
||
|
||
```go
|
||
// 外部构建完整的请求参数
|
||
params := map[string]string{
|
||
"PhoneNumbers": "13800138000,13900139000",
|
||
"SignName": "我的签名",
|
||
"TemplateCode": "SMS_123456789",
|
||
"TemplateParam": `{"code":"123456","expire":"5"}`,
|
||
}
|
||
|
||
// 发送短信(工具只负责添加系统参数、计算签名并发送)
|
||
resp, err := smsClient.SendRaw(params)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
fmt.Printf("发送成功,RequestID: %s\n", resp.RequestID)
|
||
```
|
||
|
||
### 3. 发送简单短信(便捷方法)
|
||
|
||
```go
|
||
// 使用配置中的模板代码发送短信
|
||
templateParam := map[string]string{
|
||
"code": "123456",
|
||
}
|
||
|
||
resp, err := smsClient.SendSimple(
|
||
[]string{"13800138000"},
|
||
templateParam,
|
||
)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
fmt.Printf("发送成功,RequestID: %s\n", resp.RequestID)
|
||
```
|
||
|
||
### 4. 使用指定模板发送短信(便捷方法)
|
||
|
||
```go
|
||
// 使用指定的模板代码发送短信
|
||
templateParam := map[string]string{
|
||
"code": "123456",
|
||
"expire": "5",
|
||
}
|
||
|
||
resp, err := smsClient.SendWithTemplate(
|
||
[]string{"13800138000"},
|
||
"SMS_123456789", // 模板代码
|
||
templateParam,
|
||
)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
```
|
||
|
||
### 5. 使用SendRequest结构发送(便捷方法)
|
||
|
||
```go
|
||
import "git.toowon.com/jimmy/go-commom/sms"
|
||
|
||
req := &sms.SendRequest{
|
||
PhoneNumbers: []string{"13800138000", "13900139000"},
|
||
TemplateCode: "SMS_123456789",
|
||
TemplateParam: map[string]string{
|
||
"code": "123456",
|
||
},
|
||
SignName: "我的签名", // 可选,如果为空使用配置中的签名
|
||
}
|
||
|
||
resp, err := smsClient.Send(req)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
```
|
||
|
||
### 6. 使用JSON字符串作为模板参数
|
||
|
||
```go
|
||
// TemplateParam可以是JSON字符串
|
||
req := &sms.SendRequest{
|
||
PhoneNumbers: []string{"13800138000"},
|
||
TemplateCode: "SMS_123456789",
|
||
TemplateParam: `{"code":"123456","expire":"5"}`, // 直接使用JSON字符串
|
||
}
|
||
|
||
resp, err := smsClient.Send(req)
|
||
```
|
||
|
||
## API 参考
|
||
|
||
### NewSMS(cfg *config.SMSConfig) (*SMS, error)
|
||
|
||
创建短信发送器。
|
||
|
||
**参数:**
|
||
- `cfg`: 短信配置对象
|
||
|
||
**返回:** 短信发送器实例和错误信息
|
||
|
||
### (s *SMS) SendRaw(params map[string]string) (*SendResponse, error)
|
||
|
||
发送原始请求(推荐使用,最灵活)。
|
||
|
||
**参数:**
|
||
- `params`: 请求参数map,工具只负责添加必要的系统参数(如签名、时间戳等)并发送
|
||
|
||
**返回:** 发送响应和错误信息
|
||
|
||
**说明:** 此方法允许外部完全控制请求参数,工具只负责添加系统参数、计算签名并发送。
|
||
|
||
### (s *SMS) Send(req *SendRequest) (*SendResponse, error)
|
||
|
||
发送短信(使用SendRequest结构)。
|
||
|
||
**参数:**
|
||
- `req`: 发送请求对象
|
||
|
||
**返回:** 发送响应和错误信息
|
||
|
||
**说明:** 如果需要完全控制请求参数,请使用SendRaw方法。
|
||
|
||
### (s *SMS) SendSimple(phoneNumbers []string, templateParam map[string]string) (*SendResponse, error)
|
||
|
||
发送简单短信(便捷方法,使用配置中的模板代码)。
|
||
|
||
**参数:**
|
||
- `phoneNumbers`: 手机号列表
|
||
- `templateParam`: 模板参数
|
||
|
||
### (s *SMS) SendWithTemplate(phoneNumbers []string, templateCode string, templateParam map[string]string) (*SendResponse, error)
|
||
|
||
使用指定模板发送短信(便捷方法)。
|
||
|
||
**参数:**
|
||
- `phoneNumbers`: 手机号列表
|
||
- `templateCode`: 模板代码
|
||
- `templateParam`: 模板参数
|
||
|
||
### SendRequest 结构体
|
||
|
||
```go
|
||
type SendRequest struct {
|
||
PhoneNumbers []string // 手机号列表
|
||
TemplateCode string // 模板代码(可选,如果为空使用配置中的)
|
||
TemplateParam interface{} // 模板参数(可以是map[string]string或JSON字符串)
|
||
SignName string // 签名(可选,如果为空使用配置中的)
|
||
}
|
||
```
|
||
|
||
### SendResponse 结构体
|
||
|
||
```go
|
||
type SendResponse struct {
|
||
RequestID string // 请求ID
|
||
Code string // 响应码(OK表示成功)
|
||
Message string // 响应消息
|
||
BizID string // 业务ID
|
||
}
|
||
```
|
||
|
||
## 配置说明
|
||
|
||
短信配置通过 `config.SMSConfig` 提供:
|
||
|
||
| 字段 | 类型 | 说明 | 默认值 |
|
||
|------|------|------|--------|
|
||
| AccessKeyID | string | 阿里云AccessKey ID | - |
|
||
| AccessKeySecret | string | 阿里云AccessKey Secret | - |
|
||
| Region | string | 区域(如:cn-hangzhou) | cn-hangzhou |
|
||
| SignName | string | 短信签名 | - |
|
||
| TemplateCode | string | 短信模板代码 | - |
|
||
| Endpoint | string | 服务端点(可选) | - |
|
||
| Timeout | int | 请求超时时间(秒) | 10 |
|
||
|
||
## 阿里云短信配置步骤
|
||
|
||
1. **开通阿里云短信服务**
|
||
- 登录阿里云控制台
|
||
- 开通短信服务
|
||
|
||
2. **创建AccessKey**
|
||
- 在AccessKey管理页面创建AccessKey
|
||
- 保存AccessKey ID和Secret
|
||
|
||
3. **申请短信签名**
|
||
- 在短信服务控制台申请签名
|
||
- 等待审核通过
|
||
|
||
4. **创建短信模板**
|
||
- 在短信服务控制台创建模板
|
||
- 模板格式示例:`您的验证码是${code},有效期${expire}分钟`
|
||
- 等待审核通过,获取模板代码(如:SMS_123456789)
|
||
|
||
5. **配置参数**
|
||
```json
|
||
{
|
||
"sms": {
|
||
"accessKeyId": "your-access-key-id",
|
||
"accessKeySecret": "your-access-key-secret",
|
||
"region": "cn-hangzhou",
|
||
"signName": "您的签名",
|
||
"templateCode": "SMS_123456789"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 模板参数示例
|
||
|
||
### 验证码模板
|
||
模板内容:`您的验证码是${code},有效期${expire}分钟`
|
||
|
||
```go
|
||
templateParam := map[string]string{
|
||
"code": "123456",
|
||
"expire": "5",
|
||
}
|
||
```
|
||
|
||
### 通知模板
|
||
模板内容:`您的订单${orderNo}已发货,物流单号:${trackingNo}`
|
||
|
||
```go
|
||
templateParam := map[string]string{
|
||
"orderNo": "ORD123456",
|
||
"trackingNo": "SF1234567890",
|
||
}
|
||
```
|
||
|
||
## 响应码说明
|
||
|
||
| Code | 说明 |
|
||
|------|------|
|
||
| OK | 发送成功 |
|
||
| InvalidSignName | 签名不存在 |
|
||
| InvalidTemplateCode | 模板不存在 |
|
||
| InvalidPhoneNumbers | 手机号格式错误 |
|
||
| Throttling | 请求被限流 |
|
||
| 其他 | 参考阿里云短信服务错误码文档 |
|
||
|
||
## 注意事项
|
||
|
||
1. **推荐使用SendRaw方法**:
|
||
- `SendRaw`方法允许外部完全控制请求参数
|
||
- 可以发送任意阿里云短信API支持的请求
|
||
- 工具只负责添加系统参数、计算签名并发送
|
||
|
||
2. **模板参数格式**:
|
||
- `TemplateParam`可以是`map[string]string`或JSON字符串
|
||
- 如果使用JSON字符串,必须是有效的JSON格式
|
||
- 模板参数必须与模板中定义的变量匹配
|
||
|
||
3. **AccessKey安全**:
|
||
- AccessKey具有账户权限,请妥善保管
|
||
- 建议使用子账户AccessKey,并限制权限
|
||
|
||
4. **签名和模板**:
|
||
- 签名和模板需要先申请并审核通过
|
||
- 模板参数必须与模板中定义的变量匹配
|
||
|
||
5. **手机号格式**:
|
||
- 支持国内手机号(11位数字)
|
||
- 支持国际手机号(需要加国家代码)
|
||
|
||
6. **发送频率**:
|
||
- 注意阿里云的发送频率限制
|
||
- 建议实现发送频率控制
|
||
|
||
7. **错误处理**:
|
||
- 所有操作都应该进行错误处理
|
||
- 建议记录详细的错误日志
|
||
- 注意区分业务错误和系统错误
|
||
|
||
8. **批量发送**:
|
||
- 支持一次发送给多个手机号
|
||
- 注意批量发送的数量限制
|
||
|
||
## 完整示例
|
||
|
||
```go
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
|
||
"git.toowon.com/jimmy/go-commom/config"
|
||
"git.toowon.com/jimmy/go-commom/sms"
|
||
)
|
||
|
||
func main() {
|
||
// 加载配置
|
||
cfg, err := config.LoadFromFile("./config.json")
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
// 创建短信发送器
|
||
smsClient, err := sms.NewSMS(cfg.GetSMS())
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
// 发送验证码短信
|
||
templateParam := map[string]string{
|
||
"code": "123456",
|
||
"expire": "5",
|
||
}
|
||
|
||
resp, err := smsClient.SendSimple(
|
||
[]string{"13800138000"},
|
||
templateParam,
|
||
)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
fmt.Printf("发送成功,RequestID: %s\n", resp.RequestID)
|
||
}
|
||
```
|
||
|
||
## 示例
|
||
|
||
完整示例请参考 `examples/sms_example.go`
|
||
|