Merge pull request #30028 from FrankySpot/notifications/extend-model
feat(plugin/notifications) add generic attribute field to NotificationPayload
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-notifications-backend': patch
|
||||
'@backstage/plugin-notifications-common': minor
|
||||
---
|
||||
|
||||
Add an optional generic object `metadata` field to `NotificationPayload`. Metadata can be used to store additional unstructured data for the notification and are available to use by processors.
|
||||
@@ -211,10 +211,7 @@ export type NotificationPayload = {
|
||||
topic?: string;
|
||||
scope?: string;
|
||||
icon?: string;
|
||||
metadata?: Array<{
|
||||
type: string;
|
||||
value: JsonValue;
|
||||
}>;
|
||||
metadata?: { [KMetadataKey in string]?: JsonValue };
|
||||
};
|
||||
|
||||
export type Notification = {
|
||||
|
||||
@@ -210,3 +210,68 @@ notificationsApi.getNotification(yourId);
|
||||
// or with connection to signals:
|
||||
notificationsApi.getNotification(lastSignal.notification_id);
|
||||
```
|
||||
|
||||
## Metadata Field
|
||||
|
||||
The metadata field is a freeform object that is designed to be used by processors.
|
||||
|
||||
### Well-known Notification Metadata Fields
|
||||
|
||||
Below are metadata fields that will be commonly used between processors and have defined schematics.
|
||||
|
||||
#### backstage.io/body.markdown
|
||||
|
||||
```ts
|
||||
# Example:
|
||||
const payload = {
|
||||
title: 'Entities Require Attention',
|
||||
description: 'Entities: Service A, Service B'
|
||||
metadata: {
|
||||
'backstage.io/body.markdown': `
|
||||
# Entities
|
||||
- Service A
|
||||
- System B
|
||||
`
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This value of this metadata field should be the notification message in markdown format. This allows additional formatting options for processors that support markdown.
|
||||
|
||||
### Usage
|
||||
|
||||
Below is an example of using the `backstage.io/body.markdown` metadata field in a custom processor.
|
||||
|
||||
When sending a notification:
|
||||
|
||||
```ts
|
||||
notificationService.send({
|
||||
recipients: { type: 'entity', entityRef: 'group/default:team-a' },
|
||||
payload: {
|
||||
title: 'Notification',
|
||||
description: 'Description'
|
||||
metadata: {
|
||||
'backstage.io/body.markdown': `
|
||||
### Notification
|
||||
Description
|
||||
`,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
In the processor, you can then use the metadata field accordingly:
|
||||
|
||||
```ts
|
||||
async postProcess(notification: Notification): Promise<void> {
|
||||
// We suggest you parse the metadata field with a schema, i.e. Zod
|
||||
const parseResult = CustomProcessorMetadataSchema.safeParse(notification.payload.metadata ?? {});
|
||||
const metadata = parseResult.success ? parseResult.data : {};
|
||||
|
||||
customNotificationSender.send({
|
||||
to: getUsers(notification.recipients),
|
||||
subject: notification.payload.title,
|
||||
markdownText: metadata['backstage.io/body.markdown'] ?? notification.payload.description,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
@@ -241,6 +241,9 @@ describe.each(databases.eachSupportedId())('createRouter (%s)', databaseId => {
|
||||
},
|
||||
payload: {
|
||||
title: 'test notification',
|
||||
metadata: {
|
||||
attr: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -253,6 +256,9 @@ describe.each(databases.eachSupportedId())('createRouter (%s)', databaseId => {
|
||||
payload: {
|
||||
severity: 'normal',
|
||||
title: 'test notification',
|
||||
metadata: {
|
||||
attr: 1,
|
||||
},
|
||||
},
|
||||
user: 'user:default/mock',
|
||||
},
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"@material-ui/icons": "^4.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
```ts
|
||||
import { Config } from '@backstage/config';
|
||||
import { JsonValue } from '@backstage/types';
|
||||
|
||||
// @public (undocumented)
|
||||
export type ChannelSetting = {
|
||||
@@ -52,6 +53,9 @@ export type NotificationPayload = {
|
||||
topic?: string;
|
||||
scope?: string;
|
||||
icon?: string;
|
||||
metadata?: {
|
||||
[KMetadataKey in string]?: JsonValue;
|
||||
};
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { JsonValue } from '@backstage/types';
|
||||
|
||||
/** @public */
|
||||
export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low';
|
||||
|
||||
@@ -50,6 +52,10 @@ export type NotificationPayload = {
|
||||
* Optional notification icon
|
||||
*/
|
||||
icon?: string;
|
||||
/**
|
||||
* Optional additional customizable metadata.
|
||||
*/
|
||||
metadata?: { [KMetadataKey in string]?: JsonValue };
|
||||
};
|
||||
|
||||
/** @public */
|
||||
|
||||
Reference in New Issue
Block a user