Skip to main content
Version: 13.x (Current)

Notification Manager configuration

The Notification Manager needs some configuration in order to be used effectively.

CRUD collections

To use the Notification Manager you need to create the following CRUD collections:

  • users: a CRUD containing the users;
  • templates: a CRUD containing the notification templates;
  • event settings: a CRUD containing the event settings;
  • events: a CRUD containing events (used to store details about unknown events);
  • notifications: a CRUD containing the notifications sent;
  • notification settings: a CRUD containing the notification settings.

Users CRUD

info

Since version v2.3.0 the users collection is no longer required if the USERS_API_ENDPOINT is specified and it points to an external service that handles users.

This CRUD collection contains the data of the users you want to send messages to. The collection is required and can be named however you want (we suggest users) as long as you specify the name in the USERS_CRUD_NAME environment variable.

The CRUD collection must have the properties listed in the following table.

NameTypeRequiredDescription
idstringNoThe user's unique identifier.
clustersArray of stringsNoA list of clusters the user belongs to (used to decide if the user should be included as a recipient when sending a message to a particular cluster).
groupsArray of stringsNoA list of groups the user belongs to (used to decide if the user should be included as a recipient when sending a message to a particular group).
rolesArray of stringsNoA list of roles associated to the user.
emailAddressstringFor email notificationsA valid e-mail address.
phoneNumberstringFor SMS notificationsA phone number in E.164 formatformat.
deviceTokenstringFor push notificationsA Firebase devices token.
tip

The naming of these properties is up to you. By default, the service will look for the names listed above, but if you prefer using other names you just need to map them correctly in the userFields properties of the service configuration.

tip

None of these properties are required. If the service does not find a value for a user, it will simply not send messages to that user over the missing channel(s).

tip

The collection can have any number of additional properties, the service will ignore them.

Templates CRUD

The templates collection contains all the information needed to create standardized messages.

danger

v2.0.0. Since version 2.0.0 this collection is required both for sending automatic notifications based on events and whatsapp messaging service. Also, the name field is now required.

info

v1.5.0. Since version 1.5.0 the pushTitle and pushMessage fields are no longer required, since you can use pushData to provide a custom payload for push notifications.

This CRUD collection contains the message templates for sending notifications, both manually (optional) and automatically (required). Like for the users collection, it does not matter how the CRUD is named (we suggest message_templates) as long as you specify the name in the TEMPLATES_CRUD_NAME environment variable.

The CRUD collection must have the properties listed in the following table.

NameTypeRequiredDescription
namestringYesA human-readable name of the template. Required since v2.0.0.
emailTitlestringFor email notificationsEmail title. It supports interpolation.
emailMessagestringFor email notificationsEmail plain-text body. Required if htmlMessage is not defined. It will be ignored if emailHtmlMessage is set and supports interpolation.
emailHtmlMessagestringFor email notificationsEmail HTML body. Required if emailMessage is not defined; if both are defined, only emailHtmlMessage is used. It supports interpolation.
emailAttachmentsArray of objectFor email notificationsList of objects with the same interface given by File Service. The only compulsory field is the file attribute.
smsMessagestringFor SMS notificationsSMS body. It supports interpolation.
voiceMessagestringFor voice notificationsVoice message body. It supports interpolation.
pushTitlestringFor push notificationsOptional since v1.5.0. Push notification title. It supports interpolation.
pushSubtitlestringFor push notificationsPush notification subtitle. It supports interpolation.
pushMessagestringFor push notificationsOptional since v1.5.0. Push notification message. It supports interpolation.
pushDatastringFor push notificationsJSON payload of the notification. It supports interpolation.
whatsappTemplateNamestringFor whatsapp notificationsWhatsapp template name.
whatsappTemplateParametersstringFor whatsapp notificationsA comma-separated list of values to pass as parameters (see TEMPLATE_PARAMETERS in Kaleyra API documentation). It supports interpolation.

Since version 1.5.0, the pushData field is available to customize the push notifications, for example to provide localized messages, and takes precedence over the other fields - pushTitle, pushSubtitle and pushMessage. The field accepts as value a JSON object with the following fields:

  • android - object: android-specific information to be included in the message. The object must conform the shape described here.
  • apns - object: information specific to APNS (Apple Push Notification Service). The object must conform the shape described here.
tip

