Louis Lam
3 years ago
25 changed files with 836 additions and 411 deletions
@ -0,0 +1,89 @@ |
|||
//
|
|||
// bark.js
|
|||
// UptimeKuma
|
|||
//
|
|||
// Created by Lakr Aream on 2021/10/24.
|
|||
// Copyright © 2021 Lakr Aream. All rights reserved.
|
|||
//
|
|||
|
|||
const NotificationProvider = require("./notification-provider"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
const { default: axios } = require("axios"); |
|||
|
|||
// bark is an APN bridge that sends notifications to Apple devices.
|
|||
|
|||
const barkNotificationGroup = "UptimeKuma"; |
|||
const barkNotificationAvatar = "https://github.com/louislam/uptime-kuma/raw/master/public/icon.png"; |
|||
const barkNotificationSound = "telegraph"; |
|||
const successMessage = "Successes!"; |
|||
|
|||
class Bark extends NotificationProvider { |
|||
name = "Bark"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
try { |
|||
var barkEndpoint = notification.barkEndpoint; |
|||
|
|||
// check if the endpoint has a "/" suffix, if so, delete it first
|
|||
if (barkEndpoint.endsWith("/")) { |
|||
barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1); |
|||
} |
|||
|
|||
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == UP) { |
|||
let title = "UptimeKuma Monitor Up"; |
|||
return await this.postNotification(title, msg, barkEndpoint); |
|||
} |
|||
|
|||
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == DOWN) { |
|||
let title = "UptimeKuma Monitor Down"; |
|||
return await this.postNotification(title, msg, barkEndpoint); |
|||
} |
|||
|
|||
if (msg != null) { |
|||
let title = "UptimeKuma Message"; |
|||
return await this.postNotification(title, msg, barkEndpoint); |
|||
} |
|||
|
|||
} catch (error) { |
|||
throw error; |
|||
} |
|||
} |
|||
|
|||
// add additional parameter for better on device styles (iOS 15 optimized)
|
|||
appendAdditionalParameters(postUrl) { |
|||
// grouping all our notifications
|
|||
postUrl += "?group=" + barkNotificationGroup; |
|||
// set icon to uptime kuma icon, 11kb should be fine
|
|||
postUrl += "&icon=" + barkNotificationAvatar; |
|||
// picked a sound, this should follow system's mute status when arrival
|
|||
postUrl += "&sound=" + barkNotificationSound; |
|||
return postUrl; |
|||
} |
|||
|
|||
// thrown if failed to check result, result code should be in range 2xx
|
|||
checkResult(result) { |
|||
if (result.status == null) { |
|||
throw new Error("Bark notification failed with invalid response!"); |
|||
} |
|||
if (result.status < 200 || result.status >= 300) { |
|||
throw new Error("Bark notification failed with status code " + result.status); |
|||
} |
|||
} |
|||
|
|||
async postNotification(title, subtitle, endpoint) { |
|||
// url encode title and subtitle
|
|||
title = encodeURIComponent(title); |
|||
subtitle = encodeURIComponent(subtitle); |
|||
let postUrl = endpoint + "/" + title + "/" + subtitle; |
|||
postUrl = this.appendAdditionalParameters(postUrl); |
|||
let result = await axios.get(postUrl); |
|||
this.checkResult(result); |
|||
if (result.statusText != null) { |
|||
return "Bark notification succeed: " + result.statusText; |
|||
} |
|||
// because returned in range 200 ..< 300
|
|||
return successMessage; |
|||
} |
|||
} |
|||
|
|||
module.exports = Bark; |
@ -0,0 +1,42 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class ClickSendSMS extends NotificationProvider { |
|||
|
|||
name = "clicksendsms"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully."; |
|||
try { |
|||
console.log({ notification }); |
|||
let config = { |
|||
headers: { |
|||
"Content-Type": "application/json", |
|||
"Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString('base64'), |
|||
"Accept": "text/json", |
|||
} |
|||
}; |
|||
let data = { |
|||
messages: [ |
|||
{ |
|||
"body": msg.replace(/[^\x00-\x7F]/g, ""), |
|||
"to": notification.clicksendsmsToNumber, |
|||
"source": "uptime-kuma", |
|||
"from": notification.clicksendsmsSenderName, |
|||
} |
|||
] |
|||
}; |
|||
let resp = await axios.post("https://rest.clicksend.com/v3/sms/send", data, config); |
|||
if (resp.data.data.messages[0].status !== "SUCCESS") { |
|||
let error = "Something gone wrong. Api returned " + resp.data.data.messages[0].status + "."; |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
|
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = ClickSendSMS; |
@ -0,0 +1,15 @@ |
|||
<template> |
|||
<div class="mb-3"> |
|||
<label for="Bark Endpoint" class="form-label">{{ $t("Bark Endpoint") }}<span style="color: red;"><sup>*</sup></span></label> |
|||
<input id="Bark Endpoint" v-model="$parent.notification.barkEndpoint" type="text" class="form-control" required> |
|||
<div class="form-text"> |
|||
<p><span style="color: red;"><sup>*</sup></span>{{ $t("Required") }}</p> |
|||
</div> |
|||
<i18n-t tag="div" keypath="wayToGetTeamsURL" class="form-text"> |
|||
<a |
|||
href="https://github.com/Finb/Bark" |
|||
target="_blank" |
|||
>{{ $t("here") }}</a> |
|||
</i18n-t> |
|||
</div> |
|||
</template> |
@ -0,0 +1,38 @@ |
|||
<template> |
|||
<div class="mb-3"> |
|||
<label for="clicksendsms-login" class="form-label">API Username</label> |
|||
<div class="form-text"> |
|||
{{ $t("apiCredentials") }} |
|||
<a href="http://dashboard.clicksend.com/account/subaccounts" target="_blank">here</a> |
|||
</div> |
|||
<input id="clicksendsms-login" v-model="$parent.notification.clicksendsmsLogin" type="text" class="form-control" required> |
|||
<label for="clicksendsms-key" class="form-label">API Key</label> |
|||
<HiddenInput id="clicksendsms-key" v-model="$parent.notification.clicksendsmsPassword" :required="true" autocomplete="one-time-code"></HiddenInput> |
|||
</div> |
|||
<div class="mb-3"> |
|||
<div class="form-text"> |
|||
{{ $t("checkPrice", [$t("clicksendsms")]) }} |
|||
<a href="https://www.clicksend.com/us/pricing" target="_blank">https://clicksend.com/us/pricing</a> |
|||
</div> |
|||
</div> |
|||
<div class="mb-3"> |
|||
<label for="clicksendsms-to-number" class="form-label">Recipient Number</label> |
|||
<input id="clicksendsms-to-number" v-model="$parent.notification.clicksendsmsToNumber" type="text" minlength="8" maxlength="14" class="form-control" required> |
|||
</div> |
|||
<div class="mb-3"> |
|||
<label for="clicksendsms-sender-name" class="form-label">From Name/Number - |
|||
<a href="https://help.clicksend.com/article/4kgj7krx00-what-is-a-sender-id-or-sender-number" target="_blank">More Info</a> |
|||
</label> |
|||
<input id="clicksendsms-sender-name" v-model="$parent.notification.clicksendsmsSenderName" type="text" minlength="3" maxlength="11" class="form-control"> |
|||
<div class="form-text">Leave blank to use a shared sender number.</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
import HiddenInput from "../HiddenInput.vue"; |
|||
|
|||
export default { |
|||
components: { |
|||
HiddenInput, |
|||
}, |
|||
}; |
|||
</script> |
Loading…
Reference in new issue