Disclaimer

This document is only collection of author’s notes, experiences and point of views. It is not, in any meaning, either complete description of the topic nor official RTB documentation. It may be inaccurate, incomplete, obsolete, misleading or completely wrong. It may even cause loss of data or damage system integrity. It may not comply with company codex, values, presentation style or economic interests or may reveal company secrets.

As such, it is absolutely prohibited to distribute this document outside of RTB & Co. GmbH. Such an action may result into legal acts against both the sender and the company. It is only intended, after review of technical and presentational correctness and accuracy, to be used as an information source for official documentation.

Always contact documentation department for information about current presentation style and allowed formats before creating customer’s documentation.

1. Introduction

To create content of various e-mail and SMS notification user configurable a template engine is used. The Thymeleaf was selected. Please see following resources to get idea how to use it.

2. Templates

There are two types of templates. Text (with .txt suffix) and HTML (with .html suffix). Variables or processing instructions can be used inside of both template types. Which exact variables can be used depends on exact use case. See chapter Use cases to find out more.

Please note that content of all templates must be UTF-8 encoded.

2.1. HTML

HTML templates must have *.html suffix to be correctly recognized. Most typical usage of HTML templates is e-mail body.

Advantage of using template engine is fast prototyping. It allows to develop whole html page in any editor and preview it in standard web browser during development. When the development is finished it can be easily integrated with PDM.control. All tag processed by Thymeleaf starts with th: and are ignored by web browser. Then Thymeleaf replaces content of standard HTML tags based on those with th: prefix.

Name of Thymeleaf tag usually corresponds with standard HTML tag. E.g. srcth:src, styleth:style. See documentation for more information.

2.1.1. Variables

Assume that we have variable name = "Jon" and age = 30. Then we can create following template.

HTML template with variables
My <span th:text="${name}">Jakob</span> is <span th:text="${age}">60</span> years old.

Such a template can be easily displayed in browser because unknown tags are ignored. After processing it will became My friend Jon is 30 years old.

2.1.2. Conditions

A part of the template can be used only under certain condition. See Simple conditionals: "if" and "unless".

HTML template with condition
My  friend
<span th:text="${name}">Jakob</span>
is
<span th:text="${age}">60</span>
years old
<span th:if="${age} < 30">and still young</span>
.

This will expand, depending on age to following text.

  • age < 30 ⇒ My friend John is 30 year old and still young.

  • age >= 30 ⇒ My friend John is 30 year old.

2.1.3. Switch statement

Sometimes it is necessary to branch condition with switch statement especially in case of enumeration. See Switch statements. Assume that there is a variable animal which can be bird, cat or ant.

HTML template with switch
My animal has got
<span th:swich="${animal}">
    <span th:case="'bird'">2</span>
    <span th:case="'cat'">4</span>
    <span th:case="'ant'">6</span>
    <span th:case="*">?</span>
</span>
legs.

Result of this template will depend on chosen animal. It will be

  • birdMy animal has got 2 legs.

  • catMy animal has got 4 legs.

  • antMy animal has got 6 legs.

  • other ⇒ My animal has got ? legs.

2.1.4. Images

It is possible to use images together with HTML templates. There are three possible image references. They are briefly discussed in next chapters. More information can be found in article Embedding Images in HTML Email: Have the Rules Changed?

Linked images

It is possible provide link to the image hosted on some external server. It is super easy and doesn’t impact the email size. You just refer the image as a link in the HTML body with a simple img tag:

<img src="/wp-content/uploads/2018/11/blog/-illustration-email-embedding-images.png?w=640" alt="img" />

Advantage:

  • it does not increase e-mail size.

Disadvantage

  • external images may be blocked by e-mail client.

PDM control support

PDM.control helps to resolve this case by serving all images found on user defined path pcon.mail.notification.template-path under static path. Always use variable ${imageURL} to get this path. Path it self may change in future releases.

Example of linked image
<img src="mock.png" th:src="${imageURL + '/rtb_logo.png'">
URL encoding

Another way to display an image in the body of your message is to embed base64 image in HTML. It also refers to the MIME standard but here you don’t need to worry much about it. Base64 is a group of similar binary-to-text encoding schemes. If you want to know more about it, refer to Wikipedia since it has a comprehensive article on this topic.

To insert a picture to your email, you need to encode the image file as base64: use one of the many encoding services and then just paste base64 digits into HTML code like this:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAADSCAMAAABThmYtAAAAXVB" alt="img" />

Disadvantage:

  • Such an encoding is totally blocked by Outlook

  • Limited support by clients.

  • Email message can become big because of 6bit encoding.

