Files
go-common/docs/sms.md
2025-11-30 13:43:43 +08:00

8.7 KiB
Raw Permalink Blame History

短信工具文档

概述

短信工具提供了阿里云短信发送功能使用Go标准库实现无需第三方依赖。

功能特性

  • 支持阿里云短信服务
  • 支持发送原始请求(完全由外部控制请求参数)
  • 支持模板短信发送
  • 支持批量发送
  • 自动签名计算
  • 使用配置工具统一管理配置

使用方法

1. 创建短信发送器

import (
    "git.toowon.com/jimmy/go-common/config"
    "git.toowon.com/jimmy/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. 发送原始请求(推荐,最灵活)

// 外部构建完整的请求参数
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. 发送简单短信(便捷方法)

// 使用配置中的模板代码发送短信
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. 使用指定模板发送短信(便捷方法)

// 使用指定的模板代码发送短信
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结构发送便捷方法

import "git.toowon.com/jimmy/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字符串作为模板参数

// 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 结构体

type SendRequest struct {
    PhoneNumbers  []string          // 手机号列表
    TemplateCode  string            // 模板代码(可选,如果为空使用配置中的)
    TemplateParam interface{}       // 模板参数可以是map[string]string或JSON字符串
    SignName      string            // 签名(可选,如果为空使用配置中的)
}

SendResponse 结构体

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. 配置参数

    {
      "sms": {
        "accessKeyId": "your-access-key-id",
        "accessKeySecret": "your-access-key-secret",
        "region": "cn-hangzhou",
        "signName": "您的签名",
        "templateCode": "SMS_123456789"
      }
    }
    

模板参数示例

验证码模板

模板内容:您的验证码是${code},有效期${expire}分钟

templateParam := map[string]string{
    "code": "123456",
    "expire": "5",
}

通知模板

模板内容:您的订单${orderNo}已发货,物流单号:${trackingNo}

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. 批量发送

    • 支持一次发送给多个手机号
    • 注意批量发送的数量限制

完整示例

package main

import (
    "fmt"
    "log"
    
    "git.toowon.com/jimmy/go-common/config"
    "git.toowon.com/jimmy/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