The fields relative to a channel are required only if plan to use templates, and you want to send messages through that channel (this applies also to the fields marked as required in the list above).

Event settings CRUD

info

v2.0.0. This CRUD collection was introduced and is required since version 2.0.0.

This CRUD collection contains the settings for each class of events. The collection is required and can be named however you want (we suggest event_settings) as long as you specify the name in the EVENTS_SETTINGS_CRUD_NAME environment variable.

The CRUD collection must have the properties listed in the following table.

NameTypeRequiredDescription
eventNamestringYesName of the event the settings refer.
userGroupsArray of stringNoList of groups the event is visible to (all by default if the field is not set).
supportedChannelsArray of stringNoList of channels supported by the event, must be a subset of the channels enabled at the service level.
eventSchemaObjectNoJSON schema to validate the received event.
handlerNamestringNoName of the custom handler to use to process the event.
handlerConfigObjectNoAn arbitrary configuration for the event handler.
note

The handlerConfig is not currently used, but it has been introduced in anticipation of new features planned for future releases.

Events CRUD

info

v2.0.0. This CRUD collection was added and is required since version 2.0.0.

This CRUD collection contains details about events, in particular unknown events, that were received. The collection is required and can be named however you want (we suggest events) as long as you specify the name in the EVENTS_CRUD_NAME environment variable.

The CRUD collection must have the properties listed in the following table.

NameTypeRequiredDescription
idstringYesEvent identifier (must be unique across the system).
keystringNoEvent key (ID of the main resource associated to the event, like an appointment or plan).
namestringYesEvent name.
metadataObjectNoEvent metdata, to provide additional details to the event handler.
payloadObjectNoEvent payload
sourceObjectYesEvent source (HTTP request)
statusstringYesEvent status (RECEIVED, PROCESSED, ERROR)
errorsArray of objectNoList of errors occurred processing the event

Notifications CRUD

info

v2.0.0. This CRUD collection was added and is required since version 2.0.0.

This CRUD collection contains details about the notifications sent in response to events. The collection is required and can be named however you want (we suggest notifications) as long as you specify the name in the NOTIFICATIONS_CRUD_NAME environment variable.

The CRUD collection must have the properties listed in the following table.

NameTypeRequiredDescription
eventObjectYesThe event the notification is about, as in the events CRUD.
recipientstringNoID of the user the notification was sent to.
messagesArray of objectNoList of messages processed.
remindersArray of objectNoList of reminders processed.
failuresArray of objectNoList of generic errors occurred processing the notification.

Notification messages

Each message in the messages field represents a single message sent to the recipient using the given template on a specific channel.

Each message has the properties illustrated in the following table.

NameTypeRequiredDescription
statusstringYesIf the message was processed correctly (SUCCESS) or not (FAILURE).
channelstringYesName of the channel the message was sent on.
templateNamestringYesName of the template used to send the message on the channel.
attachmentsArray of objectNoList of custom attachments sent (available since version 2.3.0).
serviceObjectNoAn object containing information about the notification processed by a service provider.
errorObjectNoIn case of errors, it contains additional information about the error.

So, for example, if you configure a notification settings with the following reminders:

{
"user": "auth0|john.doe",
"channel": "email",
"templateName": "create-appointment-patient",
"attachments": [{"file" :"patient-medical-record.pdf"}]
}

in the notification you could find something like this:

{
"messages": [
{
"status": "SUCCESS",
"channel": "email",
"templateName": "create-appointment-patient",
"attachments": [{"file" :"patient-medical-record.pdf"}],
"service": {
"message": {
"sender": "noreply@example.com",
"recipient": "patient0@example.com",
"subject": "New appointment confirmed on 2023/12/15 at 09:30",
"htmlMessage": "Dear patient, we confirm your appointment on 2023/12/15 at 09:30."
}
}
},
{
"status": "FAILURE",
"channel": "sms",
"templateName": "create-appointment-patient",
"service": {
"message": {
"sender": "St.Claire Hospital",
"receiver": "+391234567890",
"body": "Dear patient, we confirm your appointment on 2023/12/15 at 09:30.",
}
},
"error": { "statusCode": 401, "error": "Unauthorized", "message": "..." }
},
{
"status": "SUCCESS",
"channel": "voice",
"templateName": "create-appointment-patient",
"service": {
"message": {
"receiver": "+391234567890",
"body": "Dear patient, we confirm your appointment on 2023/12/15 at 09:30.",
}
}
},
{
"status": "FAILURE",
"channel": "whatsapp",
"templateName": "create-appointment-patient",
"service": {
"message": {
"sender": "St.Claire Hospital",
"receiver": "+391234567890",
"templateName": "whatsapp-create-appointment-patient",
"params": "John,Doe,2023-12-15T09:30:00",
}
},
"error": { "statusCode": 503, "error": "Service Unavailable", "message": "..." }
}
]
}

