Service - Notification Manager: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| (20 intermediate revisions by 2 users not shown) | |||
| Line 7: | Line 7: | ||
= Repository = | = Repository = | ||
https://bitbucket.org/ | https://bitbucket.org/izara-core-shared/izara-core-shared-notification-manager | ||
= | = Object Schemas = | ||
; Additional Information: [[Per Service Schemas]] | |||
=== | == objType == | ||
=== notificationGroup === | |||
* Groups many triggerGroups together | |||
<syntaxhighlight lang="JavaScript"> | <syntaxhighlight lang="JavaScript"> | ||
{ | { | ||
objectType: "notificationGroup", | |||
canDelete: false, | |||
storageResources: { | |||
myGraph: { | |||
storageType: "graph", | |||
graphServerTag: "GraphHandler" | |||
}, | |||
dynamoDB: { | |||
storageType: "dynamoDB", | |||
tableName: "NotificationGroupProcessing" | |||
} | |||
}, | |||
addOnDataStructure: [ | |||
{ | |||
type: "versionedData", | |||
versionedDataLabel: "notificationGroupSettings", | |||
storageResourceTag: "myGraph", | |||
fieldNames: { | |||
"notificationGroupName": { | |||
type: "string", | |||
requiredOnCreate: true, | |||
canUpdate: true, | |||
validation: { | |||
pattern: pattern | |||
} | |||
}, | |||
"consolidatedType": { | |||
type: "string", | |||
optionalOnCreate: true, | |||
requiredOnCreate: false, | |||
canUpdate: true, | |||
validation: { | |||
pattern: pattern | |||
} | |||
}, | |||
"consolidatedFrequency": { | |||
type: "number", | |||
optionalOnCreate: true, | |||
requiredOnCreate: false, | |||
canUpdate: true, | |||
validation: { | |||
pattern: pattern | |||
} | |||
}, | |||
"consolidatedSendIfEmpty": { | |||
type: "boolean", | |||
optionalOnCreate: true, | |||
requiredOnCreate: false, | |||
canUpdate: true, | |||
validation: { | |||
pattern: pattern | |||
} | |||
}, | |||
"consolidatedMessageCount": { | |||
type: "number", | |||
optionalOnCreate: true, | |||
requiredOnCreate: false, | |||
canUpdate: true, | |||
validation: { | |||
pattern: pattern | |||
} | |||
}, | |||
"consolidatedConfigs": { | |||
type: "array", | |||
optionalOnCreate: true, | |||
requiredOnCreate: false, | |||
canUpdate: true, | |||
validation: { | |||
pattern: pattern | |||
} | |||
} | |||
} | |||
} | |||
], | |||
fieldNames: { | |||
notificationGroupId: { | |||
type: "string", | |||
randomOnCreate: true, | |||
canUpdate: false, | |||
validation: { | |||
pattern: pattern | |||
}, | |||
storageResourceTags: ['myGraph', "dynamoDB"] | |||
}, | |||
consolidatedLastTimeSent: { | |||
type: "number", | |||
optionalOnCreate: true, | |||
canUpdate: true, | |||
validation: { | |||
pattern: pattern | |||
}, | |||
storageResourceTags: ["dynamoDB"] | |||
}, | |||
}, | |||
identifiers: [ | |||
{ | |||
type: "identifier", | |||
fieldName: "notificationGroupId" | |||
} | |||
] | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | ==== fieldNames ==== | ||
; notificationGroupId (identifier) | |||
: comes from: randomOnCreate | |||
; notificationGroupId | ; consolidatedLastTimeSent | ||
: start time for recurring or last time for send consolidated message | |||
: comes from: | |||
; | |||
: | |||
; notificationGroupName | ; notificationGroupName | ||
: string name set by | : string name set by user | ||
; consolidatedType | ; consolidatedType | ||
: | : none | recurring | messageCount | ||
: | : ''none'' is not consolidated, process immediately | ||
: ''recurring'' process at a specific frequency | |||
: ''messageCount'' process when a specific number of messages have been received | |||
; consolidatedFrequency | ; consolidatedFrequency | ||
: | : for consolidatedType = recurring, number of milliseconds between each processing | ||
; consolidatedSendIfEmpty | ; consolidatedSendIfEmpty | ||
: true | : setting for if have no consolidated message | ||
; | : true = send message out | ||
: | : false = not send message out | ||
; consolidatedMessageCount | |||
; | : send a consolidated message when the number of messages reaches | ||
: | ; consolidatedConfigs | ||
: pattern for message to send data in consolidated message | |||
== | === consolidated === | ||
<syntaxhighlight lang="JavaScript"> | |||
{ | |||
objectType: "consolidated", | |||
canDelete: false, | |||
storageResources: { | |||
dynamoDB: { | |||
storageType: "dynamoDB", | |||
tableName: "PendingConsolidation" | |||
} | |||
}, | |||
fieldNames: { | |||
notificationGroupId: { | |||
type: "string", | |||
canUpdate: false, | |||
storageResourceTags: ['dynamoDB'], | |||
fromObjType: { | |||
serviceTag: "NotificationManager", | |||
objectType: "notificationGroup" | |||
} | |||
}, | |||
checkedTriggerTime: { | |||
type: "string", | |||
requiredOnCreate: true, | |||
canUpdate: false, | |||
validation: { | |||
pattern: pattern | |||
}, | |||
storageResourceTags: ['dynamoDB'] | |||
}, | |||
activityMsg: { | |||
type: "object", | |||
requiredOnCreate: true, | |||
canUpdate: false, | |||
validation: { | |||
pattern: pattern | |||
}, | |||
storageResourceTags: ['dynamoDB'] | |||
}, | |||
flowTag: { | |||
type: "string", | |||
requiredOnCreate: true, | |||
canUpdate: false, | |||
validation: { | |||
pattern: pattern | |||
}, | |||
storageResourceTags: ['dynamoDB'] | |||
}, | |||
flowStep: { | |||
type: "string", | |||
requiredOnCreate: true, | |||
canUpdate: false, | |||
validation: { | |||
pattern: pattern | |||
}, | |||
storageResourceTags: ['dynamoDB'] | |||
} | |||
}, | |||
identifiers: [ | |||
{ | |||
type: "partitionKey", | |||
fieldName: "notificationGroupId" | |||
}, | |||
{ | |||
type: "sortKey", | |||
fieldName: "checkedTriggerTime" | |||
} | |||
] | |||
} | |||
</syntaxhighlight> | |||
==== fieldNames ==== | |||
; notificationGroupId (partition key) | |||
: comes from: randomOnCreate | |||
; | ; checkedTriggerTime (sort key) | ||
: | |||
: | |||
; | |||
: comes from {timestamp activity handled in Activity Switchboard}_{small random UUID} | : comes from {timestamp activity handled in Activity Switchboard}_{small random UUID} | ||
: adding the UUID to ensure no clashing records with the same timestamp and notificationGroupId | : adding the UUID to ensure no clashing records with the same timestamp and notificationGroupId | ||
; activityMsg | ; activityMsg | ||
: | : the message delivered from Activity Switchboard | ||
; flowTag | |||
: defines the consolidated configuration for the notification group | |||
; flowType | |||
: defines the consolidated configuration for the notification group | |||
= | == Object Relationships == | ||
=== ownsNotificationGroup === | |||
<syntaxhighlight lang="JavaScript"> | |||
{ | |||
"ownsNotificationGroup": { | |||
fieldNames: { | |||
"originTimestamp": { | |||
type: "number", | |||
requiredOnCreate: true, // default = false | |||
canUpdate: true, // default = true | |||
validation: {} // ajv syntax | |||
} | |||
}, | |||
storageResources: { | |||
myGraph: { | |||
storageType: "graph", | |||
graphServerTag: "GraphHandler" | |||
} | |||
}, | |||
links: [ | |||
{ | |||
storageResourceTags: ["myGraph"], | |||
from: { | |||
objType: { | |||
serviceTag: "UserAccount", | |||
objectType: "user" | |||
}, | |||
linkType: "one", | |||
}, | |||
to: { | |||
objType: { | |||
serviceTag: "NotificationManager", | |||
objectType: "notificationGroup" | |||
}, | |||
requiredOnCreate: true, | |||
linkType: "many", | |||
handler: true | |||
} | |||
} | |||
] | |||
} | |||
} | |||
</syntaxhighlight> | |||
: links the user to their created notification group | |||
=== hasTriggerGroup === | |||
<syntaxhighlight lang="JavaScript"> | |||
{ | |||
"hasTriggerGroup": { | |||
canChangeToRelTypes: [ | |||
{ | |||
serviceTag: "NotificationManager", | |||
relationshipTag: "disabledTriggerGroup" | |||
} | |||
], | |||
fieldNames: { | |||
"originTimestamp": { | |||
type: "number", // "string" | "number" ... | |||
requiredOnCreate: true, // default = false | |||
canUpdate: true, // default = true | |||
validation: {} // ajv syntax | |||
} | |||
}, | |||
storageResources: { | |||
myGraph: { | |||
storageType: "graph", | |||
graphServerTag: "GraphHandler" | |||
} | |||
}, | |||
links: [ | |||
{ | |||
storageResourceTags: ["myGraph"], | |||
from: { | |||
objType: { | |||
serviceTag: "NotificationManager", | |||
objectType: "notificationGroup" | |||
}, | |||
linkType: "many", | |||
handler: true | |||
}, | |||
to: { | |||
objType: { | |||
serviceTag: "ActivitySwitchboard", | |||
objectType: "triggerGroup" | |||
}, | |||
linkType: "many" | |||
} | |||
} | |||
] | |||
} | |||
} | |||
</syntaxhighlight> | |||
=== disabledTriggerGroup === | |||
<syntaxhighlight lang="JavaScript"> | <syntaxhighlight lang="JavaScript"> | ||
[ | { | ||
"disabledTriggerGroup": { | |||
canChangeToRelTypes: [ | |||
{ | |||
serviceTag: "NotificationManager", | |||
relationshipTag: "hasTriggerGroup" | |||
} | |||
], | |||
] | fieldNames: { | ||
"originTimestamp": { | |||
type: "number", // "string" | "number" ... | |||
requiredOnCreate: true, // default = false | |||
canUpdate: true, // default = true | |||
validation: {} // ajv syntax | |||
} | |||
}, | |||
storageResources: { | |||
myGraph: { | |||
storageType: "graph", | |||
graphServerTag: "GraphHandler" | |||
} | |||
}, | |||
links: [ | |||
{ | |||
storageResourceTags: ["myGraph"], | |||
from: { | |||
objType: { | |||
serviceTag: "NotificationManager", | |||
objectType: "notificationGroup" | |||
}, | |||
linkType: "many", | |||
handler: true | |||
}, | |||
to: { | |||
objType: { | |||
serviceTag: "ActivitySwitchboard", | |||
objectType: "triggerGroup" | |||
}, | |||
linkType: "many" | |||
} | |||
} | |||
] | |||
} | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== value or values array | = value or values array = | ||
* Either 'value' or 'values' should be set, not both, if 'values' is used it means any of the elements in the 'values' array can match. | |||
* To achieve this on Activity Switchboard a new trigger group is created for each element, each activity group has the full list of other triggers, and one option from this trigger's ''values'' array. If a notification has multiple ''values'' type triggers than a new trigger group on Activity Switchboard is created for each combination. | |||
* "serviceName" and "topicName" valueTypes do not have propertyName | |||
= serviceName and topicName triggers = | |||
* Notifications do not have to set their serviceName and/or topicName, if not set then any message that matches the properties will pass | |||
* Can set only the serviceName, then any message that passess the properties and is from that serviceName passes | |||
* Can set serviceName+topicName, then only messages in that topic will pass | |||
* serviceName and topicName can both be submitted as "values" array, creating multiple trigger groups for each combination | |||
= Consolidated notifications = | = Consolidated notifications = | ||
Latest revision as of 05:59, 11 September 2025
Overview
Consolidates and sends notifications to any number of receiver services. Will be used for user notifications but can have other types of receiver services added. Activities are received from Activity Switchboard service.
Notification groups set whether activities are considated (eg per day/per month/per x number of activities), if considated activities are stored here until sending is triggered, according to the considation rules. If not consolidated they are sent on immediately.
Repository
https://bitbucket.org/izara-core-shared/izara-core-shared-notification-manager
Object Schemas
- Additional Information
- Per Service Schemas
objType
notificationGroup
- Groups many triggerGroups together
{
objectType: "notificationGroup",
canDelete: false,
storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "GraphHandler"
},
dynamoDB: {
storageType: "dynamoDB",
tableName: "NotificationGroupProcessing"
}
},
addOnDataStructure: [
{
type: "versionedData",
versionedDataLabel: "notificationGroupSettings",
storageResourceTag: "myGraph",
fieldNames: {
"notificationGroupName": {
type: "string",
requiredOnCreate: true,
canUpdate: true,
validation: {
pattern: pattern
}
},
"consolidatedType": {
type: "string",
optionalOnCreate: true,
requiredOnCreate: false,
canUpdate: true,
validation: {
pattern: pattern
}
},
"consolidatedFrequency": {
type: "number",
optionalOnCreate: true,
requiredOnCreate: false,
canUpdate: true,
validation: {
pattern: pattern
}
},
"consolidatedSendIfEmpty": {
type: "boolean",
optionalOnCreate: true,
requiredOnCreate: false,
canUpdate: true,
validation: {
pattern: pattern
}
},
"consolidatedMessageCount": {
type: "number",
optionalOnCreate: true,
requiredOnCreate: false,
canUpdate: true,
validation: {
pattern: pattern
}
},
"consolidatedConfigs": {
type: "array",
optionalOnCreate: true,
requiredOnCreate: false,
canUpdate: true,
validation: {
pattern: pattern
}
}
}
}
],
fieldNames: {
notificationGroupId: {
type: "string",
randomOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph', "dynamoDB"]
},
consolidatedLastTimeSent: {
type: "number",
optionalOnCreate: true,
canUpdate: true,
validation: {
pattern: pattern
},
storageResourceTags: ["dynamoDB"]
},
},
identifiers: [
{
type: "identifier",
fieldName: "notificationGroupId"
}
]
}
fieldNames
- notificationGroupId (identifier)
- comes from: randomOnCreate
- consolidatedLastTimeSent
- start time for recurring or last time for send consolidated message
- notificationGroupName
- string name set by user
- consolidatedType
- none | recurring | messageCount
- none is not consolidated, process immediately
- recurring process at a specific frequency
- messageCount process when a specific number of messages have been received
- consolidatedFrequency
- for consolidatedType = recurring, number of milliseconds between each processing
- consolidatedSendIfEmpty
- setting for if have no consolidated message
- true = send message out
- false = not send message out
- consolidatedMessageCount
- send a consolidated message when the number of messages reaches
- consolidatedConfigs
- pattern for message to send data in consolidated message
consolidated
{
objectType: "consolidated",
canDelete: false,
storageResources: {
dynamoDB: {
storageType: "dynamoDB",
tableName: "PendingConsolidation"
}
},
fieldNames: {
notificationGroupId: {
type: "string",
canUpdate: false,
storageResourceTags: ['dynamoDB'],
fromObjType: {
serviceTag: "NotificationManager",
objectType: "notificationGroup"
}
},
checkedTriggerTime: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['dynamoDB']
},
activityMsg: {
type: "object",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['dynamoDB']
},
flowTag: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['dynamoDB']
},
flowStep: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['dynamoDB']
}
},
identifiers: [
{
type: "partitionKey",
fieldName: "notificationGroupId"
},
{
type: "sortKey",
fieldName: "checkedTriggerTime"
}
]
}
fieldNames
- notificationGroupId (partition key)
- comes from: randomOnCreate
- checkedTriggerTime (sort key)
- comes from {timestamp activity handled in Activity Switchboard}_{small random UUID}
- adding the UUID to ensure no clashing records with the same timestamp and notificationGroupId
- activityMsg
- the message delivered from Activity Switchboard
- flowTag
- defines the consolidated configuration for the notification group
- flowType
- defines the consolidated configuration for the notification group
Object Relationships
ownsNotificationGroup
{
"ownsNotificationGroup": {
fieldNames: {
"originTimestamp": {
type: "number",
requiredOnCreate: true, // default = false
canUpdate: true, // default = true
validation: {} // ajv syntax
}
},
storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "GraphHandler"
}
},
links: [
{
storageResourceTags: ["myGraph"],
from: {
objType: {
serviceTag: "UserAccount",
objectType: "user"
},
linkType: "one",
},
to: {
objType: {
serviceTag: "NotificationManager",
objectType: "notificationGroup"
},
requiredOnCreate: true,
linkType: "many",
handler: true
}
}
]
}
}
- links the user to their created notification group
hasTriggerGroup
{
"hasTriggerGroup": {
canChangeToRelTypes: [
{
serviceTag: "NotificationManager",
relationshipTag: "disabledTriggerGroup"
}
],
fieldNames: {
"originTimestamp": {
type: "number", // "string" | "number" ...
requiredOnCreate: true, // default = false
canUpdate: true, // default = true
validation: {} // ajv syntax
}
},
storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "GraphHandler"
}
},
links: [
{
storageResourceTags: ["myGraph"],
from: {
objType: {
serviceTag: "NotificationManager",
objectType: "notificationGroup"
},
linkType: "many",
handler: true
},
to: {
objType: {
serviceTag: "ActivitySwitchboard",
objectType: "triggerGroup"
},
linkType: "many"
}
}
]
}
}
disabledTriggerGroup
{
"disabledTriggerGroup": {
canChangeToRelTypes: [
{
serviceTag: "NotificationManager",
relationshipTag: "hasTriggerGroup"
}
],
fieldNames: {
"originTimestamp": {
type: "number", // "string" | "number" ...
requiredOnCreate: true, // default = false
canUpdate: true, // default = true
validation: {} // ajv syntax
}
},
storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "GraphHandler"
}
},
links: [
{
storageResourceTags: ["myGraph"],
from: {
objType: {
serviceTag: "NotificationManager",
objectType: "notificationGroup"
},
linkType: "many",
handler: true
},
to: {
objType: {
serviceTag: "ActivitySwitchboard",
objectType: "triggerGroup"
},
linkType: "many"
}
}
]
}
}
value or values array
- Either 'value' or 'values' should be set, not both, if 'values' is used it means any of the elements in the 'values' array can match.
- To achieve this on Activity Switchboard a new trigger group is created for each element, each activity group has the full list of other triggers, and one option from this trigger's values array. If a notification has multiple values type triggers than a new trigger group on Activity Switchboard is created for each combination.
- "serviceName" and "topicName" valueTypes do not have propertyName
serviceName and topicName triggers
- Notifications do not have to set their serviceName and/or topicName, if not set then any message that matches the properties will pass
- Can set only the serviceName, then any message that passess the properties and is from that serviceName passes
- Can set serviceName+topicName, then only messages in that topic will pass
- serviceName and topicName can both be submitted as "values" array, creating multiple trigger groups for each combination
Consolidated notifications
How to trigger processing for time based consolidations
- ....
- maybe can use some sort of queue to store a list of NotificationGroup’s that are due to be sent (either because consolidatedSendIfEmpty == true or there are some activities waiting to be processed)
Formating the notification body
- Initially the format will be hardwired and simple, but in the future we could create templates for formating the notification body
- The notificationBody is currently sent to receiver as a JSON stringified object containing all activityMsgs
Ideas
- overview notifications currently count per notification, but could be extended to do aggregates on a per notification, per field level
- If set to overview maybe can store just aggregate/s needed for the consolidated notification, at the moment store entire messages, create the overview once when sending notification