Skip to content

Commit 86b86fa

Browse files
feat: add whatsApp (360messenger) notification provider (louislam#7046)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 953d97f commit 86b86fa

File tree

6 files changed

+484
-0
lines changed

6 files changed

+484
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
const NotificationProvider = require("./notification-provider");
2+
const axios = require("axios");
3+
4+
class Whatsapp360messenger extends NotificationProvider {
5+
name = "Whatsapp360messenger";
6+
7+
/**
8+
* @inheritdoc
9+
*/
10+
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
11+
const okMsg = "Sent Successfully.";
12+
13+
try {
14+
let config = {
15+
headers: {
16+
Accept: "application/json",
17+
"Content-Type": "application/json",
18+
Authorization: "Bearer " + notification.Whatsapp360messengerAuthToken,
19+
},
20+
};
21+
config = this.getAxiosConfigWithProxy(config);
22+
23+
// Use custom template if enabled
24+
let message = msg;
25+
if (notification.Whatsapp360messengerUseTemplate && notification.Whatsapp360messengerTemplate) {
26+
message = this.applyTemplate(
27+
notification.Whatsapp360messengerTemplate,
28+
msg,
29+
monitorJSON,
30+
heartbeatJSON
31+
);
32+
}
33+
34+
// Normalize recipients: support comma/semicolon-separated list
35+
const recipients = (notification.Whatsapp360messengerRecipient || "")
36+
.split(/[;,]/)
37+
.map((r) => r.trim())
38+
.filter((r) => r !== "");
39+
40+
// Normalize group IDs: support array (multi-select) and fallback to single value / delimited string
41+
const rawGroupIds =
42+
notification.Whatsapp360messengerGroupIds || notification.Whatsapp360messengerGroupId || "";
43+
44+
let groupIds = [];
45+
if (Array.isArray(rawGroupIds)) {
46+
groupIds = rawGroupIds
47+
.map((g) => {
48+
if (typeof g === "string") {
49+
return g.trim();
50+
}
51+
if (g && typeof g === "object" && g.id) {
52+
return String(g.id).trim();
53+
}
54+
return "";
55+
})
56+
.filter((g) => g !== "");
57+
} else if (typeof rawGroupIds === "string" && rawGroupIds.trim() !== "") {
58+
groupIds = rawGroupIds
59+
.split(/[;,]/)
60+
.map((g) => g.trim())
61+
.filter((g) => g !== "");
62+
}
63+
64+
const hasGroupId = groupIds.length > 0;
65+
const hasRecipient = recipients.length > 0;
66+
67+
// Send to both if both are provided
68+
if (hasGroupId && hasRecipient) {
69+
// Send to all individual recipients
70+
await Promise.all(
71+
recipients.map((recipient) => {
72+
const recipientData = {
73+
phonenumber: recipient,
74+
text: message,
75+
};
76+
return axios.post("https://api.360messenger.com/v2/sendMessage", recipientData, config);
77+
})
78+
);
79+
80+
// Send to all selected groups
81+
await Promise.all(
82+
groupIds.map((groupId) => {
83+
const groupData = {
84+
groupId,
85+
text: message,
86+
};
87+
return axios.post("https://api.360messenger.com/v2/sendGroup", groupData, config);
88+
})
89+
);
90+
91+
return `${okMsg} (Sent to ${recipients.length} recipient(s) and ${groupIds.length} group(s))`;
92+
} else if (hasGroupId) {
93+
// Send to group(s) only
94+
await Promise.all(
95+
groupIds.map((groupId) => {
96+
const data = {
97+
groupId,
98+
text: message,
99+
};
100+
return axios.post("https://api.360messenger.com/v2/sendGroup", data, config);
101+
})
102+
);
103+
104+
return `${okMsg} (Sent to ${groupIds.length} group(s))`;
105+
} else if (hasRecipient) {
106+
// Send to recipient(s) only
107+
await Promise.all(
108+
recipients.map((recipient) => {
109+
const data = {
110+
phonenumber: recipient,
111+
text: message,
112+
};
113+
return axios.post("https://api.360messenger.com/v2/sendMessage", data, config);
114+
})
115+
);
116+
117+
return `${okMsg} (Sent to ${recipients.length} recipient(s))`;
118+
} else {
119+
throw new Error("No recipient or group specified");
120+
}
121+
} catch (error) {
122+
this.throwGeneralAxiosError(error);
123+
}
124+
}
125+
126+
/**
127+
* Apply template with variables
128+
* @param {string} template - Template string
129+
* @param {string} msg - Default message
130+
* @param {object} monitorJSON - Monitor data
131+
* @param {object} heartbeatJSON - Heartbeat data
132+
* @returns {string} Formatted message
133+
*/
134+
applyTemplate(template, msg, monitorJSON, heartbeatJSON) {
135+
try {
136+
// Simple template replacement
137+
let result = template;
138+
139+
// Replace monitor variables
140+
if (monitorJSON) {
141+
result = result.replace(/{{ monitorJSON\['name'\] }}/g, monitorJSON.name || "");
142+
result = result.replace(/{{ monitorJSON\['url'\] }}/g, monitorJSON.url || "");
143+
}
144+
145+
// Replace message variable
146+
result = result.replace(/{{ msg }}/g, msg);
147+
148+
// Handle conditional blocks (simple if statements)
149+
result = result.replace(/{% if monitorJSON %}([\s\S]*?){% endif %}/g, (match, content) => {
150+
return monitorJSON ? content : "";
151+
});
152+
153+
return result;
154+
} catch (error) {
155+
// If template parsing fails, return original message
156+
return msg;
157+
}
158+
}
159+
}
160+
161+
module.exports = Whatsapp360messenger;

server/notification.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ const SMSPlanet = require("./notification-providers/sms-planet");
8686
const SpugPush = require("./notification-providers/spugpush");
8787
const SMSIR = require("./notification-providers/smsir");
8888
const { commandExists } = require("./util-server");
89+
const Whatsapp360messenger = require("./notification-providers/360messenger");
8990
const Webpush = require("./notification-providers/Webpush");
9091
const HaloPSA = require("./notification-providers/HaloPSA");
9192

@@ -189,6 +190,7 @@ class Notification {
189190
new Notifery(),
190191
new SMSIR(),
191192
new SendGrid(),
193+
new Whatsapp360messenger(),
192194
new Webpush(),
193195
new HaloPSA(),
194196
];

src/components/NotificationDialog.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ export default {
244244
whapi: "WhatsApp (Whapi)",
245245
evolution: "WhatsApp (Evolution)",
246246
waha: "WhatsApp (WAHA)",
247+
Whatsapp360messenger: "WhatsApp (360messenger)",
247248
};
248249
249250
// Push Services - Push notification services

0 commit comments

Comments
 (0)