2021-10-12 23:55:01 -04:00
|
|
|
const NotificationProvider = require("./notification-provider");
|
|
|
|
const { DOWN, UP } = require("../../src/util");
|
2021-10-13 02:41:59 -04:00
|
|
|
const { default: axios } = require("axios");
|
|
|
|
const Crypto = require("crypto");
|
|
|
|
const qs = require("qs");
|
2021-10-12 23:55:01 -04:00
|
|
|
|
|
|
|
class AliyunSMS extends NotificationProvider {
|
|
|
|
name = "AliyunSMS";
|
|
|
|
|
2023-08-11 03:46:41 -04:00
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
2021-10-12 23:55:01 -04:00
|
|
|
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
|
2024-03-14 09:21:15 -04:00
|
|
|
const okMsg = "Sent Successfully.";
|
2021-10-12 23:55:01 -04:00
|
|
|
|
|
|
|
try {
|
|
|
|
if (heartbeatJSON != null) {
|
2021-10-14 04:24:03 -04:00
|
|
|
let msgBody = JSON.stringify({
|
2021-10-12 23:55:01 -04:00
|
|
|
name: monitorJSON["name"],
|
|
|
|
time: heartbeatJSON["time"],
|
|
|
|
status: this.statusToString(heartbeatJSON["status"]),
|
|
|
|
msg: heartbeatJSON["msg"],
|
|
|
|
});
|
2023-08-14 16:14:28 -04:00
|
|
|
if (await this.sendSms(notification, msgBody)) {
|
2021-10-13 02:41:59 -04:00
|
|
|
return okMsg;
|
|
|
|
}
|
|
|
|
} else {
|
2021-10-14 04:24:03 -04:00
|
|
|
let msgBody = JSON.stringify({
|
2021-10-13 02:41:59 -04:00
|
|
|
name: "",
|
|
|
|
time: "",
|
|
|
|
status: "",
|
|
|
|
msg: msg,
|
|
|
|
});
|
2023-08-14 16:14:28 -04:00
|
|
|
if (await this.sendSms(notification, msgBody)) {
|
2021-10-12 23:55:01 -04:00
|
|
|
return okMsg;
|
|
|
|
}
|
2021-10-13 02:41:59 -04:00
|
|
|
}
|
2021-10-12 23:55:01 -04:00
|
|
|
} catch (error) {
|
|
|
|
this.throwGeneralAxiosError(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-16 15:24:53 -04:00
|
|
|
/**
|
|
|
|
* Send the SMS notification
|
|
|
|
* @param {BeanModel} notification Notification details
|
|
|
|
* @param {string} msgbody Message template
|
2024-03-15 10:02:55 -04:00
|
|
|
* @returns {Promise<boolean>} True if successful else false
|
2022-04-16 15:24:53 -04:00
|
|
|
*/
|
2021-10-13 02:41:59 -04:00
|
|
|
async sendSms(notification, msgbody) {
|
2021-10-14 04:24:03 -04:00
|
|
|
let params = {
|
2021-10-13 02:41:59 -04:00
|
|
|
PhoneNumbers: notification.phonenumber,
|
|
|
|
TemplateCode: notification.templateCode,
|
|
|
|
SignName: notification.signName,
|
|
|
|
TemplateParam: msgbody,
|
|
|
|
AccessKeyId: notification.accessKeyId,
|
|
|
|
Format: "JSON",
|
|
|
|
SignatureMethod: "HMAC-SHA1",
|
|
|
|
SignatureVersion: "1.0",
|
|
|
|
SignatureNonce: Math.random().toString(),
|
|
|
|
Timestamp: new Date().toISOString(),
|
|
|
|
Action: "SendSms",
|
|
|
|
Version: "2017-05-25",
|
|
|
|
};
|
|
|
|
|
|
|
|
params.Signature = this.sign(params, notification.secretAccessKey);
|
2021-10-14 04:24:03 -04:00
|
|
|
let config = {
|
2021-10-13 02:41:59 -04:00
|
|
|
method: "POST",
|
|
|
|
url: "http://dysmsapi.aliyuncs.com/",
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
|
|
},
|
|
|
|
data: qs.stringify(params),
|
|
|
|
};
|
|
|
|
|
2021-10-14 04:24:03 -04:00
|
|
|
let result = await axios(config);
|
2022-04-17 03:43:03 -04:00
|
|
|
if (result.data.Message === "OK") {
|
2021-10-13 02:41:59 -04:00
|
|
|
return true;
|
|
|
|
}
|
2023-08-14 16:14:28 -04:00
|
|
|
|
|
|
|
throw new Error(result.data.Message);
|
2021-10-13 02:41:59 -04:00
|
|
|
}
|
|
|
|
|
2022-04-16 15:24:53 -04:00
|
|
|
/**
|
|
|
|
* Aliyun request sign
|
2023-08-11 03:46:41 -04:00
|
|
|
* @param {object} param Parameters object to sign
|
2022-04-16 15:24:53 -04:00
|
|
|
* @param {string} AccessKeySecret Secret key to sign parameters with
|
2023-08-11 03:46:41 -04:00
|
|
|
* @returns {string} Base64 encoded request
|
2022-04-16 15:24:53 -04:00
|
|
|
*/
|
2021-10-13 02:41:59 -04:00
|
|
|
sign(param, AccessKeySecret) {
|
2021-10-14 04:24:03 -04:00
|
|
|
let param2 = {};
|
|
|
|
let data = [];
|
2021-10-13 02:41:59 -04:00
|
|
|
|
2021-10-14 04:24:03 -04:00
|
|
|
let oa = Object.keys(param).sort();
|
2021-10-13 02:41:59 -04:00
|
|
|
|
2021-10-14 04:24:03 -04:00
|
|
|
for (let i = 0; i < oa.length; i++) {
|
|
|
|
let key = oa[i];
|
2021-10-13 02:41:59 -04:00
|
|
|
param2[key] = param[key];
|
|
|
|
}
|
2022-04-29 22:45:38 -04:00
|
|
|
|
2022-04-29 22:42:59 -04:00
|
|
|
// Escape more characters than encodeURIComponent does.
|
|
|
|
// For generating Aliyun signature, all characters except A-Za-z0-9~-._ are encoded.
|
|
|
|
// See https://help.aliyun.com/document_detail/315526.html
|
2022-05-01 00:10:47 -04:00
|
|
|
// This encoding methods as known as RFC 3986 (https://tools.ietf.org/html/rfc3986)
|
2022-04-29 18:28:16 -04:00
|
|
|
let moreEscapesTable = function (m) {
|
2022-04-29 17:56:10 -04:00
|
|
|
return {
|
2022-04-29 18:28:16 -04:00
|
|
|
"!": "%21",
|
|
|
|
"*": "%2A",
|
|
|
|
"'": "%27",
|
|
|
|
"(": "%28",
|
2022-04-29 17:56:10 -04:00
|
|
|
")": "%29"
|
2022-04-29 18:28:16 -04:00
|
|
|
}[m];
|
2022-04-29 17:56:10 -04:00
|
|
|
};
|
2021-10-13 02:41:59 -04:00
|
|
|
|
2021-10-14 04:24:03 -04:00
|
|
|
for (let key in param2) {
|
2022-04-29 17:56:10 -04:00
|
|
|
let value = encodeURIComponent(param2[key]).replace(/[!*'()]/g, moreEscapesTable);
|
|
|
|
data.push(`${encodeURIComponent(key)}=${value}`);
|
2021-10-13 02:41:59 -04:00
|
|
|
}
|
|
|
|
|
2021-10-14 04:24:03 -04:00
|
|
|
let StringToSign = `POST&${encodeURIComponent("/")}&${encodeURIComponent(data.join("&"))}`;
|
2021-10-13 02:41:59 -04:00
|
|
|
return Crypto
|
|
|
|
.createHmac("sha1", `${AccessKeySecret}&`)
|
|
|
|
.update(Buffer.from(StringToSign))
|
|
|
|
.digest("base64");
|
|
|
|
}
|
|
|
|
|
2022-04-16 15:24:53 -04:00
|
|
|
/**
|
|
|
|
* Convert status constant to string
|
|
|
|
* @param {const} status The status constant
|
2023-08-11 03:46:41 -04:00
|
|
|
* @returns {string} Status
|
2022-04-16 15:24:53 -04:00
|
|
|
*/
|
2021-10-12 23:55:01 -04:00
|
|
|
statusToString(status) {
|
|
|
|
switch (status) {
|
|
|
|
case DOWN:
|
|
|
|
return "DOWN";
|
|
|
|
case UP:
|
|
|
|
return "UP";
|
|
|
|
default:
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = AliyunSMS;
|