CID attachments, or embedding an image using MIME object

MIME (Multipurpose Internet Mail Extensions) is an Internet standard initially designed for SMTP that allows sending several content types (like HTML and text) in a single message body and supports non-text attachments like images.

It means that your message should contain at least two parts, HTML and plain text, which should be separated by defining boundaries. To embed an image, attach it and reference in the message body by setting its CID (Content-ID) and using a standard HTML tag:

<img src="cid:some-image-cid" alt="img" />

Advantage:

  • Displayed properly by clients

Disadvantage:

  • Email message can become big because image is part of the message.

PDM.control support

The help template designer to work with cid attached images, PDM.control offers automatic attachment of referenced image. It is enough to put image name (without) path to src tag and put the image to user defined location. You can also use local depended imaged for customers for various regions.

For instance, we have such reference hit be request from local de_at

CID image
<img src="cid:logo.png" alt="logo" />

PDM.control will find appropriate image variant. See chapter Localization and customization how it exactly works. Found image is then automatically attached under cid:logo.png.

2.2. Text

Text template must end whit .txt suffix to be correctly recognized. Most typical usage of text templates is for SMS or e-mail subjects.

2.2.1. Variables

Assume that we have variable name = "Jon" and age = 30. Then we can create following template.

Text template with variables
My friend [(${name})] is [(${age})] years old.

Which will become text My friend John is 30 year old..

2.2.2. Conditions

A part of the template can be used only under certain condition.

