golang调用阿里云发短信

之前用golang封装的一个发送阿里云短信的工具包,代码如下

client.go

package sms

import (
	"context"

	"github.com/go-playground/validator/v10"
	"github.com/pkg/errors"
)

type Client interface {
	// Send 发送短信
	Send(ctx context.Context, opt *SendOpt) error
}

type SendOpt struct {
	// 必填:待发送手机号
	// 批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
	PhoneNumbers []string `validate:"required,max=1000"`
	SignName     string
	// 必填:短信模板-可在短信控制台中找到
	TemplateCode string `validate:"required"`
	// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
	// 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,
	// 否则会导致JSON在服务端解析失败
	TemplateParam string `validate:"required"`
	// 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
	SmsUpExtendCode string
	// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
	OutId string
}

func (p *SendOpt) Valid() error {
	if err := validator.New().Struct(p); err != nil {
		return errors.WithStack(err)
	}
	return nil
}

impl.go

package sms

import (
	"context"
	"strings"
	"time"

	"github.com/denverdino/aliyungo/sms"
	"github.com/pkg/errors"
)

const (
	defaultSignName = ""
)

var (
	ErrBusinessLimitControl = errors.New("BUSINESS_LIMIT_CONTROL")
)

type ClientImpl struct {
	aliyunSms *sms.DYSmsClient
}

type CodeStore interface {
	Save(ctx context.Context, key, smsCode string, expire time.Duration) error
	Get(ctx context.Context, key string) (string, error)
}

type ClientOpt struct {
	Key    string
	Secret string
}

func NewClient(opt *ClientOpt) Client {
	return &ClientImpl{
		aliyunSms: sms.NewDYSmsClient(opt.Key, opt.Secret),
	}
}

