In this page

Notification emails

Send content status notification emails to stakeholders periodically with the Better Content Archiving app. This is done by defining notification schemes.

Each notification scheme has one or more notification rules with an associated email template defined. Email templates are fully customizable.

View notification email templates

Configure notification email templates by navigating to Confluence Settings (cog icon "⚙" in the top right) → AppsBetter Content ArchivingConfigurationNotification configuration.

There, select the Notification email templates tab.

The list of notification email templates is shown.

The notification email template list has the following columns:

  • Notification email template: This column shows the name and, if provided, the description of the notification email template.
  • Used in schemes: Contains a link to the Notification schemes tab and filters the scheme list to those that use this notification email template, or "Not used in any scheme" if the notification email template is unused.
  • Actions: Contains a Delete button for unused notification email templates.

The subject and content fields support Handlebars expressions. These expressions help you customize the contents of the notification emails. You can use HTML markup to format your email content. See below for details on the Handlebars syntax and how you can reference contents queried by the Better Content Archiving app.

Factory default notification email templates

The Better Content Archiving app comes with a factory default set of pre-defined notification email templates. Add a new template, modify the factory default ones, or delete them. You can define a fairly large set of notification email templates (up to 20). A notification email template can be used in multiple notification schemes.

Reset templates to default

Restore the factory default notification email templates using the Reset schemes option on the Notification schemes tab. This resets your notification schemes as well as your notification email templates, and there is no undo. Refer to Configuration for general information on schemes. Refer to Notification schemes for more information on notification schemes specifically.

Note: for Confluence administrators, this list is also visible from any space under Space SettingsIntegrationsBetter Content Archiving. On the Notification scheme tab, click Choose a new scheme and then in the modal, click Manage schemes. Changes made there have the exact same effect as if they were made under Confluence Settings (cog icon "⚙" in the top right) → AppsBetter Content ArchivingConfigurationNotification configuration.

Configure a notification email template

Create a new notification email template by clicking the Add new template button on the right above the notification email template list. Click the name of a notification email template to edit it.

The Add new template modal dialog is opened.

A notification email template has

  • a name,
  • a subject,
  • a content,
  • and an optional description

that you can configure. The subject and content fields are where the actual email template is defined.

Click Save when done.

Delete a notification email template

You can only delete a notification email template if it is not used in any notification scheme. Usage is shown in the Used in schemes column. Here, you can find a link if the notification email template is in use.

This link takes you to the Notification schemes tab, with the list of schemes filtered to those that use the template. See Notification schemes for more details.

If the notification email template is not used in any scheme, you can delete it with the Delete button next to the notification email template. After confirmation, the notification email template is deleted permanently.

Customize email subject and content with Handlebars

Skip this part of the documentation if you just want to add some custom instructions to the email content, or remove or rephrase some text. Read on if you want to make significant changes to the logic, numbers, and lists.

Notification email templates in the Better Content Archiving app support the Handlebars syntax. Handlebars is a templating tool based on Mustache.

Handlebars expressions are written between double curly braces {{}}. You can control the flow of generating a notification email's subject line and content (the email body). The factory default notification email templates are designed to suit the most common use cases. They are great starting points for building your own templates.

Data types

You can use the following expressions in a template:

Expression Description
baseUrl The base URL of your Confluence site. Useful when creating links in the email.

Example (from the default notification email templates):
<html>
	<head>
		<!-- ... -->
		<base href="{{baseUrl}}"/>
	<!-- ... -->
	</head>
	<!-- ... -->
</html>
totalContentCount The overall count of all contents processed when creating the notification. For performance reasons, this number may be greater than the number of contents that you can actually list in the notification.