Notification reminders

Each reminder in the reminders field matches the corresponding reminder in the notification settings field with the same name.

Each reminder has the properties illustrated in the following table.

NameTypeRequiredDescription
statusstringYesIf the reminder was processed correctly (ACTIVE or ABORTED) or not (ERROR).
expirationDatestringYesWhen the reminder expires, as an ISO 8601 date-time string.
expirationIdstringNoThe ID of the job scheduled on the Timer Service (if the reminder was processed correctly).
schedulestringNoThe reminder schedule, as an ISO 8601 duration string.
triggersArray of stringNoThe IDs of the notification settings that triggered this notification.
errorObjectNoIn case of errors, it contains additional information about the error, like the response received by the Timer Service.

So, for example, if you configure a notification settings with the following reminders:

{
"reminders": ["P1D", "PT2H"]
}

in the notification you could find something like this:

{
"reminders": [
{
"status": "ACTIVE",
"expirationDate": "2023-08-12T09:30:00Z",
"schedule": "P1D",
"expirationId": "4b5f068c-5f8b-4f0b-ba69-1b0025633edc"
},
{
"status": "ERROR",
"expirationDate": "2023-08-13T07:30:00Z",
"schedule": "PT2H",
"error": {
"statusCode": 503,
"error": "Service Unavailable",
"message": "..."
}
}
]
}

Notification settings CRUD

info

v2.0.0. This CRUD collection was introduced with version 2.0.0.

This CRUD collection contains the notification settings. The collection is required and can be named however you want (we suggest notifications_settings) as long as you specify the name in the NOTIFICATIONS_SETTINGS_CRUD_NAME environment variable.

The properties used by the service are the following.

NameTypeRequiredDescription
eventNamestringYesName of the event for which notifications are sent.
userstringNoID of a user who can receive notifications.
groupstringNoGroup of users who can receive notifications.
clusterstringNoCluster who can receive notifications.
rolestringNoRole who can receive notifications.
channelsArray of stringYesList of channels to send notifications on.
hoursArray of stringNoList of time slots when notifications can be sent. Each time value must be expressed in ISO 8601 time format (for example, 09:00-18:00).
templateNamestringYesTemplate name from the templates CRUD to use.
rulestringNoIf the given users, groups and/or cluster should receive (SEND) or not (IGNORE) notifications.
emittersArray of stringNoList of emitters that should trigger the sending of notifications.
remindersArray of stringNoList of reminders to set, expressed as ISO 8601 duration strings (for example, P1D for one day and PT1H for an hour before).

Views

Notification messages view

info

This view is required by the following endpoints and must be enabled explicitly by setting the NOTIFICATIONS_MESSAGES_VIEW_NAME environment variable:

By default, the view is not enabled and these endpoints are not available.

This MongoDB view runs an aggregation pipeline on the notifications CRUD collection to return a distinct document for each message sent, i.e. each element in the notification messages array field.

The MongoDB view must have the properties listed in the following table.

NameTypeRequiredDescription
notificationIdStringNoCRUD _id of the notification.
recipientStringNoID of the user the message was sent to.
eventStringNoThe name of the event.
dateDateNoWhen the message was sent.
statusStringNoIf the message was processed correctly (SUCCESS) or not (FAILURE).
channelStringNoName of the channel the message was sent on.
templateNameStringNoName of the template used to send the message on the channel.
messageObjectNoThe details about the message sent (title, subtitle, body, etc.)

This is the aggregation pipeline, that you can customize for example by adding additional fields.

