add slack webhooks messaging (#5569)
* add slack webhooks messaging Signed-off-by: si458 <simonsmith5521@gmail.com> * remove my test slack incoming webhook Signed-off-by: si458 <simonsmith5521@gmail.com> --------- Signed-off-by: si458 <simonsmith5521@gmail.com>
Simon Smith committed
Nov 25, 2023 at 20:45 UTC
5581f3ace8ee324a06d11bb949b023ec27f4d6fb
6 files changed
+58
-2
docs/docs/meshcentral/config.md
+5
@@ -3419,6 +3419,11 @@ See description for information about each item.
3419
"default": false,
3420
"description": "Enabled CallMeBot integration support."
3421
},
3422
+ "slack": {
3423
+ "type": "boolean",
3424
+ "default": false,
3425
+ "description": "Enabled Slack integration support."
3426
+ },
3427
"pushover": {
3428
"type": "object",
3429
"description": "Configure Pushover messaging system",
docs/docs/messaging/index.md
+15
@@ -231,6 +231,21 @@ You can enable the MeshCentral [Zulip](https://zulip.com/) integration with the
231
}
232
```
233
234
+## Slack setup
235
+
236
+[Slack](https://slack.com/) integration is achieved by the use of Incoming Webhooks.
237
+You can get started by following the Slack guide [here](https://api.slack.com/messaging/webhooks) and getting your URL
238
+
239
+Once you have your incoming webhooks url, You can enable the [Slack](https://slack.com/) integration with the following config.json section
240
+
241
+```json
242
+{
243
+ "messaging": {
244
+ "slack": true
245
+ }
246
+}
247
+```
248
+
249
## User Setup
250
251
Once one or more messaging systems are setup with MeshCentral, users will be able to register their handle and verify that they own that account by typing in a 6 digit code.
meshcentral-config-schema.json
+5
@@ -3412,6 +3412,11 @@
3412
"default": false,
3413
"description": "Enabled CallMeBot integration support."
3414
},
3415
+ "slack": {
3416
+ "type": "boolean",
3417
+ "default": false,
3418
+ "description": "Enabled Slack integration support."
3419
+ },
3420
"pushover": {
3421
"type": "object",
3422
"description": "Configure Pushover messaging system",
meshmessaging.js
+20
-1
@@ -107,13 +107,20 @@
107
}
108
}
109
110
+// For Slack Webhook
111
+{
112
+ "messaging": {
113
+ "slack": true
114
+ }
115
+}
116
+
117
*/
118
119
// Construct a messaging server object
120
module.exports.CreateServer = function (parent) {
121
var obj = {};
122
obj.parent = parent;
116
- obj.providers = 0; // 1 = Telegram, 2 = Signal, 4 = Discord, 8 = XMPP, 16 = CallMeBot, 32 = Pushover, 64 = ntfy, 128 = Zulip
123
+ obj.providers = 0; // 1 = Telegram, 2 = Signal, 4 = Discord, 8 = XMPP, 16 = CallMeBot, 32 = Pushover, 64 = ntfy, 128 = Zulip, 256 = Slack
124
obj.telegramClient = null;
125
obj.discordClient = null;
126
obj.discordUrl = null;
@@ -122,6 +129,7 @@ module.exports.CreateServer = function (parent) {
129
obj.callMeBotClient = null;
130
obj.pushoverClient = null;
131
obj.zulipClient = null;
132
+ obj.slackClient = null;
133
const sortCollator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' })
134
135
// Telegram client setup
@@ -270,6 +278,12 @@ module.exports.CreateServer = function (parent) {
278
obj.providers += 128; // Enable zulip messaging
279
}
280
281
+ // Slack Webhook setup (https://slack.com)
282
+ if (parent.config.messaging.slack) {
283
+ obj.slackClient = true;
284
+ obj.providers += 256; // Enable slack messaging
285
+ }
286
+
287
// Send a direct message to a specific userid
288
async function discordSendMsg(userId, message) {
289
const user = await obj.discordClient.users.fetch(userId).catch(function () { return null; });
@@ -350,6 +364,11 @@ module.exports.CreateServer = function (parent) {
364
subject: domain.title ? domain.title : 'MeshCentral'
365
});
366
if (func != null) { func(true); }
367
+ }else if ((to.startsWith('slack:')) && (obj.slackClient != null)) { //slack
368
+ const req = require('https').request(new URL(to.substring(6)), { method: 'POST' }, function (res) { if (func != null) { func(true); } });
369
+ req.on('error', function (err) { if (func != null) { func(false); } });
370
+ req.write(JSON.stringify({"text": msg }));
371
+ req.end();
372
} else {
373
// No providers found
374
if (func != null) { func(false, "No messaging providers found for this message."); }
meshuser.js
+3
-1
@@ -1,4 +1,4 @@
1
-/**
1
+/**
2
* @description MeshCentral MeshAgent
3
* @author Ylian Saint-Hilaire & Bryan Roe
4
* @copyright Intel Corporation 2018-2022
@@ -6775,6 +6775,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
6775
if ((command.service == 32) && ((parent.parent.msgserver.providers & 32) != 0)) { handle = 'pushover:' + command.handle; }
6776
if ((command.service == 64) && ((parent.parent.msgserver.providers & 64) != 0)) { handle = 'ntfy:' + command.handle; }
6777
if ((command.service == 128) && ((parent.parent.msgserver.providers & 128) != 0)) { handle = 'zulip:' + command.handle; }
6778
+ if ((command.service == 256) && ((parent.parent.msgserver.providers & 256) != 0)) { handle = 'slack:' + command.handle; }
6779
if (handle == null) return;
6780
6781
// Send a verification message
@@ -6921,6 +6922,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
6922
if ((parent.parent.msgserver.providers & 32) != 0) { r.push("Usage: MSG \"pushover:[userkey]\" \"Message\"."); }
6923
if ((parent.parent.msgserver.providers & 64) != 0) { r.push("Usage: MSG \"ntfy:[topic]\" \"Message\"."); }
6924
if ((parent.parent.msgserver.providers & 128) != 0) { r.push("Usage: MSG \"zulip:[topic]\" \"Message\"."); }
6925
+ if ((parent.parent.msgserver.providers & 256) != 0) { r.push("Usage: MSG \"slack:[webhook]\" \"Message\"."); }
6926
cmdData.result = r.join('\r\n');
6927
} else {
6928
parent.parent.msgserver.sendMessage(cmdData.cmdargs['_'][0], cmdData.cmdargs['_'][1], domain, function (status, msg) {
views/default.handlebars
+10
@@ -12276,6 +12276,7 @@
12276
if ((serverinfo.userMsgProviders & 32) != 0) { y += '<option value=32>' + "Pushover" + '</option>'; }
12277
if ((serverinfo.userMsgProviders & 64) != 0) { y += '<option value=64>' + "ntfy" + '</option>'; }
12278
if ((serverinfo.userMsgProviders & 128) != 0) { y += '<option value=128>' + "Zulip" + '</option>'; }
12279
+ if ((serverinfo.userMsgProviders & 256) != 0) { y += '<option value=256>' + "Slack" + '</option>'; }
12280
y += '</select>';
12281
x += '<table><tr><td>' + "Service" + '<td>' + y;
12282
x += '<tr><td>' + "Handle" + '<td><input maxlength=1024 style=width:160px;margin-left:8px id=d2handleinput onKeyUp=account_manageMessagingValidate() onkeypress="if (event.key==\'Enter\') account_manageMessagingValidate(1)">';
@@ -12285,6 +12286,7 @@
12286
x += '<div id=d2pushoverinfo style=display:none><br /><a href=https://pushover.net/ target="_pushover">' + "Information at Pushover.net" + '</a></div>';
12287
console.log(serverinfo.userMsgNftyUrl);
12288
x += '<div id=d2ntfyinfo style=display:none><br /><a href="' + (serverinfo.userMsgNftyUrl ? serverinfo.userMsgNftyUrl : 'https://ntfy.sh/') + '" target="_ntfy">' + "Free service at ntfy.sh" + '</a></div>';
12289
+ x += '<div id=d2slackinfo style=display:none><br /><a href=https://api.slack.com/messaging/webhooks target="_slack">' + "Slack Webhook Setup" + '</a></div>';
12290
setDialogMode(2, "Messaging Notifications", 3, account_manageMessagingAdd, x, 'verifyMessaging');
12291
Q('d2handleinput').focus();
12292
account_manageMessagingValidate();
@@ -12296,12 +12298,14 @@
12298
QV('d2callmebotinfo', Q('d2serviceselect').value == 16);
12299
QV('d2pushoverinfo', Q('d2serviceselect').value == 32);
12300
QV('d2ntfyinfo', Q('d2serviceselect').value == 64);
12301
+ QV('d2slackinfo', Q('d2serviceselect').value == 256);
12302
if (Q('d2serviceselect').value == 4) { Q('d2handleinput')['placeholder'] = "Username:0000"; }
12303
else if (Q('d2serviceselect').value == 8) { Q('d2handleinput')['placeholder'] = "username@server.com"; }
12304
else if (Q('d2serviceselect').value == 16) { Q('d2handleinput')['placeholder'] = "https://api.callmebot.com/..."; }
12305
else if (Q('d2serviceselect').value == 32) { Q('d2handleinput')['placeholder'] = "User key"; }
12306
else if (Q('d2serviceselect').value == 64) { Q('d2handleinput')['placeholder'] = "Topic"; }
12307
else if (Q('d2serviceselect').value == 128) { Q('d2handleinput')['placeholder'] = "username@sample.com"; }
12308
+ else if (Q('d2serviceselect').value == 256) { Q('d2handleinput')['placeholder'] = "https://hooks.slack.com/..."; }
12309
else { Q('d2handleinput')['placeholder'] = "Username"; }
12310
var ok = (Q('d2handleinput').value.length > 0); QE('idx_dlgOkButton', ok); if ((x == 1) && ok) { dialogclose(1); }
12311
}
@@ -16185,6 +16189,7 @@
16189
if ((serverinfo.userMsgProviders & 32) != 0) { y += '<option value=32>' + "Pushover" + '</option>'; }
16190
if ((serverinfo.userMsgProviders & 64) != 0) { y += '<option value=64>' + "ntfy" + '</option>'; }
16191
if ((serverinfo.userMsgProviders & 128) != 0) { y += '<option value=128>' + "Zulip" + '</option>'; }
16192
+ if ((serverinfo.userMsgProviders & 256) != 0) { y += '<option value=256>' + "Slack" + '</option>'; }
16193
y += '</select>';
16194
x += '<table style=margin-top:12px><tr><td>' + "Service" + '<td>' + y;
16195
x += '<tr><td>' + "Handle" + '<td><input maxlength=1024 style=width:160px;margin-left:8px id=d2handleinput onKeyUp=p30editMessagingValidate() onkeypress="if (event.key==\'Enter\') p30editMessagingValidate(1)">';
@@ -16193,6 +16198,7 @@
16198
x += '<div id=d2callmebotinfo style=display:none><br /><a href=https://www.callmebot.com/blog/free-api-signal-send-messages/ target="_callmebot">' + "Signal" + '</a>, <a href=https://www.callmebot.com/blog/free-api-whatsapp-messages/ target="_callmebot">' + "Whatsapp" + '</a>, <a href=https://www.callmebot.com/blog/free-api-facebook-messenger/ target="_callmebot">' + "Facebook" + '</a>, <a href=https://www.callmebot.com/blog/telegram-text-messages/ target="_callmebot">' + "Telegram" + '</a></div>';
16199
x += '<div id=d2pushoverinfo style=display:none><br /><a href=https://pushover.net/ target="_pushover">' + "Information at Pushover.net" + '</a></div>';
16200
x += '<div id=d2ntfyinfo style=display:none><br /><a href="' + (serverinfo.userMsgNftyUrl ? serverinfo.userMsgNftyUrl : 'https://ntfy.sh/') + '" target="_ntfy">' + "Free service at ntfy.sh" + '</a></div>';
16201
+ x += '<div id=d2slackinfo style=display:none><br /><a href=https://api.slack.com/messaging/webhooks target="_slack">' + "Slack Webhook Setup" + '</a></div>';
16202
setDialogMode(2, "Messaging Notifications", 3, p30editMessagingEx, x, 'verifyMessaging');
16203
Q('d2handleinput').focus();
16204
if (currentUser.msghandle) {
@@ -16209,6 +16215,7 @@
16215
if (currentUser.msghandle.startsWith('pushover:') && ((serverinfo.userMsgProviders & 32) != 0)) { Q('d2serviceselect').value = 32; Q('d2handleinput').value = currentUser.msghandle.substring(9); }
16216
if (currentUser.msghandle.startsWith('ntfy:') && ((serverinfo.userMsgProviders & 64) != 0)) { Q('d2serviceselect').value = 64; Q('d2handleinput').value = currentUser.msghandle.substring(5); }
16217
if (currentUser.msghandle.startsWith('zulip:') && ((serverinfo.userMsgProviders & 128) != 0)) { Q('d2serviceselect').value = 128; Q('d2handleinput').value = currentUser.msghandle.substring(6); }
16218
+ if (currentUser.msghandle.startsWith('slack:') && ((serverinfo.userMsgProviders & 256) != 0)) { Q('d2serviceselect').value = 256; Q('d2handleinput').value = currentUser.msghandle.substring(6); }
16219
}
16220
p30editMessagingValidate();
16221
}
@@ -16219,6 +16226,7 @@
16226
QV('d2callmebotinfo', Q('d2serviceselect').value == 16);
16227
QV('d2pushoverinfo', Q('d2serviceselect').value == 32);
16228
QV('d2ntfyinfo', Q('d2serviceselect').value == 64);
16229
+ QV('d2slackinfo', Q('d2serviceselect').value == 256);
16230
if (Q('d2serviceselect').value == 0) { Q('d2handleinput')['placeholder'] = ''; }
16231
else if (Q('d2serviceselect').value == 4) { Q('d2handleinput')['placeholder'] = "Username:0000"; }
16232
else if (Q('d2serviceselect').value == 8) { Q('d2handleinput')['placeholder'] = "username@server.com"; }
@@ -16226,6 +16234,7 @@
16234
else if (Q('d2serviceselect').value == 32) { Q('d2handleinput')['placeholder'] = "User key"; }
16235
else if (Q('d2serviceselect').value == 64) { Q('d2handleinput')['placeholder'] = "Topic"; }
16236
else if (Q('d2serviceselect').value == 128) { Q('d2handleinput')['placeholder'] = "username@sample.com"; }
16237
+ else if (Q('d2serviceselect').value == 256) { Q('d2handleinput')['placeholder'] = "https://hooks.slack.com/..."; }
16238
else { Q('d2handleinput')['placeholder'] = "Username"; }
16239
if (x == 1) { dialogclose(1); }
16240
}
@@ -16241,6 +16250,7 @@
16250
else if (Q('d2serviceselect').value == 32) { handle = 'pushover:' + Q('d2handleinput').value; }
16251
else if (Q('d2serviceselect').value == 64) { handle = 'ntfy:' + Q('d2handleinput').value; }
16252
else if (Q('d2serviceselect').value == 128) { handle = 'zulip:' + Q('d2handleinput').value; }
16253
+ else if (Q('d2serviceselect').value == 256) { handle = 'slack:' + Q('d2handleinput').value; }
16254
if (handle != null) { meshserver.send({ action: 'edituser', id: currentUser._id, msghandle: handle }); }
16255
}
16256