const axios = require("axios");
const {R} = require("redbean-node");
const FormData = require('form-data');
const nodemailer = require("nodemailer");
class Notification {
static async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
if (notification.type === "telegram") {
try {
await axios.get(`https://api.telegram.org/bot${notification.telegramBotToken}/sendMessage`, {
params: {
chat_id: notification.telegramChatID,
text: msg,
}
})
return true;
} catch (error) {
console.log(error)
return false;
}
} else if (notification.type === "gotify") {
try {
if (notification.gotifyserverurl.endsWith("/")) {
notification.gotifyserverurl = notification.gotifyserverurl.slice(0, -1);
}
await axios.post(`${notification.gotifyserverurl}/message?token=${notification.gotifyapplicationToken}`, {
"message": msg,
"priority": notification.gotifyPriority || 8,
"title": "Uptime-Kuma"
})
return true;
} catch (error) {
console.log(error)
return false;
}
} else if (notification.type === "webhook") {
try {
let data = {
heartbeat: heartbeatJSON,
monitor: monitorJSON,
msg,
};
let finalData;
let config = {};
if (notification.webhookContentType === "form-data") {
finalData = new FormData();
finalData.append('data', JSON.stringify(data));
config = {
headers: finalData.getHeaders()
}
} else {
finalData = data;
}
let res = await axios.post(notification.webhookURL, finalData, config)
return true;
} catch (error) {
console.log(error)
return false;
}
} else if (notification.type === "smtp") {
return await Notification.smtp(notification, msg)
} else if (notification.type === "discord") {
try {
// If heartbeatJSON is null, assume we're testing.
if(heartbeatJSON == null) {
let data = {
username: 'Uptime-Kuma',
content: msg
}
let res = await axios.post(notification.discordWebhookUrl, data)
return true;
}
// If heartbeatJSON is not null, we go into the normal alerting loop.
if(heartbeatJSON['status'] == 0) {
var alertColor = "16711680";
} else if(heartbeatJSON['status'] == 1) {
var alertColor = "65280";
}
let data = {
username: 'Uptime-Kuma',
embeds: [{
title: "Uptime-Kuma Alert",
color: alertColor,
fields: [
{
name: "Time (UTC)",
value: heartbeatJSON["time"]
},
{
name: "Message",
value: msg
}
]
}]
}
let res = await axios.post(notification.discordWebhookUrl, data)
return true;
} catch(error) {
console.log(error)
return false;
}
} else if (notification.type === "signal") {
try {
let data = {
"message": msg,
"number": notification.signalNumber,
"recipients": notification.signalRecipients.replace(/\s/g, '').split(",")
};
let config = {};
let res = await axios.post(notification.signalURL, data, config)
return true;
} catch (error) {
console.log(error)
return false;
}
} else if (notification.type === "slack") {
try {
if (heartbeatJSON == null) {
let data = {'text': "Uptime Kuma Slack testing successful."}
let res = await axios.post(notification.slackwebhookURL, data)
return true;
}
const time = heartbeatJSON["time"];
let data = {
"blocks": [{
"type": "header",
"text": {
"type": "plain_text",
"text": "Uptime Kuma Alert"
}
},
{
"type": "section",
"fields": [{
"type": "mrkdwn",
"text": '*Message*\n'+msg
},
{
"type": "mrkdwn",
"text": "*Time (UTC)*\n"+time
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Visit Uptime Kuma",
},
"value": "Uptime-Kuma",
"url": notification.slackbutton
}
]
}
]
}
let res = await axios.post(notification.slackwebhookURL, data)
return true;
} catch (error) {
console.log(error)
return false;
}
} else if (notification.type === "pushover") {
var pushoverlink = 'https://api.pushover.net/1/messages.json'
try {
if (heartbeatJSON == null) {
let data = {'message': "Uptime Kuma Pushover testing successful.",
'user': notification.pushoveruserkey, 'token': notification.pushoverapptoken, 'sound':notification.pushoversounds,
'priority': notification.pushoverpriority, 'title':notification.pushovertitle, 'retry': "30", 'expire':"3600", 'html': 1}
let res = await axios.post(pushoverlink, data)
return true;
}
let data = {
"message": "Uptime Kuma Alert\n\nMessage:" +msg + '\nTime (UTC):' +time,
"user":notification.pushoveruserkey,
"token": notification.pushoverapptoken,
"sound": notification.pushoversounds,
"priority": notification.pushoverpriority,
"title": notification.pushovertitle,
"retry": "30",
"expire": "3600",
"html": 1
}
let res = await axios.post(pushoverlink, data)
return true;
} catch (error) {
console.log(error)
return false;
}
} else {
throw new Error("Notification type is not supported")
}
}
static async save(notification, notificationID, userID) {
let bean
if (notificationID) {
bean = await R.findOne("notification", " id = ? AND user_id = ? ", [
notificationID,
userID,
])
if (! bean) {
throw new Error("notification not found")
}
} else {
bean = R.dispense("notification")
}
bean.name = notification.name;
bean.user_id = userID;
bean.config = JSON.stringify(notification)
await R.store(bean)
}
static async delete(notificationID, userID) {
let bean = await R.findOne("notification", " id = ? AND user_id = ? ", [
notificationID,
userID,
])
if (! bean) {
throw new Error("notification not found")
}
await R.trash(bean)
}
static async smtp(notification, msg) {
let transporter = nodemailer.createTransport({
host: notification.smtpHost,
port: notification.smtpPort,
secure: notification.smtpSecure,
auth: {
user: notification.smtpUsername,
pass: notification.smtpPassword,
},
});
// send mail with defined transport object
let info = await transporter.sendMail({
from: `"Uptime Kuma" <${notification.smtpFrom}>`,
to: notification.smtpTo,
subject: msg,
text: msg,
});
return true;
}
static async discord(notification, msg) {
const client = new Discord.Client();
await client.login(notification.discordToken)
const channel = await client.channels.fetch(notification.discordChannelID);
await channel.send(msg);
client.destroy()
return true;
}
}
module.exports = {
Notification,
}