[
{
"$match": {
"__STATE__": "PUBLIC"
}
},
{
"$unwind": {
"path": "$messages"
}
},
{
"$project": {
"_id": {
"$concat": [
{
"$toString": "$_id"
},
"-",
"$messages.channel",
"-",
"$messages.templateName"
]
},
"creatorId": "$creatorId",
"createdAt": "$createdAt",
"updaterId": "$updaterId",
"updatedAt": "$updatedAt",
"__STATE__": "$__STATE__",
"notificationId": {
"$toString": "$_id"
},
"recipient": "$recipient",
"event": "$event.name",
"date": "$createdAt",
"status": "$messages.status",
"channel": "$messages.channel",
"templateName": "$messages.templateName",
"message": "$messages.service.message"
}
}
]

The _id field is computed dinamically based on the notification _id and is unique across all messages.

Environment variables

info

v2.3.0. Since version 2.3.0 the USERS_API_ENDPOINT environment variable is available, to configure the base URL of an API providing users data with a CRUD-like interface. If USERS_API_ENDPOINT is not set, the users data is retrieved as in previous versions from a CRUD collection using the CRUD_SERVICE_URL and USERS_CRUD_NAME environment variables.

info

v2.3.0. Since version 2.3.0 the DEFAULT_LOCALE environment variable is available, to configure the default locale to use with toLocale custom helper.

info

v2.2.0. Since version 2.2.0 the GOOGLE_APPLICATION_CREDENTIALS environment variable is available, to send push notifications directly to Firebase, without needing Kafka.

info

v2.0.0. Since version 2.0.0 the following environment variables are no longer available, so if you are upgrading from version 1.x you need to update the service configuration first:

  • CRUD_SERVICE_NAME (use CRUD_SERVICE_URL instead).
NameRequiredDefaultVersionDescription
SERVICE_NAMEYes-*The name of the Notification Manager microservice.
CONFIGURATION_PATHYes-*Path of the config map file containing the service configuration.
CRUD_SERVICE_URLYes->= 2.0.0The HTTP(S) URL of the CRUD service. This environment variable replaces CRUD_SERVICE_NAME since version 2.0.0.
USERS_CRUD_NAMEYes-*Name of the CRUD collection containing users data.
TEMPLATES_CRUD_NAMEYes-*Name of the CRUD collection containing messaging templates.
EVENTS_CRUD_NAMEYes-*Name of the CRUD collection containing events.
EVENTS_SETTINGS_CRUD_NAMEYes-*Name of the CRUD collection containing event settings.
NOTIFICATIONS_CRUD_NAMEYes-*Name of the CRUD collection containing statistics about notifications sent.
NOTIFICATIONS_SETTINGS_CRUD_NAMEYes-*Name of the CRUD collection containing the notifications settings.
NOTIFICATIONS_MESSAGES_VIEW_NAMENo->= 2.4.0Name of the MongoDB view containing the notification messages.
MAIL_SERVICE_URLEmail notifications-*URL of the SES Mail Notification Service. Required if you want to send e-mails.
SMS_SERVICE_URLSMS notifications-*URL of the SMS Service. Required if you want to send SMS.
FILE_SERVICE_URLEmail attachments-*URL of the File Service. Required if you want to send emails with attachments.
TIMER_SERVICE_URLReminders-*The HTTP(S) URL of the Timer Service.
KAFKA_CLIENT_IDPush notifications-*Required if you want to send push notifications.
KAFKA_BROKERSPush notifications-*List of comma separated brokers address. Required if you want to send push notifications.
KAFKA_TOPICSPush notifications-*List of comma separated topics. Required if you want to send push notifications.
KAFKA_AUTH_MECHANISMPush notificationsPLAIN*Authentication mechanism, used only if KAFKA_USERNAME and KAFKA_PASSWORD have a value.
KAFKA_USERNAMEPush notifications-*
KAFKA_PASSWORDPush notifications-*
KAFKA_CONNECTION_TIMEOUTPush notifications1000*Time in milliseconds to wait for a successful connection.
KAFKA_AUTHENTICATION_TIMEOUTPush notifications1000*Time in milliseconds to wait for a successful authentication.
KAFKA_EVENTS_TOPIC_NAMENo-*Name of the Kafka topic for incoming events. If not set, automatic notifications via Kafka are disabled.
KAFKA_ERRORS_TOPIC_NAMENo-*Name of the Kafka topic for unknown events. If not set, automatic notifications via Kafka are disabled.
KAFKA_CONSUMER_GROUPNo-*Name of the Kafka consumer group for Kafka topic for incoming events.
KALEYRA_API_BASE_URLNo-*Kaleyra API base URL for the whatsapp and outbound calling services.
KALEYRA_API_KEYNo-*Kaleyra API key for the whatsapp and outbound calling services.
KALEYRA_API_SIDNo-*Kaleyra SID for the whatsapp and outbound calling services.
CUSTOM_HANDLERS_FOLDERCustom handlers-*The path to the directory containing the definitions (i.e. the configmaps) of the custom handlers.
GOOGLE_APPLICATION_CREDENTIALSPush notifications->= 2.2.0The application credentials given by Firebase. Must be loaded from a secret.
DEFAULT_LOCALENo->= 2.3.0A BCP 47 language tag used as default locale by toLocale custom helper in message templates.
USERS_API_ENDPOINTNo->= 2.3.0The url of the API queried to fetch users data.