func (p *ClientImpl) Send(_ context.Context, opt *SendOpt) error {
	if err := opt.Valid(); err != nil {
		return err
	}
	s := defaultSignName
	if opt.SignName != "" {
		s = opt.SignName
	}
	res, err := p.aliyunSms.SendSms(&sms.SendSmsArgs{
		PhoneNumbers:    strings.Join(opt.PhoneNumbers, ","),
		SignName:        s,
		TemplateCode:    opt.TemplateCode,
		TemplateParam:   opt.TemplateParam,
		SmsUpExtendCode: opt.SmsUpExtendCode,
		OutId:           opt.OutId,
	})
	if err != nil {
		return errors.WithStack(err)
	}
	switch res.Code {
	case "OK":
		return nil
	case "isv.BUSINESS_LIMIT_CONTROL":
		return ErrBusinessLimitControl
	default:
		return errors.Errorf("send sms fail: %s, RequestId<%s>, Code<%s>, BizId<%s>",
			res.Message, res.RequestId, res.Code, res.BizId)
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/579730.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Codeforces Round 941 (Div. 1) E. Connected Cubes(构造)

题目 思路来源 官方题解 题解 可以看下官方题解的7张图&#xff0c;还是比较清晰的&#xff0c;这里直接粘贴一下 来源&#xff1a;Codeforces Round #941 (Div. 1, Div. 2) Editorial - Codeforces &#xff08;1&#xff09;原来的图 &#xff08;2&#xff09;对于偶数行…

牛客NC376 变回文串的最少插入次数【困难 动态规划,回文 C++/Java/Go/PHP 高频】力扣同一道题1312

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/bae2652b4db04a438368238498e4c13e https://leetcode.cn/problems/minimum-insertion-steps-to-make-a-string-palindrome/description/ 思路 参考答案C class Solution {public:/*** 代码中的类名、方法名、参…

炒股自动化:券商官方,散户可用,查询订单状态API如何用?

券商官方的接口&#xff0c;个人账户可申请&#xff0c;入金门槛低&#xff0c;接入文档完善&#xff0c;技术支持好的&#xff0c;经过我们筛选后&#xff0c;只有一家符合 会编程&#xff0c;有基础&#xff0c;只是需要API接口的朋友不用看这些&#xff0c;不会写程序的朋友…

nacos-redis-springboot

新项目 准备工作 nacos 版本 2.0.3 redis 最终版本说明 springcloud-alibaba&#xff1a;2.2.7RELEASE springcloud&#xff1a;Hoxton.SR12 springboot&#xff1a;2.3.12.RELEASE Nacos&#xff1a;2.0.3 步骤 启动nacos和redis 准备nacos配置文件 server: port…

avl excite python二次开发1--python解释器需用内置解释器aws_cmd

avl excite python二次开发1--python解释器需用内置解释器aws_cmd 1、python解释器问题1.1、用外置python解释器&#xff0c;import WSInterface会失败(WSInterface.pyd)1.2、用内置解释器aws_cmd运行py脚本1.3 用内置解释器aws_python执行脚本三级目录 1、python解释器问题 1…

ssm项目后端如何导出war及前端如何导出静态资源

后端如何导出war包 后端工具&#xff1a;IDEA 2020.1.3 运行我们编写工具maven里面的package 运行成功的日志 我们运行完&#xff0c;会生成一个target文件夹&#xff0c;在这个文件夹里面找到war包即可 前端如何导出静态资源 使用工具&#xff1a;WebStorm 2020.1.3 打开左…

xLua详解

目录 环境准备xLua导入 C#调用LuaLua解析器Lua文件加载重定向Lua解析管理器全局变量的获取全局函数的获取List和Dictionary映射table类映射table接口映射tableLuaTable映射table Lua调用C#准备工作Lua使用C#类Lua调用C#枚举Lua使用C# 数组 List 字典数组List字典 Lua使用C#扩展…

读天才与算法:人脑与AI的数学思维笔记12_数学的艺术

1. 数学 1.1. 灵光乍现&#xff0c;从来都是厚积薄发 1.1.1. 亨利庞加莱&#xff08;Henri Poincar&#xff09; 1.2. 数学的起源可以追溯到人类试图理解自己所生活的环境&#xff0c;预测接下来会发生什么&#xff0c;从而使我们更加适应环境&#xff0c;并选择对我们有利的…

Python-VBA函数之旅-map函数

目录 一、map函数的常见应用场景 二、map函数使用注意事项 三、如何用好map函数&#xff1f; 1、map函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;神奇夜光杯-CSDN博客 一、map函数的常见应用场景 ma…

Jammy@Jetson Orin - Tensorflow Keras Get Started: Concept

JammyJetson Orin - Tensorflow & Keras Get Started: Concept 1. 源由2. 模型2.1 推理流程2.1.1 获取图像2.1.2 算法识别2.1.3 判断决策 2.2 理想情况2.2.1 多因素输入2.2.2 理想识别概率 2.3 学习过程2.3.1 标记训练集2.3.2 损失函数2.3.3 训练网络2.3.4 渐进方法 3. 总…

使用Docker部署Jupyter Notebook并结合花生壳的内网穿透实现远程访问(详文)

一、前言 本文主要介绍如何利用宝塔面板中的Docker 3.9.3管理器,使用Docker本地部署Jupyter Notebook,并结合花生壳内网穿透工具实现任意浏览器公网远程访问Jupyter登录界面。 安装完成后在宝塔面板中图例 Jupyter Notebook是一个交互式笔记本,支持运行40多种编程语言。…

Vue 组件单元测试深度探索:组件交互与状态变更 专业解析和实践

在Vue组件单元测试中&#xff0c;验证组件之间的交互&#xff08;如父组件与子组件、兄弟组件之间的通信&#xff09;以及状态变更的正确性对于保证整个应用的协调运作至关重要。本文详细介绍了父组件向子组件传递props、子组件向父组件发送事件、兄弟组件通过共享状态&#xf…

xfce4 panel 不能显示QQ,钉钉的状态图标

有一段时间不能显示了&#xff0c;之前刚装完系统的时候很长时间内都是好的&#xff0c;所以刚开始肯定是支持显示这些状态图标的。就是因为不能显示的原因&#xff0c;所以还装了lxQt桌面&#xff0c;这个桌面确实不错。不过还是有时会怀念xfce4&#xff0c;想看看能不能解决这…

Odoo:全球排名第一的免费开源PLM管理系统介绍

概述 利用开源智造OdooPLM产品生命周期管理应用&#xff0c;重塑创新 实现产品生命周期管理数字化&#xff0c;高效定义、开发、交付和管理创新的可持续产品&#xff0c;拥抱数字化供应链。 通过开源智造基于Odoo开源技术平台打造数字化的产品生命周期管理&#xff08;PLM&am…

Java UUID 类中的 getMostSignificantBits 和 leastSignificantBits 方法

getMostSignificantBits() 方法的一些介绍&#xff1a; getMostSignificantBits 这个方法主要用于在 UUID 中获取高64 位的有效位后返回 Long 数据类型。 在获取最高有效位时不会引发异常。 对应的还有一个 getLeastSignificantBits() 方法。 这个方式是从 UUID 中获取低 6…

阳光能源,创造永远:光模块的未来”:随着大数据、区块链、云计算和5G的发展,光模块成为满足不断增长的数据流量需求的关键技术

光模块的类型介绍&#xff1a; 为了适应不同的应用需求&#xff0c;不同参数和功能的光模块应运而生。光模块的分类方式及类型详见如下&#xff1a; &#x1f50e;封装形式&#x1f50d;&#xff1a; &#x1f4e3;&#x1f4e2;光模块按照封装形式来分有以下几种常见类型&a…

如何将本地Android studio项目上传到GitHub

操作步骤&#xff1a; 1、在GitHub上创建账户 2、在androd studio中添加上述创建的GitHub账号 3、在android studio上找到"share project on GitHub"&#xff0c;点击此选项上传当前项目到GitHub 上传成功后&#xff0c;会在GitHub上创建默认仓库repository 注&a…

LeetCode - LCR 008.长度最小的子数组

一. 题目链接 LeetCode - 209. 长度最小的子数组 二. 思路分析 由于此问题分析的对象是「⼀段连续的区间」&#xff0c;因此可以考虑「滑动窗口」的思想来解决这道题。 让滑动窗口满足&#xff1a;从 i 位置开始&#xff0c;窗口内所有元素的和小于target &#xff08;那么当…

图像处理到神经网络:线性代数的跨领域应用探索

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 python数据分析…

Python爬虫--Scrapy框架安装

Scrapy框架安装 &#xff0c; Scrapy 是 Python 领域专业的爬虫开发框架&#xff0c;已经完成爬虫程序的大部分通用工具 它使用了 Twisted 异步网络库来处理网络通讯。整体架构大致如下 第一步&#xff1a;挂小灰机或者将要安装的文件下载到本地 Scrapy 框架安装踩坑中 为什…
最新文章