The @cap-js/notifications package is a CDS plugin that provides support for publishing business notifications in SAP Build Work Zone.
- Setup
- Send Notifications
- Use Notification Types
- API Reference
- Test-drive Locally
- Run in Production
- Advanced Usage
- Contributing
- Code of Conduct
- Licensing
To enable notifications, simply add this self-configuring plugin package to your project:
npm add @cap-js/notificationsIn this guide, we use the Bookshop reference sample app as the basis for publishing notifications.
With that you can use the NotificationService as any other CAP Service like so in you event handlers:
const alert = await cds.connect.to('notifications')You can use the following signature to send the simple notification with title and description
alert.notify({
recipients: [ ...readers() ],
priority: "HIGH",
title: "New book arrived!",
description: "Book 'Wuthering Heights' has been added to the catalogue."
})Note: The simple API supports only:
recipients,priority,title, anddescription. For advanced properties likeActorId,NavigationTargetObject,TargetParameters, etc., use a named notification type or the low-level API.
- priority - Priority of the notification, this argument is optional, it defaults to NEUTRAL
- description - Subtitle for the notification, this argument is optional
The plugin supports two ways to define notification types. These can be combined with types from both sources are merged at startup.
The recommended approach is to annotate CDS events directly in your service model. The plugin discovers these at startup and registers them as notification types automatically. No separate file is needed.
Define events in your srv/ model and annotate them with @notification:
@description: 'Sent when a book is ordered'
@notification: {
template: {
title : 'Book {{title}} Ordered',
publicTitle : 'Book Ordered',
subtitle : '{{buyer}} ordered {{title}}',
groupedTitle : 'Bookshop Updates'
}
}
@Common.SemanticObject: 'Books'
@Common.SemanticObjectAction: 'display'
event BookOrdered {
title : String;
buyer : String;
}Any event with at least one @notification annotation (the bare @notification flag or any @notification.* property) is picked up as a notification type. The notification type key is derived from the event name. Namespace prefixes are stripped, so my.bookshop.BookOrdered becomes BookOrdered.
Note: The plugin automatically injects a
recipientselement into every notification event at model-load time, no need to declare it yourself.
Note: Be sure that the event is contained within a service. This can be done by wrapping the event with a service or using the keyword
usingto include the event within an existing service.
The following annotations are supported:
| Annotation | Notification field |
|---|---|
@description |
Description |
@notification.template.title |
TemplateSensitive |
@notification.template.publicTitle |
TemplatePublic |
@notification.template.subtitle |
Subtitle |
@notification.template.groupedTitle |
TemplateGrouped |
@notification.template.email.subject |
EmailSubject |
@notification.template.email.html |
EmailHtml |
@Common.SemanticObject |
NavigationTargetObject |
@Common.SemanticObjectAction |
NavigationTargetAction |
Annotation values support {i18n>key} syntax. Keys are resolved against your project's _i18n/i18n.properties English labels at startup:
@notification.template.title: '{i18n>BOOK_ORDERED_TITLE}'
@notification.template.subtitle: '{i18n>BOOK_ORDERED_SUBTITLE}'
event BookOrdered { ... }Build integration: Running cds build also processes @notification-annotated events and writes a merged notification-types.json to the build output. This file combines types derived from your CDS annotations with any types defined in the JSON file.
As an alternative (or in addition) to CDS annotations, you can define types statically in srv/notification-types.json:
[
{
"NotificationTypeKey": "BookOrdered",
"NotificationTypeVersion": "1",
"Templates": [
{
"Language": "en",
"TemplatePublic": "Book Ordered",
"TemplateSensitive": "Book '{{title}}' Ordered",
"TemplateGrouped": "Bookshop Updates",
"TemplateLanguage": "mustache",
"Subtitle": "{{buyer}} ordered {{title}}."
}
]
}
]To enable email delivery for a notification type, add deliveryChannels and email template fields. Both definition approaches support this.
Via CDS annotations:
@notification: {
template: {
title : 'Book {{title}} Ordered',
publicTitle : 'Book Ordered',
subtitle : '{{buyer}} ordered {{title}}',
groupedTitle : 'Bookshop Updates',
email: {
subject: 'Your order: {{title}}',
html : '<p>Thanks for ordering <b>{{title}}</b>!</p>'
}
},
deliveryChannels: [{ channel: #Mail, enabled: true, defaultPreference: true, editablePreference: true }]
}
event BookOrdered { ... }Via JSON:
{
"NotificationTypeKey": "BookOrdered",
"Templates": [
{
"Language": "en",
"TemplatePublic": "Book Ordered",
"TemplateSensitive": "Book '{{title}}' Ordered",
"TemplateGrouped": "Bookshop Updates",
"TemplateLanguage": "mustache",
"EmailSubject": "Your order: {{title}}",
"EmailHtml": "<p>Thanks for ordering <b>{{title}}</b>!</p>"
}
],
"DeliveryChannels": [
{ "Type": "MAIL", "Enabled": true, "DefaultPreference": true, "EditablePreference": true }
]
}Note: Email delivery requires the SAP Alert Notification service with the
business-notificationsplan and a corresponding BTP destination. Thebusiness-notificationsplan enforces thatTemplatePublicandTemplateGroupedare set on all notification types (including those without email).
await alert.notify ('BookOrdered', {
recipients: [ buyer.id ],
data: {
title: book.title,
buyer: buyer.name,
}
})- recipients - List of the recipients, this argument is mandatory
- type - Notification type key, this argument is mandatory
- priority - Priority of the notification, this argument is optional, it defaults to NEUTRAL
- data - A key-value pair that is used to fill a placeholder of the notification type template, this argument is optional
In local environment, when you publish notification, it is mocked to publish the nofication to the console.
As a pre-requisite to publish the notification, you need to have a destination configured to publish the notification. The plugin is pre-configured to use destination name SAP_Notifications by default for hybrid and production environments. You can override this in your application's CDS configuration if needed (see Advanced Usage section below).
Once application is deployed and integrated with SAP Build Work Zone, you can see the notification under Fiori notifications icon!
Notification types are automatically registered and synced with the notification service each time the application starts in hybrid or production mode. No manual cds build or content deployment step is required as any additions, changes, or removals to your notification types (whether defined via CDS annotations or JSON) are applied on the next startup.
Notifications plugin configures srv/notification-types.json as default notification types file. If you are using different file, you can update the file path in cds.env.requires.notifications.types
To make notification types unique to the application, prefix is added to the type key. By default, application name is added as the prefix. You can update the cds.env.requires.notifications.prefix if required.
cds.env.requires.notifications.authenticationIdentifier controls which recipient key the plugin uses when publishing notifications. Supported values:
auto(default): the recipient key is chosen per recipient. Values matching the UUID format are published withGlobalUserId, everything else withRecipientId. If a value is neither a UUID nor an email a warning is logged. This allows mixing UUIDs and emails in the samerecipientsarray without additional configuration.UserUUID: always publish withGlobalUserId. Use this when the authentication identifier in Work Zone is set toUser ID.RecipientId: always publish withRecipientId. Use this when recipients are identified by email or login name.
Note, that in order for E-Mail Notifications to be sent for notifications published with a User ID, a destination to the IDS needs to be configured for the lookup of the corresponding email address.
For the Work Zone Authentication Identifier configuration details refer to: Work Zone Subaccount Settings
You can use these two signature to send the custom notification with pre-defined notification types.
By using this approach you can send notifications with the predefined parameters - recipients, data, priority, type and other parameters listed in the API documentation
alert.notify({
recipients: [...readers()],
type: "BookOrdered",
priority: 'NEUTRAL',
data: {
title: book.title,
buyer: buyer.name,
},
OriginId: "Example Origin Id",
NotificationTypeVersion: "1",
ProviderId: "/SAMPLEPROVIDER",
ActorId: "BACKENDACTORID",
ActorDisplayText: "ActorName",
ActorImageURL: "https://some-url",
NotificationTypeTimestamp: "2022-03-15T09:58:42.807Z",
TargetParameters: [
{
"Key": "string",
"Value": "string"
}
]
})By using this approach you need to pass the whole notification object as described in the API documentation
alert.notify({
NotificationTypeKey: 'BookOrdered',
NotificationTypeVersion: '1',
Priority: 'NEUTRAL',
Properties: [
{
Key: 'title',
IsSensitive: false,
Language: 'en',
Value: 'Wuthering Heights',
Type: 'String'
},
{
Key: 'buyer',
IsSensitive: false,
Language: 'en',
Value: 'reader@bookshop.com',
Type: 'String'
}
],
Recipients: [{ RecipientId: "reader1@bookshop.com" },{ RecipientId: "reader2@bookshop.com" }]
})This project is open to feature requests/suggestions, bug reports etc. via GitHub issues. Contribution and feedback are encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines.
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone. By participating in this project, you agree to abide by its Code of Conduct at all times.
Copyright 2023 SAP SE or an SAP affiliate company and contributors. Please see our LICENSE for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available via the REUSE tool.