Channels configuration

Kaleyra integration

The outbound calling and the whatsapp services will need the Kaleyra integration to work properly. In order to setup the Kaleyra integration, you will need, firstly, to create a Kaleyra account and create an API Key. To successfully set up your Kaleyra account, please refer to the Getting Started section of the official Kaleyra documentation. The obtained Kaleyra API Key and SID will be provided to the notification-manager via environment variables, namely KALEYRA_API_KEY and KALEYRA_API_SID.

Outbound calls

In order to use the outbound calls service, you will then need to setup a valid bridge number, that will be provided to the notification-manager in the service configuration map, as stated in the next section.

Whatsapp messaging

In order to use the Whatsapp messaging service, you need firstly to enable the Whatsapp channel on your Kaleyra account. When setting up the Whatsapp channel, you will need to create a WhatsApp Business account on the Meta developer platform. This account will be then linked to your Kaleyra account. You will also need a valid phone number to associate to your Whatsapp business account, which will be the number that will appear to users who will receive your messages. This number will be provided to the notification-manager in the service configuration map, as stated in the next section.

In order to set up a correct configuration, we kindly recommend to follow the official Kaleyra documentation for Whatsapp integration.

Service configuration

The service needs a configuration file in JSON format, that can be provided to it as a configmap. You can choose the name and mounting point of the map, as long as you specify the correct path in the CONFIGURATION_PATH environment variable.

It follows a description of the fields of the map.

  • userFields - object: if you have given a different name to any of the properties listed in the Users CRUD section, you can use this map to tell the service how to find them.
    • id - string: the name of the property in the Users CRUD containing the user's unique identifier. It will be matched with the values specified in the recipients field. If not set, the service will use _id as default.
    • emailAddress - string: the name of the property in the Users CRUD containing the user's e-mail address.
    • phoneNumber - string: the name of the property in the Users CRUD containing the user's phone number.
    • deviceToken - string: the name of the property in the Users CRUD containing the user's device token.
    • clusters - string: the name of the property in the Users CRUD containing the user's clusters list.
    • groups - string: the name of the property in the Users CRUD containing the user's groups list.
    • roles - string: the name of the property in the Users CRUD containing the user's roles list.
  • activeChannels (required) - string array: the list of active channels over which each message will be delivered. Possible values are email, sms, push, voice and whatsapp.
tip

Keep in mind that even if a channel is active, a user will not receive messages over that channel if the correspondent property in the Users CRUD does not have a value.

  • sender - object: the senders for the various channels. Required if at least one among email, sms and whatsapp channels are enabled.
    • email - string: the e-mail address that will appear as the sender of e-mail messages. Required if the email channel is enabled.
    • sms - string: the sender of the SMS messages. Required if the sms channel is enabled. It can be one of the following:
      • a phone number in E.164 format
      • an alphanumeric sender ID
    • voice - string: the caller phone number of the voice messages. Required if the voice channel is enabled. The phone number must be registered in the Kaleyra console.
    • whatsappPhoneNumberId - string: Required when using whatsapp. It is the phone number id of the phone number registered in your whatsapp business account. It can be retrieved from the dashboard of the application created inside your whatsapp business account or, alternatively, in the management section of the Whatsapp channel of your Kaleyra account.
caution

