Notification Manager Usage
This sections illustrates how to use the Notification Manager.
As you may recall from the overview you can send notifications in two different ways:
- manually: by sending a request to the
POST /send
endpoint, passing the channels, recipients, template, … in the request body; - automatically when specific events occur, by calling the
POST /notification-events
.
You can create, update or delete notification settings through the endpoints described in the following section:
GET /notification-settings/
PATCH /notification-settings/:id
POST /notification-settings/
DELETE /notification-settings/:id
HTTP API
POST /send
With this API you can send a new message to your users through different channels.
Request
The body of the request should have the following shape.
- channels (required) -
array of strings
: list of channels you want to send you message over. Possible values areemail
,sms
,push
,voice
andwhatsapp
.
This list has to be a subset of the activeChannels
property specified in the service configuration.
recipients -
array of string
: list of unique identifiers of the users you want to send your messages to. Required ifclusters
is not defined.clusters -
array of string
: users' clusters you want to send your messages to. Required ifrecipients
is not defined.messageTitle -
string
: title of the message. It will be used as title for e-mails and push notifications. Required iftemplateId
is not defined. It will be ignored iftemplateId
is defined. It supports interpolation.messageContent -
string
: content of the message. It will be used as content for e-mails, sms, push and voice notifications. Required iftemplateId
is not defined. It will be ignored iftemplateId
is defined. It supports interpolation.templateId -
ObjectId
: id of the template to be used for composing the message. Required ifmessageTitle
andmessageContent
are not defined, or, if you are sending a Whatsapp message.data -
object
: data used for messages interpolation.emailAttachments -
array of strings
: list of filenames that should be sent as mail attachments. The filename must be the same as that used in the file service to download it. It is possible to send attachments no larger than 15 MB. If no File Service is declared in the environment variables an error will be thrown.:::tip If you use a template in which some attachments are listed, they will be merged with the attachments specified in the
emailAttachments
property of the request body (i.e. both the attachments specified in the template and in the body will be sent.) :::emailCarbonCopies -
array of strings
: list of email addresses that should be included as carbon copies (CC). Any invalid email addresses will be ignored. Available since version 1.4.0.emailBlindCarbonCopies -
array of strings
: list of email addresses that should be included as blind carbon copies (BCC). Any invalid email addresses will be ignored. Available since version 1.4.0.emailSender -
string
: email address of the message sender. This value overwrites the email set in the service configuration. Available since version 2.1.0.
Response
Exceptions
If something goes wrong during the request, the response will have a 4xx
or 5xx
status code and the following payload:
{
"statusCode": "400",
"error": "Bad request",
"message": "Exception description"
}
Success
A successful response (status code 200
) is issued if the process of messages sending starts without errors. However,
it is still possible that the dispatch of some messages to some users fails on some channels. The body of the response
will contain a list of those failures, with a brief explanation of the error, if applicable.
{
"failures": [
{
"userId": "auth0|userId",
"channel": "whatsapp",
"error": "Error: Missing required template name for WhatsApp message"
}
]
}
POST /saga/send
With this API you can send a new message to your users through different channels directly with a Flow manager command. You should avoid calling this endpoint in a different way.
Body
It has the same structure of a Flow Manager command.
Response
Exceptions
If something goes wrong during the request, the response will have a 4xx
or 5xx
status code and the following payload:
{
"statusCode": "400",
"error": "Bad Request",
"message": "Exception description"
}
Moreover, if enabled by configuration, it sends an event with failEventlabel
as messageLabel and empty messagePayload.
Success
A successful response (status code 200
) with an empty body is issued if the process of messages sending starts without errors.
Moreover, if enabled by configuration, it sends an event with successEventlabel
as messageLabel and empty messagePayload.
POST /notification-events/
v2.3.0. Since v2.3.0 the endpoint accepts arbitrary fields in the request body JSON object, that are automatically merged inside the event payload
.
If a field with the same name already exists in the event payload
, the corresponding value will be overwritten.
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint allows you to notify that an event occurred and trigger the sending of notifications according to the notification settings.
This endpoint takes care of routing the request to the appropriate handler depending on the event:
- if a custom handler is registered for the event, the event payload will be passed to the registered handler;
- if no custom handler is registered for the event, the event payload will be passed to a default handler, if available;
- otherwise, the event will be considered as not processable, a response with
400
status code will be returned and and a record will be created in theevents
CRUD.
The event settings are loaded once at startup, so please note that, if you change anything in the event settings CRUD, including updating the handler name or schema or deleting the settings entirely, the effects will be visible only after the service has been restarted.
After an handler is found, the event is validated against its schema. All default events have a schema to be validated against, but it is not mandatory to provide a schema for custom events; if none is specified in the corresponding Event settings document, no validation is performed.
This endpoint creates a record in the notifications CRUD you can later query using the returned _id
to check the actual messages sent to the users on the various channels.
Request body
The request body must be a JSON object with the fields described in the the following table.
Name | Type | Required | Description |
---|---|---|---|
name | string | Yes | Event name. |
id | string | No | Event identifier (must be unique across the system). |
key | string | No | Event key (ID of the main resource associated to the event, like an appointment or plan). |
metadata | Object | No | Event metdata, to provide additional details to the event handler. |
payload | Object | No | Event payload |
Response
A successful response (status code 200
) is issued if the notifications were processed without errors. However,
it is still possible that the dispatch of some messages to some users fails on some channels.
The body of the response will contain the list of the notifications sent, to allow the client to check if failures occurred sending the messages.
{
"_id": "ID of the notification created in the notifications CRUD",
"notifications": []
}
If there is no handler available to process the event, the response will return a 400
status code and a payload looking like this:
{
"statusCode": "400",
"error": "Bad Request",
"message": "Unknown event"
}
If any other error occurs, the response will return a 4xx
or 5xx
status code and a payload looking like this:
{
"statusCode": "400",
"error": "Bad Request",
"message": "Error description"
}
GET /notifications/
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint is a proxy to the GET /
endpoint of the notifications CRUD.
GET /notifications/count
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the GET /count
endpoint of the notifications CRUD.
GET /notifications/:id
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint is a proxy to the GET /:id
endpoint of the notifications CRUD.
GET /notification-settings/
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint is a proxy to the GET /
endpoint of the notification settings CRUD.
GET /notification-settings/:id
This endpoint is a proxy to the GET /:id
endpoint of the notification settings CRUD.
GET /notification-settings/count
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the GET /count
endpoint of the notification settings CRUD.
PATCH /notification-settings/:id
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint is a proxy to the PATCH /:id
endpoint of the notification settings CRUD.
A valid notification setting must satisfy the following conditions:
- No multiple notification settings are allowed with the same combination of event name, template name and users selectors;
- All the notification settings channels must be enabled at the service or event level;
- The notification settings template must exist and must support all the selected channels
- The
hours
field must not have duplicated values - The
emitters
field must not have duplicated values - The
reminders
field must not have duplicated values
POST /notification-settings/
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint is a proxy to the POST /
endpoint of the notification settings CRUD.
A notification setting can target any combination of a single user, group, role or cluster, which means that any combination of the following fields can be set in the request body: user
, cluster
, role
or group
.
A valid notification setting must satisfy the following conditions:
- No multiple notification settings are allowed with the same combination of event name, template name and users selectors;
- All the notification settings channels must be enabled at the service or event level;
- The notification settings template must exist and must support all the selected channels
- The
hours
field must not have duplicated values - The
emitters
field must not have duplicated values - The
reminders
field must not have duplicated values
DELETE /notification-settings/:id
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint is a proxy to the DELETE /:id
endpoint of the notification settings CRUD.
GET /user-notification-settings/
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint returns the notification settings of the logged user, meaning those that match at least one of the following conditions:
- the
user
field contains the user ID; - the
group
field contains a group the user belongs to; - the
role
field contains a role assigned to the user; - the
cluster
field contains a cluster the user belongs to.
The endpoint request and response specifications are the same as for the GET /notification-settings/
endpoint. The endpoint does not support pagination, so it can only return the first 200 results.
PATCH /user-notification-settings/:id
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint allows the logged user to edit the notification settings having its user ID in the user
field.
Since the logged user can only modify his/her own settings, the notification setting user
can not be updated through this endpoint. Any attempt to do so will result in a response with a 400 HTTP status code.
The endpoint request and response specifications are the same as for the PATCH /notification-settings/:id
endpoint.
DELETE /user-notification-settings/:id
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint allows the logged user to delete a notification setting having its user ID in the user
field.
The endpoint request and response specifications are the same as for the DELETE /notification-settings/:id
endpoint.
GET /user/events/
v2.1.0. The response schema has been updated and is not compatible with previous versions.
v2.0.0. This endpoint is available only since v2.0.0.
This endpoint returns the event settings that apply to events visible to the logged user.
If a default event has no settings, it will be considered visible to all users and the supported channels will include all the active channels from the service configuration.
An event is visible to the user if and only if the user belongs to at least one of the groups listed in the userGroups
fields of the CRUD for an event or no userGroups
is specified.
The supported channels are automatically filtered to be a subset of the active channels from the service configuration.
The enabled channels are automatically filtered to be a subset of the supported channels.
Response
If the request is processed correctly, the service returns a response with a 200 status code and a list of events looking like this:
[
{
"eventName": "AM/AppointmentCreated/v1",
"supportedChannels": [
"voice",
"push"
],
"enabledChannels": [
"voice"
]
}
]
Each event has the properties described in the following table.
Name | Type | Description |
---|---|---|
eventName | string | Name of the event. |
supportedChannels | string[] | The supported channels from the event settings CRUD or the active channels from the service configuration. |
enabledChannels | string[] | The channels enabled for the event in the notification settings targeting the user. |
PATCH /user/notification-settings/
v2.1.0. This endpoint is available only since version 2.1.0.
Update all the notification settings targeting a specific event and user (and optionally roles, groups and clusters).
If no user notification settings is updated, a new one is created targeting the given event and user. The template name will be inherited from the notification settings with highest precedence that targets the user group, role or cluster.
Request
The request body must provide the event name (eventName
) and the list of enabled channels (enabledChannels
).
{
"eventName": "AM/AppointmentCreated/v1",
"enabledChannels": ["email", "sms"]
}
For each notification setting targeting the logged user and the given event, the channels (channels
) are overwritten with the enabled channels.
Response
If the request is processed correctly, the endpoint returns a 200 HTTP status code and a response containing the number of notification settings updated.
If the service encounters an error processing the request, it responds with the appropriate status code (3xx, 4xx or 5xx) and a JSON body looking like this:
{
"statusCode": "500",
"error": "Internal Server Error",
"message": "An error occurred while processing the request"
}
Here are the most common errors:
- if the user is not authenticated, the service returns a 401 (
Unauthorized
) error; - if the event is not visible to the user, the service returns a 403 (
Unauthorized
) error; - if the user tries to enable an unsupported channel, the service returns a 400 (
Bad Request
) error; - if a new user notification settings must be created but there are no notification settings to inherit the template name from, the service returns a 400 (
Bad Request
) error.
GET /event-settings
v2.1.0. This endpoint is available only since v2.1.0.
This endpoint is a proxy to the GET /
endpoint of the event settings CRUD.
DELETE /event-settings/:id
v2.1.0. This endpoint is available only since v2.1.0.
The endpoint provides a way to delete event settings without the need to restart the microservice in order to register the change.
This endpoint acts as a proxy to the DELETE /:id
endpoint of the event settings CRUD.
After deleting successfully the event settings, the routing table is automatically updated, restoring the default handler for the event, if available.
POST /event-settings
v2.1.0. This endpoint is available only since v2.1.0.
The endpoint provides a way to create new event settings without the need to restart the microservice in order to register them.
This endpoint acts as a proxy to the POST /
endpoint of the event settings CRUD
After inserting successfully an event settings in the CRUD, the routing configuration is automatically updated if any of the following fields are set in the new event settings:
eventSchema
handlerName
handlerConfig
Since the event settings must be unique for a given event, identified by the eventName
field, the endpoint does not create a new record and returns 409 when an event settings for the same event already exists.
PATCH /event-settings/:id
v2.1.0. This endpoint is available only since v2.1.0.
The endpoint provides a way to update an event settings without the need to restart the microservice in order to register the changes.
This endpoint acts as a proxy to the PATCH /:id
endpoint of the event settings CRUD
After updating successfully an event settings in the CRUD, the routing configuration is automatically updated if any of the following fields are updated in the new event settings:
eventSchema
handlerName
handlerConfig
GET /templates/
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the GET /
endpoint of the templates CRUD.
GET /templates/count
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the GET /count
endpoint of the templates CRUD.
GET /templates/:id
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the GET /:id
endpoint of the templates CRUD.
POST /templates/
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the POST /
endpoint of the templates CRUD.
A valid template must satisfy the following conditions:
- it must have a unique name;
- only one among
emailMessage
andemailHtmlMessage
fields can be defined; - if the
pushData
field is set,pushTitle
,pushSubtitle
andpushMessage
must not be defined; - if
pushTitle
,pushSubtitle
and/orpushMessage
are set,pushData
must not be set.
PATCH /templates/:id
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the PATCH /:id
endpoint of the templates CRUD.
A valid template must satisfy the following conditions:
- it must have a unique name;
- only one among
emailMessage
andemailHtmlMessage
fields can be defined; - if the
pushData
field is set,pushTitle
,pushSubtitle
andpushMessage
must not be defined; - if
pushTitle
,pushSubtitle
and/orpushMessage
are set,pushData
must not be set.
DELETE /templates/:id
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the DELETE /:id
endpoint of the templates CRUD.
POST /templates/state
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the POST /state
endpoint of the templates CRUD.
GET /notification-messages/
This endpoint is available in preview, breaking changes could be introduced in next minor versions. Please check the CHANGELOG before upgrading.
v2.4.0. This endpoint requires the Notification Messages MongoDB view.
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the GET /
of Notification Messages MongoDB view and returns the messages matching the given query.
Given a notification like this:
{
"_id": "663ccd65dee93b2a6a6885d1",
"event": "Update appointment"{
"_id": "663ccd63dee93b2a6a6885d0",
"name": ,
"payload": {
"recipient": "663ccce5dee93b2a6a6885ty",
"templateName": "update-appointment"
},
"source": {
"channel": "http",
"requestId": "6e4ddc4eda4ce1f422b285a80da3128a"
},
"status": "RECEIVED"
},
"recipient": "663ccce5dee93b2a6a6885ty",
"messages": [
{
"channel": "email",
"templateName": "new-appointment",
"status": "SUCCESS"
},
{
"channel": "sms",
"templateName": "new-appointment",
"status": "FAILED"
}
]
}
the following messages would be returned:
[
{
"_id": "663ccd65dee93b2a6a6885d1-fea80f2db003d4ebc4536023814aa885",
"event": "Update appointment",
"recipient": "663ccce5dee93b2a6a6885ty",
"channel": "email",
"templateName": "new-appointment",
"status": "SUCCESS"
},
{
"_id": "663ccd65dee93b2a6a6885d1-0956d2fbd5d5c29844a4d21ed2f76e0c",
"event": "Update appointment",
"recipient": "663ccce5dee93b2a6a6885ty",
"channel": "sms",
"templateName": "new-appointment",
"status": "FAILED"
},
{
"_id": "812rcd65dee93b2a6a9845z98-3a685826dee20d9afd3bc637b0615adb",
"event": "New appointment",
"recipient": "675cdse5dee93b2a6a64565rf",
"channel": "email",
"templateName": "new-appointment",
"status": "SUCCESS"
}
]
GET /notification-messages/count
This endpoint is available in preview, breaking changes could be introduced in next minor versions. Please check the CHANGELOG before upgrading.
v2.4.0. This endpoint requires the Notification Messages MongoDB view.
v2.3.0. This endpoint is available only since v2.3.0.
This endpoint is a proxy to the GET /count
endpoint of the Notification Messages MongoDB view and returns the number of messages matching the given query.
Custom handler API
v2.0.0. Custom handlers are available only since v2.0.0.
To set reminders you need to have an instance of the Timer Service running and the TIMER_SERVICE_URL
environment variable set accordingly.
The following section provides usage details about the API you can access inside a custom handler to perform common tasks, like:
- retrieve the user notification settings for an event using
getNotificationSettings
; - fetching the user details using
getRecipients
; - sending notifications using
sendNotification
; - set reminders using
setReminders
.
buildMessages
buildMessages(service, notificationSettings)
This function takes as input a list of notification settings and build the messages to send according to the constraint of sending at most one message with a given template on each channel.
The function clusters the notification settings according to the template name and channel and return, for each cluster, the specifications of the message to send, something like this:
{
"channel": "email",
"templateName": "doctor-new-appointment"
}
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
query | Yes | A list of notification settings |
Return value
A list of messages specifications, where each message uses a different channel and/or template.
[
{
"channel": "email",
"templateName": "doctor-new-appointment"
},
{
"channel": "sms",
"templateName": "doctor-new-appointment"
},
{
"channel": "email",
"templateName": "patient-updated-appointment"
},
]
getNotificationSettings
async getNotificationSettings(service, event, user, emitters)
This function takes an event (required), a user (optional) and a list of emitters (optional) and return the notification settings that apply to the event and, if provided, to the given user and emitters.
A notification setting applies to an event if its eventName
matches the event name (event.name
).
A notification setting applies to a user if all the following conditions are satisfied:
- if the user id (
user.id
) is specified, the rule must target the same user, i.e. theuser
field must match theuser.id
; - if the user belongs to one or more groups (
user.groups
), the rule must target one of these groups, i.e. thegroup
field must match one of the values in theuser.groups
field; - if the user belongs to one or more clusters (
user.clusters
), the rule must target one of these clusters, i.e. thecluster
field must match one of the values in theuser.clusters
field; - if the user has one or more roles (
user.roles
), the rule must target one of these roles, i.e. therole
field must match one of the values in theuser.roles
field.
A notification setting applies to the given list of emitters if its emitters
field contains at least one of the given emitters.
The list of notification settings is sorted according to the following precedence (from highest to lowest).
- user: settings targeting a specific user have precedence over rules targeting clusters, roles and/or groups;
- cluster: settings targeting a cluster have precedence over rules targeting roles and/or groups;
- role: settings targeting a role have precedence over rules targeting groups;
- group.
Notification settings with the same precedence (for example, rules targeting a specific user) are recursively sorted based on the precedence of the remaining fields (for example, rules targeting a user are sorted again to have rules targeting a cluster before rules targeting groups and roles and so forth).
For example, if we had some notification settings targeting:
- a single doctor (
user
); - a single doctor (
user
) in a hospital (clusters
); - all doctors (
groups
) in a hospital (clusters
); - all doctors (
groups
) that can sign patient's discharge (roles
); - all doctors (
groups
)
they would be sorted as follows:
- a single doctor (
user
) in a hospital (clusters
); - a single doctor (
user
); - all doctors (
groups
) in a hospital (clusters
); - all doctors (
groups
) that can sign patient's discharge (roles
); - all doctors (
groups
).
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
event | Yes | Event with id, name and payload |
user | No | A user from the users CRUD |
emitters | No | One or more emitters, as an array of strings |
Return value
An array of CRUD notification settings sorted by precedence (see the Overview section for further details about precedence and sorting).
The function throws an error if the CRUD service does not respond correctly or any other kind of fatal error occurs.
mergeNotificationSettings
mergeNotificationSettings(service, notificationSettings)
This function takes a list of CRUD notification settings and filters them according to the following criteria:
- Remove all settings with
IGNORE
rule; - Discard the settings with
SEND
rule that have lower precedence; - Discard the rules that define one or more sending hours not matching the current time.
The process by which precedence is given to the notification settings is explained in the getNotificationSettings method description.
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
notificationSettings | Yes | List of Crud Notification Settings |
Return value
An array of CRUD notification settings.
getRecipients
async getRecipients(service, query)
This function takes a CRUD query for the users CRUD and return the users having any of the given ids, roles, groups and clusters. If multiple filters are passed, for example ids and groups, the function returns all the user having any of the given ids and any of the given groups.
You can’t currently search for recipients that belongs to all the given groups, roles and/or clusters. The function currently returns the user that belongs to any group, role and cluster.
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
query | Yes | A CRUD query object to filter CRUD users |
The query can have any combination of the following fields:
{
"ids": ["john.doe", "mark.greene"],
"roles": ["sign-discharge"],
"groups": ["doctors", "administrators"],
"clusters": ["mia-care-clinic", "mia-care-hospital"]
}
Here are some examples:
- all the doctors (
groups
) from an hospital (clusters
);
{
"groups": ["doctors"],
"clusters": ["mia-care-center"]
}
- all the doctors (
groups
) from one of the hospitals (clusters
)
{
"groups": ["doctors"],
"clusters": ["mia-care-center-1", "mia-care-center-2"]
}
- the user dr.mario.rossi (
ids
)
{
"ids": ["dr.mario.rossi"],
}
- the user dr.mario.rossi (
ids
) with role sign-report (roles
)
{
"ids": ["dr.mario.rossi"],
"roles": ["sign-report"]
}
- all the doctors and/or administrators
{
"groups": ["doctors", "administrators"],
}
Return value
An array of CRUD users.
The function throws an error if the CRUD service does not respond correctly or any other kind of fatal error occurs.
sendMessages
v2.3.0. Custom attachments specified in the message attachments
field will be sent if the email
channel is specified.
async sendMessages(service, event, user, messages)
This functions takes as input a list of messages for a given user and event, like those generated by the buildMessages
utility function, and sends them using the specified channels and templates.
If one or more attachments are specified in combination with the email
channel, those attachments will be sent together with template attachments.
If the list of messages is empty, no record is stored in the notifications CRUD.
In the message templates you can use the following variables for interpolation:
data
: this variable holds the event payload;user
: this variable holds the user properties.
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
event | Yes | An event with id, name and payload |
user | Yes | A user from the users CRUD |
messages | Yes | A list of notification messages with channel, template and attachments |
Return value
A CRUD notification, containing all the details about the messages sent.
The function throws an error if the CRUD service returns an error or any other fatal error occurs, with a notable exception: if an error occurs sending a specific message, the error details are included in the returned notification.
sendNotification
async sendNotification(service, event, user, notification)
This function takes an event, a user and a notification setting, send all the messages and return the details about the notification sent.
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
event | Yes | Event with id, name and payload |
user | Yes | A user from the users CRUD |
notification | Yes | A CRUD notification setting |
Return value
A CRUD notification, containing all the details about the messages sent.
The function throws an error if the CRUD service returns an error or any other fatal error occurs, with a notable exception: if an error occurs sending a specific message, the error details are included in the returned notification.
buildReminders
buildReminders(service, user, notificationSettings, eventDateTime)
This function takes as input a list of notification settings and a user, and compute the reminders to send by merging all the values in the reminders
field of the notification settings into a single set of values.
The reminders are scheduled subtracting the respective duration from the passed isoEventDate
.
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
user | Yes | A user from the users CRUD |
notificationSettings | Yes | A list of notification settings |
eventDateTime | Yes | Event date to compute reminders from, expressed as ISO 8601 date-time string |
Return value
A list of reminders specifications, each one having an expirationDate
and optionally a schedule
.
, recipients[
{"schedule": "P1D", "expirationDate": "2023-06-24T09:30:00Z", "recipients": ["patientId"]},
{"schedule": "PT1H", "expirationDate": "2023-06-25T08:30:00Z", "recipients": ["doctorId"]},
]
setReminders
async setReminders(service, event, user, reminders)
This functions takes as input a list of reminders for a given user and event, like those generated by the buildReminders
utility function, and schedule them by calling the Timer Service. If the list of reminders is empty, no record is stored in the notifications CRUD.
For each provided reminder, at the expiration date the Timer Service will send a request to the POST /notification-events/.
For example, if we have the following reminder:
{
"expirationDate": "2023-09-02T09:30:00.000Z",
"schedule": "P1D",
"recipients": ["customer-id"],
"triggers": ["notification-setting-12345"]
}
the body of the request sent to the Timer Service would look like this:
{
"payload": {
"id": "f5a9ed5f-c6c2-44e6-85a4-1bd64458a4c0",
"key": "order-12345",
"name": "ACME/OrderCreated/v1",
"metadata": {
"reminder": {
"expirationDate": "2023-09-02T09:30:00.000Z",
"schedule": "P1D",
"recipients": ["customer-id"],
"triggers": ["notification-setting-12345"]
}
},
"payload": {},
"source": "http",
"status": "PROCESSED"
},
"startDate": "2023-09-02T09:30:00.000Z",
"expirationIntervalMs": 1,
"applicantService": "notification-manager",
"outputMode": {
"type": "rest",
"method": "post",
"protocol": "http",
"hostname": "https://www.example.com/notification-manager",
"path": "/notification-events/",
},
}
If the original event had a reminder
field in the metadata
section, its original value would be overwritten by the given notification reminder object.
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
event | Yes | Event with id, name and payload |
user | Yes | A user from the users CRUD |
reminders | Yes | A CRUD notification setting |
Return value
A notification, containing all the details about the scheduled reminders in the reminders
field.
If an error occurs scheduling a specific reminder, the error details are included in the returned notification.
If an error occurs saving the notification into the CRUD, an error is thrown and the client can decide how to handle it.
abortReminders
async abortReminders(service, event, user, query)
This function searches for the reminders matching the given event, user and query and abort all the active reminders.
- Fetch the notifications that satisfy the following conditions:
- the event name matches any of the
query.eventName
, if provided; - the event key matches the
event.key
; - the participant matches the
user.id
; - there is at least one reminder.
- the event name matches any of the
- For each notification, filter the reminders that satisfy the following conditions:
- the
status
field isACTIVE
; - the
expirationId
field is set.
- the
- For each active reminder, call the
POST /abort
endpoint of the Timer Service:- if the Timer Service returns a successfull response, set the reminder status to
ABORTED
; - if the Timer Service returns an error, catch it and leave the reminder status to
ACTIVE
.
- if the Timer Service returns a successfull response, set the reminder status to
- Update the notification reminders in the CRUD.
Parameters
Parameter name | Description |
---|---|
service | Fastify decorated instance |
event | Event with id, name and payload |
user | A user from the users CRUD |
query | An object containing a list of event names that should be included in the search |
Here's an example of a query to abort reminders related to the ACME/OrderCreated/v1
and ACME/OrderShipped/v1
events:
{
"eventName": ["ACME/OrderCreated/v1", "ACME/OrderShipped/v1"]
}
Return value
An array of updated notifications.
mergeNotifications
mergeNotifications(service, event, user, notifications)
This function merges one or more notifications referring a given user and event, by creating a new notification for the given user and event with all the messages, reminders and failures from all the given notifications.
Parameters
Parameter name | Required | Description |
---|---|---|
service | Yes | Fastify decorated instance |
event | Yes | Notification event |
user | Yes | A user from the users CRUD |
notifications | Yes | An array of CRUD notification settings |
Return value
This function returns a new notification for the given user and event with all the messages, reminders and failures from all the given notifications. If no notification is provided, a new notification with zero messages, reminders and failures is returned. If exactly one notification is provided, the exact same notification is returned.
Event handlers
This section illustrates how events are processed by the default handlers available in the Notification Manager.
All the events mentioned in the following sections follow this naming convention:
<product>/<event>/<version>
where:
product
represent the name, usually abbreviated and in upper case, of the Mia Care product for which the event was originally designed, likeAM
(Appointment Manager) orTMM
(Therapy and Monitoring Manager);event
: the name, usually in camel case, of the event, like appointment created (AppointmentCreated
) or therapy updated (TherapyUpdated
);version
: the version of the event, which should be incremented every time a breaking change to the metadata or payload schema is introduced.
You can override a default event handlers by providing a custom handler for any of the events discussed below.
AM/AppointmentCreated/v1
This event is fired when a new appointment is created in the AM and it looks like this:
{
"name": "AM/AppointmentCreated/v1",
"key": "appointment-12345",
"metadata": {
"userFields": ["resourceId", "participantIds"]
},
"payload": {
"startDate": "2023-08-01T09:30:00Z",
"endDate": "2023-08-01T10:15:00Z",
"resourceId": "auth0|dr.mario.rossi",
"participantIds": [
"auth0|jenny.king",
"auth0|dr.mark.greene"
],
"...": "..."
}
}
When the handler receives such an event it performs the following operations:
- retrieve the list of participant IDs from the
metadata.userFields
and fetch the users details by calling thegetRecipients
utility function; - for each participant:
- fetch the notification settings that applies by calling the
getNotificationSettings
utility function - merge the notification settings by calling the
mergeNotificationSettings
utility function - get the messages to send by calling the
buildMessages
utility function - send the messages by calling the
sendMessages
utility function - get the reminders to send by calling the
buildReminders
utility function - set the reminders by calling the
setReminders
function and passing an event with the same payload and metadata of the original, but with nameAM/AppointmentReminder/v1
- fetch the notification settings that applies by calling the
AM/AppointmentReminder/v1
After an appointment is created or updated and the reminders scheduled, the Timer Service sends to the NM at the appropriate times a new event named AM/AppointmentReminder/v1
. The event looks like this:
{
"name": "AM/AppointmentReminder/v1",
"metadata": {
"reminder": {
"schedule": "PT1H",
"expirationDate": "2022-06-04T23:00:00Z",
"recipients": ["auth0|dr.mark.greene"]
},
"userFields": ["resourceId", "participantIds"]
},
"payload": {
"startDate": "2023-08-01T09:30:00Z",
"endDate": "2023-08-01T10:15:00Z",
"resourceId": "auth0|dr.mario.rossi",
"participantIds": [
"auth0|joe.hart",
"auth0|dr.mark.greene"
],
"...": "..."
}
}
The event should include in the metadata.reminder
field the schedule that triggered this event. The value is a time duration expressed as ISO 8601 duration string.
When the handler receives such an event it performs the following operations:
- retrieve the list of participant IDs from the
event.metadata.reminder.participants
field and fetch the users detail by calling thegetRecipients
function; - for each participant:
- fetch the notification settings that applies by calling the
getNotificationSettings
function; - filter the notification settings having the
event.metadata.reminder.schedule
among the reminders, if provided; - merge the notification settings by calling the
mergeNotificationSettings
utility function - build the messages to send by calling the
buildMessages
utility function - send the messages by calling the
sendMessages
utility function
- fetch the notification settings that applies by calling the
AM/AppointmentDeleted/v1
When an appointment is deleted the AM sends to the NM a new event named AM/AppointmentDeleted/v1
that looks like this:
{
"name": "AM/AppointmentDeleted/v1",
"metadata": {
"userFields": ["resourceId","participantIds"]
},
"payload": {
"startDate": "2023-08-01T09:30:00Z",
"endDate": "2023-08-01T10:15:00Z",
"resourceId": "auth0|dr.mario.rossi",
"participantIds": [
"auth0|mary.shelley",
"auth0|dr.mark.greene"
],
"...": "..."
}
}
When the handler receives such an event it performs the following operations:
- retrieve the list of participant IDs from the
metadata.userFields
and fetch the users details by calling thegetRecipients
utility function; - for each user:
- fetch the notification settings that apply by calling the
getNotificationSettings
utility function; - merge the notification settings by calling the
mergeNotificationSettings
utility function - get the messages to send by calling the
buildMessages
utility function - send the messages by calling the
sendMessages
utility function - abort all active reminders scheduled when the appointment was created or updated by calling the
abortReminders
utility functions.
- fetch the notification settings that apply by calling the
AM/AppointmentUpdated/v1
This event is triggered by an update to an appointment that is performed by a request to the PATCH /appointments/:id
of the Appointment Manager. The event looks like this:
{
"name": "AM/AppointmentUpdated/v1",
"metadata": {
"userFields": ["resourceId","participantIds"]
},
"payload": {
"originalAppointment": {
"startDate": "2023-08-01T09:30:00Z",
"endDate": "2023-08-01T10:15:00Z",
"resourceId": "auth0|dr.mario.rossi",
"participantIds": [
"auth0|lucia.verdi",
"auth0|dr.luigi.rossi"
],
"...": "..."
},
"currentAppointment": {
"startDate": "2023-08-01T09:30:00Z",
"endDate": "2023-08-01T10:15:00Z",
"resourceId": "auth0|dr.mario.rossi",
"participantIds": [
"auth0|lucia.verdi",
"auth0|dr.marta.rossi"
],
"...": "..."
}
}
}
When the handler receives such an event it performs the following operations:
- retrieve the list of participant IDs from the
metadata.userFields
and fetch the users details; - cluster the participant IDs in the following groups:
- new participants: if the user ID is in the updated appointment, but not in the original;
- existing participants: if the user ID is in both the updated and original appointment;
- deleted participants: if the user ID is in the original appointment, but not in the updated version;
- for each participant:
- fetch the notification settings that apply by calling the
getNotificationSettings
utility function with the correct event:- for new participants,
AM/AppointmentCreated/v1
as event name and the updated appointment as payload; - for existing participants, the original event;
- for deleted participants,
AM/AppointmentDeleted/v1
as event name and the original appointment as payload;
- for new participants,
- merge the notification settings by calling the
mergeNotificationSettings
utility function; - for deleted participants, and for existing participants if the appointment has been rescheduled, abort the reminders by calling the
abortReminders
utility function; - get the messages to send by calling the
buildMessages
utility function; - send the messages by calling the
sendMessages
utility function with the correct event:- for new participants,
AM/AppointmentCreated/v1
as event name and the updated appointment as payload; - for existing participants, the original event;
- for deleted participants,
AM/AppointmentDeleted/v1
as event name and the original appointment as payload;
- for new participants,
- for new participants, and for existing participants if the appointment has been rescheduled:
- get the reminders to send by calling the
buildReminders
utility function; - set the reminders by calling the
setReminders
function and passing an event with the updated appointment as payload and nameAM/AppointmentReminder/v1
.
- get the reminders to send by calling the
- fetch the notification settings that apply by calling the
IC/ResourceForbiddenEvent/v1
This event is fired when a resource integrity violation is detected by the [IC][integrity-checker] and the event looks like this:
{
"id": "8f77103f-9466-418b-b9e9-478054f82900",
"key": "medical-reports/628fa7713d35760c790b8f30",
"name": "IC/ResourceForbiddenEvent/v1",
"payload": {
"collectionName": "medical-reports",
"resourceUuid": "628fa7713d35760c790b8f30",
"operation": {
"updatedFields": {
"signedDocument": "61669154bea7010012c9ebd2.pdf"
}
},
"resource": {
"_id": "628fa7713d35760c790b8f30",
"creatorId": "auth0|dr.lucia.viola",
"createdAt": "2022-05-26T16:14:41.621Z",
"updaterId": "auth0|dr.andrea.rossi",
"updatedAt": "2022-05-26T16:14:41.621Z",
"__STATE__": "PUBLIC",
"formSchemaId": "628f6ec74301f05c9d3c9257",
"signedDocument": "61669154bea7010012c9ebd2.pdf",
"data": {},
"uuid": "KGWfJ31BL4mgVpu"
}
}
}
When the handler receives such an event it performs the following operations:
- fetch the notification settings that apply to the event by calling the
getNotificationSettings
utility function; - merge the notification settings by calling the
mergeNotificationSettings
utility function; - fetch all the users targeted by the notification settings;
- for each user:
- build the messages to send by calling the
buildMessages
utility function; - send the messages by calling the
sendMessages
utility function;
- build the messages to send by calling the
TMM/MonitoringCreated/v1
This event is fired when a new monitoring plan is created in the TMM and the event looks like this:
{
"id": "06efe38d-0e46-4863-9bb4-4c11ff63c912",
"key": "blood-pressure-monitoring-12345",
"name": "TMM/MonitoringCreated/v1",
"metadata": {
"excludeUsers": ["jill.marlowe"],
"includeUsers": ["dr.john.watson"]
},
"payload": {
"planName": "Blood pressure monitoring",
"prototypeId": "bloodPressure",
"notes": "Takes the blood",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"times": 2,
"doctorId": "dr.mark.greene",
"patientId": "jill.marlowe",
"adherenceStatus": "enabled",
"adherenceToleranceFrequency": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90,
"thresholds": [
{
"propertyName": "minimumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 60
},
{
"propertyName": "maximumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 120
}
]
}
}
When the handler receives such an event it performs the following operations:
- fetch the details of the doctor and patient by calling the
getRecipients
utility function and passing the values of thedoctorId
andpatientId
as ids; - remove the users in
metadata.excludeUsers
from the participants; - add the users in
metadata.includeUsers
to the participants; - for each user:
- fetch the notification settings by calling the
getNotificationSettings
utility function; - merge the notification settings by calling the
mergeNotificationSettings
utility function; - get the messages to send by calling the
buildMessages
utility function and passing the merged notification settings as argument; - send the messages by calling the
sendMessages
utility function; - compute the first event date according to the monitoring plan;
- build the reminders by calling
buildReminders
; - schedule the reminders by calling the
setReminders
for theTMM/MonitoringReminder/v1
event; - merge the user notifications by calling the
mergeNotifications
.
- fetch the notification settings by calling the
TMM/MonitoringDeleted/v1
This event is fired when a monitoring plan is deleted in the TMM and the event looks like this:
{
"id": "da03558a-f283-4d9b-b1c7-50282716802c",
"key": "blood-pressure-monitoring-12345",
"name": "TMM/MonitoringDeleted/v1",
"metadata": {
"excludeUsers": ["lucy.heart"],
"includeUsers": ["dr.john.watson"]
},
"payload": {
"planName": "Blood pressure monitoring",
"prototypeId": "bloodPressure",
"notes": "Takes the blood",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"times": 2,
"doctorId": "dr.mark.greene",
"patientId": "lucy.heart",
"adherenceStatus": "enabled",
"adherenceToleranceFrequency": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90,
"thresholds": [
{
"propertyName": "minimumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 60
},
{
"propertyName": "maximumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 120
}
]
}
}
When the handler receives such an event it performs the following operations:
- add the doctor (
payload.doctorId
) and patient (payload.patientId
) to the list of notification recipients; - add the user IDs in the
metadata.includeUsers
field to the recipients list, if present; - remove the user IDs in the
metadata.excludeUsers
field from the recipients list, if present; - for each recipient:
- fetch and merge the notification settings that applies to the given event and participant;
- build and send the messages to the participant;
- abort all active reminders scheduled when the monitoring was created or updated or a recurring reminder was set.
The fourth step relies on the notification utils available in all handlers to perform most of the operations.
TMM/MonitoringUpdated/v1
This event is fired when a monitoring plan is updated in the TMM and the event looks like this:
{
"name": "TMM/MonitoringUpdated/v1",
"metadata": {
"excludeUsers": ["dr.mario.rossi"],
"includeUsers": []
},
"payload": {
"originalMonitoring": {
"planName": "Blood pressure monitoring",
"prototypeId": "bloodPressure",
"notes": "Takes the blood",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"times": 2,
"doctorId": "dr.mario.rossi",
"patientId": "lucia.viola",
"adherenceStatus": "enabled",
"adherenceToleranceFrequency": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90,
"thresholds": [
{
"propertyName": "minimumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 60,
},
{
"propertyName": "maximumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 120
}
]
},
"currentMonitoring": {
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-07-01T00:00:00Z",
"each": ["monday", "wednesday", "friday"],
"doctorId": "dr.andrea.verdi",
"patientId": "lucia.viola",
"...": "...",
}
}
}
The payload must have both the original and the updated version of the monitoring plan, in order for the handler to correctly identify the messages to send and the reminders to abort or schedule. In the example above, we are both changing the participants (doctorId
) and the plan schedule (endDate
, each
).
When the handler receives such an event it performs the following operations:
- cluster the user IDs (
doctorId
,patientId
) in three groups:- new participants: if the user ID is in the updated monitoring, but not in the original;
- existing participants: if the user ID is in both the updated and original monitoring;
- old participants: if the user ID is in the original monitoring, but not in the updated version;
- add the user IDs in the
metadata.includeUsers
field to the list of existing recipients, if present; - remove the user IDs in the
metadata.excludeUsers
field from any recipients list, if present; - fetch the user details of all the participants;
- for each new participant, using
TMM/MonitoringCreated/v1
as event name and the updated monitoring as payload:- fetch and merge the notification settings that applies to the event;
- build and send the messages to the participant;
- for each old participant, using
TMM/MonitoringDeleted/v1
as event name and the original monitoring as payload:- fetch and merge the notification settings that applies to the event;
- build and send the messages to the participant;
- abort all active reminders scheduled when the monitoring was created or previously updated;
- for each existing participant:
- fetch and merge the notification settings that applies to the given event and participant;
- build and send the messages to the participant;
- abort all active reminders scheduled when the monitoring was created or updated;
- build and schedule all the reminders, using
TMM/MonitoringReminder/v1
as reminder event name and the current appointment as payload.
The last four steps rely on the notification utils available in all handlers to perform most of the operations.
TMM/MonitoringReminder/v1
This event is fired when the patient is notified about an ongoing monitoring plan in the TMM and the event looks like this:
{
"id": "06efe38d-0e46-4863-9bb4-4c11ff63c912",
"key": "blood-pressure-monitoring-12345",
"name": "TMM/MonitoringReminder/v1",
"metadata": {
"reminder": {
"schedule": "PT1H",
"expirationDate": "2022-06-04T23:00:00Z",
"recipients": ["jill.marlowe"]
}
},
"payload": {
"planName": "Blood pressure monitoring",
"prototypeId": "bloodPressure",
"notes": "Takes the blood",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"times": 2,
"doctorId": "dr.mark.greene",
"patientId": "jill.marlowe",
"adherenceStatus": "enabled",
"adherenceToleranceFrequency": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90,
"thresholds": [
{
"propertyName": "minimumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 60
},
{
"propertyName": "maximumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 120
}
]
}
}
This handler automatically schedules the next reminder according to the following criteria:
- if the plan has a daily schedule (the
each
field containsday
), the reminders are sent at the beginning of each day; - if the plan has a weekly schedule (the
each
field contains one or more weekdays, likemonday
orfriday
), the reminders are sent at the beginning of each day of the week specified in the plan.
The reminders are scheduled if and only if the monitoring plan is still active on a given day and are sent the desired time before midnight UTC, for example one hour.
The notification settings for monitoring reminders should set a single reminder no more than a few hours before each day the patient needs to take action, particularly if the plan has a daily schedule.
Given the monitoring plan shown above, for example, and the following notification setting:
{
"eventName": "TMM/MonitoringReminder/v1",
"channels": ["email", "sms"],
"templateName": "patient-monitoring-reminder",
"user": "jill.marlowe",
"reminders": ["PT1H"]
}
we would send the following reminders:
- May 31st, 2022 at 23:00 UTC (reminder for June 1st, one hour earlier than midnight UTC);
- June 1st, 2022 at 23:00 UTC (reminder for June 2nd, one hour earlier than midnight UTC);
- etc.
- June 14th, 2022 at 23:00 UTC (reminder for June 15th, one hour earlier than midnight UTC).
When the handler receives such an event it performs the following operations:
- add the user IDs from the reminder recipients (
metadata.reminder.recipients
) to the list of notification recipients; - for each recipient:
- fetch and merge the notification settings that apply to the given event and user;
- filter the notification settings whose
reminders
field contains the reminder schedule (metadata.reminders.schedule
); - build and send the messages to the participant;
- build and schedule the next reminders, according to the notification settings and using the same event.
TMM/ThresholdExceeded/v1
This event is fired when a detection submitted by a patient exceeds one or more thresholds associated to a monitoring plan in the TMM and the event looks like this:
{
"id": "f303f2e9-f37b-4565-91e4-628e36872df5",
"key": "blood-pressure-monitoring-12345",
"name": "TMM/ThresholdExceeded/v1",
"payload": {
"plan": {
"planName": "Blood pressure monitoring",
"prototypeId": "bloodPressure",
"notes": "Takes the blood",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"times": 2,
"doctorId": "auth0|doctorId",
"patientId": "auth0|patientId",
"adherenceStatus": "enabled",
"adherenceToleranceFrequency": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90,
"thresholds": [
{
"propertyName": "minimumBloodPressure",
"thresholdOperator": "lt",
"thresholdValue": 80
},
{
"propertyName": "maximumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 120
}
]
},
"detection": {
"planType": "monitoring",
"planId": "blood-pressure-monitoring-12345",
"isCompliant": true,
"value": {
"minimumBloodPressure": 80,
"maximumBloodPressure": 130
},
"observedAt": "2022-06-01T10:00:00.000Z",
"doctorId": "auth0|doctorId",
"patientId": "auth0|patientId",
},
"validations": [
{
"threshold": {
"propertyName": "minimumBloodPressure",
"thresholdOperator": "lt",
"thresholdValue": 80
},
"value": 82,
"status": "OK"
},
{
"threshold": {
"propertyName": "maximumBloodPressure",
"thresholdOperator": "gt",
"thresholdValue": 120
},
"value": 130,
"status": "KO",
"error": "maximumBloodPressure_gt_120",
"message": "minimumBloodPressure' is greater than 120"
}
]
}
}
When the handler receives such an event it performs the following operations:
- add the doctor (
payload.doctorId
) to the list of notification recipients; - add the user IDs in the
metadata.includeUsers
field to the recipients list, if present; - remove the user IDs in the
metadata.excludeUsers
field from the recipients list, if present; - for each recipient:
- fetch and merge the notification settings that applies to the given event and participant;
- build and send the messages to the participant.
TMM/TherapyCreated/v1
This event is fired when a new therapy is created in the TMM and the event looks like this:
{
"id": "f303f2e9-f37b-4565-91e4-628e36872df5",
"key": "high-blood-pressure-therapy-12345",
"name": "TMM/TherapyCreated/v1",
"metadata": {
"includeUsers": ["auth0|anotherDoctorId"],
"excludeUsers": ["auth0|doctorId"]
},
"payload": {
"planName": "Drug therapy",
"prototypeId": "medication",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"hours": ["10:00"],
"doctorId": "auth0|doctorId",
"patientId": "auth0|patientId",
"adherenceStatus": "enabled",
"adherenceToleranceTime": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90
}
}
When the handler receives such an event it performs the following operations:
- fetch the details of the doctor and patient by calling the
getRecipients
utility function and passing the values of thedoctorId
andpatientId
as ids; - remove the users in
metadata.excludeUsers
from the participants; - add the users in
metadata.includeUsers
to the participants; - for each user:
- fetch the notification settings by calling the
getNotificationSettings
utility function; - merge the notification settings by calling the
mergeNotificationSettings
utility function; - get the messages to send by calling the
buildMessages
utility function and passing the merged notification settings as argument; - send the messages by calling the
sendMessages
utility function; - compute the first event date according to the therapy plan;
- build the reminders by calling
buildReminders
; - schedule the reminders by calling the
setReminders
for theTMM/TherapyReminder/v1p
event; - merge the user notifications by calling the
mergeNotifications
.
- fetch the notification settings by calling the
TMM/TherapyDeleted/v1
When a therapy is deleted the TMM sends to the NM a new event named TMM/TherapyDeleted/v1
that looks like this:
{
"id": "da03558a-f283-4d9b-b1c7-50282716802c",
"key": "high-blood-pressure-therapy-12345",
"name": "TMM/TherapyDeleted/v1",
"metadata": {
"excludeUsers": ["lucy.heart"],
"includeUsers": ["dr.john.watson"]
},
"payload": {
"planName": "Drug therapy",
"prototypeId": "medication",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"hours": ["10:00"],
"doctorId": "auth0|doctorId",
"patientId": "auth0|patientId",
"adherenceStatus": "enabled",
"adherenceToleranceTime": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90,
}
}
When the handler receives such an event it performs the following operations:
- add the doctor (
payload.doctorId
) and patient (payload.patientId
) to the list of notification recipients; - add the user IDs in the
metadata.includeUsers
field to the recipients list, if present; - remove the user IDs in the
metadata.excludeUsers
field from the recipients list, if present; - for each user:
- fetch the notification settings that apply by calling the
getNotificationSettings
utility function; - merge the notification settings by calling the
mergeNotificationSettings
utility function; - get the messages to send by calling the
buildMessages
utility function; - send the messages by calling the
sendMessages
utility function; - abort all active reminders scheduled when the appointment was created or updated or a recurring reminder was set, by calling the
abortReminders
utility function.
- fetch the notification settings that apply by calling the
TMM/TherapyUpdated/v1
This event is fired when a therapy is updated in the TMM and the event looks like this:
{
"name": "TMM/TherapyUpdated/v1",
"metadata": {
"excludeUsers": ["dr.mario.rossi"],
"includeUsers": []
},
"payload": {
"originalTherapy": {
"planName": "Blood pressure therapy",
"prototypeId": "bloodPressure",
"notes": "Takes the blood pressure pills",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"times": 2,
"doctorId": "dr.mario.rossi",
"patientId": "lucia.viola",
"adherenceStatus": "enabled",
"adherenceToleranceFrequency": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90,
},
"currentTherapy": {
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-07-01T00:00:00Z",
"each": ["monday", "wednesday", "friday"],
"doctorId": "dr.andrea.verdi",
"patientId": "lucia.viola",
"...": "...",
}
}
}
The payload must have both the original and the updated version of the therapy plan, in order for the handler to correctly identify the messages to send and the reminders to abort or schedule. In the example above, we are both changing the participants (doctorId
) and the plan schedule (endDate
, each
).
When the handler receives such an event it performs the following operations:
- cluster the user IDs (
doctorId
,patientId
) in three groups:- new participants: if the user ID is in the updated therapy, but not in the original;
- existing participants: if the user ID is in both the updated and original therapy;
- old participants: if the user ID is in the original therapy, but not in the updated version;
- add the user IDs in the
metadata.includeUsers
field to the list of existing recipients, if present; - remove the user IDs in the
metadata.excludeUsers
field from any recipients list, if present; - fetch the user details of all the participants;
- for each new participant, using
TMM/TherapyCreated/v1
as event name and the updated therapy as payload:- fetch and merge the notification settings that applies to the event;
- build and send the messages to the participant;
- build and schedule all the reminders, using
TMM/TherapyReminder/v1
as reminder event name and the current appointment as payload.
- for each old participant, using
TMM/TherapyDeleted/v1
as event name and the original therapy as payload:- fetch and merge the notification settings that applies to the event;
- build and send the messages to the participant;
- abort all active reminders scheduled when the therapy was created or previously updated;
- for each existing participant:
- fetch and merge the notification settings that applies to the given event and participant;
- build and send the messages to the participant;
- abort all active reminders scheduled when the therapy was created or updated;
- build and schedule all the reminders, using
TMM/TherapyReminder/v1
as reminder event name and the current appointment as payload.
The last four steps rely on the notification utils available in all handlers to perform most of the operations.
TMM/TherapyReminder/v1
This event is fired when the patient is notified about an ongoing therapy plan in the TMM and the event looks like this:
{
"id": "06efe38d-0e46-4863-9bb4-4c11ff63c912",
"key": "blood-pressure-therapy-12345",
"metadata": {
"reminder": {
"schedule": "PT1H",
"expirationDate": "2022-06-04T23:00:00Z",
"recipients": ["jill.marlowe"]
}
},
"name": "TMM/TherapyReminder/v1",
"payload": {
"planName": "High blood pressure therapy",
"prototypeId": "bloodPressure",
"notes": "Takes the blood pills",
"startDate": "2022-06-01T00:00:00Z",
"endDate": "2022-06-15T00:00:00Z",
"each": ["day"],
"times": 2,
"doctorId": "dr.mark.greene",
"patientId": "jill.marlowe",
"adherenceStatus": "enabled",
"adherenceToleranceFrequency": 1,
"adherenceMinimumPercentage": 90,
"complianceStatus": "enabled",
"complianceMinimumPercentage": 90,
}
}
This handler automatically schedules the next reminder in the same way of the TMM/MonitoringReminder/v1 event handler.
When the handler receives such an event it performs the following operations:
- add the user IDs from the reminder recipients (
metadata.reminder.recipients
) to the list of notification recipients; - for each recipient:
- fetch and merge the notification settings that apply to the given event and user;
- filter the notification settings whose
reminders
field contains the reminder schedule (metadata.reminders.schedule
); - build and send the messages to the participant;
- build and schedule the next reminders, according to the notification settings and using the same event.