New notification provider: Threema Gateway (#4854)
commit
39c1283ba6
@ -0,0 +1,77 @@
|
||||
const NotificationProvider = require("./notification-provider");
|
||||
const axios = require("axios");
|
||||
|
||||
class Threema extends NotificationProvider {
|
||||
name = "threema";
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
|
||||
const url = "https://msgapi.threema.ch/send_simple";
|
||||
|
||||
const config = {
|
||||
headers: {
|
||||
"Accept": "*/*",
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"
|
||||
}
|
||||
};
|
||||
|
||||
const data = {
|
||||
from: notification.threemaSenderIdentity,
|
||||
secret: notification.threemaSecret,
|
||||
text: msg
|
||||
};
|
||||
|
||||
switch (notification.threemaRecipientType) {
|
||||
case "identity":
|
||||
data.to = notification.threemaRecipient;
|
||||
break;
|
||||
case "phone":
|
||||
data.phone = notification.threemaRecipient;
|
||||
break;
|
||||
case "email":
|
||||
data.email = notification.threemaRecipient;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported recipient type: ${notification.threemaRecipientType}`);
|
||||
}
|
||||
|
||||
try {
|
||||
await axios.post(url, new URLSearchParams(data), config);
|
||||
return "Threema notification sent successfully.";
|
||||
} catch (error) {
|
||||
const errorMessage = this.handleApiError(error);
|
||||
this.throwGeneralAxiosError(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Threema API errors
|
||||
* @param {any} error The error to handle
|
||||
* @returns {string} Additional error context
|
||||
*/
|
||||
handleApiError(error) {
|
||||
if (!error.response) {
|
||||
return error.message;
|
||||
}
|
||||
switch (error.response.status) {
|
||||
case 400:
|
||||
return "Invalid recipient identity or account not set up for basic mode (400).";
|
||||
case 401:
|
||||
return "Incorrect API identity or secret (401).";
|
||||
case 402:
|
||||
return "No credits remaining (402).";
|
||||
case 404:
|
||||
return "Recipient not found (404).";
|
||||
case 413:
|
||||
return "Message is too long (413).";
|
||||
case 500:
|
||||
return "Temporary internal server error (500).";
|
||||
default:
|
||||
return error.message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Threema;
|
@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="threema-recipient">{{ $t("threemaRecipientType") }}</label>
|
||||
<select
|
||||
id="threema-recipient" v-model="$parent.notification.threemaRecipientType" required
|
||||
class="form-select"
|
||||
>
|
||||
<option value="identity">{{ $t("threemaRecipientTypeIdentity") }}</option>
|
||||
<option value="phone">{{ $t("threemaRecipientTypePhone") }}</option>
|
||||
<option value="email">{{ $t("threemaRecipientTypeEmail") }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div v-if="$parent.notification.threemaRecipientType === 'identity'" class="mb-3">
|
||||
<label class="form-label" for="threema-recipient">{{ $t("threemaRecipient") }} {{ $t("threemaRecipientTypeIdentity") }}</label>
|
||||
<input
|
||||
id="threema-recipient"
|
||||
v-model="$parent.notification.threemaRecipient"
|
||||
class="form-control"
|
||||
minlength="8"
|
||||
maxlength="8"
|
||||
pattern="[A-Z0-9]{8}"
|
||||
required
|
||||
type="text"
|
||||
>
|
||||
<div class="form-text">
|
||||
<p>{{ $t("threemaRecipientTypeIdentityFormat") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="$parent.notification.threemaRecipientType === 'phone'" class="mb-3">
|
||||
<label class="form-label" for="threema-recipient">{{ $t("threemaRecipient") }} {{ $t("threemaRecipientTypePhone") }}</label>
|
||||
<input
|
||||
id="threema-recipient"
|
||||
v-model="$parent.notification.threemaRecipient"
|
||||
class="form-control"
|
||||
maxlength="15"
|
||||
pattern="\d{1,15}"
|
||||
required
|
||||
type="text"
|
||||
>
|
||||
<div class="form-text">
|
||||
<p>{{ $t("threemaRecipientTypePhoneFormat") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="$parent.notification.threemaRecipientType === 'email'" class="mb-3">
|
||||
<label class="form-label" for="threema-recipient">{{ $t("threemaRecipient") }} {{ $t("threemaRecipientTypeEmail") }}</label>
|
||||
<input
|
||||
id="threema-recipient"
|
||||
v-model="$parent.notification.threemaRecipient"
|
||||
class="form-control"
|
||||
maxlength="254"
|
||||
required
|
||||
type="email"
|
||||
>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="threema-sender">{{ $t("threemaSenderIdentity") }}</label>
|
||||
<input
|
||||
id="threema-sender"
|
||||
v-model="$parent.notification.threemaSenderIdentity"
|
||||
class="form-control"
|
||||
minlength="8"
|
||||
maxlength="8"
|
||||
pattern="^\*[A-Z0-9]{7}$"
|
||||
required
|
||||
type="text"
|
||||
>
|
||||
<div class="form-text">
|
||||
<p>{{ $t("threemaSenderIdentityFormat") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="threema-secret">{{ $t("threemaApiAuthenticationSecret") }}</label>
|
||||
<HiddenInput
|
||||
id="threema-secret" v-model="$parent.notification.threemaSecret" required
|
||||
autocomplete="false"
|
||||
></HiddenInput>
|
||||
</div>
|
||||
<i18n-t class="form-text" keypath="wayToGetThreemaGateway" tag="div">
|
||||
<a href="https://threema.ch/en/gateway" target="_blank">{{ $t("here") }}</a>
|
||||
</i18n-t>
|
||||
<i18n-t class="form-text" keypath="threemaBasicModeInfo" tag="div">
|
||||
<a href="https://gateway.threema.ch/en/developer/api" target="_blank">{{ $t("here") }}</a>
|
||||
</i18n-t>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import HiddenInput from "../HiddenInput.vue";
|
||||
</script>
|
Loading…
Reference in new issue