Go API 教程中使用腾讯云发送短信

由于没有阿里云发送短信免费资源包,花50块又舍不得,于是转战腾讯云发送短信,腾讯云有200条免费国内短信额度。(阿里云官网有免费资源包,但是我用2个账号申请都提示不符合活动条件)

0. 准备工作

  1. 确保有个人网站、APP、微信公众号或者微信小程序,用于申请签名;
  2. 进入 腾讯云后台 - 签名管理 创建签名,如果是公众号的话,建议签名内容中要带 “公众号” 3个字,记下签名内容;
  3. 进入 腾讯云后台 - 正文模板管理 创建模板,建议使用标准模板,审核起来快些,记下模板 ID;
  4. 进入 腾讯云后台 - 应用列表 创建或者使用默认的 SDK AppID;
  5. 进入 腾讯云后台 - API密钥管理 创建或使用默认的密钥,记下 SecretId 和 SecretKey。

至此,准备工作完毕。

1. 获取腾讯云包

可以按需获取指定的包,这里图省事就全部获取了

go get -v -u github.com/tencentcloud/tencentcloud-sdk-go

详细使用可以参考 腾讯云 - 官方文档

2. 创建驱动文件

创建文件 pkg/sms/driver_tencet.go

这里与阿里云短信有 2 个不同,腾讯云短信需要设置 SmsSdkAppId,另外模板参数的设置方式也不一样,阿里云是传入 JSON 字符串,腾讯云是直接传入参数值列表。

package sms

import (
    "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
    "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
    "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
    tencentsms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms/v20210111"
    "gohub/pkg/logger"
)

// Tencent 实现 sms.Driver interface
type Tencent struct{}

// Send 实现 sms.Driver interface 的 Send 方法
func (s *Tencent) Send(phone string, message Message, config map[string]string) bool {
    logger.DebugJSON("短信[腾讯云]", "配置信息", config)

    credential := common.NewCredential(
        config["access_key_id"],
        config["access_key_secret"],
    )
    cpf := profile.NewClientProfile()
    cpf.HttpProfile.Endpoint = "sms.tencentcloudapi.com"
    client, _ := tencentsms.NewClient(credential, "ap-guangzhou", cpf)

    request := tencentsms.NewSendSmsRequest()
    request.PhoneNumberSet = common.StringPtrs([]string{phone})
    request.SignName = common.StringPtr(config["sign_name"])
    request.TemplateId = common.StringPtr(config["template_code"])
    // 为了和阿里云保持兼容,使用腾讯云发送短信时传入的 sms.Message{} 中的 Data 格式还是
    // Data: map[string]string{"code": code}
    request.TemplateParamSet = common.StringPtrs([]string{message.Data["code"]})
    request.SmsSdkAppId = common.StringPtr(config["sdk_app_id"])

    response, err := client.SendSms(request)
    logger.DebugJSON("短信[腾讯云]", "请求内容", request)
    logger.DebugJSON("短信[腾讯云]", "接口响应", response)

    if _, ok := err.(*errors.TencentCloudSDKError); ok {
        logger.ErrorString("短信[腾讯云]", "调用接口错误", err.Error())
        return false
    }
    if err != nil {
        logger.ErrorString("短信[腾讯云]", "服务商返回错误", err.Error())
        return false
    }

    // 当前只有一条
    statusSet := response.Response.SendStatusSet
    code := *statusSet[0].Code
    if code == "Ok" {
        logger.DebugString("短信[腾讯云]", "发信成功", response.ToJsonString())
        return true
    } else {
        logger.ErrorString("短信[腾讯云]", "发信失败", response.ToJsonString())
        return false
    }

}

3. 修改发送短信代码

修改文件 pkg/sms/sms.go,将函数 NewSMS()Send() 中的阿里云换成腾讯云

func NewSMS() *SMS {
    once.Do(func() {
        internalSMS = &SMS{
            Driver: &Tencent{},
        }
    })

    return internalSMS
}

func (sms *SMS) Send(phone string, message Message) bool {
    return sms.Driver.Send(phone, message, config.GetStringMapString("sms.tencent"))
}

4. 修改配置文件

修改文件 config/sms.go,在 aliyun 配置的下方增加 tencent 配置

// 腾讯云
"tencent": map[string]interface{}{
    "access_key_id":     config.Env("SMS_TENCENT_ACCESS_ID"),
    "access_key_secret": config.Env("SMS_TENCENT_ACCESS_SECRET"),
    "sign_name":         config.Env("SMS_TENCENT_SIGN_NAME"),
    "template_code":     config.Env("SMS_TENCENT_TEMPLATE_CODE"),
    "sdk_app_id":        config.Env("SMS_TENCENT_SDK_APP_ID"),
},

5. 修改项目配置文件

修改文件 .env,在项目配置文件增加以下内容,填上腾讯云管理后台对应的值。

  • SMS_TENCENT_ACCESS_ID 和 SMS_TENCENT_ACCESS_SECRET 为 准备工作中的 SecretId 和 SecretKey,
  • SMS_TENCENT_SIGN_NAME 为准备工作中的短信签名,
  • SMS_TENCENT_TEMPLATE_CODE 为准备工作中的短信模板
  • SMS_TENCENT_SDK_APP_ID:为准备工作中获取的 SDK AppID
SMS_TENCENT_ACCESS_ID=
SMS_TENCENT_ACCESS_SECRET=
SMS_TENCENT_SIGN_NAME=
SMS_TENCENT_TEMPLATE_CODE=
SMS_TENCENT_SDK_APP_ID=

至此,便可以使用腾讯云发送短信了

本帖已被设为精华帖!
本帖由系统于 1年前 自动加精
讨论数量: 3

这个可以有,我一直觉得使用官方的包比较好,像教程使用第三方的库,将来还要用到其他功能,例如OSS功能,又得找库。

另外还缺少一个最终的发送平台开关,像数据库那样,选择mysql还是sqlite那样,在配置中切换了

1年前 评论
sreio

如果不想麻烦的,可以如图所示充值一块钱

file

1年前 评论
jxdr 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!