diff --git a/aliyunSmsClient.js b/aliyunSmsClient.js index 6d380c1..b0d1fc8 100644 --- a/aliyunSmsClient.js +++ b/aliyunSmsClient.js @@ -7,46 +7,84 @@ const Tea = require('@alicloud/tea-typescript'); class AliyunSMSClient { - /** - * 使用AK&SK初始化账号Client - * @return Client - * @throws Exception - */ - static createClient(myConfig) { - // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。 - // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378664.html。 - let config = new OpenApi.Config({ - accessKeyId: myConfig.ALIBABA_CLOUD_ACCESS_KEY_ID, - accessKeySecret: myConfig.ALIBABA_CLOUD_ACCESS_KEY_SECRET, - }); - - // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi - config.endpoint = `dysmsapi.aliyuncs.com`; - return new Dysmsapi20170525.default(config); - } - - static async send(myConfig, signName, templateCode, templateParam, phoneNumber) { - let sendSmsRequest = new Dysmsapi20170525.SendSmsRequest({ - signName: signName, - templateCode: templateCode, - templateParam: templateParam, - phoneNumbers: phoneNumber, - }); - - let runtime = new Util.RuntimeOptions({ }); - let client = AliyunSMSClient.createClient(myConfig); - - let done = false; - - try { - await client.sendSmsWithOptions(sendSmsRequest, runtime); - done = true; - } catch (error) { - console.error("AliyunSMSClient send sms message failed: %s", error.message); - } - - return done; - } + /** + * 使用AK&SK初始化账号Client + * @return Client + * @throws Exception + */ + static createClient(myConfig) { + // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。 + // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378664.html。 + let config = new OpenApi.Config({ + accessKeyId: myConfig.ALIBABA_CLOUD_ACCESS_KEY_ID, + accessKeySecret: myConfig.ALIBABA_CLOUD_ACCESS_KEY_SECRET, + }); + + // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi + config.endpoint = `dysmsapi.aliyuncs.com`; + return new Dysmsapi20170525.default(config); + } + + static async send(myConfig, signName, templateCode, templateParam, phoneNumber) { + let sendSmsRequest = new Dysmsapi20170525.SendSmsRequest({ + signName: signName, + templateCode: templateCode, + templateParam: templateParam, + phoneNumbers: phoneNumber, + }); + + let runtime = new Util.RuntimeOptions({ }); + let client = AliyunSMSClient.createClient(myConfig); + + let done = false; + + try { + await client.sendSmsWithOptions(sendSmsRequest, runtime); + done = true; + } catch (error) { + console.error("AliyunSMSClient send sms message failed: %s", error.message); + } + + return done; + } + + //返回值:发送状态,可选值:[-1, 0, 1, 2, 3] + //分别对应:默认值,没发送过,发送中,发送失败,发送成功 + static async queryLastOneDetail(myConfig, phoneNumber) { + let today = new Date(); + let year = today.getFullYear(), + month = (today.getMonth() + 1).toString().padStart(2, '0'), + date = today.getDate().toString().padStart(2, '0'); + let querySmsRequest = new Dysmsapi20170525.QuerySendDetailsRequest({ + phoneNumber: phoneNumber, + sendDate: `${year}${month}${date}`, + pageSize: 10, //只查询最新的一条,此参数API貌似忽略了 + currentPage: 1, + //bizId: '' //可选 + }); + + let runtime = new Util.RuntimeOptions({ }); + let client = AliyunSMSClient.createClient(myConfig); + + let done = -1; + + try { + let queryResp = await client.querySendDetails(querySmsRequest); + let dtos = queryResp.body.smsSendDetailDTOs.smsSendDetailDTO; + + let total = queryResp.body.totalCount; + if (total == 0) { + done = 0; + }else { + let dto = dtos[0]; //取最新的一条 + done = dto.sendStatus; + } + } catch (error) { + console.error("AliyunSMSClient query sms send detail failed: %s", error.message); + } + + return done; + } } exports.default = AliyunSMSClient; \ No newline at end of file diff --git a/router_aliyun.js b/router_aliyun.js index 40e0dac..d15b227 100644 --- a/router_aliyun.js +++ b/router_aliyun.js @@ -14,7 +14,7 @@ const router = express.Router(); let customConfig = null; -//发送注册验证码短信接口 +//发送注册/登录验证码短信接口 /** * @phoneNumber: 手机号码 * @codeNumber: 4位数字的验证码 @@ -78,4 +78,69 @@ router.post('/sendverifycode', async (req, res) => { return res.status(200).json(data); }); +//查询验证码短信发送状态接口 +/** + * @phoneNumber: 手机号码 + * @action: ['register', 'login'] + * @sign: 签名 + */ +router.post('/querysendresult', async (req, res) => { + let phoneNumber = req.body.phoneNumber; + let action = req.body.action ? req.body.action : 'register'; + let sign = req.body.sign; + + let data = {code: 0, message: ''}; + + //使用默认配置 + let myConfig = defaultConfig; + + //加载自定义配置 + if (!customConfig) { + customConfig = await getCustomConfigs('./conf/custom_config.json'); + } + + //使用自定义配置 + myConfig = customConfig; + + + if (!phoneNumber || !sign) { + data.message = '参数不能为空'; + }else if (common.isPhoneNumber(phoneNumber) == false) { + data.message = '手机号码格式错误'; + }else { + let paramsCheck = {}; + for (const key in req.body) { + if (key != 'sign') { + paramsCheck[key] = req.body[key]; + } + } + + let mySign = common.sign(paramsCheck, myConfig.secret); + if (mySign.toLowerCase() != sign.toLowerCase()) { + data.message = `签名 ${sign} 不匹配,请确保密钥正确及签名方法跟文档一致`; + } + } + + if (!data.message) { + let sendResult = await aliyunSmsClient.queryLastOneDetail(myConfig, phoneNumber); + if (sendResult > -1) { + data.code = 1; + data.rescode = sendResult; + if (sendResult == 1) { + data.message = '验证码发送中'; + }else if (sendResult == 2) { + data.message = '验证码发送失败'; + }else if (sendResult == 3) { + data.message = '验证码发送成功'; + }else if (sendResult == 0) { + data.message = '没发送过验证码'; + } + }else { + data.message = '验证码发送结果查询失败,请稍后重试'; + } + } + + return res.status(200).json(data); +}); + exports.default = router; \ No newline at end of file diff --git a/test/aliyun.test.js b/test/aliyun.test.js index f01641f..485dea4 100644 --- a/test/aliyun.test.js +++ b/test/aliyun.test.js @@ -17,31 +17,42 @@ test('Custom config load test', async (t) => { console.log('Config data', defaultConfig); assert.equal(defaultConfig.ALIBABA_CLOUD_ACCESS_KEY_ID, '你的AccessKey ID'); - let myConfig = await getCustomConfigs('./conf/custom_config.json'); + let myConfig = await getCustomConfigs('../conf/custom_config.json'); console.log('Custom config data', myConfig); assert.ok(myConfig); }); -test('AliyunSmsClient test', async (t) => { - let myConfig = await getCustomConfigs('./conf/custom_config.json'); +/* +test('AliyunSmsClient send sms test', async (t) => { + let myConfig = await getCustomConfigs('../conf/custom_config.json'); let client = aliyunSmsClient.createClient(myConfig); assert.ok(client); - /* let signName = 'Ta荐', templateCode = 'SMS_465915662', templateParam = '{"code":"2345"}', phoneNumber = '13168946847'; let sended = await aliyunSmsClient.send(myConfig, signName, templateCode, templateParam, phoneNumber); - assert.equal(sended, true); - */ }); -test('Aliyun api test', async (t) => { - let myConfig = await getCustomConfigs('./conf/custom_config.json'); +test('AliyunSmsClient send query test', async (t) => { + let myConfig = await getCustomConfigs('../conf/custom_config.json'); + let client = aliyunSmsClient.createClient(myConfig); + + assert.ok(client); + + let phoneNumber = '13168946847'; + let sendRes = await aliyunSmsClient.queryLastOneDetail(myConfig, phoneNumber); + assert.equal(sendRes, 2); +}); +*/ + +/* +test('Aliyun api sms send test', async (t) => { + let myConfig = await getCustomConfigs('../conf/custom_config.json'); let api = 'http://127.0.0.1:8081/aliyun/sendverifycode'; let params = { @@ -58,6 +69,28 @@ test('Aliyun api test', async (t) => { const response = await axios.post(api, params, axiosConfig); console.log(response.data); + assert.equal(response.status, 200); + assert.equal(response.data.code, 1); +}); +*/ + +test('Aliyun api sms query test', async (t) => { + let myConfig = await getCustomConfigs('../conf/custom_config.json'); + + let api = 'http://127.0.0.1:8081/aliyun/querysendresult'; + let params = { + phoneNumber: '13168946847', + action: 'register' + }; + + let sign = common.sign(params, myConfig.secret); + assert.ok(myConfig); + assert.ok(sign); + + params.sign = sign; + const response = await axios.post(api, params, axiosConfig); + console.log(response.data); + assert.equal(response.status, 200); assert.equal(response.data.code, 1); }); \ No newline at end of file