# 短信工具文档 ## 概述 短信工具提供了阿里云短信发送功能,使用Go标准库实现,无需第三方依赖。 ## 功能特性 - 支持阿里云短信服务 - 支持发送原始请求(完全由外部控制请求参数) - 支持模板短信发送 - 支持批量发送 - 自动签名计算 - 使用配置工具统一管理配置 ## 使用方法 ### 1. 创建短信发送器 ```go import ( "github.com/go-common/config" "github.com/go-common/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 "github.com/go-common/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" "github.com/go-common/config" "github.com/go-common/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`