From a2f22532213353da4dd5b6d1b543602102ddc7a6 Mon Sep 17 00:00:00 2001 From: wuwenjing Date: Wed, 13 Oct 2021 11:55:01 +0800 Subject: [PATCH 1/9] Add aliyun sms notification --- package.json | 1 + server/notification-providers/aliyun-sms.js | 70 +++++++++++++++++++++ server/notification.js | 2 + src/components/notifications/AliyunSms.vue | 24 +++++++ src/components/notifications/index.js | 2 + 5 files changed, 99 insertions(+) create mode 100644 server/notification-providers/aliyun-sms.js create mode 100644 src/components/notifications/AliyunSms.vue diff --git a/package.json b/package.json index 03112518a..1dd79e905 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "update-language-files": "cd extra/update-language-files && node index.js && eslint ../../src/languages/**.js --fix" }, "dependencies": { + "@alicloud/pop-core": "^1.7.10", "@fortawesome/fontawesome-svg-core": "~1.2.36", "@fortawesome/free-regular-svg-icons": "~5.15.4", "@fortawesome/free-solid-svg-icons": "~5.15.4", diff --git a/server/notification-providers/aliyun-sms.js b/server/notification-providers/aliyun-sms.js new file mode 100644 index 000000000..9111c429a --- /dev/null +++ b/server/notification-providers/aliyun-sms.js @@ -0,0 +1,70 @@ +const NotificationProvider = require("./notification-provider"); +const { DOWN, UP } = require("../../src/util"); +const Core = require("@alicloud/pop-core"); + +class AliyunSMS extends NotificationProvider { + name = "AliyunSMS"; + + async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { + let okMsg = "Sent Successfully."; + + try { + var client = new Core({ + accessKeyId: notification.accessKeyId, + accessKeySecret: notification.secretAccessKey, + endpoint: "https://dysmsapi.aliyuncs.com", + apiVersion: "2017-05-25", + }); + + var params = { + PhoneNumbers: notification.phonenumber, + TemplateCode: notification.templateCode, + SignName: notification.signName, + TemplateParam: JSON.stringify({ + name: "", + time: "", + status: "", + msg: msg, + }), + }; + + if (heartbeatJSON != null) { + params.TemplateParam = JSON.stringify({ + name: monitorJSON["name"], + time: heartbeatJSON["time"], + status: this.statusToString(heartbeatJSON["status"]), + msg: heartbeatJSON["msg"], + }); + } + + var requestOption = { + method: "POST", + }; + + await client.request("SendSms", params, requestOption).then( + (result) => { + console.log(JSON.stringify(result)); + return okMsg; + }, + (ex) => { + console.log(ex); + } + ); + } catch (error) { + this.throwGeneralAxiosError(error); + } + } + + statusToString(status) { + switch (status) { + case DOWN: + return "DOWN"; + case UP: + return "UP"; + default: + return status; + } + } +} + +module.exports = AliyunSMS; diff --git a/server/notification.js b/server/notification.js index 41a0063c3..21bd2b1e6 100644 --- a/server/notification.js +++ b/server/notification.js @@ -19,6 +19,7 @@ const Teams = require("./notification-providers/teams"); const Telegram = require("./notification-providers/telegram"); const Webhook = require("./notification-providers/webhook"); const Feishu = require("./notification-providers/feishu"); +const AliyunSms = require("./notification-providers/aliyun-sms"); class Notification { @@ -31,6 +32,7 @@ class Notification { const list = [ new Apprise(), + new AliyunSms(), new Discord(), new Teams(), new Gotify(), diff --git a/src/components/notifications/AliyunSms.vue b/src/components/notifications/AliyunSms.vue new file mode 100644 index 000000000..07dca8bbb --- /dev/null +++ b/src/components/notifications/AliyunSms.vue @@ -0,0 +1,24 @@ + diff --git a/src/components/notifications/index.js b/src/components/notifications/index.js index 140c1180c..74fe0df38 100644 --- a/src/components/notifications/index.js +++ b/src/components/notifications/index.js @@ -18,6 +18,7 @@ import Pushbullet from "./Pushbullet.vue"; import Line from "./Line.vue"; import Mattermost from "./Mattermost.vue"; import Matrix from "./Matrix.vue"; +import AliyunSMS from "./AliyunSms.vue"; /** * Manage all notification form. @@ -40,6 +41,7 @@ const NotificationFormList = { "promosms": PromoSMS, "lunasea": LunaSea, "Feishu": Feishu, + "AliyunSMS":AliyunSMS, "apprise": Apprise, "pushbullet": Pushbullet, "line": Line, From 57a76e6129145bdeb75755885ca31099795473e5 Mon Sep 17 00:00:00 2001 From: wuwenjing Date: Wed, 13 Oct 2021 14:41:59 +0800 Subject: [PATCH 2/9] remove `alicloud/pop-core` keep simple --- package.json | 1 - server/notification-providers/aliyun-sms.js | 106 +++++++++++++------- src/components/notifications/AliyunSms.vue | 1 + 3 files changed, 73 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index 1dd79e905..03112518a 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "update-language-files": "cd extra/update-language-files && node index.js && eslint ../../src/languages/**.js --fix" }, "dependencies": { - "@alicloud/pop-core": "^1.7.10", "@fortawesome/fontawesome-svg-core": "~1.2.36", "@fortawesome/free-regular-svg-icons": "~5.15.4", "@fortawesome/free-solid-svg-icons": "~5.15.4", diff --git a/server/notification-providers/aliyun-sms.js b/server/notification-providers/aliyun-sms.js index 9111c429a..d5d59be91 100644 --- a/server/notification-providers/aliyun-sms.js +++ b/server/notification-providers/aliyun-sms.js @@ -1,6 +1,8 @@ const NotificationProvider = require("./notification-provider"); const { DOWN, UP } = require("../../src/util"); -const Core = require("@alicloud/pop-core"); +const { default: axios } = require("axios"); +const Crypto = require("crypto"); +const qs = require("qs"); class AliyunSMS extends NotificationProvider { name = "AliyunSMS"; @@ -9,52 +11,88 @@ class AliyunSMS extends NotificationProvider { let okMsg = "Sent Successfully."; try { - var client = new Core({ - accessKeyId: notification.accessKeyId, - accessKeySecret: notification.secretAccessKey, - endpoint: "https://dysmsapi.aliyuncs.com", - apiVersion: "2017-05-25", - }); - - var params = { - PhoneNumbers: notification.phonenumber, - TemplateCode: notification.templateCode, - SignName: notification.signName, - TemplateParam: JSON.stringify({ - name: "", - time: "", - status: "", - msg: msg, - }), - }; - if (heartbeatJSON != null) { - params.TemplateParam = JSON.stringify({ + var msgBody = JSON.stringify({ name: monitorJSON["name"], time: heartbeatJSON["time"], status: this.statusToString(heartbeatJSON["status"]), msg: heartbeatJSON["msg"], }); - } - - var requestOption = { - method: "POST", - }; - - await client.request("SendSms", params, requestOption).then( - (result) => { - console.log(JSON.stringify(result)); + if (this.sendSms(notification, msgBody)) { return okMsg; - }, - (ex) => { - console.log(ex); } - ); + } else { + var msgBody = JSON.stringify({ + name: "", + time: "", + status: "", + msg: msg, + }); + if (this.sendSms(notification, msgBody)) { + return okMsg; + } + } } catch (error) { this.throwGeneralAxiosError(error); } } + async sendSms(notification, msgbody) { + var params = { + 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); + var config = { + method: "POST", + url: "http://dysmsapi.aliyuncs.com/", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + data: qs.stringify(params), + }; + + var result = await axios(config); + if (result.data.Message == "OK") { + return true; + } + return false; + } + + /** Aliyun request sign */ + sign(param, AccessKeySecret) { + var param2 = {}, + data = []; + + var oa = Object.keys(param).sort(); + + for (var i = 0; i < oa.length; i++) { + var key = oa[i]; + param2[key] = param[key]; + } + + for (var key in param2) { + data.push(`${encodeURIComponent(key)}=${encodeURIComponent(param2[key])}`); + } + + var StringToSign = `POST&${encodeURIComponent("/")}&${encodeURIComponent(data.join("&"))}`; + return Crypto + .createHmac("sha1", `${AccessKeySecret}&`) + .update(Buffer.from(StringToSign)) + .digest("base64"); + } + statusToString(status) { switch (status) { case DOWN: diff --git a/src/components/notifications/AliyunSms.vue b/src/components/notifications/AliyunSms.vue index 07dca8bbb..3f65b3464 100644 --- a/src/components/notifications/AliyunSms.vue +++ b/src/components/notifications/AliyunSms.vue @@ -16,6 +16,7 @@
+

Sms template must contain parameters:
${name} ${time} ${status} ${msg}

https://help.aliyun.com/document_detail/101414.html From 843992c4104160b76439c455e414dbe6cb8a678c Mon Sep 17 00:00:00 2001 From: wuwenjing Date: Wed, 13 Oct 2021 16:13:46 +0800 Subject: [PATCH 3/9] Add DingDing notification --- server/notification-providers/dingding.js | 79 +++++++++++++++++++++++ server/notification.js | 2 + src/components/notifications/DingDing.vue | 16 +++++ src/components/notifications/index.js | 2 + 4 files changed, 99 insertions(+) create mode 100644 server/notification-providers/dingding.js create mode 100644 src/components/notifications/DingDing.vue diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js new file mode 100644 index 000000000..5a64f4aaf --- /dev/null +++ b/server/notification-providers/dingding.js @@ -0,0 +1,79 @@ +const NotificationProvider = require("./notification-provider"); +const { DOWN, UP } = require("../../src/util"); +const { default: axios } = require("axios"); +const Crypto = require("crypto"); + +class DingDing extends NotificationProvider { + name = "DingDing"; + + async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { + let okMsg = "Sent Successfully."; + + try { + if (heartbeatJSON != null) { + var params = { + msgtype:"markdown", + markdown:{ + title: monitorJSON["name"], + text: `## [${this.statusToString(heartbeatJSON["status"])}] \n > ${heartbeatJSON["msg"]} \n > Time(UTC):${heartbeatJSON["time"]}`, + } + }; + if (this.sendToDingDing(notification, params)) { + return okMsg; + } + } else { + var params = { + msgtype:"text", + text:{ + content:msg + } + }; + if (this.sendToDingDing(notification, params)) { + return okMsg; + } + } + } catch (error) { + this.throwGeneralAxiosError(error); + } + } + + async sendToDingDing(notification, params) { + var timestamp=Date.now() + + var config = { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + url: `${notification.webHookUrl}×tamp=${timestamp}&sign=${encodeURIComponent(this.sign(timestamp, notification.secretKey))}`, + data: JSON.stringify(params), + }; + + var result = await axios(config); + if (result.data.errmsg == "ok") { + return true; + } + return false; + } + + /** DingDing sign */ + sign(timestamp,secretKey) { + return Crypto + .createHmac("sha256",Buffer.from(secretKey, 'utf8')) + .update(Buffer.from(`${timestamp}\n${secretKey}`, 'utf8')) + .digest("base64"); + } + + statusToString(status) { + switch (status) { + case DOWN: + return "DOWN"; + case UP: + return "UP"; + default: + return status; + } + } +} + +module.exports = DingDing; diff --git a/server/notification.js b/server/notification.js index 21bd2b1e6..658216f91 100644 --- a/server/notification.js +++ b/server/notification.js @@ -20,6 +20,7 @@ const Telegram = require("./notification-providers/telegram"); const Webhook = require("./notification-providers/webhook"); const Feishu = require("./notification-providers/feishu"); const AliyunSms = require("./notification-providers/aliyun-sms"); +const DingDing = require("./notification-providers/dingding"); class Notification { @@ -33,6 +34,7 @@ class Notification { const list = [ new Apprise(), new AliyunSms(), + new DingDing(), new Discord(), new Teams(), new Gotify(), diff --git a/src/components/notifications/DingDing.vue b/src/components/notifications/DingDing.vue new file mode 100644 index 000000000..3ee475c80 --- /dev/null +++ b/src/components/notifications/DingDing.vue @@ -0,0 +1,16 @@ + diff --git a/src/components/notifications/index.js b/src/components/notifications/index.js index 74fe0df38..ff0acc6a5 100644 --- a/src/components/notifications/index.js +++ b/src/components/notifications/index.js @@ -19,6 +19,7 @@ import Line from "./Line.vue"; import Mattermost from "./Mattermost.vue"; import Matrix from "./Matrix.vue"; import AliyunSMS from "./AliyunSms.vue"; +import DingDing from "./DingDing.vue"; /** * Manage all notification form. @@ -47,6 +48,7 @@ const NotificationFormList = { "line": Line, "mattermost": Mattermost, "matrix": Matrix, + "DingDing":DingDing } export default NotificationFormList From cae194f58f9410beacf8ea255113f9c758ef3965 Mon Sep 17 00:00:00 2001 From: xJoker Date: Thu, 14 Oct 2021 07:34:24 +0800 Subject: [PATCH 4/9] Update server/notification-providers/dingding.js Co-authored-by: Adam Stachowicz --- server/notification-providers/dingding.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js index 5a64f4aaf..5fd21c415 100644 --- a/server/notification-providers/dingding.js +++ b/server/notification-providers/dingding.js @@ -12,8 +12,8 @@ class DingDing extends NotificationProvider { try { if (heartbeatJSON != null) { var params = { - msgtype:"markdown", - markdown:{ + msgtype: "markdown", + markdown: { title: monitorJSON["name"], text: `## [${this.statusToString(heartbeatJSON["status"])}] \n > ${heartbeatJSON["msg"]} \n > Time(UTC):${heartbeatJSON["time"]}`, } From 2d471a5e8461275c3c2c15c8cf0f8fc306e70c76 Mon Sep 17 00:00:00 2001 From: xJoker Date: Thu, 14 Oct 2021 07:34:33 +0800 Subject: [PATCH 5/9] Update server/notification-providers/dingding.js Co-authored-by: Adam Stachowicz --- server/notification-providers/dingding.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js index 5fd21c415..ef348e2f7 100644 --- a/server/notification-providers/dingding.js +++ b/server/notification-providers/dingding.js @@ -23,8 +23,8 @@ class DingDing extends NotificationProvider { } } else { var params = { - msgtype:"text", - text:{ + msgtype: "text", + text: { content:msg } }; From 6e04ec436e8316665cadabd7a779dbebbeeb447d Mon Sep 17 00:00:00 2001 From: xJoker Date: Thu, 14 Oct 2021 07:34:45 +0800 Subject: [PATCH 6/9] Update server/notification-providers/dingding.js Co-authored-by: Adam Stachowicz --- server/notification-providers/dingding.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js index ef348e2f7..1dd52a526 100644 --- a/server/notification-providers/dingding.js +++ b/server/notification-providers/dingding.js @@ -59,7 +59,7 @@ class DingDing extends NotificationProvider { /** DingDing sign */ sign(timestamp,secretKey) { return Crypto - .createHmac("sha256",Buffer.from(secretKey, 'utf8')) + .createHmac("sha256", Buffer.from(secretKey, 'utf8')) .update(Buffer.from(`${timestamp}\n${secretKey}`, 'utf8')) .digest("base64"); } From 4e4ab0577ec5b763c093f1c5fdbb7fe21d01d244 Mon Sep 17 00:00:00 2001 From: xJoker Date: Thu, 14 Oct 2021 09:33:31 +0800 Subject: [PATCH 7/9] Update src/components/notifications/index.js Co-authored-by: Adam Stachowicz --- src/components/notifications/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/notifications/index.js b/src/components/notifications/index.js index ff0acc6a5..9018602cf 100644 --- a/src/components/notifications/index.js +++ b/src/components/notifications/index.js @@ -42,7 +42,7 @@ const NotificationFormList = { "promosms": PromoSMS, "lunasea": LunaSea, "Feishu": Feishu, - "AliyunSMS":AliyunSMS, + "AliyunSMS": AliyunSMS, "apprise": Apprise, "pushbullet": Pushbullet, "line": Line, From 8ab4788f80230d06e0a42764b27e50d806cc0bdb Mon Sep 17 00:00:00 2001 From: xJoker Date: Thu, 14 Oct 2021 09:33:36 +0800 Subject: [PATCH 8/9] Update src/components/notifications/index.js Co-authored-by: Adam Stachowicz --- src/components/notifications/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/notifications/index.js b/src/components/notifications/index.js index 9018602cf..96ee2824b 100644 --- a/src/components/notifications/index.js +++ b/src/components/notifications/index.js @@ -48,7 +48,7 @@ const NotificationFormList = { "line": Line, "mattermost": Mattermost, "matrix": Matrix, - "DingDing":DingDing + "DingDing": DingDing } export default NotificationFormList From f51156f18e2031631bfd8163264c0b0e6f407298 Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Thu, 14 Oct 2021 16:24:03 +0800 Subject: [PATCH 9/9] run eslint for #687 --- server/notification-providers/aliyun-sms.js | 24 ++++++++++----------- server/notification-providers/dingding.js | 18 ++++++++-------- src/components/notifications/AliyunSms.vue | 2 +- src/components/notifications/DingDing.vue | 2 +- src/components/notifications/Feishu.vue | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/server/notification-providers/aliyun-sms.js b/server/notification-providers/aliyun-sms.js index d5d59be91..6a2063200 100644 --- a/server/notification-providers/aliyun-sms.js +++ b/server/notification-providers/aliyun-sms.js @@ -12,7 +12,7 @@ class AliyunSMS extends NotificationProvider { try { if (heartbeatJSON != null) { - var msgBody = JSON.stringify({ + let msgBody = JSON.stringify({ name: monitorJSON["name"], time: heartbeatJSON["time"], status: this.statusToString(heartbeatJSON["status"]), @@ -22,7 +22,7 @@ class AliyunSMS extends NotificationProvider { return okMsg; } } else { - var msgBody = JSON.stringify({ + let msgBody = JSON.stringify({ name: "", time: "", status: "", @@ -38,7 +38,7 @@ class AliyunSMS extends NotificationProvider { } async sendSms(notification, msgbody) { - var params = { + let params = { PhoneNumbers: notification.phonenumber, TemplateCode: notification.templateCode, SignName: notification.signName, @@ -54,7 +54,7 @@ class AliyunSMS extends NotificationProvider { }; params.Signature = this.sign(params, notification.secretAccessKey); - var config = { + let config = { method: "POST", url: "http://dysmsapi.aliyuncs.com/", headers: { @@ -63,7 +63,7 @@ class AliyunSMS extends NotificationProvider { data: qs.stringify(params), }; - var result = await axios(config); + let result = await axios(config); if (result.data.Message == "OK") { return true; } @@ -72,21 +72,21 @@ class AliyunSMS extends NotificationProvider { /** Aliyun request sign */ sign(param, AccessKeySecret) { - var param2 = {}, - data = []; + let param2 = {}; + let data = []; - var oa = Object.keys(param).sort(); + let oa = Object.keys(param).sort(); - for (var i = 0; i < oa.length; i++) { - var key = oa[i]; + for (let i = 0; i < oa.length; i++) { + let key = oa[i]; param2[key] = param[key]; } - for (var key in param2) { + for (let key in param2) { data.push(`${encodeURIComponent(key)}=${encodeURIComponent(param2[key])}`); } - var StringToSign = `POST&${encodeURIComponent("/")}&${encodeURIComponent(data.join("&"))}`; + let StringToSign = `POST&${encodeURIComponent("/")}&${encodeURIComponent(data.join("&"))}`; return Crypto .createHmac("sha1", `${AccessKeySecret}&`) .update(Buffer.from(StringToSign)) diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js index 1dd52a526..f099192d8 100644 --- a/server/notification-providers/dingding.js +++ b/server/notification-providers/dingding.js @@ -11,7 +11,7 @@ class DingDing extends NotificationProvider { try { if (heartbeatJSON != null) { - var params = { + let params = { msgtype: "markdown", markdown: { title: monitorJSON["name"], @@ -22,10 +22,10 @@ class DingDing extends NotificationProvider { return okMsg; } } else { - var params = { + let params = { msgtype: "text", text: { - content:msg + content: msg } }; if (this.sendToDingDing(notification, params)) { @@ -38,9 +38,9 @@ class DingDing extends NotificationProvider { } async sendToDingDing(notification, params) { - var timestamp=Date.now() + let timestamp = Date.now(); - var config = { + let config = { method: "POST", headers: { "Content-Type": "application/json", @@ -49,7 +49,7 @@ class DingDing extends NotificationProvider { data: JSON.stringify(params), }; - var result = await axios(config); + let result = await axios(config); if (result.data.errmsg == "ok") { return true; } @@ -57,10 +57,10 @@ class DingDing extends NotificationProvider { } /** DingDing sign */ - sign(timestamp,secretKey) { + sign(timestamp, secretKey) { return Crypto - .createHmac("sha256", Buffer.from(secretKey, 'utf8')) - .update(Buffer.from(`${timestamp}\n${secretKey}`, 'utf8')) + .createHmac("sha256", Buffer.from(secretKey, "utf8")) + .update(Buffer.from(`${timestamp}\n${secretKey}`, "utf8")) .digest("base64"); } diff --git a/src/components/notifications/AliyunSms.vue b/src/components/notifications/AliyunSms.vue index 3f65b3464..2c25a3a9c 100644 --- a/src/components/notifications/AliyunSms.vue +++ b/src/components/notifications/AliyunSms.vue @@ -15,7 +15,7 @@ -
+

Sms template must contain parameters:
${name} ${time} ${status} ${msg}

https://help.aliyun.com/document_detail/101414.html diff --git a/src/components/notifications/DingDing.vue b/src/components/notifications/DingDing.vue index 3ee475c80..713859aca 100644 --- a/src/components/notifications/DingDing.vue +++ b/src/components/notifications/DingDing.vue @@ -6,7 +6,7 @@ -
+

For safety, must use secret key

https://developers.dingtalk.com/document/robots/custom-robot-access diff --git a/src/components/notifications/Feishu.vue b/src/components/notifications/Feishu.vue index 18dc26422..6e00a3140 100644 --- a/src/components/notifications/Feishu.vue +++ b/src/components/notifications/Feishu.vue @@ -5,7 +5,7 @@

*{{ $t("Required") }}

- +