前言

Amazon Simple Notification Service (Amazon SNS) is a web service that coordinates and manages the delivery or sending of messages to subscribing endpoints or clients. In Amazon SNS, there are two types of clients—publishers and subscribers—also referred to as producers and consumers. Publishers communicate asynchronously with subscribers by producing and sending a message to a topic, which is a logical access point and communication channel. Subscribers (i.e., web servers, email addresses, Amazon SQS queues, AWS Lambda functions) consume or receive the message or notification over one of the supported protocols (i.e., Amazon SQS, HTTP/S, email, SMS, Lambda) when they are subscribed to the topic. [1]

正如SNS的介绍所述,SNS是AWS提供的一个消息收发服务,它包括了诸如消息推送、短信、电子邮件等服务。AWS官方文档提供了非常多的内容,但提供的示例代码是以Java或.Net为主,关于Node.js的直接资料较少,所以这里便来介绍如何使用AWS SNS服务发送短信。

Node.js中使用SNS发送短信

在Node.js中使用AWS的服务,需要先安装aws-sdk依赖。AWS SDK中包括了众多服务的接口,在这里我们需要的是AWS.SNS类。首先,需要实例化AWS.SNS对象,其构造函数的参数为一个对象,通常需要包括accessKeyIdsecretAccessKeyregion等属性。在AWS IAM中,可生成并下载使用的用户对应的accessKeyIdsecretAccessKey。需要注意的是,使用的用户需要在IAM中设置SNS对应的权限。

const AWS = require('aws-sdk');const options = {accessKeyId: 'String',secretAccessKey: 'String',apiVersion: '2010-03-31',
};const snsService = new AWS.SNS(options);

通过AWS.SNS类的实例,就可以使用其进行SNS服务的相关操作。本文的主题为使用SNS服务发送短信,所以接下来即可通过AWS.SNS实例的publish方法以短信形式发送消息。

AWS SDK for Node.js中,publish方法接收一个Object类型的参数,它其中包括MessageMessageAttributesMessageStructurePhoneNumberSubjectTargetArn以及TopicArn属性。publish是一个SNS中通用的方法,发送邮件、消息推送也是通过它进行完成,所以在发送短信时部分的参数不是必须的。下面是一个发送短信所需最少参数的例子。