Example for a typical notification email subject (note the singular vs. plural form of the word "content"):
{{totalContentCount}} content{{#if(gt totalContentCount 1)}}s{{/if}} expired
contents The contents in your Confluence site that you can actually iterate over when generating a notification. Their backing Java data type is LimitedMap<NotificationSpace, LimitedList<NotificationContent>>. See below for more details on these types.

The following example iterates over the keys of the contents collection (whose keys are actually the spaces for which contents have been collected for the notification) in the outer each loop, and uses the key's key and name values in headings. It does so by referencing @key.key and @key.name. (The expression @key.key can be a little confusing. The first part (@key) references the map's key which is a space object, and the second part (.key) references the space's key field. These two fields are both named "key" accidentally, but they have completely different meanings.) It also prints some text with basic information.

Then, it iterates over the contents listed for each space in a nested loop. It accesses contents using this, which references the current element in the outer loop. Given that the current element in the outer loop is a list in this case, it can be iterated over in a nested loop.

Inside the nested loop, we can access the current content element's data. For example, @type.apiValue can be used to determine the content type (page or blogpost). Based on the type, a link is constructed that points to the content. When generating the link's label, {{title}} is used as a convenient way to access the content's title.

{{#each contents}}
	<h3><a href="wiki/spaces/{{@key.key}}">{{@key.name}}</a></h3>
	{{this.size}} content{{#if(gt this.size 1)}}s{{/if}} not viewed in {{abbreviate @key.key 23}}.
	{{#each this}}
		<div class="content-item">
			{{#if (eq @type.apiValue "page")}}
				<a href="wiki/spaces/{{../@key.key}}/pages/{{id}}">{{title}}</a>
			{{/if}}
			{{#if (eq @type.apiValue "blogpost")}}
				<a href="wiki/spaces/{{../@key.key}}/blog/{{id}}">{{title}}</a>
			{{/if}}
		</div>
	{{/each}}
{{/each}}

For performance and usability reasons, the email notification templates cannot access "large" amounts of data (10000 spaces, for example). Instead, they will receive size-limited views (a maximum of 20 spaces are detailed, with a maximum of 50 contents listed for each) of the data as instances of the following collection types:

Limited collection types
Type name Description
LimitedList A size limited decorator for the Java List type.

Think about it as a list that maximizes the number of items it actually holds, but also knows the total number of items it would contain if it were non-limited. Example: when the list receives 135 items, 100 as max size, then it will return 100 items and 35 as the remaining count.

It extends the java.util.List interface with:
  • list.size: the number of items actually contained in the list
  • list.totalSize: the number of items that would be contained in the list if it was not limited
  • list.remainingCount: the number of items beyond those that are contained in the list
LimitedMap A size limited decorator for the Java Map type.

It has the semantics with map entries, as LimitedList has with the list items.

It extends the java.util.Map interface with:
  • map.size: the number of items actually contained in the map
  • map.remainingCount: the number of entries beyond those that are contained in the map
DTO types

The items in the above collections are lightweight DTO objects of the following types:

Type name Description
NotificationSpace A lightweight replacement for a Confluence Space.

Available fields:
  • id: numerical ID of the space
  • key: the space key
  • name: the name of the space
  • type: the type of the space (global or personal); use type.apiValue field to access the actual value
NotificationContent A lightweight replacement for a Confluence content (page or blog post).

Available fields:
  • id: numerical ID of the content
  • title: the title of the content
  • type: the type of the content (page or blogpost); use type.apiValue field to access the actual value
Handlebars helpers

Handlebars is a "logic-less" templating tool, but it supports the definition of so-called helpers. Helpers are expressions that can be used in a template to implement simple logic like comparing two values or evaluating a true/false condition, backed by custom built-in functionality in the service that parses the template.

Handlebars has a set of default helpers which you can use. You can find them here and here.

Complementing the default helpers, the Better Content Archiving app comes with the following set of Handlebars helpers that you can also use in your templates.

Helper Description
abbreviate Abbreviates a string to a given length (at least 4). Appends '...' to the end of the string. This suffix counts against the overall length the string is abbreviated to. Uses StringUtils.abbreviate() under the hood.
{{abbreviate "long string" 6}}
and Logical AND operator. Takes a list of expressions. Evaluates to true if all expressions are true, or false otherwise.
{{#if (and (gt contents.size 0) (gt totalContentCount 10))}}
	There is at least one space listed, and there are at least 11 contents overall
{{/if}}
eq Logical EQUALS operator. Takes two expressions. Evaluates to true if they are equal, false otherwise.
{{#if (eq contents.size 1)}}
	There is exactly one space listed
{{/if}}
gt Logical GREATER THAN operator. Takes two values. Evaluates to true if the first is greater than the second, false otherwise.
{{#if (gt contents.size 1)}}
	There are at least two spaces listed
{{/if}}
gte Logical GREATER THAN OR EQUALS operator. Takes two values. Evaluates to true if the first is greater than or equal to the second, false otherwise.
{{#if (gte contents.size 2)}}
	There are at least two spaces listed
{{/if}}
lt Logical LESS THAN operator. Takes two values. Evaluates to true if the first is less than the second, false otherwise.
{{#if (lt contents.size 10)}}
	There are less than 10 spaces listed
{{/if}}
lte Logical LESS THAN OR EQUALS operator. Takes two values. Evaluates to true if the first is less than or equal to the second, false otherwise.
{{#if (lte contents.size 10)}}
	There are no more than 10 spaces listed
{{/if}}
ne Logical NOT EQUALS operator. Takes two expressions. Evaluates to true if they are not equal, false otherwise.
{{#if (ne contents.size 0)}}
	There is at least one space listed
{{/if}}
not Logical NOT operator. Takes a boolean expressions. Evaluates to the opposite of the expression, i.e. to true if the original value was false, and to false if the original value was true.
{{#if (not (eq contents.size 0))}}
	There is at least one space listed
{{/if}}
or Logical OR operator. Takes a list of expressions. Evaluates to true if any of the expressions is true, or false otherwise.
{{#if (or (gte contents.size 2) (gt totalContentCount 10))}}
	There are at least two space listed, or there are at least 11 contents overall
{{/if}}

Combine and nest the above helpers to create complex conditions:

and (gt contents.size 0) (gt totalContentCount 10)

Questions?

Ask us any time.