mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-03-15 13:54:45 +00:00
feat: rework notification templating and add support for telegram (#5637)
Some checks are pending
Auto Test / auto-test (18, ARM64) (push) Blocked by required conditions
Auto Test / auto-test (18, macos-latest) (push) Blocked by required conditions
Auto Test / auto-test (18, ubuntu-latest) (push) Blocked by required conditions
Auto Test / auto-test (18, windows-latest) (push) Blocked by required conditions
Auto Test / auto-test (20, ARM64) (push) Blocked by required conditions
Auto Test / auto-test (20, macos-latest) (push) Blocked by required conditions
Auto Test / auto-test (20, ubuntu-latest) (push) Blocked by required conditions
Auto Test / auto-test (20, windows-latest) (push) Blocked by required conditions
Auto Test / armv7-simple-test (18, ARMv7) (push) Waiting to run
Auto Test / armv7-simple-test (20, ARMv7) (push) Waiting to run
Auto Test / check-linters (push) Waiting to run
Auto Test / e2e-test (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Merge Conflict Labeler / Labeling (push) Waiting to run
validate / json-yaml-validate (push) Waiting to run
validate / validate (push) Waiting to run
Some checks are pending
Auto Test / auto-test (18, ARM64) (push) Blocked by required conditions
Auto Test / auto-test (18, macos-latest) (push) Blocked by required conditions
Auto Test / auto-test (18, ubuntu-latest) (push) Blocked by required conditions
Auto Test / auto-test (18, windows-latest) (push) Blocked by required conditions
Auto Test / auto-test (20, ARM64) (push) Blocked by required conditions
Auto Test / auto-test (20, macos-latest) (push) Blocked by required conditions
Auto Test / auto-test (20, ubuntu-latest) (push) Blocked by required conditions
Auto Test / auto-test (20, windows-latest) (push) Blocked by required conditions
Auto Test / armv7-simple-test (18, ARMv7) (push) Waiting to run
Auto Test / armv7-simple-test (20, ARMv7) (push) Waiting to run
Auto Test / check-linters (push) Waiting to run
Auto Test / e2e-test (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Merge Conflict Labeler / Labeling (push) Waiting to run
validate / json-yaml-validate (push) Waiting to run
validate / validate (push) Waiting to run
This commit is contained in:
parent
fce824f5a8
commit
9857770cc7
10 changed files with 290 additions and 88 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
const { Liquid } = require("liquidjs");
|
||||||
|
const { DOWN } = require("../../src/util");
|
||||||
|
|
||||||
class NotificationProvider {
|
class NotificationProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,6 +52,50 @@ class NotificationProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a message template with notification context
|
||||||
|
* @param {string} template the template
|
||||||
|
* @param {string} msg the message that will be included in the context
|
||||||
|
* @param {?object} monitorJSON Monitor details (For Up/Down/Cert-Expiry only)
|
||||||
|
* @param {?object} heartbeatJSON Heartbeat details (For Up/Down only)
|
||||||
|
* @returns {Promise<string>} rendered template
|
||||||
|
*/
|
||||||
|
async renderTemplate(template, msg, monitorJSON, heartbeatJSON) {
|
||||||
|
const engine = new Liquid();
|
||||||
|
const parsedTpl = engine.parse(template);
|
||||||
|
|
||||||
|
// Let's start with dummy values to simplify code
|
||||||
|
let monitorName = "Monitor Name not available";
|
||||||
|
let monitorHostnameOrURL = "testing.hostname";
|
||||||
|
|
||||||
|
if (monitorJSON !== null) {
|
||||||
|
monitorName = monitorJSON["name"];
|
||||||
|
monitorHostnameOrURL = this.extractAddress(monitorJSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
let serviceStatus = "⚠️ Test";
|
||||||
|
if (heartbeatJSON !== null) {
|
||||||
|
serviceStatus = (heartbeatJSON["status"] === DOWN) ? "🔴 Down" : "✅ Up";
|
||||||
|
}
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
// for v1 compatibility, to be removed in v3
|
||||||
|
"STATUS": serviceStatus,
|
||||||
|
"NAME": monitorName,
|
||||||
|
"HOSTNAME_OR_URL": monitorHostnameOrURL,
|
||||||
|
|
||||||
|
// variables which are officially supported
|
||||||
|
"status": serviceStatus,
|
||||||
|
"name": monitorName,
|
||||||
|
"hostnameOrURL": monitorHostnameOrURL,
|
||||||
|
monitorJSON,
|
||||||
|
heartbeatJSON,
|
||||||
|
msg,
|
||||||
|
};
|
||||||
|
|
||||||
|
return engine.render(parsedTpl, context);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws an error
|
* Throws an error
|
||||||
* @param {any} error The error to throw
|
* @param {any} error The error to throw
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
const nodemailer = require("nodemailer");
|
const nodemailer = require("nodemailer");
|
||||||
const NotificationProvider = require("./notification-provider");
|
const NotificationProvider = require("./notification-provider");
|
||||||
const { DOWN } = require("../../src/util");
|
|
||||||
const { Liquid } = require("liquidjs");
|
|
||||||
|
|
||||||
class SMTP extends NotificationProvider {
|
class SMTP extends NotificationProvider {
|
||||||
name = "smtp";
|
name = "smtp";
|
||||||
|
@ -53,15 +51,11 @@ class SMTP extends NotificationProvider {
|
||||||
const customSubject = notification.customSubject?.trim() || "";
|
const customSubject = notification.customSubject?.trim() || "";
|
||||||
const customBody = notification.customBody?.trim() || "";
|
const customBody = notification.customBody?.trim() || "";
|
||||||
|
|
||||||
const context = this.generateContext(msg, monitorJSON, heartbeatJSON);
|
|
||||||
const engine = new Liquid();
|
|
||||||
if (customSubject !== "") {
|
if (customSubject !== "") {
|
||||||
const tpl = engine.parse(customSubject);
|
subject = await this.renderTemplate(customSubject, msg, monitorJSON, heartbeatJSON);
|
||||||
subject = await engine.render(tpl, context);
|
|
||||||
}
|
}
|
||||||
if (customBody !== "") {
|
if (customBody !== "") {
|
||||||
const tpl = engine.parse(customBody);
|
body = await this.renderTemplate(customBody, msg, monitorJSON, heartbeatJSON);
|
||||||
body = await engine.render(tpl, context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,43 +72,6 @@ class SMTP extends NotificationProvider {
|
||||||
|
|
||||||
return okMsg;
|
return okMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate context for LiquidJS
|
|
||||||
* @param {string} msg the message that will be included in the context
|
|
||||||
* @param {?object} monitorJSON Monitor details (For Up/Down/Cert-Expiry only)
|
|
||||||
* @param {?object} heartbeatJSON Heartbeat details (For Up/Down only)
|
|
||||||
* @returns {{STATUS: string, status: string, HOSTNAME_OR_URL: string, hostnameOrUrl: string, NAME: string, name: string, monitorJSON: ?object, heartbeatJSON: ?object, msg: string}} the context
|
|
||||||
*/
|
|
||||||
generateContext(msg, monitorJSON, heartbeatJSON) {
|
|
||||||
// Let's start with dummy values to simplify code
|
|
||||||
let monitorName = "Monitor Name not available";
|
|
||||||
let monitorHostnameOrURL = "testing.hostname";
|
|
||||||
|
|
||||||
if (monitorJSON !== null) {
|
|
||||||
monitorName = monitorJSON["name"];
|
|
||||||
monitorHostnameOrURL = this.extractAddress(monitorJSON);
|
|
||||||
}
|
|
||||||
|
|
||||||
let serviceStatus = "⚠️ Test";
|
|
||||||
if (heartbeatJSON !== null) {
|
|
||||||
serviceStatus = (heartbeatJSON["status"] === DOWN) ? "🔴 Down" : "✅ Up";
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
// for v1 compatibility, to be removed in v3
|
|
||||||
"STATUS": serviceStatus,
|
|
||||||
"NAME": monitorName,
|
|
||||||
"HOSTNAME_OR_URL": monitorHostnameOrURL,
|
|
||||||
|
|
||||||
// variables which are officially supported
|
|
||||||
"status": serviceStatus,
|
|
||||||
"name": monitorName,
|
|
||||||
"hostnameOrURL": monitorHostnameOrURL,
|
|
||||||
monitorJSON,
|
|
||||||
heartbeatJSON,
|
|
||||||
msg,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SMTP;
|
module.exports = SMTP;
|
||||||
|
|
|
@ -22,6 +22,14 @@ class Telegram extends NotificationProvider {
|
||||||
params.message_thread_id = notification.telegramMessageThreadID;
|
params.message_thread_id = notification.telegramMessageThreadID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (notification.telegramUseTemplate) {
|
||||||
|
params.text = await this.renderTemplate(notification.telegramTemplate, msg, monitorJSON, heartbeatJSON);
|
||||||
|
|
||||||
|
if (notification.telegramTemplateParseMode !== "plain") {
|
||||||
|
params.parse_mode = notification.telegramTemplateParseMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await axios.get(`${url}/bot${notification.telegramBotToken}/sendMessage`, {
|
await axios.get(`${url}/bot${notification.telegramBotToken}/sendMessage`, {
|
||||||
params: params,
|
params: params,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const NotificationProvider = require("./notification-provider");
|
const NotificationProvider = require("./notification-provider");
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
const FormData = require("form-data");
|
const FormData = require("form-data");
|
||||||
const { Liquid } = require("liquidjs");
|
|
||||||
|
|
||||||
class Webhook extends NotificationProvider {
|
class Webhook extends NotificationProvider {
|
||||||
name = "webhook";
|
name = "webhook";
|
||||||
|
@ -28,17 +27,7 @@ class Webhook extends NotificationProvider {
|
||||||
config.headers = formData.getHeaders();
|
config.headers = formData.getHeaders();
|
||||||
data = formData;
|
data = formData;
|
||||||
} else if (notification.webhookContentType === "custom") {
|
} else if (notification.webhookContentType === "custom") {
|
||||||
// Initialize LiquidJS and parse the custom Body Template
|
data = await this.renderTemplate(notification.webhookCustomBody, msg, monitorJSON, heartbeatJSON);
|
||||||
const engine = new Liquid();
|
|
||||||
const tpl = engine.parse(notification.webhookCustomBody);
|
|
||||||
|
|
||||||
// Insert templated values into Body
|
|
||||||
data = await engine.render(tpl,
|
|
||||||
{
|
|
||||||
msg,
|
|
||||||
heartbeatJSON,
|
|
||||||
monitorJSON
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification.webhookAdditionalHeaders) {
|
if (notification.webhookAdditionalHeaders) {
|
||||||
|
|
75
src/components/TemplatedInput.vue
Normal file
75
src/components/TemplatedInput.vue
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
<template>
|
||||||
|
<div class="form-text mb-2">
|
||||||
|
<i18n-t tag="div" keypath="liquidIntroduction">
|
||||||
|
<a href="https://liquidjs.com/" target="_blank">{{ $t("documentation") }}</a>
|
||||||
|
</i18n-t>
|
||||||
|
|
||||||
|
<code v-pre>{{ msg }}</code>: {{ $t("templateMsg") }}<br />
|
||||||
|
<code v-pre>{{ name }}</code>: {{ $t("templateServiceName") }}<br />
|
||||||
|
<code v-pre>{{ status }}</code>: {{ $t("templateStatus") }}<br />
|
||||||
|
<code v-pre>{{ hostnameOrURL }}</code>: {{ $t("templateHostnameOrURL") }}<br />
|
||||||
|
<code v-pre>{{ heartbeatJSON }}</code>: {{ $t("templateHeartbeatJSON") }} <b>({{ $t("templateLimitedToUpDownNotifications") }})</b><br />
|
||||||
|
<code v-pre>{{ monitorJSON }}</code>: {{ $t("templateMonitorJSON") }} <b>({{ $t("templateLimitedToUpDownCertNotifications") }})</b><br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
:id="id"
|
||||||
|
ref="templatedInput"
|
||||||
|
v-model="model"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:required="required"
|
||||||
|
autocomplete="false"
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* The value of the templated input.
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* id for the templated input.
|
||||||
|
*/
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Whether the templated input is required.
|
||||||
|
* @example true
|
||||||
|
*/
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Placeholder text for the templated input.
|
||||||
|
*/
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: [ "update:modelValue" ],
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* Send value update to parent on change.
|
||||||
|
*/
|
||||||
|
model: {
|
||||||
|
get() {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit("update:modelValue", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
80
src/components/TemplatedTextarea.vue
Normal file
80
src/components/TemplatedTextarea.vue
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
<template>
|
||||||
|
<div class="form-text mb-2">
|
||||||
|
<i18n-t tag="div" keypath="liquidIntroduction">
|
||||||
|
<a href="https://liquidjs.com/" target="_blank">{{ $t("documentation") }}</a>
|
||||||
|
</i18n-t>
|
||||||
|
|
||||||
|
<code v-pre>{{ msg }}</code>: {{ $t("templateMsg") }}<br />
|
||||||
|
<code v-pre>{{ name }}</code>: {{ $t("templateServiceName") }}<br />
|
||||||
|
<code v-pre>{{ status }}</code>: {{ $t("templateStatus") }}<br />
|
||||||
|
<code v-pre>{{ hostnameOrURL }}</code>: {{ $t("templateHostnameOrURL") }}<br />
|
||||||
|
<code v-pre>{{ heartbeatJSON }}</code>: {{ $t("templateHeartbeatJSON") }} <b>({{ $t("templateLimitedToUpDownNotifications") }})</b><br />
|
||||||
|
<code v-pre>{{ monitorJSON }}</code>: {{ $t("templateMonitorJSON") }} <b>({{ $t("templateLimitedToUpDownCertNotifications") }})</b><br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
:id="id"
|
||||||
|
ref="templatedTextarea"
|
||||||
|
v-model="model"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:required="required"
|
||||||
|
autocomplete="false"
|
||||||
|
></textarea>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* The value of the templated textarea.
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* id for the templated textarea.
|
||||||
|
*/
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Whether the templated textarea is required.
|
||||||
|
* @example true
|
||||||
|
*/
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Placeholder text for the templated textarea.
|
||||||
|
*/
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: [ "update:modelValue" ],
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* Send value update to parent on change.
|
||||||
|
*/
|
||||||
|
model: {
|
||||||
|
get() {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit("update:modelValue", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
textarea {
|
||||||
|
min-height: 150px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -67,25 +67,15 @@
|
||||||
<input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient">
|
<input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="form-text">
|
|
||||||
<i18n-t tag="div" keypath="smtpLiquidIntroduction" class="form-text mb-3">
|
|
||||||
<a href="https://liquidjs.com/" target="_blank">{{ $t("documentation") }}</a>
|
|
||||||
</i18n-t>
|
|
||||||
<code v-pre>{{name}}</code>: {{ $t("emailTemplateServiceName") }}<br />
|
|
||||||
<code v-pre>{{msg}}</code>: {{ $t("emailTemplateMsg") }}<br />
|
|
||||||
<code v-pre>{{status}}</code>: {{ $t("emailTemplateStatus") }}<br />
|
|
||||||
<code v-pre>{{heartbeatJSON}}</code>: {{ $t("emailTemplateHeartbeatJSON") }}<b>{{ $t("emailTemplateLimitedToUpDownNotification") }}</b><br />
|
|
||||||
<code v-pre>{{monitorJSON}}</code>: {{ $t("emailTemplateMonitorJSON") }} <b>{{ $t("emailTemplateLimitedToUpDownNotification") }}</b><br />
|
|
||||||
<code v-pre>{{hostnameOrURL}}</code>: {{ $t("emailTemplateHostnameOrURL") }}<br />
|
|
||||||
</p>
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="subject-email" class="form-label">{{ $t("emailCustomSubject") }}</label>
|
<label for="subject-email" class="form-label">{{ $t("emailCustomSubject") }}</label>
|
||||||
<input id="subject-email" v-model="$parent.notification.customSubject" type="text" class="form-control" autocomplete="false" placeholder="">
|
<TemplatedInput id="subject-email" v-model="$parent.notification.customSubject" :required="false" placeholder=""></TemplatedInput>
|
||||||
<div class="form-text">{{ $t("leave blank for default subject") }}</div>
|
<div class="form-text">{{ $t("leave blank for default subject") }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="body-email" class="form-label">{{ $t("emailCustomBody") }}</label>
|
<label for="body-email" class="form-label">{{ $t("emailCustomBody") }}</label>
|
||||||
<textarea id="body-email" v-model="$parent.notification.customBody" type="text" class="form-control" autocomplete="false" placeholder=""></textarea>
|
<TemplatedTextarea id="body-email" v-model="$parent.notification.customBody" :required="false" placeholder=""></TemplatedTextarea>
|
||||||
<div class="form-text">{{ $t("leave blank for default body") }}</div>
|
<div class="form-text">{{ $t("leave blank for default body") }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -124,11 +114,15 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import HiddenInput from "../HiddenInput.vue";
|
import HiddenInput from "../HiddenInput.vue";
|
||||||
|
import TemplatedInput from "../TemplatedInput.vue";
|
||||||
|
import TemplatedTextarea from "../TemplatedTextarea.vue";
|
||||||
import ToggleSection from "../ToggleSection.vue";
|
import ToggleSection from "../ToggleSection.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
HiddenInput,
|
HiddenInput,
|
||||||
|
TemplatedInput,
|
||||||
|
TemplatedTextarea,
|
||||||
ToggleSection,
|
ToggleSection,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -32,7 +32,42 @@
|
||||||
<label for="message_thread_id" class="form-label">{{ $t("telegramMessageThreadID") }}</label>
|
<label for="message_thread_id" class="form-label">{{ $t("telegramMessageThreadID") }}</label>
|
||||||
<input id="message_thread_id" v-model="$parent.notification.telegramMessageThreadID" type="text" class="form-control">
|
<input id="message_thread_id" v-model="$parent.notification.telegramMessageThreadID" type="text" class="form-control">
|
||||||
<p class="form-text">{{ $t("telegramMessageThreadIDDescription") }}</p>
|
<p class="form-text">{{ $t("telegramMessageThreadIDDescription") }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input v-model="$parent.notification.telegramUseTemplate" class="form-check-input" type="checkbox">
|
||||||
|
<label class="form-check-label">{{ $t("telegramUseTemplate") }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-text">
|
||||||
|
{{ $t("telegramUseTemplateDescription") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="$parent.notification.telegramUseTemplate">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label" for="message_parse_mode">{{ $t("Message Format") }}</label>
|
||||||
|
<select
|
||||||
|
id="message_parse_mode"
|
||||||
|
v-model="$parent.notification.telegramTemplateParseMode"
|
||||||
|
class="form-select"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<option value="plain">{{ $t("Plain Text") }}</option>
|
||||||
|
<option value="HTML">HTML</option>
|
||||||
|
<option value="MarkdownV2">MarkdownV2</option>
|
||||||
|
</select>
|
||||||
|
<i18n-t tag="p" keypath="telegramTemplateFormatDescription" class="form-text">
|
||||||
|
<a href="https://core.telegram.org/bots/api#formatting-options" target="_blank">{{ $t("documentation") }}</a>
|
||||||
|
</i18n-t>
|
||||||
|
|
||||||
|
<label class="form-label" for="message_template">{{ $t('Message Template') }}</label>
|
||||||
|
<TemplatedTextarea id="message_template" v-model="$parent.notification.telegramTemplate" :required="true" :placeholder="telegramTemplatedTextareaPlaceholder"></TemplatedTextarea>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
<div class="form-check form-switch">
|
<div class="form-check form-switch">
|
||||||
<input v-model="$parent.notification.telegramSendSilently" class="form-check-input" type="checkbox">
|
<input v-model="$parent.notification.telegramSendSilently" class="form-check-input" type="checkbox">
|
||||||
<label class="form-check-label">{{ $t("telegramSendSilently") }}</label>
|
<label class="form-check-label">{{ $t("telegramSendSilently") }}</label>
|
||||||
|
@ -57,11 +92,24 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import HiddenInput from "../HiddenInput.vue";
|
import HiddenInput from "../HiddenInput.vue";
|
||||||
|
import TemplatedTextarea from "../TemplatedTextarea.vue";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
HiddenInput,
|
HiddenInput,
|
||||||
|
TemplatedTextarea,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
telegramTemplatedTextareaPlaceholder() {
|
||||||
|
return this.$t("Example:", [
|
||||||
|
`
|
||||||
|
Uptime Kuma Alert{% if monitorJSON %} - {{ monitorJSON['name'] }}{% endif %}
|
||||||
|
|
||||||
|
{{ msg }}
|
||||||
|
`,
|
||||||
|
]);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
|
@ -115,3 +163,9 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
textarea {
|
||||||
|
min-height: 150px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -32,20 +32,7 @@
|
||||||
</template>
|
</template>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
<template v-else-if="$parent.notification.webhookContentType == 'custom'">
|
<template v-else-if="$parent.notification.webhookContentType == 'custom'">
|
||||||
<i18n-t tag="div" keypath="liquidIntroduction" class="form-text">
|
<TemplatedTextarea id="customBody" v-model="$parent.notification.webhookCustomBody" :required="true" :placeholder="customBodyPlaceholder"></TemplatedTextarea>
|
||||||
<a href="https://liquidjs.com/" target="_blank">{{ $t("documentation") }}</a>
|
|
||||||
</i18n-t>
|
|
||||||
<code v-pre>{{msg}}</code>: {{ $t("templateMsg") }}<br />
|
|
||||||
<code v-pre>{{heartbeatJSON}}</code>: {{ $t("templateHeartbeatJSON") }} <b>({{ $t("templateLimitedToUpDownNotifications") }})</b><br />
|
|
||||||
<code v-pre>{{monitorJSON}}</code>: {{ $t("templateMonitorJSON") }} <b>({{ $t("templateLimitedToUpDownCertNotifications") }})</b><br />
|
|
||||||
|
|
||||||
<textarea
|
|
||||||
id="customBody"
|
|
||||||
v-model="$parent.notification.webhookCustomBody"
|
|
||||||
class="form-control"
|
|
||||||
:placeholder="customBodyPlaceholder"
|
|
||||||
required
|
|
||||||
></textarea>
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -67,7 +54,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import TemplatedTextarea from "../TemplatedTextarea.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
TemplatedTextarea,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showAdditionalHeadersField: this.$parent.notification.webhookAdditionalHeaders != null,
|
showAdditionalHeadersField: this.$parent.notification.webhookAdditionalHeaders != null,
|
||||||
|
|
|
@ -231,6 +231,9 @@
|
||||||
"templateMonitorJSON": "object describing the monitor",
|
"templateMonitorJSON": "object describing the monitor",
|
||||||
"templateLimitedToUpDownCertNotifications": "only available for UP/DOWN/Certificate expiry notifications",
|
"templateLimitedToUpDownCertNotifications": "only available for UP/DOWN/Certificate expiry notifications",
|
||||||
"templateLimitedToUpDownNotifications": "only available for UP/DOWN notifications",
|
"templateLimitedToUpDownNotifications": "only available for UP/DOWN notifications",
|
||||||
|
"templateServiceName": "service name",
|
||||||
|
"templateHostnameOrURL": "hostname or URL",
|
||||||
|
"templateStatus": "status",
|
||||||
"webhookAdditionalHeadersTitle": "Additional Headers",
|
"webhookAdditionalHeadersTitle": "Additional Headers",
|
||||||
"webhookAdditionalHeadersDesc": "Sets additional headers sent with the webhook. Each header should be defined as a JSON key/value.",
|
"webhookAdditionalHeadersDesc": "Sets additional headers sent with the webhook. Each header should be defined as a JSON key/value.",
|
||||||
"webhookBodyPresetOption": "Preset - {0}",
|
"webhookBodyPresetOption": "Preset - {0}",
|
||||||
|
@ -421,6 +424,9 @@
|
||||||
"telegramSendSilentlyDescription": "Sends the message silently. Users will receive a notification with no sound.",
|
"telegramSendSilentlyDescription": "Sends the message silently. Users will receive a notification with no sound.",
|
||||||
"telegramProtectContent": "Protect Forwarding/Saving",
|
"telegramProtectContent": "Protect Forwarding/Saving",
|
||||||
"telegramProtectContentDescription": "If enabled, the bot messages in Telegram will be protected from forwarding and saving.",
|
"telegramProtectContentDescription": "If enabled, the bot messages in Telegram will be protected from forwarding and saving.",
|
||||||
|
"telegramUseTemplate": "Use custom message template",
|
||||||
|
"telegramUseTemplateDescription": "If enabled, the message will be sent using a custom template.",
|
||||||
|
"telegramTemplateFormatDescription": "Telegram allows using different markup languages for messages, see Telegram {0} for specifc details.",
|
||||||
"supportTelegramChatID": "Support Direct Chat / Group / Channel's Chat ID",
|
"supportTelegramChatID": "Support Direct Chat / Group / Channel's Chat ID",
|
||||||
"wayToGetTelegramChatID": "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:",
|
"wayToGetTelegramChatID": "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:",
|
||||||
"YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE",
|
"YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE",
|
||||||
|
@ -519,9 +525,6 @@
|
||||||
"leave blank for default subject": "leave blank for default subject",
|
"leave blank for default subject": "leave blank for default subject",
|
||||||
"emailCustomBody": "Custom Body",
|
"emailCustomBody": "Custom Body",
|
||||||
"leave blank for default body": "leave blank for default body",
|
"leave blank for default body": "leave blank for default body",
|
||||||
"emailTemplateServiceName": "Service Name",
|
|
||||||
"emailTemplateHostnameOrURL": "Hostname or URL",
|
|
||||||
"emailTemplateStatus": "Status",
|
|
||||||
"emailTemplateMonitorJSON": "object describing the monitor",
|
"emailTemplateMonitorJSON": "object describing the monitor",
|
||||||
"emailTemplateHeartbeatJSON": "object describing the heartbeat",
|
"emailTemplateHeartbeatJSON": "object describing the heartbeat",
|
||||||
"emailTemplateMsg": "message of the notification",
|
"emailTemplateMsg": "message of the notification",
|
||||||
|
@ -1053,5 +1056,8 @@
|
||||||
"SendGrid API Key": "SendGrid API Key",
|
"SendGrid API Key": "SendGrid API Key",
|
||||||
"Separate multiple email addresses with commas": "Separate multiple email addresses with commas",
|
"Separate multiple email addresses with commas": "Separate multiple email addresses with commas",
|
||||||
"YZJ Webhook URL": "YZJ Webhook URL",
|
"YZJ Webhook URL": "YZJ Webhook URL",
|
||||||
"YZJ Robot Token": "YZJ Robot token"
|
"YZJ Robot Token": "YZJ Robot token",
|
||||||
|
"Plain Text": "Plain Text",
|
||||||
|
"Message Template": "Message Template",
|
||||||
|
"Template Format": "Template Format"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue