mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-05-20 14:02:34 +02:00
Update SMSEagle support adding APIv2 and calls integration (#5756)
Co-authored-by: Frank Elsinga <frank@elsinga.de>
This commit is contained in:
parent
b3a11a4d9d
commit
e7d3fa6a78
3 changed files with 250 additions and 65 deletions
|
@ -11,59 +11,127 @@ class SMSEagle extends NotificationProvider {
|
||||||
const okMsg = "Sent Successfully.";
|
const okMsg = "Sent Successfully.";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (notification.smseagleApiType === "smseagle-apiv1") { // according to https://www.smseagle.eu/apiv1/
|
||||||
let config = {
|
let config = {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let postData;
|
|
||||||
let sendMethod;
|
let sendMethod;
|
||||||
let recipientType;
|
let recipientType;
|
||||||
|
let duration;
|
||||||
let encoding = (notification.smseagleEncoding) ? "1" : "0";
|
let voiceId;
|
||||||
let priority = (notification.smseaglePriority) ? notification.smseaglePriority : "0";
|
|
||||||
|
|
||||||
if (notification.smseagleRecipientType === "smseagle-contact") {
|
if (notification.smseagleRecipientType === "smseagle-contact") {
|
||||||
recipientType = "contactname";
|
recipientType = "contactname";
|
||||||
sendMethod = "sms.send_tocontact";
|
sendMethod = "/send_tocontact";
|
||||||
}
|
} else if (notification.smseagleRecipientType === "smseagle-group") {
|
||||||
if (notification.smseagleRecipientType === "smseagle-group") {
|
|
||||||
recipientType = "groupname";
|
recipientType = "groupname";
|
||||||
sendMethod = "sms.send_togroup";
|
sendMethod = "/send_togroup";
|
||||||
}
|
} else if (notification.smseagleRecipientType === "smseagle-to") {
|
||||||
if (notification.smseagleRecipientType === "smseagle-to") {
|
|
||||||
recipientType = "to";
|
recipientType = "to";
|
||||||
sendMethod = "sms.send_sms";
|
sendMethod = "/send_sms";
|
||||||
|
if (notification.smseagleMsgType !== "smseagle-sms") {
|
||||||
|
duration = notification.smseagleDuration ?? 10;
|
||||||
|
|
||||||
|
if (notification.smseagleMsgType === "smseagle-ring") {
|
||||||
|
sendMethod = "/ring_call";
|
||||||
|
} else if (notification.smseagleMsgType === "smseagle-tts") {
|
||||||
|
sendMethod = "/tts_call";
|
||||||
|
} else if (notification.smseagleMsgType === "smseagle-tts-advanced") {
|
||||||
|
sendMethod = "/tts_adv_call";
|
||||||
|
voiceId = notification.smseagleTtsModel ? notification.smseagleTtsModel : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let params = {
|
const url = new URL(notification.smseagleUrl + "/http_api" + sendMethod);
|
||||||
access_token: notification.smseagleToken,
|
|
||||||
[recipientType]: notification.smseagleRecipient,
|
|
||||||
message: msg,
|
|
||||||
responsetype: "extended",
|
|
||||||
unicode: encoding,
|
|
||||||
highpriority: priority
|
|
||||||
};
|
|
||||||
|
|
||||||
postData = {
|
url.searchParams.append("access_token", notification.smseagleToken);
|
||||||
method: sendMethod,
|
url.searchParams.append(recipientType, notification.smseagleRecipient);
|
||||||
params: params
|
if (!notification.smseagleRecipientType || notification.smseagleRecipientType === "smseagle-sms") {
|
||||||
};
|
url.searchParams.append("unicode", (notification.smseagleEncoding) ? "1" : "0");
|
||||||
|
url.searchParams.append("highpriority", notification.smseaglePriority ?? "0");
|
||||||
let resp = await axios.post(notification.smseagleUrl + "/jsonrpc/sms", postData, config);
|
|
||||||
|
|
||||||
if ((JSON.stringify(resp.data)).indexOf("message_id") === -1) {
|
|
||||||
let error = "";
|
|
||||||
if (resp.data.result && resp.data.result.error_text) {
|
|
||||||
error = `SMSEagle API returned error: ${JSON.stringify(resp.data.result.error_text)}`;
|
|
||||||
} else {
|
} else {
|
||||||
error = "SMSEagle API returned an unexpected response";
|
url.searchParams.append("duration", duration);
|
||||||
}
|
}
|
||||||
|
if (notification.smseagleRecipientType !== "smseagle-ring") {
|
||||||
|
url.searchParams.append("message", msg);
|
||||||
|
}
|
||||||
|
if (voiceId) {
|
||||||
|
url.searchParams.append("voice_id", voiceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp = await axios.get(url.toString(), config);
|
||||||
|
|
||||||
|
if (resp.data.indexOf("OK") === -1) {
|
||||||
|
let error = `SMSEagle API returned error: ${resp.data}`;
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return okMsg;
|
return okMsg;
|
||||||
|
} else if (notification.smseagleApiType === "smseagle-apiv2") { // according to https://www.smseagle.eu/docs/apiv2/
|
||||||
|
let config = {
|
||||||
|
headers: {
|
||||||
|
"access-token": notification.smseagleToken,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let encoding = (notification.smseagleEncoding) ? "unicode" : "standard";
|
||||||
|
let priority = (notification.smseaglePriority) ?? 0;
|
||||||
|
|
||||||
|
let postData = {
|
||||||
|
text: msg,
|
||||||
|
encoding: encoding,
|
||||||
|
priority: priority
|
||||||
|
};
|
||||||
|
|
||||||
|
if (notification.smseagleRecipientContact) {
|
||||||
|
postData["contacts"] = notification.smseagleRecipientContact.split(",").map(Number);
|
||||||
|
}
|
||||||
|
if (notification.smseagleRecipientGroup) {
|
||||||
|
postData["groups"] = notification.smseagleRecipientGroup.split(",").map(Number);
|
||||||
|
}
|
||||||
|
if (notification.smseagleRecipientTo) {
|
||||||
|
postData["to"] = notification.smseagleRecipientTo.split(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
let endpoint = "/messages/sms";
|
||||||
|
|
||||||
|
if (notification.smseagleMsgType !== "smseagle-sms") {
|
||||||
|
|
||||||
|
postData["duration"] = notification.smseagleDuration ?? 10;
|
||||||
|
|
||||||
|
if (notification.smseagleMsgType === "smseagle-ring") {
|
||||||
|
endpoint = "/calls/ring";
|
||||||
|
} else if (notification.smseagleMsgType === "smseagle-tts") {
|
||||||
|
endpoint = "/calls/tts";
|
||||||
|
} else if (notification.smseagleMsgType === "smseagle-tts-advanced") {
|
||||||
|
endpoint = "/calls/tts_advanced";
|
||||||
|
postData["voice_id"] = notification.smseagleTtsModel ?? 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp = await axios.post(notification.smseagleUrl + "/api/v2" + endpoint, postData, config);
|
||||||
|
|
||||||
|
const queuedCount = resp.data.filter(x => x.status === "queued").length;
|
||||||
|
const unqueuedCount = resp.data.length - queuedCount;
|
||||||
|
|
||||||
|
if (resp.status !== 200 || queuedCount === 0) {
|
||||||
|
if (!resp.data.length) {
|
||||||
|
throw new Error("SMSEagle API returned an empty response");
|
||||||
|
}
|
||||||
|
throw new Error(`SMSEagle API returned error: ${JSON.stringify(resp.data)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unqueuedCount) {
|
||||||
|
return `Sent ${queuedCount}/${resp.data.length} Messages Successfully.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return okMsg;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.throwGeneralAxiosError(error);
|
this.throwGeneralAxiosError(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,33 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="smseagle-url" class="form-label">{{ $t("smseagleUrl") }}</label>
|
<label for="smseagle-url" class="form-label">{{ $t("smseagleUrl") }}</label>
|
||||||
<input id="smseagle-url" v-model="$parent.notification.smseagleUrl" type="text" minlength="7" class="form-control" placeholder="http://127.0.0.1" required>
|
<input
|
||||||
|
id="smseagle-url" v-model="$parent.notification.smseagleUrl" type="text" minlength="7"
|
||||||
|
class="form-control" placeholder="http://127.0.0.1" required
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="smseagle-token" class="form-label">{{ $t("smseagleToken") }}</label>
|
<label for="smseagle-token" class="form-label">{{ $t("smseagleToken") }}</label>
|
||||||
<HiddenInput id="smseagle-token" v-model="$parent.notification.smseagleToken" :required="true"></HiddenInput>
|
<HiddenInput id="smseagle-token" v-model="$parent.notification.smseagleToken" :required="true"></HiddenInput>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="smseagle-api-type" class="form-label">{{ $t("smseagleApiType") }} </label>
|
||||||
|
<select id="smseagle-api-type" v-model="$parent.notification.smseagleApiType" class="form-select">
|
||||||
|
<option value="smseagle-apiv1" selected>{{ $t("smseagleApiv1") }} </option>
|
||||||
|
<option value="smseagle-apiv2">{{ $t("smseagleApiv2") }} </option>
|
||||||
|
</select>
|
||||||
|
<i18n-t tag="div" keypath="smseagleDocs" class="form-text">
|
||||||
|
<a href="https://www.smseagle.eu/api/" target="_blank">https://www.smseagle.eu/api/</a>
|
||||||
|
</i18n-t>
|
||||||
|
</div>
|
||||||
|
<div v-if="$parent.notification.smseagleApiType === 'smseagle-apiv1'" class="mb-3">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="smseagle-recipient-type" class="form-label">{{ $t("smseagleRecipientType") }}</label>
|
<label for="smseagle-recipient-type" class="form-label">{{ $t("smseagleRecipientType") }}</label>
|
||||||
<select id="smseagle-recipient-type" v-model="$parent.notification.smseagleRecipientType" class="form-select">
|
<select
|
||||||
|
id="smseagle-recipient-type" v-model="$parent.notification.smseagleRecipientType"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
|
<!-- phone number -->
|
||||||
<option value="smseagle-to" selected>{{ $t("smseagleTo") }}</option>
|
<option value="smseagle-to" selected>{{ $t("smseagleTo") }}</option>
|
||||||
<option value="smseagle-group">{{ $t("smseagleGroup") }}</option>
|
<option value="smseagle-group">{{ $t("smseagleGroup") }}</option>
|
||||||
<option value="smseagle-contact">{{ $t("smseagleContact") }}</option>
|
<option value="smseagle-contact">{{ $t("smseagleContact") }}</option>
|
||||||
|
@ -19,14 +37,88 @@
|
||||||
<label for="smseagle-recipient" class="form-label">{{ $t("smseagleRecipient") }}</label>
|
<label for="smseagle-recipient" class="form-label">{{ $t("smseagleRecipient") }}</label>
|
||||||
<input id="smseagle-recipient" v-model="$parent.notification.smseagleRecipient" type="text" class="form-control" required>
|
<input id="smseagle-recipient" v-model="$parent.notification.smseagleRecipient" type="text" class="form-control" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div
|
||||||
|
v-if="$parent.notification.smseagleMsgType === 'smseagle-sms'
|
||||||
|
|| $parent.notification.smseagleRecipientType !== 'smseagle-to'" class="mb-3"
|
||||||
|
>
|
||||||
<label for="smseagle-priority" class="form-label">{{ $t("smseaglePriority") }}</label>
|
<label for="smseagle-priority" class="form-label">{{ $t("smseaglePriority") }}</label>
|
||||||
<input id="smseagle-priority" v-model="$parent.notification.smseaglePriority" type="number" class="form-control" min="0" max="9" step="1" placeholder="0">
|
<input id="smseagle-priority" v-model="$parent.notification.smseaglePriority" type="number" class="form-control" min="0" max="9" step="1" placeholder="0" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3 form-check form-switch">
|
<div
|
||||||
|
v-if="$parent.notification.smseagleMsgType === 'smseagle-sms'
|
||||||
|
|| $parent.notification.smseagleRecipientType !== 'smseagle-to'" class="mb-3 form-check form-switch"
|
||||||
|
>
|
||||||
<label for="smseagle-encoding" class="form-label">{{ $t("smseagleEncoding") }}</label>
|
<label for="smseagle-encoding" class="form-label">{{ $t("smseagleEncoding") }}</label>
|
||||||
<input id="smseagle-encoding" v-model="$parent.notification.smseagleEncoding" type="checkbox" class="form-check-input">
|
<input id="smseagle-encoding" v-model="$parent.notification.smseagleEncoding" type="checkbox" class="form-check-input">
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="$parent.notification.smseagleRecipientType === 'smseagle-to'" class="mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="smseagle-msg-type" class="form-label">{{ $t("smseagleMsgType") }} </label>
|
||||||
|
<select id="smseagle-msg-type" v-model="$parent.notification.smseagleMsgType" class="form-select">
|
||||||
|
<option value="smseagle-sms" selected>{{ $t("smseagleMsgSms") }} </option>
|
||||||
|
<option value="smseagle-ring">{{ $t("smseagleMsgRing") }} </option>
|
||||||
|
<option value="smseagle-tts">{{ $t("smseagleMsgTts") }} </option>
|
||||||
|
<option value="smseagle-tts-advanced">{{ $t("smseagleMsgTtsAdvanced") }} </option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="$parent.notification.smseagleMsgType === 'smseagle-ring'
|
||||||
|
|| $parent.notification.smseagleMsgType === 'smseagle-tts'
|
||||||
|
|| $parent.notification.smseagleMsgType === 'smseagle-tts-advanced'" class="mb-3"
|
||||||
|
>
|
||||||
|
<label for="smseagle-duration" class="form-label">{{ $t("smseagleDuration") }}</label>
|
||||||
|
<input id="smseagle-duration" v-model="$parent.notification.smseagleDuration" type="number" class="form-control" min="0" max="30" step="1" placeholder="10">
|
||||||
|
</div>
|
||||||
|
<div v-if="$parent.notification.smseagleMsgType === 'smseagle-tts-advanced'" class="mb-3">
|
||||||
|
<label for="smseagle-tts-model" class="form-label">{{ $t("smseagleTtsModel") }} </label>
|
||||||
|
<input id="smseagle-tts-model" v-model="$parent.notification.smseagleTtsModel" type="number" class="form-control" placeholder="1" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="$parent.notification.smseagleApiType === 'smseagle-apiv2'" class="mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<!-- phone number -->
|
||||||
|
<label for="smseagle-recipient-to" class="form-label">{{ $t("smseagleTo") }}</label>
|
||||||
|
<input id="smseagle-recipient-to" v-model="$parent.notification.smseagleRecipientTo" type="text" class="form-control">
|
||||||
|
<i18n-t tag="div" keypath="smseagleComma" class="form-text" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="smseagle-recipient-group" class="form-label">{{ $t("smseagleGroupV2") }}</label>
|
||||||
|
<input id="smseagle-recipient-group" v-model="$parent.notification.smseagleRecipientGroup" type="text" class="form-control">
|
||||||
|
<i18n-t tag="div" keypath="smseagleComma" class="form-text" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="smseagle-recipient-contact" class="form-label">{{ $t("smseagleContactV2") }}</label>
|
||||||
|
<input id="smseagle-recipient-contact" v-model="$parent.notification.smseagleRecipientContact" type="text" class="form-control">
|
||||||
|
<i18n-t tag="div" keypath="smseagleComma" class="form-text" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="smseagle-priority-v2" class="form-label">{{ $t("smseaglePriority") }}</label>
|
||||||
|
<input id="smseagle-priority-v2" v-model="$parent.notification.smseaglePriority" type="number" class="form-control" min="0" max="9" step="1" placeholder="0">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3 form-check form-switch">
|
||||||
|
<label for="smseagle-encoding-v2" class="form-label">{{ $t("smseagleEncoding") }}</label>
|
||||||
|
<input id="smseagle-encoding-v2" v-model="$parent.notification.smseagleEncoding" type="checkbox" class="form-check-input">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="smseagle-msg-type-v2" class="form-label">{{ $t("smseagleMsgType") }} </label>
|
||||||
|
<select id="smseagle-msg-type-v2" v-model="$parent.notification.smseagleMsgType" class="form-select">
|
||||||
|
<option value="smseagle-sms" selected>{{ $t("smseagleMsgSms") }} </option>
|
||||||
|
<option value="smseagle-ring">{{ $t("smseagleMsgRing") }} </option>
|
||||||
|
<option value="smseagle-tts">{{ $t("smseagleMsgTts") }} </option>
|
||||||
|
<option value="smseagle-tts-advanced">{{ $t("smseagleMsgTtsAdvanced") }} </option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div v-if="$parent.notification.smseagleMsgType && $parent.notification.smseagleMsgType !== 'smseagle-sms'" class="mb-3">
|
||||||
|
<label for="smseagle-duration-v2" class="form-label">{{ $t("smseagleDuration") }}</label>
|
||||||
|
<input id="smseagle-duration-v2" v-model="$parent.notification.smseagleDuration" type="number" class="form-control" min="0" max="30" step="1" placeholder="10">
|
||||||
|
</div>
|
||||||
|
<div v-if="$parent.notification.smseagleMsgType === 'smseagle-tts-advanced'" class="mb-3">
|
||||||
|
<label for="smseagle-tts-model-v2" class="form-label">{{ $t("smseagleTtsModel") }} </label>
|
||||||
|
<input id="smseagle-tts-model-v2" v-model="$parent.notification.smseagleTtsModel" type="number" class="form-control" placeholder="1" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -36,5 +128,16 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
HiddenInput,
|
HiddenInput,
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
if (!this.$parent.notification.smseagleApiType) {
|
||||||
|
this.$parent.notification.smseagleApiType = "smseagle-apiv1";
|
||||||
|
}
|
||||||
|
if (!this.$parent.notification.smseagleMsgType) {
|
||||||
|
this.$parent.notification.smseagleMsgType = "smseagle-sms";
|
||||||
|
}
|
||||||
|
if (!this.$parent.notification.smseagleRecipientType) {
|
||||||
|
this.$parent.notification.smseagleRecipientType = "smseagle-to";
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -757,12 +757,26 @@
|
||||||
"smseagleTo": "Phone number(s)",
|
"smseagleTo": "Phone number(s)",
|
||||||
"smseagleGroup": "Phonebook group name(s)",
|
"smseagleGroup": "Phonebook group name(s)",
|
||||||
"smseagleContact": "Phonebook contact name(s)",
|
"smseagleContact": "Phonebook contact name(s)",
|
||||||
|
"smseagleGroupV2": "Phonebook group ID(s)",
|
||||||
|
"smseagleContactV2": "Phonebook contact ID(s)",
|
||||||
"smseagleRecipientType": "Recipient type",
|
"smseagleRecipientType": "Recipient type",
|
||||||
"smseagleRecipient": "Recipient(s) (multiple must be separated with comma)",
|
"smseagleRecipient": "Recipient(s) (multiple must be separated with comma)",
|
||||||
"smseagleToken": "API Access token",
|
"smseagleToken": "API Access token",
|
||||||
"smseagleUrl": "Your SMSEagle device URL",
|
"smseagleUrl": "Your SMSEagle device URL",
|
||||||
"smseagleEncoding": "Send as Unicode",
|
"smseagleEncoding": "Send as Unicode (default=GSM-7)",
|
||||||
"smseaglePriority": "Message priority (0-9, default = 0)",
|
"smseaglePriority": "Message priority (0-9, highest priority = 9)",
|
||||||
|
"smseagleMsgType": "Message type",
|
||||||
|
"smseagleMsgSms": "Sms message (default)",
|
||||||
|
"smseagleMsgRing": "Ring call",
|
||||||
|
"smseagleMsgTts": "Text-to-speech call",
|
||||||
|
"smseagleMsgTtsAdvanced": "Text-to-speech Advanced call",
|
||||||
|
"smseagleDuration": "Duration (in seconds)",
|
||||||
|
"smseagleTtsModel": "Text-to-speech model ID",
|
||||||
|
"smseagleApiType": "API version",
|
||||||
|
"smseagleApiv1": "APIv1 (for existing projects and backward compatibility)",
|
||||||
|
"smseagleApiv2": "APIv2 (recommended for new integrations)",
|
||||||
|
"smseagleDocs": "Check documentation or APIv2 availability: {0}",
|
||||||
|
"smseagleComma": "Multiple must be separated with comma",
|
||||||
"smspartnerApiurl": "You can find your API key in your dashboard at {0}",
|
"smspartnerApiurl": "You can find your API key in your dashboard at {0}",
|
||||||
"smspartnerPhoneNumber": "Phone number(s)",
|
"smspartnerPhoneNumber": "Phone number(s)",
|
||||||
"smspartnerPhoneNumberHelptext": "The number must be in the international format {0}, {1}. Multiple numbers must be separated by {2}",
|
"smspartnerPhoneNumberHelptext": "The number must be in the international format {0}, {1}. Multiple numbers must be separated by {2}",
|
||||||
|
|
Loading…
Add table
Reference in a new issue