@memberjunction/communication-engine 2.43.0 → 2.44.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/package.json +6 -6
- package/readme.md +280 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/communication-engine",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.44.0",
|
|
4
4
|
"description": "MemberJunction: Core Communication Framework Library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"typescript": "^5.4.5"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@memberjunction/global": "2.
|
|
23
|
-
"@memberjunction/core": "2.
|
|
24
|
-
"@memberjunction/templates": "2.
|
|
25
|
-
"@memberjunction/core-entities": "2.
|
|
26
|
-
"@memberjunction/communication-types": "2.
|
|
22
|
+
"@memberjunction/global": "2.44.0",
|
|
23
|
+
"@memberjunction/core": "2.44.0",
|
|
24
|
+
"@memberjunction/templates": "2.44.0",
|
|
25
|
+
"@memberjunction/core-entities": "2.44.0",
|
|
26
|
+
"@memberjunction/communication-types": "2.44.0",
|
|
27
27
|
"rxjs": "^7.8.1"
|
|
28
28
|
}
|
|
29
29
|
}
|
package/readme.md
CHANGED
|
@@ -1,5 +1,282 @@
|
|
|
1
|
-
# @memberjunction/communication-
|
|
1
|
+
# @memberjunction/communication-engine
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The MemberJunction Communication Engine provides a robust framework for sending messages through various communication providers (email, SMS, etc.) with template support and comprehensive logging.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package serves as the core engine for the MemberJunction communication system, providing:
|
|
8
|
+
|
|
9
|
+
- **Provider-agnostic message sending**: Support for multiple communication providers through a plugin architecture
|
|
10
|
+
- **Template integration**: Seamless integration with the MemberJunction template system for dynamic message content
|
|
11
|
+
- **Message processing**: Automatic template rendering with context data
|
|
12
|
+
- **Communication runs**: Batch message sending with transaction-like run management
|
|
13
|
+
- **Comprehensive logging**: Built-in logging of all communication attempts
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @memberjunction/communication-engine
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Core Components
|
|
22
|
+
|
|
23
|
+
### CommunicationEngine
|
|
24
|
+
|
|
25
|
+
The main class that orchestrates all communication operations. It follows a singleton pattern and manages providers, message sending, and logging.
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { CommunicationEngine } from '@memberjunction/communication-engine';
|
|
29
|
+
|
|
30
|
+
// Get the singleton instance
|
|
31
|
+
const engine = CommunicationEngine.Instance;
|
|
32
|
+
|
|
33
|
+
// Configuration must be called before use
|
|
34
|
+
await engine.Config();
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### ProcessedMessageServer
|
|
38
|
+
|
|
39
|
+
Server-side message processor that handles template rendering for message bodies, HTML bodies, and subjects.
|
|
40
|
+
|
|
41
|
+
## Usage Examples
|
|
42
|
+
|
|
43
|
+
### Sending a Single Message
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { CommunicationEngine } from '@memberjunction/communication-engine';
|
|
47
|
+
import { Message } from '@memberjunction/communication-types';
|
|
48
|
+
|
|
49
|
+
// Create a message
|
|
50
|
+
const message = new Message();
|
|
51
|
+
message.Subject = 'Welcome to MemberJunction';
|
|
52
|
+
message.Body = 'Thank you for joining!';
|
|
53
|
+
message.To = 'user@example.com';
|
|
54
|
+
message.From = 'noreply@memberjunction.com';
|
|
55
|
+
|
|
56
|
+
// Send using a specific provider
|
|
57
|
+
const result = await CommunicationEngine.Instance.SendSingleMessage(
|
|
58
|
+
'SendGrid', // Provider name
|
|
59
|
+
'Email', // Provider message type
|
|
60
|
+
message
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
if (result.Success) {
|
|
64
|
+
console.log('Message sent successfully');
|
|
65
|
+
} else {
|
|
66
|
+
console.error('Failed to send:', result.Error);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Sending Messages with Templates
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { CommunicationEngine } from '@memberjunction/communication-engine';
|
|
74
|
+
import { Message } from '@memberjunction/communication-types';
|
|
75
|
+
import { Metadata } from '@memberjunction/core';
|
|
76
|
+
|
|
77
|
+
// Get template from metadata
|
|
78
|
+
const md = new Metadata();
|
|
79
|
+
const template = await md.GetEntityObject('Templates');
|
|
80
|
+
await template.LoadByName('Welcome Email');
|
|
81
|
+
|
|
82
|
+
// Create message with template
|
|
83
|
+
const message = new Message();
|
|
84
|
+
message.BodyTemplate = template;
|
|
85
|
+
message.To = 'user@example.com';
|
|
86
|
+
message.From = 'noreply@memberjunction.com';
|
|
87
|
+
message.ContextData = {
|
|
88
|
+
firstName: 'John',
|
|
89
|
+
accountType: 'Premium',
|
|
90
|
+
activationDate: new Date()
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// Send the message - templates will be automatically processed
|
|
94
|
+
const result = await CommunicationEngine.Instance.SendSingleMessage(
|
|
95
|
+
'SendGrid',
|
|
96
|
+
'Email',
|
|
97
|
+
message
|
|
98
|
+
);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Batch Message Sending
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { CommunicationEngine } from '@memberjunction/communication-engine';
|
|
105
|
+
import { Message, MessageRecipient } from '@memberjunction/communication-types';
|
|
106
|
+
|
|
107
|
+
// Create base message
|
|
108
|
+
const baseMessage = new Message();
|
|
109
|
+
baseMessage.Subject = 'Monthly Newsletter';
|
|
110
|
+
baseMessage.BodyTemplate = newsletterTemplate;
|
|
111
|
+
baseMessage.From = 'newsletter@memberjunction.com';
|
|
112
|
+
|
|
113
|
+
// Create recipient list with individual context data
|
|
114
|
+
const recipients: MessageRecipient[] = [
|
|
115
|
+
{
|
|
116
|
+
To: 'user1@example.com',
|
|
117
|
+
ContextData: { name: 'Alice', memberSince: '2023' }
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
To: 'user2@example.com',
|
|
121
|
+
ContextData: { name: 'Bob', memberSince: '2022' }
|
|
122
|
+
}
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
// Send to all recipients
|
|
126
|
+
const results = await CommunicationEngine.Instance.SendMessages(
|
|
127
|
+
'SendGrid',
|
|
128
|
+
'Email',
|
|
129
|
+
baseMessage,
|
|
130
|
+
recipients
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// Check results
|
|
134
|
+
results.forEach((result, index) => {
|
|
135
|
+
if (result.Success) {
|
|
136
|
+
console.log(`Sent to ${recipients[index].To}`);
|
|
137
|
+
} else {
|
|
138
|
+
console.error(`Failed for ${recipients[index].To}: ${result.Error}`);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Preview Mode
|
|
144
|
+
|
|
145
|
+
You can preview processed messages without actually sending them:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const result = await CommunicationEngine.Instance.SendSingleMessage(
|
|
149
|
+
'SendGrid',
|
|
150
|
+
'Email',
|
|
151
|
+
message,
|
|
152
|
+
undefined, // No communication run
|
|
153
|
+
true // Preview only
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
if (result.Success) {
|
|
157
|
+
const processedMessage = result.Message;
|
|
158
|
+
console.log('Subject:', processedMessage.ProcessedSubject);
|
|
159
|
+
console.log('Body:', processedMessage.ProcessedBody);
|
|
160
|
+
console.log('HTML Body:', processedMessage.ProcessedHTMLBody);
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Working with Providers
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// Get a specific provider instance
|
|
168
|
+
const provider = CommunicationEngine.Instance.GetProvider('SendGrid');
|
|
169
|
+
|
|
170
|
+
// List all available providers
|
|
171
|
+
const providers = CommunicationEngine.Instance.Providers;
|
|
172
|
+
providers.forEach(p => {
|
|
173
|
+
console.log(`Provider: ${p.Name}`);
|
|
174
|
+
p.MessageTypes.forEach(mt => {
|
|
175
|
+
console.log(` - ${mt.Name}`);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## API Reference
|
|
181
|
+
|
|
182
|
+
### CommunicationEngine
|
|
183
|
+
|
|
184
|
+
#### Properties
|
|
185
|
+
|
|
186
|
+
- `Instance: CommunicationEngine` - Static singleton instance
|
|
187
|
+
- `Providers: CommunicationProviderEntity[]` - List of configured providers
|
|
188
|
+
- `Loaded: boolean` - Whether metadata has been loaded
|
|
189
|
+
|
|
190
|
+
#### Methods
|
|
191
|
+
|
|
192
|
+
##### `Config(contextUser?: UserInfo): Promise<void>`
|
|
193
|
+
Initializes the engine with metadata. Must be called before using other methods.
|
|
194
|
+
|
|
195
|
+
##### `GetProvider(providerName: string): BaseCommunicationProvider`
|
|
196
|
+
Returns an instance of the specified communication provider.
|
|
197
|
+
|
|
198
|
+
##### `SendSingleMessage(providerName: string, providerMessageTypeName: string, message: Message, run?: CommunicationRunEntity, previewOnly?: boolean): Promise<MessageResult>`
|
|
199
|
+
Sends a single message using the specified provider.
|
|
200
|
+
|
|
201
|
+
Parameters:
|
|
202
|
+
- `providerName`: Name of the provider (e.g., 'SendGrid', 'Twilio')
|
|
203
|
+
- `providerMessageTypeName`: Type of message for the provider (e.g., 'Email', 'SMS')
|
|
204
|
+
- `message`: The message to send
|
|
205
|
+
- `run`: Optional communication run for grouping messages
|
|
206
|
+
- `previewOnly`: If true, processes templates but doesn't send
|
|
207
|
+
|
|
208
|
+
##### `SendMessages(providerName: string, providerMessageTypeName: string, message: Message, recipients: MessageRecipient[], previewOnly?: boolean): Promise<MessageResult[]>`
|
|
209
|
+
Sends messages to multiple recipients in a single run.
|
|
210
|
+
|
|
211
|
+
### ProcessedMessageServer
|
|
212
|
+
|
|
213
|
+
#### Methods
|
|
214
|
+
|
|
215
|
+
##### `Process(forceTemplateRefresh?: boolean, contextUser?: UserInfo): Promise<{Success: boolean, Message?: string}>`
|
|
216
|
+
Processes all templates in the message and populates the processed fields.
|
|
217
|
+
|
|
218
|
+
## Template Processing
|
|
219
|
+
|
|
220
|
+
The engine automatically processes templates in the following order:
|
|
221
|
+
|
|
222
|
+
1. **Body Template**:
|
|
223
|
+
- Renders 'Text' content type for `ProcessedBody`
|
|
224
|
+
- Renders 'HTML' content type for `ProcessedHTMLBody` (if no separate HTML template)
|
|
225
|
+
|
|
226
|
+
2. **HTML Body Template**:
|
|
227
|
+
- Renders 'HTML' content type for `ProcessedHTMLBody`
|
|
228
|
+
|
|
229
|
+
3. **Subject Template**:
|
|
230
|
+
- Renders 'HTML' content type for `ProcessedSubject`
|
|
231
|
+
|
|
232
|
+
Context data passed in the message is available to all templates during rendering.
|
|
233
|
+
|
|
234
|
+
## Error Handling
|
|
235
|
+
|
|
236
|
+
The engine provides detailed error messages for common scenarios:
|
|
237
|
+
|
|
238
|
+
- Provider not found
|
|
239
|
+
- Provider message type not found
|
|
240
|
+
- Template rendering failures
|
|
241
|
+
- Communication run failures
|
|
242
|
+
- Missing required template content types
|
|
243
|
+
|
|
244
|
+
Always wrap communication calls in try-catch blocks:
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
try {
|
|
248
|
+
const result = await CommunicationEngine.Instance.SendSingleMessage(...);
|
|
249
|
+
if (!result.Success) {
|
|
250
|
+
// Handle send failure
|
|
251
|
+
console.error(result.Error);
|
|
252
|
+
}
|
|
253
|
+
} catch (error) {
|
|
254
|
+
// Handle engine errors
|
|
255
|
+
console.error('Engine error:', error.message);
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Dependencies
|
|
260
|
+
|
|
261
|
+
- `@memberjunction/global`: Core MemberJunction utilities
|
|
262
|
+
- `@memberjunction/core`: Core MemberJunction functionality
|
|
263
|
+
- `@memberjunction/templates`: Template engine integration
|
|
264
|
+
- `@memberjunction/core-entities`: Entity definitions
|
|
265
|
+
- `@memberjunction/communication-types`: Type definitions
|
|
266
|
+
- `rxjs`: Reactive Extensions for JavaScript
|
|
267
|
+
|
|
268
|
+
## Integration with Other MJ Packages
|
|
269
|
+
|
|
270
|
+
This package integrates seamlessly with:
|
|
271
|
+
|
|
272
|
+
- **@memberjunction/templates**: For dynamic content generation
|
|
273
|
+
- **@memberjunction/core-entities**: For communication logging entities
|
|
274
|
+
- **Provider packages**: Such as `@memberjunction/communication-sendgrid`, `@memberjunction/communication-twilio`
|
|
275
|
+
|
|
276
|
+
## Provider Implementation
|
|
277
|
+
|
|
278
|
+
To implement a custom provider, extend `BaseCommunicationProvider` from `@memberjunction/communication-types` and register it with the MemberJunction class factory using the `@RegisterClass` decorator.
|
|
279
|
+
|
|
280
|
+
## License
|
|
281
|
+
|
|
282
|
+
ISC
|