更新时间:2024-11-14 GMT+08:00
Node.js
- 发送短信为单模板群发短信示例,发送分批短信为多模板群发短信示例。
- 本文档所述Demo在提供服务的过程中,可能会涉及个人数据的使用,建议您遵从国家的相关法律采取足够的措施,以确保用户的个人数据受到充分的保护。
- 本文档所述Demo仅用于功能演示,不允许客户直接进行商业使用。
- 本文档信息仅供参考,不构成任何要约或承诺。
发送短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
/*jshint esversion: 6 */ var https = require('https'); //引入https模块 var url = require('url'); //引入url模块 var querystring = require('querystring'); // 引入querystring模块 //必填,请参考"开发准备"获取如下数据,替换为实际值 var realUrl = 'https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1'; //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI var appKey = 'c8RWg3ggEcyd4D3p94bf3Y7x1Ile'; //APP_Key // 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; var appSecret = 'q4Ii87Bh************80SfD7Al'; //APP_Secret var sender = 'csms12345678'; //国内短信签名通道号 var templateId = '8ff55eac1d0b478ab3c06c3c6a492300'; //模板ID //条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称 var signature = "华为云短信测试"; //签名名称 //必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔 var receiver = '+86151****6789,+86152****7890'; //短信接收人号码 //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 var statusCallBack = ''; /** * 选填,使用无变量模板时请赋空值 var templateParas = ''; * 单变量模板示例:模板内容为"您的验证码是${1}"时,templateParas可填写为'["369751"]' * 双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,templateParas可填写为'["3","人民公园正门"]' * 模板中的每个变量都必须赋值,且取值不能为空 * 查看更多模板规范和变量规范:产品介绍>短信模板须知和短信变量须知 */ var templateParas = '["369751"]'; //模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 /** * 构造请求Body体 * * @param sender * @param receiver * @param templateId * @param templateParas * @param statusCallBack * @param signature | 签名名称,使用国内短信通用模板时填写 * @returns */ function buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, signature){ if (null !== signature && signature.length > 0) { return querystring.stringify({ 'from': sender, 'to': receiver, 'templateId': templateId, 'templateParas': templateParas, 'statusCallback': statusCallBack, 'signature': signature }); } return querystring.stringify({ 'from': sender, 'to': receiver, 'templateId': templateId, 'templateParas': templateParas, 'statusCallback': statusCallBack }); } /** * 构造X-WSSE参数值 * * @param appKey * @param appSecret * @returns */ function buildWsseHeader(appKey, appSecret){ var crypto = require('crypto'); var util = require('util'); var time = new Date(Date.now()).toISOString().replace(/.[0-9]+\Z/, 'Z'); //Created var nonce = crypto.randomBytes(64).toString('hex'); //Nonce var passwordDigestBase64Str = crypto.createHash('sha256').update(nonce + time + appSecret).digest('base64'); //PasswordDigest return util.format('UsernameToken Username="%s",PasswordDigest="%s",Nonce="%s",Created="%s"', appKey, passwordDigestBase64Str, nonce, time); } var urlobj = url.parse(realUrl); //解析realUrl字符串并返回一个 URL对象 var options = { host: urlobj.hostname, //主机名 port: urlobj.port, //端口 path: urlobj.pathname, //URI method: 'POST', //请求方法为POST headers: { //请求Headers 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"', 'X-WSSE': buildWsseHeader(appKey, appSecret) }, rejectUnauthorized: false //为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题 }; // 请求Body,不携带签名名称时,signature请填null var body = buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, signature); var req = https.request(options, (res) => { console.log('statusCode:', res.statusCode); //打印响应码 res.setEncoding('utf8'); //设置响应数据编码格式 res.on('data', (d) => { console.log('resp:', d); //打印响应数据 }); }); req.on('error', (e) => { console.error(e.message); //请求错误时,打印错误信息 }); req.write(body); //发送请求Body数据 req.end(); //结束请求 |
发送分批短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
/*jshint esversion: 6 */ var https = require('https'); //引入https模块 var url = require('url'); //引入url模块 //必填,请参考"开发准备"获取如下数据,替换为实际值 var realUrl = 'https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendDiffSms/v1'; //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI var appKey = 'c8RWg3ggEcyd4D3p94bf3Y7x1Ile'; //APP_Key // 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; var appSecret = 'q4Ii87Bh************80SfD7Al'; //APP_Secret var sender = 'csms12345678'; //国内短信签名通道号 var templateId1 = '8ff55eac1d0b478ab3c06c3c6a492300'; //模板ID1 var templateId2 = '8ff55eac1d0b478ab3c06c3c6a492300'; //模板ID2 //条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称 var signature1 = "华为云短信测试"; //签名名称1 var signature2 = "华为云短信测试"; //签名名称2 //必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔 var receiver1 = ['+86151****6789','+86152****7890']; //模板1的接收号码 var receiver2 = ['+86151****6789','+86152****7890']; //模板2的接收号码 //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 var statusCallBack = ''; /** * 选填,使用无变量模板时请赋空值 var templateParas = []; * 单变量模板示例:模板内容为"您的验证码是${1}"时,templateParas可填写为['369751'] * 双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,templateParas可填写为['3','人民公园正门'] * 模板中的每个变量都必须赋值,且取值不能为空 * 查看更多模板和变量规范:产品介绍>模板和变量规范 */ var templateParas1 = ['123456']; //模板1变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 var templateParas2 = ['234567']; //模板2变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 /** * 构造smsContent参数值 * * @param receiver * @param templateId * @param templateParas * @param signature | 签名名称,使用国内短信通用模板时填写 * @returns */ function initDiffSms(receiver, templateId, templateParas, signature){ if (null !== signature && signature.length > 0) { return {'to': receiver, 'templateId': templateId, 'templateParas': templateParas, 'signature': signature}; } return {'to': receiver, 'templateId': templateId, 'templateParas': templateParas}; } /** * 构造X-WSSE参数值 * * @param appKey * @param appSecret * @returns */ function buildWsseHeader(appKey, appSecret){ var crypto = require('crypto'); var util = require('util'); var time = new Date(Date.now()).toISOString().replace(/.[0-9]+\Z/, 'Z'); //Created var nonce = crypto.randomBytes(64).toString('hex'); //Nonce var passwordDigestBase64Str = crypto.createHash('sha256').update(nonce + time + appSecret).digest('base64'); //PasswordDigest return util.format('UsernameToken Username="%s",PasswordDigest="%s",Nonce="%s",Created="%s"', appKey, passwordDigestBase64Str, nonce, time); } var body = JSON.stringify({ //请求Body 'from': sender, 'statusCallback': statusCallBack, 'smsContent': [ //smsContent,不携带签名名称时,signature请填null initDiffSms(receiver1, templateId1, templateParas1, signature1), initDiffSms(receiver2, templateId2, templateParas2, signature2) ]} ); var urlobj = url.parse(realUrl); //解析realUrl字符串并返回一个 URL对象 var options = { host: urlobj.hostname, //主机名 port: urlobj.port, //端口 path: urlobj.pathname, //URI method: 'POST', //请求方法为POST headers: { //请求Headers 'Content-Type': 'application/json', 'Authorization': 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"', 'X-WSSE': buildWsseHeader(appKey, appSecret) }, rejectUnauthorized: false //为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题 }; var req = https.request(options, (res) => { console.log('statusCode:', res.statusCode); //打印响应码 res.setEncoding('utf8'); //设置响应数据编码格式 res.on('data', (d) => { console.log('resp:', d); //打印响应数据 }); }); req.on('error', (e) => { console.error(e.message); //请求错误时,打印错误信息 }); req.write(body); //发送请求Body数据 req.end(); //结束请求 |
接收状态报告
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/*jshint esversion: 6 */ // 短信平台上报状态报告数据样例(urlencode) //var success_body = "sequence=1&total=1&updateTime=2018-10-31T08%3A43%3A41Z&source=2&smsMsgId=2ea20735-f856-4376-afbf-570bd70a46ee_11840135&status=DELIVRD"; var failed_body = "sequence=1&total=1&updateTime=2018-10-31T08%3A43%3A41Z&source=2&smsMsgId=2ea20735-f856-4376-afbf-570bd70a46ee_11840135&status=E200027"; /** * 解析状态报告数据 * * @param data 短信平台上报的状态报告数据 * @returns */ function onSmsStatusReport(data) { var querystring = require('querystring'); var keyValues = querystring.parse(data); // 解析状态报告数据 /** * Example: 此处已解析status为例,请按需解析所需参数并自行实现相关处理 * * 'smsMsgId': 短信唯一标识 * 'total': 长短信拆分条数 * 'sequence': 拆分后短信序号 * 'source': 状态报告来源 * 'updateTime': 资源更新时间 * 'status': 状态码 */ var status = keyValues.status; // 状态报告枚举值 // 通过status判断短信是否发送成功 if ('DELIVRD' === status.toUpperCase()) { console.log('Send sms success. smsMsgId: ', keyValues.smsMsgId); } else { // 发送失败,打印status和orgCode console.log('Send sms failed. smsMsgId: ', keyValues.smsMsgId); console.log('Failed status: ', status); } } // onSmsStatusReport(success_body); onSmsStatusReport(failed_body); |
接收上行短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
/*jshint esversion: 6 */ // 上行短信通知样例(urlencode) var updata = "from=%2B86151****6789&to=1069****019&body=********&smsMsgId=9692b5be-c427-4525-8e73-cf4a6ac5b3f7"; /** * 解析上行短信通知数据 * * @param data 短信平台推送的上行短信通知数据 * @returns */ function onSmsUpData(data) { var querystring = require('querystring'); var keyValues = querystring.parse(data); // 解析上行短信通知数据 /** * Example: 此处已解析body为例,请按需解析所需参数并自行实现相关处理 * * 'smsMsgId': 上行短信唯一标识 * 'from': 上行短信发送方的号码 * 'to': 上行短信接收方的号码 * 'body': 上行短信发送的内容 */ var body = keyValues.body; // 上行短信发送的内容 console.log('Sms up data. Body: ', body); } onSmsUpData(updata); |
父主题: X-WSSE认证