const params = {Message: text,MessageAttributes: {'AWS.SNS.SMS.SMSType': {DataType: 'String',StringValue: 'Transactional', // Transactional or Promotional},// AWS.SNS.SMS.MaxPrice// AWS.SNS.SMS.SenderId},PhoneNumber: phoneNumber, // 电话号码,需要遵从E.164格式
};

MessageAttributes中可以包含多个属性,例如上述例子中的AWS.SNS.SMS.SMSType。MessageAttribute的值主要包括DataTypeStringValueBinaryValue,其根据DataType的值决定需要的是StringValue或是BinaryValueStringValue接受一组以UTF-8编码的字符串,而BinaryValue可以接受任何二进制值,例如压缩后的数据、图片等。

MessageAttributesAWS.SNS.SMS.SMSType属性中,其值需为TransactionalPromotional。二者的区别为Transactional更为可靠,但其价格通常更为昂贵,一般用于发送较为重要的消息(如短信验证码等),而Promotional一般用于发送推广信息。另外AWS.SNS.SMS.MaxPrice为愿意为发送消息支付以美元为单位的最高金额;AWS.SNS.SMS.SenderId为一个在接收设备上显示的自定义ID,但其支持程度受所在地区限制,如中国便不支持SenderId的显示。

使用上面定义的参数调用publish方法即可发送短信。publish方法提供了基于Promise的异步使用方法,只需将代码修改为:const response = await snsService.publish(params).promise();。同理,AWS SDK中的其它方法也可通过添加.promise()将其异步形式从回调改为基于Promise。

snsService.publish(params, (err, data) => {if (err) {// ...}// ...
})

返回结果

在参数错误、权限不足等情况下,调用publish方法将会抛出诸如InvalidParameterAuthorizationError等错误,可根据其具体错误信息判断错误原因。调用publish方法将会返回下述结果。其中,MessageId为该消息的唯一标识符,当开启CloudWatch Logs后可通过该标识符获取消息的传输信息。

{"ResponseMetadata":{"RequestId":"bfb2a062-c201-5d34-a7d8-f5fd653b27f9"},"MessageId":"2b38eec7-a3f0-5679-a116-bb5804cadcb4"
}

未收到短信

调用publish接口成功并正常返回结果,不代表短信发送成功。短信发送失败的原因可能是下列其中一个:

  • 被电话运营商作为垃圾消息屏蔽
  • 目标已加入黑名单
  • 电话号码无效
  • 消息正文无效
  • 电话运营商已屏蔽此消息
  • 电话运营商目前无法访问/不可用
  • 电话已屏蔽SMS
  • 电话已加入黑名单
  • 电话当前无法访问/可用
  • 电话号码已退出
  • 此传输会超过最高价格
  • 尝试联系电话时发生未知错误

publish方法返回的结果无法得知短信发送是否成功,只有在开启CloudWatch Logs功能后才能从日志中获取短信是否发送成功及发送失败的原因。

发送短信至多个号码

使用AWS SNS可以实现同时发送短信至多个手机号码,其中一种实现方法即为多次调用publish方法向不同号码发送短信。但重复多次调用publish方法需要耗费更多的时间,所以在此也可选用另一种方法,即使用Topic发送短信至多个号码。该方法的步骤是在创建一个topic后,为多个手机号码订阅该topic。订阅后在发送消息时,会将消息发送至订阅该topic的端点中,此处的端点即为电话号码。

在发送信息至多个号码前,需要创建一个新的Topic并使用subscribe方法为发送的号码订阅该Topic。Topic即一个消息信道,当有消息发送至topic中时,SNS服务将会将该消息发送至订阅该topic的终端节点中。Topic可通过AWS Console创建,也可通过AWS SDK中的createTopic方法创建。

通过SDK调用createTopic创建Topic,需要包括NameAttributesTags三个参数,其中Name为必须的参数。Attributes参数。

const params = {Name: 'STRING_VALUE', // Topic 名称Attributes: {'<attributeName>': 'STRING_VALUE',/* '<attributeName>': ... */},Tags: [{Key: 'STRING_VALUE', // Tag keyValue: 'STRING_VALUE', // Tag value},// ...],
};const response = await snsService.createTopic(params).promise();
// response.TopicArn

完成topic的创建之后,即可为需要发送短信的电话号码订阅所创建的topic。为电话号码订阅topic需要使用subscribe方法,它必填的参数包括TopicArnEndpoint以及Protocol。其中,Protocol的值必须为smsTopicArn的值为创建的Topic Arn地址,Endpoint为订阅Topic的电话号码。另外,它的参数还包括有Attributes以及ReturnSubscriptionArn两个属性。Attributes属性如同publish方法的MessageAttributes属性,通过它的DeliveryPolicyFilterPolicyRawMessageDelivery配置订阅的相关设置。

const params = {Protocol: 'sms',TopicArn: topicArn,// Attributes: {//   '<attributeName>': 'STRING_VALUE',// },Endpoint: phoneNumber,// ReturnSubscriptionArn: false,
};const response = await snsService.subscribe(params).promise();

在为需要发送短信的号码订阅topic后,即可调用publish方法发送消息。发送短信至多个号码时调用publish方法的参数与发送至单个号码大致相同,唯一需要修改的地方为不再需要设置PhoneNumber,而是需要设置TopicArn属性,它的值即为上面调用createTopic所得到的TopicArn字段。

const params = {Message: text,MessageAttributes: {// 发送短信至topic同样可设置SMSType, MaxPrice, SenderId三个属性'AWS.SNS.SMS.SMSType': {DataType: 'String',StringValue: 'Transactional', // Transactional or Promotional},// AWS.SNS.SMS.MaxPrice// AWS.SNS.SMS.SenderId},TopicArn: topicArn, // 群发的topic ARN地址
};const response = await snsService.publish(params).promise();

结束语

AWS的free tier提供了每月100条的免费短信可以使用,但需要注意的是此处的免费短信接收方为美国号码。若要发送短信至国内号码,价格约为0.01531 USD(约0.11元),该价格相对于国内服务商较为昂贵。另外,SNS发送短信至国内时失败率也较高,且在发送失败的情况下也是按正常价格收取费用。在实际开发中,若不是以海外业务为主的情况下,可考虑国内服务商提供的短信服务。

参考资料

  1. Amazon Simple Notification Service Developer Guide
  2. AWS Javascript SDK Docs

Node.js中使用AWS SNS服务发送短信相关推荐

  1. node.js中ws模块创建服务端和客户端,网页WebSocket客户端

    首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...

  2. 如何使用阿里巴巴短信服务发送短信验证码

    关于调用阿里巴巴短信服务发送短信验证的接口的方法: 用户的注册 1.首先我们需要在阿里大于(www.alidayu.com)注册一个账号登录 点击进入控制台 点击使用短信服务 然后需要你申请签名和模板 ...

  3. 使用阿里云的短信服务发送短信

    原文地址使用阿里云的短信服务发送短信 在给客户开发一个信息发送功能的时候,需要涉及到短信的发送,短信发送一般不同的厂商提供的接口不同,处理方式也不太一样,之前用的一个厂商的,提供了一个封装类就很容易发 ...

  4. node.js中net网络模块TCP服务端与客户端的使用

    node.js中net模块为我们提供了TCP服务器和客户端通信的各种接口. 一.创建服务器并监听端口 const net = require('net');//创建一个tcp服务 //参数一表示创建服 ...

  5. uni-app中使用native.js调用android API实现双卡发送短信

    uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台官网地址 因 ...

  6. 【微服务集成阿里SMS短信服务发送短信】

    发送短信项目中很多地方都在使用,所以集成一个单独的服务,如果某个服务需要发送短信只需要依赖短信服务即可. 1.开通阿里SMS短信,创建模板 (省略) 2.创建短信服务 common-server-sm ...

  7. 使用阿里云提供的短信服务发送短信(个人版)

    本人最近需要实现一个注册发短信验证码的功能,找了几家短信服务平台,如腾讯云,云片网等,发现他们都没有提供给用户个人的短信服务权限,申请短信签名等都需要有企业等相关证明,最后找到了阿里云的短信服务平台, ...

  8. 阿里云 短信服务——发送短信验证码图文教程

    阿里云短信服务 前言 配置阿里云短信服务 准备工作 1.获取Accesskey 1.2创建子账号 1.2为刚创建的用户分配短信服务的权限 2.1申请签名 2.2申请模板 2.3由于目前还没有使用到系统 ...

  9. 用阿里云短信服务--发送短信demo

    一. AccessKey管理 内容包括:开启子用户AccessKey,创建用户组,给用户组添加sms短信服务权限,创建用户,添加用户到用户组中. 详细操作: 登录阿里云,点击控制台右上角的头像,点击A ...

  10. 2021最新 使用阿里云的短信服务发送短信

    在给客户开发一个信息发送功能的时候,需要涉及到短信的发送,短信发送一般不同的厂商提供的接口不同,处理方式也不太一样,之前用的一个厂商的,提供了一个封装类就很容易发送短息,因此都是基于HTTP协议做的一 ...

最新文章

  1. java mysql乐观锁_java乐观锁使用
  2. python pypcap 安装失败_解决Windows 10下python安装pypcap失败的问题
  3. android 47 service绑定
  4. 北斗导航 | 北斗卫星导航信号串行捕获算法MATLAB仿真(附源代码)
  5. 判断一个数字是否存在于某一个数据之中
  6. 互联网人才流向说明了什么
  7. flask返回数据类型
  8. Android--手机root获取与判断应用是否获取
  9. linux查找、搜索字符或文件
  10. 许多年轻人,尤其是刚毕业走上社会的年轻人,都误以为做销售很赚钱
  11. html克隆元素增加id,h.js - 元素克隆与追加
  12. hdu3336 Count the string
  13. PMP知识点速记——4.1制定项目章程
  14. JS实现自定义右键菜单
  15. 百度贴吧发帖的方法技巧
  16. Python基本语法(初学者,不是很完善)
  17. Oracle 还原数据库
  18. 华为防火墙产品介绍及工作原理
  19. 那些做App启动页面应该要想到的地方(Android)
  20. 【Opencv实战】识别水果的软件叫什么?一款超好用的识别软件分享,一秒鉴定(真是活~久~见~啊)

热门文章

  1. H264视频压缩算法简析
  2. 2020年百度之星程序设计大赛-初赛一(Drink、GPA、Dec)
  3. bbsmax mysql_MySQL中自己不太常用的命令
  4. juniper防火墙命令大全(中文)
  5. eclipse 如何查看Java源码
  6. socket网络编程流程
  7. 34款管理系统、ERP、CRM、OA等(冠唐\金蝶等)
  8. 基于springboot2.0.6版本的TX-LCN分布式事务搭建说明
  9. html模板原型,政务管理系统原型模板分享
  10. 从青铜到王者的路线,javasocket编程聊天室