@memberjunction/notifications 4.0.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -0
- package/package.json +8 -8
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# @memberjunction/notifications
|
|
2
|
+
|
|
3
|
+
Unified notification engine for MemberJunction that handles in-app, email, and SMS delivery based on notification types and user preferences. This server-side package coordinates between the MJ entity system, template engine, and communication engine to deliver notifications through the appropriate channels.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
graph TD
|
|
9
|
+
subgraph notif["@memberjunction/notifications"]
|
|
10
|
+
NE["NotificationEngine\n(Singleton)"]
|
|
11
|
+
TYPES["SendNotificationParams\nNotificationResult\nDeliveryChannels"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
subgraph entities["MJ Entity System"]
|
|
15
|
+
UNT["UserNotificationTypes"]
|
|
16
|
+
UNP["UserNotificationPreferences"]
|
|
17
|
+
UNN["UserNotifications\n(In-App Records)"]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
subgraph comm["@memberjunction/communication-engine"]
|
|
21
|
+
CE["CommunicationEngine"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subgraph templates["@memberjunction/templates"]
|
|
25
|
+
TE["TemplateEngineServer"]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
subgraph providers["Delivery Channels"]
|
|
29
|
+
INAPP["In-App\n(Database Record)"]
|
|
30
|
+
EMAIL["Email\n(via SendGrid)"]
|
|
31
|
+
SMS["SMS\n(via Twilio)"]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
NE -->|reads types| UNT
|
|
35
|
+
NE -->|checks prefs| UNP
|
|
36
|
+
NE -->|creates| UNN
|
|
37
|
+
NE -->|sends via| CE
|
|
38
|
+
CE -->|renders| TE
|
|
39
|
+
UNN --> INAPP
|
|
40
|
+
CE --> EMAIL
|
|
41
|
+
CE --> SMS
|
|
42
|
+
|
|
43
|
+
style notif fill:#7c5295,stroke:#563a6b,color:#fff
|
|
44
|
+
style entities fill:#2d6a9f,stroke:#1a4971,color:#fff
|
|
45
|
+
style comm fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
46
|
+
style templates fill:#b8762f,stroke:#8a5722,color:#fff
|
|
47
|
+
style providers fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install @memberjunction/notifications
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
### Sending a Notification
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { NotificationEngine } from '@memberjunction/notifications';
|
|
62
|
+
import { SendNotificationParams } from '@memberjunction/notifications';
|
|
63
|
+
|
|
64
|
+
const engine = NotificationEngine.Instance;
|
|
65
|
+
await engine.Config(false, contextUser);
|
|
66
|
+
|
|
67
|
+
const params: SendNotificationParams = {
|
|
68
|
+
userId: 'user-uuid',
|
|
69
|
+
typeNameOrId: 'Agent Completion',
|
|
70
|
+
title: 'Agent Run Finished',
|
|
71
|
+
message: 'Your AI agent has completed processing.',
|
|
72
|
+
templateData: {
|
|
73
|
+
agentName: 'Data Analyzer',
|
|
74
|
+
duration: '2m 34s'
|
|
75
|
+
},
|
|
76
|
+
resourceTypeId: 'resource-type-uuid',
|
|
77
|
+
resourceRecordId: 'agent-run-uuid',
|
|
78
|
+
resourceConfiguration: { conversationId: 'conv-uuid' }
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const result = await engine.SendNotification(params, contextUser);
|
|
82
|
+
|
|
83
|
+
if (result.success) {
|
|
84
|
+
console.log('Channels used:', result.deliveryChannels);
|
|
85
|
+
// { inApp: true, email: true, sms: false }
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Forcing Delivery Channels
|
|
90
|
+
|
|
91
|
+
Override user preferences and type defaults by specifying exact channels:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const result = await engine.SendNotification({
|
|
95
|
+
userId: 'user-uuid',
|
|
96
|
+
typeNameOrId: 'System Alert',
|
|
97
|
+
title: 'Critical Error',
|
|
98
|
+
message: 'Database connection lost',
|
|
99
|
+
forceDeliveryChannels: {
|
|
100
|
+
inApp: true,
|
|
101
|
+
email: true,
|
|
102
|
+
sms: true
|
|
103
|
+
}
|
|
104
|
+
}, contextUser);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Channel Resolution Logic
|
|
108
|
+
|
|
109
|
+
```mermaid
|
|
110
|
+
flowchart TD
|
|
111
|
+
START["SendNotification()"] --> FORCE{"forceDeliveryChannels\nspecified?"}
|
|
112
|
+
FORCE -->|Yes| USE_FORCE["Use forced channels directly"]
|
|
113
|
+
FORCE -->|No| CHECK_PREFS{"User preference\nexists?"}
|
|
114
|
+
CHECK_PREFS -->|Yes| CHECK_ENABLED{"Preference\nenabled?"}
|
|
115
|
+
CHECK_ENABLED -->|No| ALL_OFF["All channels disabled\n(user opted out)"]
|
|
116
|
+
CHECK_ENABLED -->|Yes| CHECK_ALLOW{"Type allows\nuser preference?"}
|
|
117
|
+
CHECK_ALLOW -->|Yes| USE_PREFS["Use user preference\nper-channel settings"]
|
|
118
|
+
CHECK_ALLOW -->|No| USE_DEFAULTS["Use type defaults"]
|
|
119
|
+
CHECK_PREFS -->|No| USE_DEFAULTS
|
|
120
|
+
|
|
121
|
+
style START fill:#2d6a9f,stroke:#1a4971,color:#fff
|
|
122
|
+
style USE_FORCE fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
123
|
+
style USE_PREFS fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
124
|
+
style USE_DEFAULTS fill:#b8762f,stroke:#8a5722,color:#fff
|
|
125
|
+
style ALL_OFF fill:#7c5295,stroke:#563a6b,color:#fff
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The engine resolves delivery channels with this priority:
|
|
129
|
+
|
|
130
|
+
1. **Force override**: If `forceDeliveryChannels` is set, use it directly
|
|
131
|
+
2. **User opt-out**: If user preference exists but `Enabled` is false, all channels are disabled
|
|
132
|
+
3. **User preference**: If the notification type allows user preferences, use per-channel settings (`InAppEnabled`, `EmailEnabled`, `SMSEnabled`)
|
|
133
|
+
4. **Type defaults**: Fall back to `DefaultInApp`, `DefaultEmail`, `DefaultSMS` from the notification type
|
|
134
|
+
|
|
135
|
+
## Delivery Channels
|
|
136
|
+
|
|
137
|
+
| Channel | How It Works |
|
|
138
|
+
|---------|-------------|
|
|
139
|
+
| **In-App** | Creates a `UserNotification` entity record in the database. Synchronous, instant. |
|
|
140
|
+
| **Email** | Renders the notification type's `EmailTemplateID` via `TemplateEngineServer`, then sends through `CommunicationEngine` using SendGrid. Fire-and-forget (async). |
|
|
141
|
+
| **SMS** | Renders the notification type's `SMSTemplateID` via `TemplateEngineServer`, then sends through `CommunicationEngine` using Twilio. Fire-and-forget (async). |
|
|
142
|
+
|
|
143
|
+
## Type Definitions
|
|
144
|
+
|
|
145
|
+
### SendNotificationParams
|
|
146
|
+
|
|
147
|
+
| Property | Type | Required | Description |
|
|
148
|
+
|----------|------|----------|-------------|
|
|
149
|
+
| `userId` | `string` | Yes | Target user ID |
|
|
150
|
+
| `typeNameOrId` | `string` | Yes | Notification type name or UUID |
|
|
151
|
+
| `title` | `string` | Yes | Short title (in-app display, email subject) |
|
|
152
|
+
| `message` | `string` | Yes | Full notification message |
|
|
153
|
+
| `templateData` | `Record<string, unknown>` | No | Data for email/SMS template rendering |
|
|
154
|
+
| `resourceTypeId` | `string` | No | Link notification to a resource type |
|
|
155
|
+
| `resourceRecordId` | `string` | No | Link notification to a specific record |
|
|
156
|
+
| `resourceConfiguration` | `object` | No | Navigation context stored as JSON |
|
|
157
|
+
| `forceDeliveryChannels` | `DeliveryChannels` | No | Override channel resolution |
|
|
158
|
+
|
|
159
|
+
### NotificationResult
|
|
160
|
+
|
|
161
|
+
| Property | Type | Description |
|
|
162
|
+
|----------|------|-------------|
|
|
163
|
+
| `success` | `boolean` | Overall operation success |
|
|
164
|
+
| `inAppNotificationId` | `string` | ID of created in-app notification |
|
|
165
|
+
| `emailSent` | `boolean` | Whether email delivery was initiated |
|
|
166
|
+
| `smsSent` | `boolean` | Whether SMS delivery was initiated |
|
|
167
|
+
| `deliveryChannels` | `DeliveryChannels` | Resolved channels used |
|
|
168
|
+
| `errors` | `string[]` | Error messages if any |
|
|
169
|
+
|
|
170
|
+
### DeliveryChannels
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
interface DeliveryChannels {
|
|
174
|
+
inApp: boolean;
|
|
175
|
+
email: boolean;
|
|
176
|
+
sms: boolean;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Dependencies
|
|
181
|
+
|
|
182
|
+
| Package | Purpose |
|
|
183
|
+
|---------|---------|
|
|
184
|
+
| `@memberjunction/core` | BaseEngine, Metadata, UserInfo, logging |
|
|
185
|
+
| `@memberjunction/core-entities` | UserNotification, UserNotificationType entities |
|
|
186
|
+
| `@memberjunction/communication-engine` | CommunicationEngine for email/SMS delivery |
|
|
187
|
+
| `@memberjunction/communication-types` | Message class |
|
|
188
|
+
| `@memberjunction/templates` | TemplateEngineServer for rendering |
|
|
189
|
+
| `@memberjunction/sqlserver-dataprovider` | UserCache for server-side user lookup |
|
|
190
|
+
|
|
191
|
+
## Development
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm run build # Compile TypeScript
|
|
195
|
+
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/notifications",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.2.0",
|
|
5
5
|
"description": "MemberJunction: Unified Notification System with Multi-Channel Delivery",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"typescript": "^5.9.3"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@memberjunction/global": "4.
|
|
24
|
-
"@memberjunction/core": "4.
|
|
25
|
-
"@memberjunction/core-entities": "4.
|
|
26
|
-
"@memberjunction/templates": "4.
|
|
27
|
-
"@memberjunction/communication-engine": "4.
|
|
28
|
-
"@memberjunction/communication-types": "4.
|
|
29
|
-
"@memberjunction/sqlserver-dataprovider": "4.
|
|
23
|
+
"@memberjunction/global": "4.2.0",
|
|
24
|
+
"@memberjunction/core": "4.2.0",
|
|
25
|
+
"@memberjunction/core-entities": "4.2.0",
|
|
26
|
+
"@memberjunction/templates": "4.2.0",
|
|
27
|
+
"@memberjunction/communication-engine": "4.2.0",
|
|
28
|
+
"@memberjunction/communication-types": "4.2.0",
|
|
29
|
+
"@memberjunction/sqlserver-dataprovider": "4.2.0"
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|