Skip to content

Commit

Permalink
added custom bodys
Browse files Browse the repository at this point in the history
  • Loading branch information
CommanderStorm committed Aug 14, 2023
1 parent b753957 commit 36ebddb
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 62 deletions.
106 changes: 55 additions & 51 deletions server/notification-providers/smtp.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,76 +37,80 @@ class SMTP extends NotificationProvider {
pass: notification.smtpPassword,
};
}
// Lets start with default subject and empty string for custom one
let subject = msg;

// Change the subject if:
// - The msg ends with "Testing" or
// - Actual Up/Down Notification
// default values in case the user does not want to template
let subject = msg;
let body = msg;
if (heartbeatJSON) {
body = `${msg}\nTime (${heartbeatJSON["timezone"]}): ${heartbeatJSON["localDateTime"]}`;
}
// subject and body are templated
if ((monitorJSON && heartbeatJSON) || msg.endsWith("Testing")) {
let customSubject = "";
// cannot end with whitespace as this often raises spam scores
const customSubject = notification.customSubject?.trim() || "";
const customBody = notification.customBody?.trim() || "";

// Our subject cannot end with whitespace it's often raise spam score
// Once I got "Cannot read property 'trim' of undefined", better be safe than sorry
if (notification.customSubject) {
customSubject = notification.customSubject.trim();
}

// If custom subject is not empty, change subject for notification
const context = this.generateContext(msg, monitorJSON, heartbeatJSON);
const engine = new Liquid();
if (customSubject !== "") {

// Let's start with dummy values to simplify code
let monitorName = "Test";
let monitorHostnameOrURL = "testing.hostname";
let serviceStatus = "⚠️ Test";

if (monitorJSON !== null) {
monitorName = monitorJSON["name"];

if (monitorJSON["type"] === "http" || monitorJSON["type"] === "keyword" || monitorJSON["type"] === "json-query") {
monitorHostnameOrURL = monitorJSON["url"];
} else {
monitorHostnameOrURL = monitorJSON["hostname"];
}
}

if (heartbeatJSON !== null) {
serviceStatus = (heartbeatJSON["status"] === DOWN) ? "🔴 Down" : "✅ Up";
}

// Initialize LiquidJS and parse the custom Body Template
const engine = new Liquid();
const tpl = engine.parse(customSubject);

// Insert templated values into Body
subject = await engine.render(tpl,
{
"STATUS": serviceStatus,
"NAME": monitorName,
"HOSTNAME_OR_URL": monitorHostnameOrURL,
});
subject = await engine.render(tpl, context);
}
if (customBody !== "") {
const tpl = engine.parse(customBody);
body = await engine.render(tpl, context);
}
}

let transporter = nodemailer.createTransport(config);

let bodyTextContent = msg;
if (heartbeatJSON) {
bodyTextContent = `${msg}\nTime (${heartbeatJSON["timezone"]}): ${heartbeatJSON["localDateTime"]}`;
}

// send mail with defined transport object
let transporter = nodemailer.createTransport(config);
await transporter.sendMail({
from: notification.smtpFrom,
cc: notification.smtpCC,
bcc: notification.smtpBCC,
to: notification.smtpTo,
subject: subject,
text: bodyTextContent,
text: body,
});

return "Sent Successfully.";
}

/**
* Generate context for LiquidJS
* @param msg {string}
* @param monitorJSON {Object|null}
* @param heartbeatJSON {Object|null}
* @returns {{STATUS: string, HOSTNAME_OR_URL: string, NAME: string, monitorJSON: Object|null, heartbeatJSON: Object|null, msg: string}}
*/
generateContext(msg, monitorJSON, heartbeatJSON) {
// Let's start with dummy values to simplify code
let monitorName = "Monitor Name not available";
let monitorHostnameOrURL = "testing.hostname";
let serviceStatus = "⚠️ Test";

if (monitorJSON !== null) {
monitorName = monitorJSON["name"];

if (monitorJSON["type"] === "http" || monitorJSON["type"] === "keyword" || monitorJSON["type"] === "json-query") {
monitorHostnameOrURL = monitorJSON["url"];
} else {
monitorHostnameOrURL = monitorJSON["hostname"];
}
}

if (heartbeatJSON !== null) {
serviceStatus = (heartbeatJSON["status"] === DOWN) ? "🔴 Down" : "✅ Up";
}
return {
"STATUS": serviceStatus,
"NAME": monitorName,
"HOSTNAME_OR_URL": monitorHostnameOrURL,
monitorJSON,
heartbeatJSON,
msg,
};
}
}

module.exports = SMTP;
33 changes: 22 additions & 11 deletions src/components/notifications/SMTP.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,28 @@
<input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient">
</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>{{HOSTNAME_OR_URL}}</code>: {{ $t("emailTemplateHostnameOrURL") }}<br />
</p>
<div class="mb-3">
<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="">
<div class="form-text">{{ $t("leave blank for default subject") }}</div>
</div>
<div class="mb-3">
<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>
<div class="form-text">{{ $t("leave blank for default body") }}</div>
</div>

<ToggleSection :heading="$t('smtpDkimSettings')">
<i18n-t tag="div" keypath="smtpDkimDesc" class="form-text mb-3">
<a href="https://nodemailer.com/dkim/" target="_blank">{{ $t("documentation") }}</a>
Expand Down Expand Up @@ -89,17 +111,6 @@
<input id="dkim-skip-fields" v-model="$parent.notification.smtpDkimskipFields" type="text" class="form-control" autocomplete="false" placeholder="message-id:date">
</div>
</ToggleSection>

<div class="mb-3">
<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="">
<div v-pre class="form-text">
(leave blank for default one)<br />
{{NAME}}: Service Name<br />
{{HOSTNAME_OR_URL}}: Hostname or URL<br />
{{STATUS}}: Status<br />
</div>
</div>
</div>
</template>

Expand Down
12 changes: 12 additions & 0 deletions src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,19 @@
"secureOptionTLS": "TLS (465)",
"Ignore TLS Error": "Ignore TLS Error",
"From Email": "From Email",
"emailCustomisableContent": "Customisable content",
"smtpLiquidIntroduction": "The following two fields are templatable via the Liquid templating Language. Please refer to the {0} for usage instructions. These are the avaliable variables:",
"emailCustomSubject": "Custom Subject",
"leave blank for default subject": "leave blank for default subject",
"emailCustomBody": "Custom 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",
"emailTemplateHeartbeatJSON": "object describing the heartbeat",
"emailTemplateMsg": "message of the notification",
"emailTemplateLimitedToUpDownNotification": "only available for UP/DOWN heartbeats, otherwise null",
"To Email": "To Email",
"smtpCC": "CC",
"smtpBCC": "BCC",
Expand Down

0 comments on commit 36ebddb

Please sign in to comment.