Concepts
Here we will explain some key concepts that are vital to Notification Service.
Topics
Topics allow modules to register notification categories that users can opt out of. When a module registers topics, users gain the ability to control which types of notifications they receive through the Notification Settings UI.
What is a Topic?
A topic represents a specific category of notifications that a module can send. Each topic:
-
Has a unique key (e.g.,
order-updates,system-alerts) -
Supports one or more notification methods (Email, Web Push)
-
Can have localized titles in multiple languages
-
Is bound to the software providing tenant of the module
Topic Registration
Topics are registered at the application level, not per tenant. When a module first registers its topics in its software providing tenant, that tenant becomes the "owning tenant" for those topics. The topics then become available across all tenants where the application is contracted to.
|
The software providing tenant is the tenant that hosts and registers the module at the Web Portal. This is typically the tenant where the module vendor or development team operates. |
|
Applications should register notification topics in their software providing tenant. A module using the Topic Registration API cannot have different topics for different tenants - any registered topic is visible in all tenants where that application is contracted to. |
Notification Methods
Each topic must specify at least one supported notification method:
-
Email: Users can opt out of email notifications for this topic
-
Web Push: Users can opt out of push notifications for this topic
If a notification method is not specified for a topic, it defaults to false (not supported).
Topic Keys
Topic keys must follow these rules:
-
Maximum 50 characters
-
Only alphanumeric characters, underscores (
_), and hyphens (-) are allowed -
Must be unique within an application
Translations
Each topic requires at least an English US (en-US) translation for the title. Translation keys must use the languageCode-countryCode format where languageCode is an ISO 639-1 two-letter code and countryCode is an ISO 3166-1 two-letter code (e.g., en-US, de-DE, de-AT). Neutral cultures like en or de are not allowed.
If a user’s preferred locale is not available, the system tries to find a matching translation by language. For example, if de-CH is requested but only de-DE is available, the German translation will be used. If no matching language is found, the system falls back to English US (en-US).
Topic-based Opt-Out Filtering for Direct Notifications
When sending a direct email or push notification via the API, modules can optionally include a topicKey in the request payload. If provided, the notification service checks each recipient’s opt-out preferences for that topic before delivering the notification. This allows users to suppress specific notification topics they are not interested in.
If no topicKey is provided, or if the topic is not registered, notifications are delivered to all recipients without any filtering.
Decision Matrix
topicKey provided |
Topic registered | Channel supported by topic | User has opt-out setting | Result |
|---|---|---|---|---|
No (null / empty) |
— |
— |
— |
Send to all recipients |
Yes |
No |
— |
— |
Send to all recipients (unknown topics are not filtered) |
Yes |
Yes |
No |
— |
Send to all recipients (channel not subject to user preference) |
Yes |
Yes |
Yes |
None (no explicit setting) |
Send (default opt-in behaviour) |
Yes |
Yes |
Yes |
Opted out ( |
Exclude recipient |
Yes |
Yes |
Yes |
Opted in ( |
Send |
Channel mapping
The topicKey filtering respects the delivery channel of the notification:
-
Email notifications are evaluated against the topic’s email opt-out settings
-
Push notifications are evaluated against the topic’s web push opt-out settings
If a topic does not support a specific channel (e.g., only email is registered for the topic), notifications sent via the unsupported channel are delivered regardless of user preferences.
Event type
|
Deprecated as of IAS version 2025.02.00: Event Types and Subscriptions are deprecated and will be removed in September 2026. Please migrate your Quick Reactions in Deviation Processor to use Direct Messages. Other modules, such as Ticket Management, have already been updated to use this new method. |
An Event Type defines a category of notifications that a module can send out. Modules register their own Event Type via the REST API and is not tenant-specific. The event type defines what dynamic variables will be available and what their data type is. This information will later be relevant when creating subscriptions and sending events.
When defining dynamic variables, you can choose between the following data-types:
-
String
-
DateTime
-
MacmaGroup
-
Device
-
DeviceType
-
MacmaUser
-
Link
The data type here impacts how the variable is used in the subscription.
In case of default subscriptions, number of event types per module varies per application, typically 1-5 (not limited)
Subscription
|
Deprecated as of IAS version 2025.02.00: Event Types and Subscriptions are deprecated and will be removed in September 2026. Please migrate your Quick Reactions in Deviation Processor to use Direct Messages. Other modules, such as Ticket Management, have already been updated to use this new method. |
The subscription represents the actual notification that gets sent and is linked to a single event type. Without a subscription, events don’t trigger notifications.
A subscription defines:
-
The event type to listen to
-
The content of a notification (e.g., subject and content of an email)
-
The recipients of a notification
-
The communication channel that is used to send the notification (email, push)
Only users with role Operator can perform CRUD-operations in the UI. Modules can create subscriptions as well.
Custom subscription
A custom subscription is a tenant-specific entity and contains the following information:
-
Notification Type (e.g. Push or Email)
-
Subject and Content
-
Recipients
-
Filters ( for more info refer here )
-
Address to send from (for email subscriptions)
For modules using the REST API to create subscriptions, you can specify recipients by their MACMA ID.
Within the subject and content, you are able to reference dynamic variables with the following expression: {{DYNAMIC_VARIABLE_NAME}}.
Example: you have the dynamic variable ImpactedMachineName and a subscription with the content Machine {{ImpactedMachineName}} has been impacted!.When an event is received with the value Machine01 for variable ImpactedMachineName, you will get the following content: Machine Machine01 has been impacted!.
Default subscription
Default subscriptions are registered with a tenant ID; however, it is not checked. It should not be used for filtering or applying authorization. It contains the following information:
-
A localizable title in English and German with supporting fallback to English if no translation is provided for the user’s preferred language.
-
A localizable description in English and German with supporting fallback to English if no translation is provided for the user’s preferred language
-
Filters ( for more info refer here )
-
RecipientFields to determine recipients with field names referencing dynamic variables from the event type and localizable labels. The recipient should always be a MACMA user, as the calling module cannot identify whether the email given is a MACMA user or a 3rd party user.
-
Localizable subscription templates in Markdown, which will be rendered to HTML for emails and as plain text for push notifications.
-
A default notification method (e.g., Email, Web Push).By default, all notification methods are enabled unless specified otherwise.
-
A flag indicating if the subscription is always-on (optional)
Number of default subscriptions per module will be 1-5 (not limited)
Filters
For subscriptions, you can define a criteria of filters which will be evaluated when an event is received. These filters can be used to only send the notification when the criteria are met. When defining filters, you will be able to choose the dynamic variable to check, the operator and the expected value. The list of available operators depends on the data type of the dynamic variable.
Parent filters supports "And" and "Or" operators only.
The system also supports nested filter groups, allowing you to create a complex tree of filters.
Default subscription filters offer additional operators: "Changed", "Changed From", and "Changed To" for variables that support value changes. These operators consider both previous and current values. You can also use these operators when creating custom subscriptions via the REST API only and not from UI.
Example1: Filter using "Changed" operator
Given a subscription filter exists with the "Changed" operator for a dynamic variable <variable> When the value of <variable> changes from <previous_value> to <current_value> Then the filter evaluates to <result>
| Dynamic Variable | Previous Value | Current Value | Result |
|---|---|---|---|
Status |
"Open" |
"In Progress" |
true |
Priority |
"High" |
"High" |
false |
Example2: Filter using "Changed From" operator
Given a subscription filter exists with the "Changed From" operator and value <filter_value> for a dynamic variable <variable> When the value of <variable> changes from <previous_value> to <current_value> Then the filter evaluates to <result>
Examples:
| Dynamic Variable | Previous Value | Current Value | Filter Value | Result |
|---|---|---|---|---|
Status |
"Open" |
"In Progress" |
"Open" |
true |
Status |
"Pending" |
"In Progress" |
"Open" |
false |
Example3: Filter using "Changed To" operator
Given a subscription filter exists with the "Changed To" operator and value <filter_value> for a dynamic variable <variable> When the value of <variable> changes from <previous_value> to <current_value> Then the filter evaluates to <result>
Examples:
| Dynamic Variable | Previous Value | Current Value | Filter Value | Result |
|---|---|---|---|---|
Status |
"Open" |
"In Progress" |
"In Progress" |
true |
Status |
"Open" |
"Pending" |
"In Progress" |
false |
Event
An Event is used to trigger an Event Type and send out notifications based on the subscriptions. An event is referencing an event type and can provide values for the custom properties of the event types. An event is always triggered by the host module (e.g. Ticket Management).
The payload of Event contains the ID of the Event Type that it is targeting and also a list of dynamic variables with their values. For each event, the system will load all the subscriptions that are linked to the given event type and will send out a notification as defined by each subscription.
Event processing
When an event is received by the notification service, it first performs the necessary validations on the event payload. If the validation passes, the event will be processed synchronously for default subscriptions and asynchronously for custom subscriptions, meaning the client does not wait for the notification delivery to complete. If the validation fails, the service responds with a 400 Bad Request status code along with a detailed error message describing the validation issues. In this case, the event details are not persisted.
The notification will be processed asynchronously in the background by the notification service, using RabbitMQ as a message broker. Notifications will be processed in the order they were received, and the system will attempt to send out notifications based on the custom subscriptions linked to the event type. If a notification fails, it will be rejected, and the corresponding notification message will be moved to the Dead Letter queue for further investigation.
The Dead Letter queue is a special queue used to store unprocessed notification messages. It allows a maximum of 1,000 events to be stored. Once the queue is full, the oldest notification will be removed to make space for new events. The Dead Letter queue has a 14-day expiry period, meaning that notification messages will be removed from the queue after 14 days. This is to ensure that the queue does not grow indefinitely and to allow for periodic cleanup of old notification messages.
Direct notifications processing
When a direct message email or push notification is received by the notification service, it first performs necessary validations on the email or push payload. If the validation passes, the service immediately responds to the client with a 202 Accepted status code (the email or push entity is not persisted), indicating successful receipt of the direct message. The direct message is then queued for asynchronous processing, and the client does not wait for the notification delivery to complete. If the validation fails, the service responds with a 400 Bad Request status code along with a detailed error message describing the validation issues. In this case, the direct message details are not persisted.
The direct message will be processed asynchronously in the background by the notification service, and RabbitMq will be used as a message broker. The direct message will be processed in the order it was received, and the system will try to send out notifications based on the direct message configuration received. If the notification fails, it will be rejected and the corresponding direct email or push message will be moved to the DeadLetter queue for further investigation.
The DeadLetter queue is a special queue that is used to store unprocessed direct messages. It allows a maximum of 1000 messages to be stored. Once the queue is full, the oldest messages will be removed to make space for new messages. The DeadLetter queue has a 14-day expiry, meaning that direct messages will be removed from the queue after 14 days. This is to ensure that the queue does not grow indefinitely and to allow for periodic cleanup of old direct messages.
As part of the email or push notification payload, a referenceId is included — a unique alphanumeric string with a maximum length of 255 characters. This ID is used to trace, correlate, or debug individual messages, and is especially useful for identifying unprocessed direct messages that end up in the dead letter queue. It helps in ensuring message traceability and diagnosing failures in downstream processing.
Optionally, a topicKey can be included in the payload to enable recipient filtering based on user opt-out preferences. When provided, recipients who have opted out of the specified topic and channel are excluded before the notification is dispatched. See Topic-based Opt-Out Filtering for Direct Notifications for the full filtering decision matrix.