Text template with condition
My friend [(${name})] is [(${age})] years old [# th:if="${name} < 30"] and still young[/].

This will expand, depending on age to following text.

  • age < 30 ⇒ My friend John is 30 year old and still young.

  • age < 30 ⇒ My friend John is 30 year old.

2.2.3. Switch statement

Sometimes it is necessary to branch condition with switch statement especially in case of enumeration. Assume that there is a variable animal which can be bird, cat or ant.

Template with switch
My animal has got
[# th:switch="${animal}"]
	[# th:case="'bird'"]2[/]
	[# th:case="'cat'"]4[/]
	[# th:case="'ant'"]6[/]
	[# th:case="*"]?[/]
[/]
legs.

Result of this template will be dependent on chosen animal. It will be

  • birdMy animal has got 2 legs.

  • catMy animal has got 4 legs.

  • antMy animal has got 6 legs.

  • other ⇒ My animal has got ? legs.

2.2.4. Normalization

In some cases (E-mail subject and SMS) are text normalized. It means that multiple spaces and line ends are removed. In such a case following template definitions will produce equal result.

Template before normalization
My            friend
John
       triggered is 30 years old.
Template after normalization
My friend John triggered is 30 years old.

3. Localization and customization

User resources have to be put to a directory on file system. Its location has to be provided as a a value of property pcon.mail.notification.template-path in configuration file (or as command line argument), see documentation.

Resource files can be provided in localized from, distinguished by resource localization suffix. For instance, we have a resource file logo.png. It can be provided for multiple locales like this.

  • logo_de_DE.png - logo for German language in Germany

  • logo_de_AT.png - logo for German language in Austria

  • logo_de.png - logo for German language in all other regions

  • logo_it.png - logo for Italian language in all regions

  • logo.png - default logo for all other languages.

PDM.control searches for the most local specific variant witch matches the required locale. First user and then default location is scanned.

This technique is valid not only for images but also for templates itself. It there is template like status_forwarding_subject.txt required it is also possible to provide any local variant like status_forwarding_subject_de_at.txt, status_forwarding_subject_de_de.txt, status_forwarding_subject_it.txt …​

4. Use cases

4.1. Common variables

In each section below is defined set of variables which can be used for that specific use case. However there is also set of variables which can be used in any use case.

Table 1. Common variables
Variable Description

serverUrl

Base URL to the server. It has to be defined in configuration (pcon.app.url).

serverName

Name of server which generated the message. It is either taken from configuration (pcon.app.name) or derived from URL if not provided.

pconUrl

Full of URL PDM.control application of server which generated the message.

imageUrl

URL from which the linked e-mail images can be loaded.

4.2. Status forwarding

Status forwarding templates are defined in following files:

  • status_forwarding_subject.txt - E-mail subject template (see chapter Text).

  • status_forwarding_body.html - E-mail body template (see chapter HTML).

  • status_forwarding_sms.txt - SMS template definition.

4.2.1. Variables

In status forwarding template following variables can be used. See also Common variables.

Table 2. Variables for status forwarding
Variable Description

alertType

Severity of alert. Can be NONE, INFO, WARNING, ERROR, CRITICAL, NEW

statusText

Text of status message in rule’s language

statusNumber

Number of status message

ruleName

Name of rule which triggered forwarding.

ruleUrl

URL of rule configuration.

pdmName

Name of PDM which caused status forwarding.

pdmNumber

Number of PDM which caused status forwarding.

pdmUrl

URL of PDM which caused status forwarding.

areaName

Name of area where PDM belongs.

areaNumber

Number of area where PDM belongs.

areaUrl

URL of area where PDM belongs.

dateTime

Date and time of the event in rule’s time zone.

4.2.2. Email subject

Email subject template must be stored in file status_forwarding_subject.txt. For example following templates can be used.

status_forwarding_subject.txt
Forwarding rule [(${ruleName})] triggered on [(${serverName})].

You may of course use anything which was explain in chapter Text and create for instance template with different emojis based on alert type.

E-mail subject for message forwarding with emojis
[# th:switch="${alertType}"]
	[# th:case="'CRITICAL'"]💥[/]
	[# th:case="'ERROR'"]❕❕[/]
	[# th:case="'WARNING'"]❕[/]
	[# th:case="*"]✔[/]
[/]
Forwarding rule [(${ruleName})] triggered on [(${serverName})].

Or just use and emoji in case of critical error

[# th:if="${alertType} == 'CRITICAL'"]💥[/]Forwarding rule [(${ruleName})] triggered on [(${serverName})].

Default template can be found in appendix.

4.2.3. Email body

Email body template must be stored in file status_forwarding_body.html. Default template can be found in appendix.

4.2.4. SMS

SMS can be customized in the same way as e-mail subject.

Additionally characters which are not encodable with GSM 03.38 are replaced by similar characters.

Default template can be found in appendix.

4.3. Logbook export

Status forwarding templates are defined in following files:

  • logbook_export_subject.txt - E-mail subject template (see chapter Text).

  • logbook_export_body.html - E-mail body template (see chapter HTML).

4.3.1. Variables

In status forwarding template following variables can be used. See also Common variables.

Table 3. Variables for status forwarding
Variable Description

downloadUrl

URL where to download file from.

fileIsAttached

Result file is attached. It is attached only if its size is smaller then value of pcon.mail.notification.max-attachment-size

dateTime

Date and time of the event in rule’s time zone.

4.3.2. Email subject

Email subject template must be stored in file logbook_export_subject.txt.

It may of course used everything which was explained in chapter Text to create own with content.

Default template used in PDM.control can be found in appendix.

4.3.3. Email body

Email body template must be stored in file logbook_export_body.html. Default template used in PDM.control can be found in appendix.

Appendix A: Default templates

A.1. Status forwarding

A.1.1. Subject

Default e-mail subject template provided with PDM control.
[# th:switch="${alertType}"]
	[# th:case="'CRITICAL'"]❌[/]
	[# th:case="'ERROR'"]❕[/]
	[# th:case="'WARNING'"]⚠[/]
	[# th:case="'INFO'"]ℹ[/]
	[# th:case="'NEW'"]🆕[/]
	[# th:case="*"]✔[/]
[/]
Forwarding rule [(${ruleName})]

A.1.2. Body

Default e-mail body template provided with PDM control.

<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv=Content-Type content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="PDM.control status message forwarding.">
    <title>Status message forwarding</title>

    <style>
        td {
            padding: 14pt;
        }

        p {
            margin: 16px 0;
        }

        .alert-type {
            font-size: 36.0pt;
            padding: 10px 25px;
        }

        .text-center {
            text-align: center;
        }

        .text-right {
            text-align: right;
        }
    </style>
</head>
</head>

<body lang="EN_US" link="#0D6EFD" vlink="#954F72" style="word-wrap: break-word; font-family: 'Arial', sans-serif;">
    <table style="border-collapse: collapse; table-layout: fixed; border: solid #E36600 3px; max-width: 726px;">
        <colgroup>
            <col style="width: 33%">
            <col style="width: 34%">
            <col style="width: 33%">
        </colgroup>
        <!-- Header -->
        <tr>
            <td style="font-size: 18pt;" colspan="2"><a href="#" th:href="${pconUrl}" style="color: #E36600;">PDM.control</a></td>
            <td style="text-align: right;">
                <img width=50 height=50 id="picRtbLogo" src="pdm_control_logo_small.png" th:src="|cid:pdm_control_logo_small.png|" alt="PDM.control logo">
            </td>
        </tr>

        <!-- Alert type -->
        <tr>
            <td colspan="3" class="text-center" style="padding-top: 40px;">
                <!-- Translate: Message type -->
                <span th:if="${alertType} eq 'CRITICAL'" class="alert-type" style="color: white; background: #d63384">Critical error</span>
                <span th:if="${alertType} eq 'ERROR'" class="alert-type" style="color: white; background: #dc3545">Error</span>
                <span th:if="${alertType} eq 'WARNING'" class="alert-type" style="color: black; background: #ffc107">Warning</span>
                <span th:if="${alertType} eq 'INFO'" class="alert-type" style="color: black; background: #0dcaf0">Info</span>
                <span th:if="${alertType} eq 'NEW'" class="alert-type" style="color: black; background: fuchsia">New</span>
                <span th:if="${alertType} eq 'NONE'" class="alert-type" style="color: white; background: #198754">OK</span>
            </td>
        </tr>

        <!-- Status text-->
        <tr>
            <td colspan="3" style=" padding-top: 30px;" class="text-center">
                <!-- Status name -->
                <p>
                    <i style="font-size: 25pt" th:text="${statusText}">Technical door open</i>
                </p>
                <p>on PDM</p>
                <p style="font-size: 15pt">
                    <span style="font-style: italic;" th:text="${pdmName}">Q-Bar (<span th:text="${pdmNumber}">5</span>)</span>
                </p>

            </td>
        </tr>

        <tr>
            <td colspan="3" style=" padding-top: 20px;font-size: 14pt;">
                <p style="text-align: justify; line-height: 1.5;">
                    <!-- Main Text -->
                    Status forwarding was caused by rule
                    <a href="#" th:href="${ruleUrl}" th:text="${ruleName}">Rule1</a>
                    triggered by message
                    '<i th:text="${statusText}">Technical door open</i>'
                    (<span th:text="${statusNumber}">55</span>)
                    on PDM
                    <a href="#" th:href="${pdmUrl}"><span style="white-space: nowrap;" th:text="${pdmName}">Q-Bar</span> (<span th:text="${pdmNumber}">5</span>)</a>
                    in area
                    <a href="#" th:href="${areaUrl}"><span style="white-space: nowrap;" th:text="${areaName}">RTB GmbH &amp; Co. KG</span> (<span th:text="${areaNumber}">1</span>)</a>
                    .
                </p>
            </td>
        </tr>


        <!-- Date and time -->
        <tr>
            <td colspan="3" class="text-right">
                &#8212;
                <span style='font-size: 11pt; font-family: "Arial", sans-serif' th:text="${dateTime}">12.11.2021,
                    19:30:00</span>
            </td>
        </tr>

        <!-- RTB footer -->
        <tr>
            <td colspan="3" style="padding: 60px 0 30px;">
                <div style="margin: 0 5px;">
                    <img style="width: 100%;" id="pictureRtbFooter" src="rtb_footer.png" th:src="|cid:rtb_footer.png|" alt="RTB footer">
                    <p style="font-size: 11.0pt;" class="text-right">
                        <i style="font-size: 11pt;">Visit us on internet</i> &gt;&gt;&gt;
                        <a href="www.rtb-bl.de"> www.rtb-bl.de</a>
                    </p>
                </div>
            </td>
        </tr>


        <!-- Signature -->
        <tr style="font-size: 10pt; color: #212529;line-height: 1.3;">
            <td style="vertical-align: top; padding-right: 0;">
                Schulze-Delitzsch-Weg 10<br>
                33175 Bad Lippspringe<br>
                Deutschland<br>
                <br><br><br>
                Telefon: +49 5252 9706-206<br>
                Telefax: +49 5252 9706-10<br>
                E-Mail: <a href="mailto:parking-helpdesk@rtb-bl.de">parking-helpdesk@rtb-bl.de</a>
            </td>
            <td style="vertical-align:middle; padding: 0 5px;" class="text-center">
                <img style="width: 100%; height: auto; min-width: 100px; max-width: 205px;" id="picRtbLogoSmall" src="rtb_logo.png" th:src="|cid:rtb_logo.png|" alt="RTB logo">
            </td>
            <td style="vertical-align: top; padding-left: 0;" class="text-right">
                Kommanditgesellschaft<br>
                Amtsgericht Paderborn HRA 2007<br><br>
                Pers. haftende Gesellschafterin:<br>
                RTB Beteiligungs GmbH<br><br>
                Amtsgericht Paderborn HRB 2718<br>
                Geschäftsführer:<br>
                Rudolf Broer, Matthias Rieger
            </td>
        </tr>

    </table>

</body>

</html>

A.1.3. SMS

Default SMS template
[(${ruleName})]: '[(${pdmName})]([(${pdmNumber})])@[(${areaNumber})])' '[(${statusText})]([(${statusNumber})])' [[(${dateTime})]].

A.2. Logbook export

A.2.1. Subject

Default export subject
Your task is done on [(${serverName})]

A.2.2. Body

Default export body
<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv=Content-Type content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="PDM.control logbook export is ready for download">
    <title>Logbook export is ready</title>

    <style>
        td {
            padding: 14pt;
        }

        p {
            margin: 16px 0;
            text-align: justify;
        }

        .text-center {
            text-align: center;
        }

        .text-right {
            text-align: right;
        }
    </style>

</head>

<body lang="EN_US" link="#0D6EFD" vlink="#954F72" style="word-wrap: break-word; font-family: 'Arial', sans-serif;">
    <table style="border-collapse: collapse; table-layout: fixed; border: solid #E36600 3px; max-width: 726px;">
        <colgroup>
            <col style="width: 33%">
            <col style="width: 34%">
            <col style="width: 33%">
        </colgroup>
        <!-- Header -->
        <tr>
            <td style="font-size: 18pt;" colspan="2"><a href="#" th:href="${pconUrl}" style="color: #E36600;">PDM.control</a></td>
            <td style="text-align: right;">
                <img width=50 height=50 id="picRtbLogo" src="pdm_control_logo_small.png" th:src="|cid:pdm_control_logo_small.png|" alt="PDM.control logo">
            </td>
        </tr>

        <!-- Export attached -->
        <tr>
            <td colspan="3" style=" padding-top: 30px;">
                <p style="line-height: 1.7; margin-top: 0">
                    Your request has been processed and the result file is ready for download. Please click the link below to download requested file.
                </p>
                <p class="text-center" style="font-size: 2em; margin-top: 1em; margin-bottom: 1.5em;">
                    <a href="#" th:href="${downloadUrl}">DOWNLOAD</a><sup style="color: gray;">*</sup>
                </p>
                <p th:if="${fileIsAttached}">
                    For your convenience the result file is also attached to this e-mail.
                </p>
                <p th:if="not ${fileIsAttached}" style=" line-height: 1.5;">
                    Result file is not attached because it is bigger then maximal allowed size.
                </p>
                <p style="font-size: .8em; color: gray;">
                    <sup>*</sup> The file stays available for download within next 24 hours. After this period it will be deleted and
                    the link becomes invalid.
                </p>
            </td>
        </tr>

        <!-- Date and time -->
        <tr>
            <td colspan="3" class="text-right">
                &#8212;
                <span style='font-size: 11pt; font-family: "Arial", sans-serif' th:text="${dateTime}">12.11.2021,
                    19:30:00</span>
            </td>
        </tr>

        <!-- RTB footer -->
        <tr>
            <td colspan="3" style="padding: 60px 0 30px;">
                <div style="margin: 0 5px;">
                    <img style="width: 100%;" id="pictureRtbFooter" src="rtb_footer.png" th:src="${imageUrl + '/rtb_footer.png'}" alt="RTB footer">
                    <p style="font-size: 11.0pt;" class="text-right">
                        <i style="font-size: 11pt;">Visit us on internet</i> &gt;&gt;&gt;
                        <a href="www.rtb-bl.de"> www.rtb-bl.de</a>
                    </p>
                </div>
            </td>
        </tr>


        <!-- Signature -->
        <tr style="font-size: 10pt; color: #212529;line-height: 1.3;">
            <td style="vertical-align: top; padding-right: 0;">
                Schulze-Delitzsch-Weg 10<br>
                33175 Bad Lippspringe<br>
                Deutschland<br>
                <br><br><br>
                Telefon: +49 5252 9706-206<br>
                Telefax: +49 5252 9706-10<br>
                E-Mail: <a href="mailto:parking-helpdesk@rtb-bl.de">parking-helpdesk@rtb-bl.de</a>
            </td>
            <td style="vertical-align:middle; padding: 0 5px;" class="text-center">
                <img style="width: 100%; height: auto; min-width: 100px; max-width: 205px;" id="picRtbLogoSmall" src="rtb_logo.png" th:src="|cid:rtb_logo.png|" alt="RTB logo">
            </td>
            <td style="vertical-align: top; padding-left: 0;" class="text-right">
                Kommanditgesellschaft<br>
                Amtsgericht Paderborn HRA 2007<br><br>
                Pers. haftende Gesellschafterin:<br>
                RTB Beteiligungs GmbH<br><br>
                Amtsgericht Paderborn HRB 2718<br>
                Geschäftsführer:<br>
                Rudolf Broer, Matthias Rieger
            </td>
        </tr>

    </table>

</body>

</html>