Notifications
Version 10
- 1 Quick Start Guides
- 2 Attachments
- 3 Templating Notifications
- 4 Addresses and address resolving
- 5 Multi-Language Notifications (i18n)
- 6 Multi-Channel Notifications
- 7 Personalized Notifications
- 8 Push Notifications
- 8.1 Subscribe to push notifications
- 8.1.1 "enabled"
- 8.1.2 "includeTopics"
- 8.1.3 "excludeTopics"
- 8.1.4 "headers"
- 8.1.5 "body"
- 8.2 Topics
- 8.2.1 pipeforce.event.app
- 8.2.1.1 .install.finished
- 8.2.1.2 .uninstall.finished
- 8.2.2 pipeforce.event.iam
- 8.2.2.1 .admin.client.create.client
- 8.2.2.2 .admin.update.client
- 8.2.2.3 .admin.delete.client.scope.client.mapping
- 8.2.2.4 .admin.create.group
- 8.2.2.5 .admin.create.user
- 8.2.2.6 .admin.client.create.role
- 8.2.2.7 .admin.create.group.membership
- 8.2.2.8 .admin.create.realm.role.mapping
- 8.2.2.9 .admin.action.user
- 8.2.2.10 .client.login
- 8.2.2.11 .code.to.token
- 8.2.2.12 .login
- 8.2.2.13 .logout
- 8.2.2.14 .refresh.token
- 8.2.2.15 .token.exchange
- 8.2.2.16 .user.info.request
- 8.2.3 pipeforce.event.property
- 8.2.3.1 .created
- 8.2.3.2 .deleted
- 8.2.3.3 .updated
- 8.2.3.4 .comment.created
- 8.2.3.5 .comment.updated
- 8.2.4 pipeforce.event.log
- 8.2.5 pipeforce.event.webhook
- 8.2.6 pipeforce.event.workflow
- 8.2.6.1 Workflow address variables ($uri:wf-)
- 8.2.6.2 .comment.create
- 8.2.6.3 .comment.update
- 8.2.6.4 .end
- 8.2.6.5 .task.assignment
- 8.2.6.6 .task.complete
- 8.2.6.7 .task.create
- 8.2.6.8 .task.delete
- 8.2.6.9 .task.timeout
- 8.2.6.10 .task.update
- 8.2.6.11 .transition
- 8.2.6.12 .start
- 8.2.1 pipeforce.event.app
- 8.3 Custom Topics
- 8.4 Exclude addresses from topics
- 8.5 Templating Push Notifications
- 8.6 Global Push Configuration
- 8.7 Default Push Subscriptions
- 8.1 Subscribe to push notifications
- 9 Testing Notifications (dryRun)
PIPEFORCE comes with a comprehensive multi-channel and multi-language framework which allows to generate notification messages dynamically from templates in different multiple languages and send them to multiple channels. Such a target channel for example can be : Email, Slack, Teams, SMS, WhatsApp, Message Queue and many others.
Additionally, this framework includes also push events. This means a user or group of users can subscribe to certain PIPEFORCE events. Every time such an event happens, they will be informed about this on the configured channel in the preferred language.
Target addresses of notifications can be for example email addresses, IAM usernames, IAM group names, chat groups or other custom addresses as further described below.
What is the difference between a message and a notification?
A notification is usually send to a human user. It is a subset of the message class since a message can be any kind of information send to users and or systems.
Quick Start Guides
For those not interested in the details but want to have a quick result, here are the quick start guides for the most common use cases using the notification framework.
Send a plain text email (simple mode)
In case you would like to send a simple plain text email to a given set of email addresses, you can simply use a pipeline like this:
pipeline:
- notification.send:
to: ["email1@domain.tld", "email2@domain.tld"]
cc: ["email3@domain.tld"]
bcc: ["email4@domain.tld"]
subject: "This is the subject"
message: "This is the plain text body."
attachments: ["$uri:attachment:path/to/attachment"]
The notification framework will automatically detect the target channel (which is email in this example) and renders and sends the according mime message for you. This is the easiest approach.
Aliases to the notification.send
command are notifcation.put
and mail.send
.
In some cases you might have the requirement to further customize the mime message. For this, see the examples below for more details.
Send a plain text email (customize mode)
In case you would like to further customize the mime headers or the multipart body of an email, you can use this approach instead:
pipeline:
- notification.send:
input: {
"headers": {
"to": ["email1@domain.tld", "email2@domain.tld"],
"cc": ["email3@domain.tld"],
"bcc": ["email4@domain.tld"],
"subject": "This is the subject",
}
"body": {
"contentType": "text/plain",
"content": "This is the plain text body."
}
}
Note that the notification input
is a 100% mime message (RFC2045. ) compliant format. This means it is separated into a headers
and a body
section. In the headers section all headers from the MIME standard are supported. They will be forwarded to the target channel, like email client for example. Also the body section is fully compliant with RFC2045 so you can construct any multipart body structure you need for the target client. For further details about such a structure please consult external documentation about how to construct valid multipart mime messages.
Send a mixed-content multipart mime message
In case you would like to compose a multipart mime message with mixed content, you can use this example as a template:
pipeline:
- notification.send:
input: {
"headers": {
"to": ["email1@domain.tld", "email2@domain.tld"],
"cc": ["email3@domain.tld"],
"bcc": ["email4@domain.tld"],
"subject": "This is the subject",
}
"body": {
"contentType": "multipart/mixed",
"content": [
{
"contentType": "multipart/alternative",
"content": [
{
"contentType": "text/plain; charset=UTF-8",
"content": "This is the plain text body."
},
{
"contentType": "text/html; charset=UTF-8",
"content": "$uri:property:global/app/my.app/template/body"
}
]
},
{
"contentType": "image/jpeg",
"contentDisposition": "attachment; filename=\"bild.jpg\"",
"contentTransferEncoding": "base64",
"content": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAHBgoJCAkLC..."
},
{
"contentType": "application/pdf",
"contentDisposition": "attachment; filename=\"dokument.pdf\"",
"contentTransferEncoding": "outbound",
"content": "$uri:attachment:some-attachment-uuid"
}
]
}
}
}
For specific details about the structure of a multipart mime message, please have look at the RFC2045.
As you can see in this example, the body
can be a list of nested content objects.
The content
value itself can be a fixed text, a base64 string or a PIPEFORCE URI pointing to a resource to load.
Attachments
You can also add (file) attachments to notifications. Depending on the target channel they will be provided as downloads or embedded when the notification shows-up in the channel client.
Simple Mode
In order to add (file) attachments to your notification, you have multiple options. The easiest approach is to use the attachments
attribute of the notification.send
command:
The command will try to autodetect all required attachment information from the list of given attachments and append it to the body content in multipart mime format at the very end. It wont overwrite any existing part there.
Combined Mode
This way you can combine the simplified parameter format with a specific one. For example:
The final multipart mime message, which will be send to the email channel will be this (since the simplified parameters are merged into the input notification):
Note:
All given values from command parameters will overwrite the values in the mime message if there are any.
In case the section doesn’t exist yet in the mime message, it will be created.
It could be that the original mime message needs to be re-arranged to insert the parameter values: For example in case you would like to add
attachments
via command parameter to an existingtext/plain
input body. In this case, the body will be converted tomultipart/mixed
and the text plus attachments will be nested inside.
Customized Mode
Another option is to create the content JSON objects inside the mime message manually and set the attachments accordingly accordingly to the RFC Mime Messages specification. This is the solution which is most flexible and highly customizable. But it is also the most complex approach.
Attaching content references
You can also use content references loaded into a pipeline scope like vars
or body
as source for attachments. For example:
In this example the file is first loaded (implicitly) to body using the command drive.read
and then linked to the attachments
parameter. You can place any content reference as attachment.
Using this approach it is also possible to create the attachments dynamically on-the-fly in the pipeline (for example by using a template engine) and then add them finally to the email.
Templating Notifications
You can create dynamic notification texts and layouts using templating.
Using a Transformer​
You can use a transformer command like transform.ftl in order to render the message. For example:
In this example, the message is rendered and then stored in the body using transform.ftl
. The command notification.send
then picks up the rendered message from the body and uses it as email message.
And here is an example to load the template from the property store from location global/app/myapp/template/email
:
Embedded template URIs
It is also possible to embed the template references inside the mime notification using PIPEFORCE URIs. For example:
In this example the $uri:template:
URI is used. This will load the template from given location in property store and will render it using the template engine which fits the Content-Type of the property. By default, this is the FreeMarker Template Engine. Also all other PIPEFORCE URIs are supported here instead.
Any time the notification is sent, the elements of the mime message will be recursively scanned for PIPEFORCE URIs. In case one is found, it will be called and in case it is supported, the current mime notification object will be auto-passed to the template and can be used there to access all relevant data from the mime message to render the template. Here is an example for a message rendered using the FreeMarker Template Language:
Template Model
Inside each template the mime notification will be provided as the template root or body model, depending on the template approach used.
This root model will provide these fields:
headers
= A key-value map which contains all header values used to configure the notification.to
= A list of resolvedto
recipient objects.cc
= A list of resolvedcc
recipient objects.bcc
= A list of resolvedbcc
recipient objects.from
= The from recipient object.subject
= Contains the (resolved) subject text.content
= Contains the nested mime part objects as configured in the notification configuration.excludedAddresses
= A list of all recipient objects excluded in this notification.allAddresses
= Combines all recipient objects fromto
,cc
andbcc
into a single list and removes any duplicates.model
= The message model provided from external. The structure of this model depends on the provider.uuid
= The unique id of this notification, if set.attachments
= A list of mime part objects extracted from the content body, defining the attachments of this notification.
Recipient
The structure of a notification recipient is like this:
name
= The display name of the recipient.locale
= The locale of the recipient to be used for this notification.address
= The address uri of the recipient.plainAddress
= The plain address without any URI prefixes or query parameters.channel
= The channel of this recipient (for exampleemail
,slack
, ...)
Part
The structure of a notification mime part is like this (also see official MIME specification for this):
contentType
= The MIME content type of the content value.contentDisposition
= The disposition header as defined in the MIME specification.contentTransferEncoding
= The transfer encoding as defined in the MIME specification.content
= The content of the part which can be one of:A PIPEFORCE URI if
contentTransferEncoding
is set tooutbound-url
.A base64 encoded string if
contentTransferEncoding
is set tobase64
.A text value with format given by
contentType
.A list of nested Part’s in case
contentType
ismultipart/mixed
.
Addresses and address resolving
In the headers section of a mime notification you can declare the addresses of the recipients where the notification must be send to. Here is an example how to do this directly inside the mime notification JSON:
As an alternative you can also use the simple mode by declaring them as parameters directly on the command:
These address parameters will be converted to a mime notification JSON and placed in its header section for you.
Addresses prefixed with $uri:
By default all addresses are assumed to be valid email addresses. But you can also use other address types to send the notification to a different channel. In case an address is not an email address, it always must be prefixed with $uri:
. Here is an example to use a Slack channel as target address instead:
In this example, the message will be send to a Slack channel instead of via email. You can also combine different addresses of different types like this example shows:
In this example the notification will be rendered as a Slack message and send to the Slack channel with name mychatgroup
and additionally it will be rendered as email message and send to the email address email1@domain.tld
.
Final and expandable addresses
There can be final and expandable addresses:
Final address: The address can be used as it is by a channel to deliver the message. For example an email address.
Expandable address: The address needs to resolved (expanded) to one or more final addresses first, before it can be used by a channel to deliver the notification. For example an address referring to a user in IAM must first be expanded (resolved) to the user’s email address before the notification can be send.
Here is an example how such a resolving could look like:
Expandable addresses could also be recursive.
The resolving (expanding) is automatically done by the notification framework.
Some notes about this example:
A: Final addresses. They will be used to send the notification directly to the channels.
B: The supervisor will get this notification via its default email.
C: Any user who is member of group
sales
will get this notification via its preferred notification channel. In this example, this is usermanager1
and his notification channels from IAM aresales1@company.tld
andprivate1@mail.tld
.D: The group
sales
contains another groupadmins
and therefore all members of this role will additionally get the notification via their preferred address.
When the notification is processed, all groups and users will be resolved and the preferred channel will be used to send the notification.
Handling address duplicates
Duplicate addresses which appear after expanding will be removed (for example because a user is member of multiple groups or roles configured for the notification, so his address is used only once).
In case the same addresses is used in to
, cc
and bcc
, then the address in the lowest visibility will be kept. The visibility is like this (from lowest to highest):
bcc
to
cc
So for example if the same address is given in bcc
, cc
and to
it will be removed from to
and cc
and only kept in bcc
. Another example: If the same address is given in to
and cc
, it will be kept in to
and removed from cc
. And if the same address is given in bcc
and cc
, it will be kept in bcc
and removed from cc
. And so on.
$uri:email:
This final address will send the notification via email. The format is like this:
For example:
This is an alternative to not using the prefix at all. So this is also a valid email address:
$uri:user:
This expandable address will lookup the user with given username in IAM (user management) and be converted to the registered target address of the user which is an email address by default.
The format is like this:
Whereas <username>
must be an enabled and exiting user in IAM with is username.
For example:
In case the user is disabled or doesn’t exist, this address will be ignored and removed from the address fields.
For example:
Let’s assume as default address of the user maxhuber
in IAM the email address foo.bar@logabit.com
is configured, then an address field like this:
|
|
Will be resolved to this:
|
|
$uri:group:
This expandable address will lookup a group with given name in IAM (user management) and it will be resolved to the default addresses of all user members of this group.
The format is like this:
Whereas <groupname>
must be an enabled and existing group in IAM with this group name. For example:
In case the group is disabled or doesn’t exist, this address will be ignored and removed from the address fields.
For example:
Let’s assume there is a group sales
in IAM with with these member users and their default target addresses configured in IAM:
Username | Target Address |
---|---|
teamlead | teamlead@mail.tld |
user1 | $uri:slack:mychannel |
user2 | $uri:email:user2@mail.tld |
Then, an address field like this:
|
|
Will be expanded (resolved) to this:
|
|
$uri:slack:
This final address will send the notification to a Slack channel as configured by the connection config id.
The format is like this:
Whereas <connection-config-id>
must be an id of a valid and enabled connection configuration.
For example:
$uri:teams:
This final address will send the notification to a Microsoft Teams channel as configured by the connection config id.
The format is like this:
Whereas <connection-config-id>
must be an id of a valid and enabled connection configuration.
For example:
$uri:message-route:
This is a final address: It will forward the message to the message broker using the given routing key.
The format is like this:
Whereas <routing-key>
is the target routing key where the message must be forwarded to. The mime notification headers will be set as message headers and the body will be serialized as JSON into the playload of the message.
For example:
$uri:pipeline:
This expandable address will call the pipeline given by path, puts the mime notification into its body and executes it. It expects a JSON array of addresses to be returned, all starting with prefix $uri:
. Otherwise, the address will be ignored. These addresses will then replace the $uri:pipeline:
address in the fields.
The format is like this:
For example:
The dynamic-addresses
pipeline could look like this example to return addresses dynamically:
$uri:property:
This expandable address will load the property at given path and expects the value to be a JSON array containing the addresses to be returned.
The format is like this:
For example:
The my-addresses
pipeline could look like this example:
Resolving of expandable addresses
Expandable addresses are resolved (expanded) recursively until the final address appears. So for example an expandable address given like this:
|
|
Could return and resolve to:
|
|
Which in term could resolve to this in the next recursion:
|
|
Which resolves to these final addresses:
|
|
Excluding addresses
It is possible to exclude certain addresses from a mime message. To do so, you can use the custom header x-pipeforce-exclude-addresses
and specify the addresses to be excluded. For example:
In this example, the New lead
notification will be send to all members of group sales
excluding those users also in group vacation
.
Exclude addresses can be final and expandable addresses.
Multi-Language Notifications (i18n)
The notification framework supports multi language notifications. This means a notification can be send in different languages to multiple recipients. The framework handles the way how the templates related to the selected language will be loaded and clusters the notifications based on the selected language (locale).
How to enable it
By default i18 is turned-off. In order to enable multi-language (i18n) support, you have to set the header x-pipeforce-multilang
to true
in your notification configuration:
How it works
The main concept behind i18n support in notifications is that any $uri:template
, $uri:property
or $uri:pipeline
which is used in subject or body of the notification will automatically be suffixed with the selected locale (= language key): For example, if you use the URI $uri:template:global/app/com.acme.myapp/mytemplate
inside your notification configuration like this:
… and the locale de
(german) is selected, the URI will automatically become $uri:template:global/app/com.acme.myapp/mytemplate_de
: It will be prefixed with _de
so the template specific to german language can be loaded. And in case the locale en
(english) is selected, this prefixed URI will be loaded instead: $uri:template:global/app/com.acme.myapp/mytemplate_en
(the suffix _en
is appended). This way you can organize your templates in the property store in a clear way. For example it could look like this:
global/app/com.acme.myapp/template/
mytemplate_de
mytemplate_en
mytemplate_fr
mytemplate_sk
Here are the steps, how this all works together:
It will look for a query param
?locale=<lang>
in each address into
,cc
orbcc
fields.
For example:$uri:email:foo@bar.tld?locale=de
. If no locale exists it will useen
as default.If the address is an IAM address like
$uri:group:
or$uri:user:
it will use the value of user attributelocale
from IAM for the locale, if exists. Otherwise, it will fallback toen
as default. If both are given (query param and locale attribute in IAM), the query param will have precedence.It will split a notification to multiple notifications for each new language and will manage to split also addresses according to these languages. For example if there are these TO addresses set:
$uri:email:my@mail.tld?locale=de, $uri:email:another@mail.tld?locale=en
this means two emails will be rendered and send: One withde
as language with german text in subject and body and one with english text. Finally, there will be two emails: The DE one is sent tomy@mail.tld
and the EN one sent toanother@mail.tld
. The same is true for addresses incc
andbcc
.As already mentioned above, any
$uri:template
,$uri:property
or$uri:pipeline
which is used in subject and body of the notification configuration will automatically be suffixed with the selected locale. So for example$uri:template:global/app/com.acme.myapp/mytemplate
will become$uri:template:global/app/com.acme.myapp/mytemplate_de
in case the detected language (locale) is set tode
.
Additionally, the detected language (locale) will be set as Content-Lang
header (which is a standard MIME header) so it can be used in the templates and/or at target client side as well.
Static suffix / disable suffixing
In some situations, suffixing the template resource path is not wanted or a static suffix must be used for all of such resources. For this, you can set the header x-pipeforce-multilang-suffix
to a static suffix. If this is set, it will be used and the calculated suffixes from the language (for example _en
) will be ignored.
In case you don’t want to use suffixes at all, set this header to empty string ""
. Then, always the template resource without suffix will be loaded. You can then add language specific logics inside your template by using the Content-Lang
header which is also provided into the template.
Multi-Channel Notifications
The notification framework also supports sending a notification to different channels. This way it is possible beside via email, the same notification can be send to a Slack channel, via SMS and Teams for example. For each channel, different templates can be provided in order to adjust the format of the message so it fits the target channel.
How to enable it
By default multi-channel support is disabled. In order to enable multi-channel support, you have to set the header x-pipeforce-multichannel
to true
in your notification configuration:
How it works
If multi-channel support is enabled, the framework will handle a notification similar to the multi-language approach:
It will look for the final addresses in the address uri. For example:
$uri:email: →
email
channel$uri:slack: →
slack
channel$uri:teams: →
teams
channel$uri:sms →
sms
channelaso.
It will split a single notification to multiple notification messages: For each new channel and will manage to split also addresses according to these channels. For example if there are these TO addresses set:
$uri:email:my@mail.tld?locale=de, $uri:slack:mygroup
this means two notifications will be rendered and send: One as email and the other one as Slack message. The same is true for addresses in CC and BCC.Any
$uri:template
,$uri:property
or$uri:pipeline
which is used in subject and body of the notification will automatically be suffixed with the selected channel. So for example$uri:template:mytemplate
will become$uri:template:mytemplate_slack
in case the channel is set toslack
via address. This way, different templates can be provided in the property store and the notification framework will pick-up the one which belongs to the selected channel.
Additionally, the detected channel will be set as x-pipeforce-channel
header so it can be used in the templates as well.
Static suffix / disable suffixing
In some situations, suffixing the template resource path is not wanted or a static suffix must be used for all of such resources. For this, you can set the header x-pipeforce-multichannel-suffix
to a static suffix. If this is set, it will be used and the calculated suffixes from the channel (for example _email
) will be ignored.
In case you don’t want to use suffixes at all, set this header to empty string ""
. Then, always the template resource without suffix will be loaded. You can then add channel specific logics inside your template by using the x-pipeforce-channel
header which is also provided into the template.
Personalized Notifications
Lets a assume you have a list of recipient addresses configured in your notification configuration like this:
… and instead of sending the same static email to all of these recipients you would like to generate and send individual text messages for each.
So for example someUser1
should get this email text:
… and someUser2
should get this email text:
To do so, you have to set the header x-pipeforce-personalized
to true
:
In this case for each recipient the templating rendering is called again so the content can be personalized then. The to
header will always be set to the personalized recipient and cc
and bcc
will be deleted.
Inside the template you can then access the personalized recipient by accessing the to
header or by calling allAddresses[0]
. Here is an example how such a template could look like:
This will be repeated for every recipient, regardless whether it is set on to
, cc
or bcc
.
Finally, the text result of each template rendering will be send as individual message.
Push Notifications
Push notifications are system and business events, a user can subscribe to. Any time there is a match, such an event is automatically converted to a notification and will be send to the registered user's preferred communication channels like email or chat group for example.
A push notification always starts with a message sent with routing key pipeforce.event.#
. All messages having a routing key starting with this prefix will be stored in the pipeforce_push
queue.
By default the pipeforce_push
queue has these restrictions:
Max. number of messages in queue: 20.000
Max. time to life: 48 hours
Max. size of all messages in queue: 100 MB
As soon as one of these restrictions are met, oldest messages will be deleted.
Subscribe to push notifications
In order to receive push notifications, you have to subscribe to event keys, called topics, first.
This is done in PIPEFORCE by creating a JSON document in a folder with name push
inside your app. For example global/app/my.app/push/my-subscription
.
This JSON document is called push subscription and has a structure like this:
The fields of this JSON are described below.
"enabled"
Is the push subscription enabled (true
)? Default is true
in case attribute is not given.
"includeTopics"
The routing keys of messages inside the pipeforce_push
queue to get informed about.
"excludeTopics"
The routing keys to exclude explicitly (for example if it is sub-pattern of an includeTopic).
Both
includeTopics
andexcludeTopics
support the wildcard pattern from RabbitMQ:* = A single part between two dots .
# = Anything which comes after.
"headers"
Since a push subscription is based on a mime notification it can contain all of its headers such as:
to
: A list of addresses, to send the push notification to.cc
: A list of addresses, to send the push notification to in CC.bcc
: A list of addresses, to send the push notification to in BCC.subject
: The subject to be used for the push notification. If no subject is set, a default subject is generated.es
: A list of addresses to exclude from the push notification.
"body"
The multipart body message to be send as the push notification payload. If no body exists, a default body is generated. Everything described for the body of mime notification can also be applied here.
Topics
A topic in a push subscription is a routing key pattern of an event message which always starts with prefix pipeforce.event
, followed by the concrete topic type.
In case the routing key of a an event message matches this pattern, a new push notification will be generated and send to all addresses as configured in the push subscription.
The topic can contain wildcards:
*
= Stands for a single word up to the next period.
#
= Stands for multiple words with multiple periods in between.
For example: pipeforce.event.workflow.#
matches all workflow event messages while pipeforce.event.workflow.*.my.app
matches only workflow event messages inside the app my.app
.
pipeforce.event.app
This topic group forwards all important events related to app management.
.install.finished
This event message is send after an app was successfully installed.
The full structure of the event message routing key is like this:
.uninstall.finished
This event message is send after an app was successfully uninstalled.
The full structure of the event message routing key is like this:
pipeforce.event.iam
This topic group forwards all important events happening inside IAM.
.admin.client.create.client
This event message is send after a new client was created.
The full structure of the event message routing key is like this:
.admin.update.client
This event message is send after a client was updated by an admin.
The full structure of the event message routing key is like this:
.admin.delete.client.scope.client.mapping
This event message is send after a client scope mapping was deleted.
The full structure of the event message routing key is like this:
.admin.create.group
This event message is send after a new group was created.
The full structure of the event message routing key is like this:
.admin.create.user
This event message is send after a new user was created.
The full structure of the event message routing key is like this:
.admin.client.create.role
This event message is send after a new role was created.
The full structure of the event message routing key is like this:
.admin.create.group.membership
This event message is send after a member was added to a group.
The full structure of the event message routing key is like this:
.admin.create.realm.role.mapping
This event message is send after a resource was mapped to a realm role.
The full structure of the event message routing key is like this:
.admin.action.user
This event message is send after a user has done a predefined action.
The full structure of the event message routing key is like this:
.client.login
This event message is send after an OAuth2 client has been logged-in.
The full structure of the event message routing key is like this:
.code.to.token
This event message is send after a code has been exchanged to token.
The full structure of the event message routing key is like this:
.login
This event message is send after user has successfully logged-in.
The full structure of the event message routing key is like this:
.logout
This event message is send after user has successfully logged-out.
The full structure of the event message routing key is like this:
.refresh.token
This event message is send after a token has been refreshed.
The full structure of the event message routing key is like this:
.token.exchange
This event message is send after a token has been exchanged.
The full structure of the event message routing key is like this:
.user.info.request
This event message is send after user information have been requested.
The full structure of the event message routing key is like this:
pipeforce.event.property
This topic group forwards all property events as push notifications.
Every property topic key can additionally contain dynamic variables which will be replaced at runtime such as:
{appName}
= Will be replaced by the app name the property is stored inside (example: io.pipeforce.myapp
).
{path}
= The path of the related property whereas slashes in path of property will become dots. Dots and special chars in origin path will be replaced by underscores. Everything in path is lower-cased.
.created
This event message is send after a new property was created.
The full structure of the event message routing key is like this:
.deleted
This event message is send after a property was deleted.
The full structure of the event message routing key is like this:
.updated
This event message is send after a property was updated.
The full structure of the event message routing key is like this:
.comment.created
This event message is send after a comment was added to a property.
The full structure of the event message routing key is like this:
.comment.updated
This event message is send after a comment was updated to a property.
The full structure of the event message routing key is like this:
pipeforce.event.log
This topic group forwards all important log events of severity level WARN
or higher.
Every log topic key can additionally contain dynamic variables which will be replaced at runtime such as:
{loggerName}
= The name of the logger used internally.
This way you can also listen to events of a certain level and logger type using a pattern. Here is an example which listens for all log levels (warn
and above) happening inside the com.logabit
package: this for example: pipeforce.event.log.*.com.logabit.#
.error
This event message is send after a new log entry of level ERROR
was created.
The full structure of the event message routing key is like this:
.warn
This event message is send after a new log entry of level WARN
was created.
The full structure of the event message routing key is like this:
pipeforce.event.webhook
This key forwards all webhook calls. The structure of the event message routing key is like this:
Whereas {name}
is the name, the user has given to this webhook in the setup. The payload of the message contains the body of the webhook request.
pipeforce.event.workflow
Every workflow topic key can additionally contain dynamic values which will be replaced at runtime such as:
{appName}
= Will be replaced by the app name the workflow is stored inside (example: io.pipeforce.myapp).
{wfName}
= Will be replaced by the property name of the workflow definition in the workflow folder inside the app (example: myworkflow)
Workflow address variables ($uri:wf-)
In case a push event is a workflow event (pipeforce.event.workflow.#
), these additional address variables can be used in TO, CC and BCC fields to refer to data from the event message:
$uri:wf-authenticated-user
= Returns the$uri:user:<username>
of the user who was logged-in at the time of this event and potentially has initiated this event.$uri:wf-process-involved-users
= Returns the$uri:user:<username>
of all users involved in the workflow process.$uri:wf-started-by
= Returns the$uri:user:<username>
of the user who started the workflow.$uri:wf-task-candidate-groups
= Returns the$uri:group:<name>
names of all groups which are set as candidate group of given task. In case there is no candidate group set, the address variable will be removed from all address fields.$uri:wf-task-assignee
= Returns the$uri:user:<username>
of the user who is set as assignee on given workflow task. In case there is no taskAssignee set, the address variable will be removed from all address fields.$uri:wf-task-owner
= Returns the$uri:user:<username>
of the user who is set as assignee on the given workflow task. In case there is no taskOwner set, the address variable will be removed from all address fields.$uri:author
= In case the event is related to a comment creation, returns the$uri:user:<username>
of the user who created the comment. This is also true for comments created outside of workflow related events.
Duplicate addresses will always be removed.
.comment.create
This event message is send after comment to a workflow process was created.
The full structure of the event message routing key is like this:
.comment.update
This event message is send after comment to a workflow process was updated.
The full structure of the event message routing key is like this:
.end
This event message is send after a workflow process have been finished.
The full structure of the event message routing key is like this:
.task.assignment
This event message is send after the task assignee has changed.
The full structure of the event message routing key is like this:
.task.complete
This event message is send after a task was completed.
The full structure of the event message routing key is like this:
.task.create
This event message is send after a new task in a workflow process was started (created).
The full structure of the event message routing key is like this:
.task.delete
This event message is send after a task was deleted.
The full structure of the event message routing key is like this:
.task.timeout
This event message is send after a task timeout happened.
The full structure of the event message routing key is like this:
.task.update
This event message is send after a metadata or variables of a task have been updated.
The full structure of the event message routing key is like this:
.transition
This event message is send after a (task) transition have been occurred from one state to another.
The full structure of the event message routing key is like this:
.start
This event message is send after a new workflow process have been started.
The full structure of the event message routing key is like this:
Custom Topics
You can also send push notifications based on your custom topics.
To do so, you need to configure these steps:
Make sure to send event messages using a routing key format like this
pipeforce.event.<yourName>
usingmessage.send
command. Replace<yourName>
by the custom name you would like to use. Best practise is to use the prefixapp
and the name of the app followed by the concrete event name to not potentially collide with other topics from other apps. For example:pipeforce.event.app.com.company.myapp.myaction
This way it is also easy to filter later using patterns. Examples:pipeforce.event.app.#
= Listens to all events from all apps.pipeforce.event.app.com.company.#
= Listens to all events from all apps from givencompany
.pipeforce.event.app.com.company.myapp.#
= Listens to all events from appmyapp
.pipeforce.event.app.com.company.myapp.myaction
= Listens to the exactmyaction
event.
Create a new push notification configuration inside the
push
folder of your app and make sure to map theincludeTopics
correctly to the recipients.
Example push notification configuration:
This push notification configuration makes sure, every time a custom event for the app myapp
appears, it will be pushed to all users of group $uri:group:my-custom-group
.
Exclude addresses from topics
There is an exclude list to make sure certain push notifications are not sent to these addresses. They can be configured using the header x-pipeforce-exclude-addresses
as described for the mime notification.
Furthermore, it is possible to set the attribute excludeTopic
for a specific user in IAM. In case the addresses $uri:group
or $uri:user
are used and excludeTopic
exists for a matching user, it will be checked whether this user should be excluded from the push notification.
See here as an example:
There can be multiple attributes with name excludeTopics
or the values can be separated by comma. Both approaches work and can also be combined (for example to group certain excludeTopics
).
Templating Push Notifications
Since push notifications are based on Mime Notifications, all rules of mime notifications apply.
In case no subject or body is defined, a default subject and body is created for each push notification.
In case you would like to use a custom text there, you can do so by setting it in the push subscription. For example:
It is also possible to refer to templates in subscription and content (which will be rendered later in the process):
Global Push Configuration
You can disable / enable global push notifications in admin settings.
Note: If disabled, events will not be catched from the pipeforce_push
queue so outdates, too many event messages there will be deleted.
Also see the restrictions of the queue above.
Default Push Subscriptions
Inside global/app/io.pipeforce.admin/push/
there are default push subscriptions for admins, developers and users.
Testing Notifications (dryRun)
In order to test notification delivery, you can enable dryRun for such a notification by adding a marker [pipeforce.dryrun:someName]
in the subject or adding an email address ending in someName@pipeforce.dryrun
.
In case such a marker exists, the notification wont be delivered but instead stored to the internal cache. From there you can pickup apply your tests.
For further information see an example for dryrun sending emails: Emailling .
Â