If you use an alphanumeric sender ID please avoid generic names (e.g. SMS, Info...), otherwise the SMS provider may return an error like Invalid 'From' Number. Please check the SMS Service documentation for more details about supported providers.

  • voice - object: the configuration for the outbound calls used for voice notifications.

    • retryCount - integer: the number of retries that can be made until a timeout is reached if the initial call fails to connect. The default retry count is 0 and the maximum count is 2. Any value higher than 2 will be considered 2.
    • speechSpeed - string: the speed of the text-to-speech. The available options are: slow, medium, fast, x-slow and x-fast. For further info, you must refer to Kaleyra official documentation. If not provided, the default speed is set to medium.
    • speechLanguage - string: the language of the text-to-speech. The available options are: en-IN, en-US, es-ES and it-IT. For further info, you must refer to Kaleyra official documentation. If not provided, the default language is set to it-IT.
  • push - object: the configuration for push notifications.

    • provider - string: the provider used to deliver push notifications. The available options are: firebase, kafka (default).
  • androidIntentAction - string: the Android intent action that is triggered by the notification (the default value is an empty string).

  • flowManagerConfiguration - object: required if you want to enable the /saga/send API and the Flow Manager direct interaction.

    • metadataSchema - object: defines the path where to find the body fields, with exactly the same meaning, inside the Flow Manager metadata object.
      • channels (required) - string or string array
      • recipients - string or string array
      • clusters - string or string array
      • messageTitle - string
      • messageContent - string
      • templateId - string: It will be ignored if getTemplateIdFilePath is defined.
      • emailAttachments - string or string array
      • emailCarbonCopies - string or string array
      • emailBlindCarbonCopies - string or string array
      • emailSender - string
    • serviceUrl - string: URL of the Flow Manager Service. Required if you want to send events back.
    • successEventLabel - string: event label. Required if you want to send an event in case of successful notification.
    • failEventLabel - string: event label. Required if you want to send an event in case of failed notification.
    • getTemplateIdFilePath - string: path of the config map file containing the custom function that retrieves a templateId based on the command received. The function must have the following signature: function getTemplateId: (event: FlowManagerEvent) => string. It follows an example of a valid file.
      module.exports = function getTemplateId(event) {
      return event.value.messageLabel
      }
    • getDataFilePath - string: path of the config map file containing the custom function that retrieves an object used as data body field, based on the command received. The function must have the following signature: function getData: (event: FlowManagerEvent) => Record<string, any>. If not defined the Flow Manager command is used as is. It follows an example of a valid file.
      module.exports = function getData(event) {
      return {
      ...event,
      value: {
      ...event.value,
      messagePayload: {
      ...event.value.messagePayload,
      amount: event.value.messagePayload.amount.toFixed(2),
      },
      },
      }
      }

It follows an example of a valid configuration file.

{
"userFields": {
"id": "fiscalCode",
"emailAddress": "mail",
"phoneNumber": "phone",
"clusters": "departments",
"groups": "teams",
},
"activeChannels": [
"email",
"push",
"sms",
"voice",
"whatsapp"
],
"sender": {
"email": "email@test.com",
"voice": "+39123456789",
"sms": "Mia Care",
"whatsappPhoneNumberId": "+39123456789"
},
"voice": {
"retryCount": 0,
"speechSpeed": "medium",
"speechLanguage": "it-IT"
},
"push": {
"provider": "kafka"
},
"androidIntentAction": "eu.miaplatform.fakeactivity",
"flowManagerConfiguration": {
"serviceUrl": "http://flow-manager-service",
"successEventLabel": "notificationSent",
"failEventLabel": "notificationFailed",
"metadataSchema": {
"channels": "notifications.channels",
"recipients": "buyer.name",
"templateId": "notification.channel",
}
}
}

Custom event handlers

To register custom handlers, first you need to create a new configuration with an arbitrary name, for example /home/node/app/custom-handlers, and assign its path to the CUSTOM_HANDLERS_FOLDER env var.

Then, to register a custom handler, simply add a new file to the configuration - like acme-shipping-handler.js in the snippet above - containing the JavaScript code implementing and exporting your handler, i.e. the function to be executed when a new HTTP request is received notifying a new event to process.

Finally, to get the custom handler loaded at application startup, add or update a record in the event settings CRUD collection by calling the PATCH /event-settings/:id endpoint with the name of the chosen event, the name of the handler, and optionally a JSON schema for the event validation.

Here's an example of an event settings specifying a custom handler, defined in the acme-shipping-handler.js config map, to process ACME/OrderShipped/v1 custom events.

