mirror of
https://github.com/louislam/uptime-kuma.git
synced 2026-03-03 00:37:01 +00:00
feat: Notification provider Teltonika RUTxxx SMS gateway (#6952)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Frank Elsinga <frank@elsinga.de>
This commit is contained in:
95
server/notification-providers/teltonika.js
Normal file
95
server/notification-providers/teltonika.js
Normal file
@@ -0,0 +1,95 @@
|
||||
// This notification provider is only compatible with Teltonika RMS >= 7.14.0 devices.
|
||||
// See: https://community.teltonika.lt/t/implementation-of-read-only-system-files-and-mobile-and-i-o-post-get-service-removal-with-rutos-7-14/12470
|
||||
// API reference https://developers.teltonika-networks.com/reference/rut241/7.19.4/v1.11.1/messages
|
||||
|
||||
const NotificationProvider = require("./notification-provider");
|
||||
const axios = require("axios");
|
||||
const https = require("https");
|
||||
|
||||
class Teltonika extends NotificationProvider {
|
||||
name = "Teltonika";
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
|
||||
const okMsg = "Sent Successfully.";
|
||||
|
||||
// baseUrl is passed via the configuration screen.
|
||||
// Must be limited to _just_ the full origin, so: proto://host:port.
|
||||
// Everything else should be stripped. Best way to validate is to use URL().
|
||||
|
||||
let passedUrl = "";
|
||||
try {
|
||||
passedUrl = new URL(notification.teltonikaUrl);
|
||||
} catch (error) {
|
||||
throw Error("Invalid URL: " + notification.teltonikaUrl);
|
||||
}
|
||||
|
||||
const baseUrl = passedUrl.origin;
|
||||
const loginUrl = baseUrl + "/api/login";
|
||||
const smsUrl = baseUrl + "/api/messages/actions/send";
|
||||
|
||||
// Teltonika SMS gateway supports a max of 160 chars for its messages.
|
||||
const cleanMsg = msg.substring(0, 159);
|
||||
|
||||
// Starting communications with the API from here on out.
|
||||
try {
|
||||
let axiosConfig = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"cache-control": "no-cache",
|
||||
Accept: "application/json",
|
||||
},
|
||||
};
|
||||
|
||||
// In many cases, Teltonika routers will be setup using a self-signed
|
||||
// certificate. Here we give them an option to disable certificate
|
||||
// validation. It's not desirable, but sometimes the only option.
|
||||
if (notification.teltonikaUnsafeTls) {
|
||||
axiosConfig.httpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false, // Danger! Disables SSL verification
|
||||
});
|
||||
}
|
||||
|
||||
axiosConfig = this.getAxiosConfigWithProxy(axiosConfig);
|
||||
|
||||
// Logging in, to get an access token.
|
||||
// API reference https://developers.teltonika-networks.com/reference/rut241/7.19.4/v1.11.1/authentication
|
||||
// Teltonika's API access tokens expire in 5 minutes, so we always get a new one.
|
||||
let loginData = {
|
||||
username: notification.teltonikaUsername,
|
||||
password: notification.teltonikaPassword,
|
||||
};
|
||||
|
||||
let loginResp = await axios.post(loginUrl, loginData, axiosConfig);
|
||||
|
||||
if (loginResp.data.success !== true) {
|
||||
throw Error("Login failed: " + loginResp.data.errors.error);
|
||||
}
|
||||
|
||||
// Sending the SMS.
|
||||
let smsData = {
|
||||
data: {
|
||||
modem: notification.teltonikaModem,
|
||||
number: notification.teltonikaPhoneNumber,
|
||||
message: cleanMsg,
|
||||
},
|
||||
};
|
||||
|
||||
axiosConfig.headers.Authorization = "Bearer " + loginResp.data.data.token;
|
||||
|
||||
let smsResp = await axios.post(smsUrl, smsData, axiosConfig);
|
||||
|
||||
if (smsResp.data.success !== true) {
|
||||
throw Error("Api returned: ", smsResp.data.errors.error);
|
||||
}
|
||||
|
||||
return okMsg;
|
||||
} catch (error) {
|
||||
this.throwGeneralAxiosError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Teltonika;
|
||||
@@ -60,6 +60,7 @@ const Stackfield = require("./notification-providers/stackfield");
|
||||
const Teams = require("./notification-providers/teams");
|
||||
const TechulusPush = require("./notification-providers/techulus-push");
|
||||
const Telegram = require("./notification-providers/telegram");
|
||||
const Teltonika = require("./notification-providers/teltonika");
|
||||
const Threema = require("./notification-providers/threema");
|
||||
const Twilio = require("./notification-providers/twilio");
|
||||
const Splunk = require("./notification-providers/splunk");
|
||||
@@ -165,6 +166,7 @@ class Notification {
|
||||
new Teams(),
|
||||
new TechulusPush(),
|
||||
new Telegram(),
|
||||
new Teltonika(),
|
||||
new Threema(),
|
||||
new Twilio(),
|
||||
new Splunk(),
|
||||
|
||||
@@ -272,6 +272,7 @@ export default {
|
||||
SevenIO: "SevenIO",
|
||||
SMSEagle: "SMSEagle",
|
||||
SMSPartner: "SMS Partner",
|
||||
Teltonika: this.$t("Teltonika SMS Gateway"),
|
||||
twilio: "Twilio",
|
||||
};
|
||||
|
||||
|
||||
97
src/components/notifications/Teltonika.vue
Normal file
97
src/components/notifications/Teltonika.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="mb-3">
|
||||
<i18n-t keypath="teltonikaVersionWarning" tag="div" class="form-text"></i18n-t>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="teltonika-url" class="form-label">{{ $t("teltonikaUrl") }}</label>
|
||||
<input
|
||||
id="teltonika-url"
|
||||
v-model="$parent.notification.teltonikaUrl"
|
||||
type="url"
|
||||
minlength="10"
|
||||
placeholder="192.168.100.1"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
<i18n-t keypath="teltonikaUrlHelptext" tag="div" class="form-text">
|
||||
<code>https://192.168.100.1</code>
|
||||
<code>http://teltonika.domain.com:8080</code>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check form-switch">
|
||||
<input v-model="$parent.notification.teltonikaUnsafeTls" class="form-check-input" type="checkbox" />
|
||||
<label class="form-check-label">{{ $t("teltonikaUnsafeTls") }}</label>
|
||||
</div>
|
||||
<i18n-t keypath="teltonikaUnsafeTlsDescription" tag="div" class="form-text"></i18n-t>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="teltonika-username" class="form-label">{{ $t("teltonikaUsername") }}</label>
|
||||
<input
|
||||
id="teltonika-username"
|
||||
v-model="$parent.notification.teltonikaUsername"
|
||||
type="text"
|
||||
minlength="3"
|
||||
maxlength="20"
|
||||
pattern="^[a-zA-Z0-9]*$"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
<i18n-t keypath="teltonikaUsernameHelptext" tag="div" class="form-text"></i18n-t>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="teltonika-password" class="form-label">{{ $t("teltonikaPassword") }}</label>
|
||||
<HiddenInput
|
||||
id="teltonika-password"
|
||||
v-model="$parent.notification.teltonikaPassword"
|
||||
:required="true"
|
||||
autocomplete="new-password"
|
||||
></HiddenInput>
|
||||
<i18n-t keypath="teltonikaPasswordHelptext" tag="div" class="form-text">
|
||||
<code>https://192.168.100.1/system/admin/multiusers/users_configuration</code>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="teltonika-modem" class="form-label">{{ $t("teltonikaModem") }}</label>
|
||||
<input
|
||||
id="teltonika-modem"
|
||||
v-model="$parent.notification.teltonikaModem"
|
||||
type="text"
|
||||
minlength="3"
|
||||
maxlength="5"
|
||||
pattern="^[0-9]-[0-9]"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
<i18n-t keypath="teltonikaModemHelptext" tag="div" class="form-text">
|
||||
<code>1-1</code>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="teltonika-phone-number" class="form-label">{{ $t("teltonikaPhoneNumber") }}</label>
|
||||
<input
|
||||
id="teltonika-phone-number"
|
||||
v-model="$parent.notification.teltonikaPhoneNumber"
|
||||
type="text"
|
||||
minlength="10"
|
||||
maxlength="20"
|
||||
pattern="^[\d+,]+$"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
<i18n-t keypath="teltonikaPhoneNumberHelptext" tag="div" class="form-text">
|
||||
<code>+336xxxxxxxx</code>
|
||||
<code>+496xxxxxxxx</code>
|
||||
</i18n-t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HiddenInput from "../HiddenInput.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HiddenInput,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -61,6 +61,7 @@ import STMP from "./SMTP.vue";
|
||||
import Teams from "./Teams.vue";
|
||||
import TechulusPush from "./TechulusPush.vue";
|
||||
import Telegram from "./Telegram.vue";
|
||||
import Teltonika from "./Teltonika.vue";
|
||||
import Threema from "./Threema.vue";
|
||||
import Twilio from "./Twilio.vue";
|
||||
import Webhook from "./Webhook.vue";
|
||||
@@ -152,6 +153,7 @@ const NotificationFormList = {
|
||||
stackfield: Stackfield,
|
||||
teams: Teams,
|
||||
telegram: Telegram,
|
||||
Teltonika: Teltonika,
|
||||
threema: Threema,
|
||||
twilio: Twilio,
|
||||
Splunk: Splunk,
|
||||
|
||||
@@ -1457,5 +1457,19 @@
|
||||
"halopsa_field_timestamp": "Event timestamp in ISO 8601 format",
|
||||
"halopsa_field_uptime_kuma_version": "Uptime Kuma version number",
|
||||
"halopsa_id_usage_hint": "💡 Tip: Use monitor_id to reliably match alerts to tickets, and heartbeat_id to track event history",
|
||||
"halopsa_setup_step5": "Configure runbook to use monitor_id for matching alerts to existing tickets"
|
||||
"halopsa_setup_step5": "Configure runbook to use monitor_id for matching alerts to existing tickets",
|
||||
"Teltonika SMS Gateway": "Teltonika SMS Gateway",
|
||||
"teltonikaVersionWarning": "This notification provider requires that your Teltonika device runs RMS version 7.14.0, or higher.",
|
||||
"teltonikaUrl": "Your Teltonika device URL",
|
||||
"teltonikaUrlHelptext": "URL should be specified as full origin, e.g. {0}, or {1}.",
|
||||
"teltonikaUnsafeTls": "Ignore certificate validation",
|
||||
"teltonikaUnsafeTlsDescription": "Turning off TLS certificate validation opens you up to on-path (man-in-the-middle) attacks, potentially leading to data leaks and systems take-over. Do not turn off certificate validation unless you accept this attack vector. We recomend using LetsEncrypt with automatic renewal.",
|
||||
"teltonikaUsername": "API username",
|
||||
"teltonikaUsernameHelptext": "Recommendation: Create a separate account which is restricted to only sending SMS messages and enter its username here",
|
||||
"teltonikaPassword": "API password",
|
||||
"teltonikaPasswordHelptext": "You can define the API user's password in your Teltonika router, e.g. {0}",
|
||||
"teltonikaModem": "Modem Id",
|
||||
"teltonikaModemHelptext": "The id of the SMS modem, must be in the format {0}. Refer to https://developers.teltonika-networks.com/reference/ for guidance.",
|
||||
"teltonikaPhoneNumber": "Phone number",
|
||||
"teltonikaPhoneNumberHelptext": "The number must be in the international format {0}, {1}. Only one number is allowed."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user