{
"eventName": "ACME/OrderShipped/v1",
"handlerName": "acme-shipping-handler.js",
"eventSchema": {
"type": "object",
"description": "AM/AppointmentCreated/v1 notification event",
"properties": {
"id": {
"type": "string",
},
"key": {
"type": "string",
"description": "Event key (affected resource, etc.)",
},
"name": {
"type": "string",
"description": "Event name",
"value": "ACME/OrderShipped/v1",
},
"metadata": {"...": "..."},
"payload": {"...": "..."},
},
"required": ["name"],
"additionalProperties": false,
}
}
note

The routing table, that specifies which custom or default handler is used to process each type of event, is built once at startup and is updated automatically if you update the [event settings CRUD][crud-event-settings] using one of the following endpoints:

Any other change requires a service restart to takes effect.

The JavaScript file must export a function with two arguments:

  • service: a decorated Fastify instance, to access the logger, CRUD proxy, …;
  • event: the event details;
{
"id": "event12345",
"key": "order-12345",
"name": "ACME/OrderCreated/v1",
"payload": {
"...": "..."
}
}
  • utils: several utility functions to send notifications, retrieve users, set reminders, … .

You can find more details about the API accessible inside a custom handler in the Usage section.

Your JavaScript module should therefore look like this:

// lodash and luxon libraries can be accessed inside the custom handler
const _ = require('lodash')
const luxon = require('luxon')

module.exports = async function handler(service, event, utils) {
// Your code to handle the event, this is an example using some of the provided utils
// Let's imagine we have a single recipient with the ID stored in the userId field of the event payload
const {payload} = event
const {userId, startDate} = payload
const recipients = await utils.getRecipients(service, {_id: userId})
return recipients.map(async recipient => {
const notificationSettings = await utils.getNotificationSettings(service, event, recipient)
const mergedNotificationSettings = utils.mergeNotificationSettings(service, notificationSettings)
const messages = utils.buildMessages(service, mergedNotificationSettings)
const messagesNotification = await utils.sendMessages(service, event, recipient, messages)
const reminders = utils.buildReminders(service, recipient, notificationSettings, startDate)
const remindersNotification = await utils.setReminders(service, reminderEvent, recipient, reminders)
const userNotifications = [messagesNotification, remindersNotification]
return mergeNotifications(event, recipient, userNotifications)
})
}
danger

Be careful with the implementation of your handler, since any error raised during its execution would interrupt the processing of the notification event, whose status would be set to ERROR.

Users configuration

Since version v2.3.0 users can be handled by an external service if the USERS_API_ENDPOINT is defined. This external service must be compatible with the Crud service interface. If the external api endpoint is not defined the USERS_CRUD_NAME must be specified, and the Notification Manager fetches users from the Crud service as usual. When both environment variables are specified, the USERS_API_ENDPOINT takes precedence and the external service is used for users.

Security configuration

General recommendations about endpoint authorization are summarized in the following table.

EndpointRecommended authorization level
/user-notification-settingsAccessible to all who can change their notification settings.
/notification-settingsAccessible to users with admin roles.
/notificationsAccessible to users that monitor anomalies in sending messages and reminders.

Event ACLs

If you want to allow certain events to be visible only to certain user groups, you can build a custom solution or you can use Rönd to enforce such security policies.

First, you need to configure, for each event type, which user groups have access to it by settings the corresponding userGroups field in the event settings CRUD collection. If the field is not set, the service assumes the event is visible to all users. For example, if you want the AM/AppointmentCreated/v1 event to be visible only to users belonging to the doctors and/or admins group, you should configure a CRUD record like this:

{
"eventName": "AM/AppointmentCreated/v1",
"userGroups": ["admins", "doctors"]
}

If you want to build a custom solution, you can use the GET /user/events endpoint to retrieve the list of events accessible to the logged user. If you are using Rönd, you can write a policy fetching directly this information from the event settings CRUD collection.

The following table provides some default policies you can use or extend to protect the most relevant endpoints.

EndpointRönd policy
DELETE /notification-settings/:idnm_update_notification_settings
PATCH /notification-settings/:idnm_update_notification_settings
POST /notification-settings/nm_create_notification_settings

Rönd policies and their tests are downloadable from the following links:

Make sure that the collections written in the policies match the crud collections name specified in the corresponding environment variables.

Notification settings

This section illustrates with examples how you can leverage notification settings to send messages and reminders to users.

Let's start with an example to break down the notification settings data model:

{
"eventName": "AM/AppointmentCreated/v1",
"emitters": ["sarah.cohen", "julie.cross"],
"group": "doctors",
"cluster": "st.mary.hospital",
"channels": ["email", "sms"],
"hours": ["09:00-18:00"],
"templateName": "doctor-new-appointment",
"reminders": ["P1D", "PT6H"],
"rule": "SEND"
}

The eventName field targets the AM/AppointmentCreated/v1, which is generated when a new appointment is created in the Appointment Manager, while the emitters field specifies that the notification setting applies only to event emitted by sarah.cohen or julie.cross; the actual semantic of the emitters field value (being a patient ID or something entirely different) depends on the specific event.

The group and cluster fields, together with user and role, target a subset of users that belong to the given group and cluster, in the example all the doctors of the fictional St. Mary Hospital.

The channels, hours and templateName determine which messages are sent on which channels, in particular the doctors are going to receive an email and a sms message based on the doctor-new-appointment template, but only if the event occurs in the 9-18 time slot, which could be their working hours.

The reminders field specifies how many and when reminders will be sent, in the example one day (P1D) and six hours earlier (PT6H); each string represent a duration expressed in ISO 8601 format and the event handler is responsible for the type of event associated to the reminder (you can check the event handlers documentation to find out). Also, the exact moment when the reminders will be sent depends on which date/time the handlers applies the specified durations: in the example, we will send the first reminder one day before the appointment starts, the second one six hours before the appointment starts.

Reminders

When a handler designed to process a reminder receives the appropriate reminder event (for example the AM/AppointmentReminder/v1 event, from the example above), the handler receives two key information in the event metadata:

  • the schedule, which is the notification settings reminder that triggered the event (P1D or PT6H from the example above);
  • the recipients, which are the ID of users that should received the messages (it could be a doctor or patient from the appointment or someone from the hospital administration).

These kind of handlers typically fetch the notification settings that apply to the given reminder event, schedule and recipients, assigning a double semantic to the reminders field of the notification settings:

  • when fetching them, will filter the notification settings containing the given schedule in the reminders field;
  • after the reminders are sent, the handler could set new reminders according to the notification settings reminders.

Which of these two semantics are applied depends entirely on the specific behavior of the event handler, could be none or both. We recommend to always check the event handlers documentation to find out which is the case for each default event handler.

Let's see with an example how we can configure the notification settings to take advantage of these semantics for the TMM/MonitoringCreated/v1 event, which is triggered when a monitoring plan is created in the Therapy & Monitoring Manager.

{
"eventName": "TMM/MonitoringCreated/v1",
"group": "patients",
"channels": ["email"],
"templateName": "patient-monitoring-plan-created",
"reminders": ["P1D", "PT1H"],
"rule": "SEND"
}

So, when a new monitoring plan is created, the patient receives an email confirmation and two reminders - one day and one hour before the day the monitoring plan starts - are scheduled for the TMM/MonitoringReminder/v1. So, let's see how we can configure two different notification settings with different templates for each reminder if the notification settings are filtered according to the reminder schedule:

{
"eventName": "TMM/MonitoringReminder/v1",
"group": "patients",
"channels": ["email"],
"templateName": "patient-monitoring-plan-reminder-1d",
"reminders": ["P1D"],
"rule": "SEND"
}
{
"eventName": "TMM/MonitoringCreated/v1",
"group": "patients",
"channels": ["sms"],
"templateName": "patient-monitoring-plan-reminder-1h",
"reminders": ["PT1H"],
"rule": "SEND"
}

In the example, we are sending the first reminder one day earlier via email and the second reminder one hour earlier via sms, using different templates.

If the handler is configured to send recurring reminders, for example to send to the patient a reminder each day he or she has to measure the blood pressure, after the current reminder has been processed, it will schedule new reminders according the reminders field of the notification settings.

info

The following default reminder event handlers filter the notification settings according to the reminders field:

  • AM/AppointmentReminder/v1

The following default reminder event handlers both filter the notification settings and set recurring reminders, until the event is considered expired, according to the reminders field:

  • TMM/MonitoringReminder/v1
  • TMM/TherapyReminder/v1