@memberjunction/communication-types 4.0.0 → 4.1.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.
Files changed (2) hide show
  1. package/README.md +194 -272
  2. package/package.json +5 -5
package/README.md CHANGED
@@ -1,10 +1,43 @@
1
1
  # @memberjunction/communication-types
2
2
 
3
- MemberJunction Communication Framework Library Generic Types - Base types and interfaces for building communication providers and engines in the MemberJunction ecosystem.
4
-
5
- ## Overview
6
-
7
- This package provides the foundational types, base classes, and interfaces for implementing communication functionality within MemberJunction applications. It includes base classes for communication engines and providers, message handling, and integration with the MemberJunction metadata system.
3
+ Core types, interfaces, and abstract base classes for the MemberJunction Communication Framework. This package defines the contract that all communication providers must implement, along with shared message types, credential utilities, and the communication engine base class.
4
+
5
+ ## Architecture
6
+
7
+ ```mermaid
8
+ graph TD
9
+ subgraph base["@memberjunction/communication-types"]
10
+ ENGINE["CommunicationEngineBase"]
11
+ BCP["BaseCommunicationProvider"]
12
+ MSG["Message / ProcessedMessage"]
13
+ CRED["Credential Utilities"]
14
+ TYPES["Params and Result Types"]
15
+ end
16
+
17
+ subgraph providers["Provider Implementations"]
18
+ SG["SendGrid Provider"]
19
+ GM["Gmail Provider"]
20
+ TW["Twilio Provider"]
21
+ MSP["MS Graph Provider"]
22
+ end
23
+
24
+ subgraph engine["@memberjunction/communication-engine"]
25
+ CE["CommunicationEngine"]
26
+ end
27
+
28
+ ENGINE --> CE
29
+ BCP --> SG
30
+ BCP --> GM
31
+ BCP --> TW
32
+ BCP --> MSP
33
+ MSG --> BCP
34
+ CRED --> BCP
35
+ TYPES --> BCP
36
+
37
+ style base fill:#2d6a9f,stroke:#1a4971,color:#fff
38
+ style providers fill:#2d8659,stroke:#1a5c3a,color:#fff
39
+ style engine fill:#7c5295,stroke:#563a6b,color:#fff
40
+ ```
8
41
 
9
42
  ## Installation
10
43
 
@@ -12,331 +45,220 @@ This package provides the foundational types, base classes, and interfaces for i
12
45
  npm install @memberjunction/communication-types
13
46
  ```
14
47
 
15
- ## Key Components
48
+ ## Key Exports
16
49
 
17
50
  ### CommunicationEngineBase
18
51
 
19
- The core engine class that manages communication metadata and orchestrates communication operations across different providers.
52
+ Singleton base class that loads communication metadata (providers, message types, entity communication fields) and provides lifecycle management for communication runs and logs.
20
53
 
21
54
  ```typescript
22
55
  import { CommunicationEngineBase } from '@memberjunction/communication-types';
23
56
 
24
- // Get the singleton instance
25
57
  const engine = CommunicationEngineBase.Instance;
58
+ await engine.Config(false, contextUser);
26
59
 
27
- // Configure the engine (required before use)
28
- await engine.Config(false, userInfo);
29
-
30
- // Access communication metadata
31
- const providers = engine.Providers;
32
- const messageTypes = engine.BaseMessageTypes;
60
+ // Access loaded metadata
61
+ const providers = engine.Providers; // CommunicationProviderEntityExtended[]
62
+ const messageTypes = engine.BaseMessageTypes; // CommunicationBaseMessageTypeEntity[]
33
63
  ```
34
64
 
35
65
  ### BaseCommunicationProvider
36
66
 
37
- Abstract base class for implementing communication providers (email, SMS, social media, etc.).
38
-
39
- ```typescript
40
- import { BaseCommunicationProvider, ProcessedMessage, MessageResult } from '@memberjunction/communication-types';
41
-
42
- export class MyEmailProvider extends BaseCommunicationProvider {
43
- public async SendSingleMessage(message: ProcessedMessage): Promise<MessageResult> {
44
- // Implement provider-specific sending logic
67
+ Abstract base class that all communication providers must extend. Defines both core operations (must implement) and extended mailbox operations (optional override).
68
+
69
+ ```mermaid
70
+ classDiagram
71
+ class BaseCommunicationProvider {
72
+ <<abstract>>
73
+ +SendSingleMessage(message, credentials?) MessageResult
74
+ +GetMessages(params, credentials?) GetMessagesResult
75
+ +ForwardMessage(params, credentials?) ForwardMessageResult
76
+ +ReplyToMessage(params, credentials?) ReplyToMessageResult
77
+ +CreateDraft(params, credentials?) CreateDraftResult
78
+ +getSupportedOperations() ProviderOperation[]
79
+ +supportsOperation(op) boolean
80
+ +GetSingleMessage() GetSingleMessageResult
81
+ +DeleteMessage() DeleteMessageResult
82
+ +MoveMessage() MoveMessageResult
83
+ +ListFolders() ListFoldersResult
84
+ +MarkAsRead() MarkAsReadResult
85
+ +ArchiveMessage() ArchiveMessageResult
86
+ +SearchMessages() SearchMessagesResult
87
+ +ListAttachments() ListAttachmentsResult
88
+ +DownloadAttachment() DownloadAttachmentResult
45
89
  }
46
90
 
47
- public async GetMessages(params: GetMessagesParams): Promise<GetMessagesResult> {
48
- // Implement message retrieval
91
+ class SendGridProvider {
92
+ SendSingleMessage only
49
93
  }
50
-
51
- public async ForwardMessage(params: ForwardMessageParams): Promise<ForwardMessageResult> {
52
- // Implement message forwarding
94
+ class GmailProvider {
95
+ All 14 operations
53
96
  }
54
-
55
- public async ReplyToMessage(params: ReplyToMessageParams): Promise<ReplyToMessageResult> {
56
- // Implement message replies
97
+ class MSGraphProvider {
98
+ All 14 operations
57
99
  }
58
-
59
- public async CreateDraft(params: CreateDraftParams): Promise<CreateDraftResult> {
60
- // Implement draft creation (or return error if not supported)
100
+ class TwilioProvider {
101
+ Send Get Forward Reply
61
102
  }
62
- }
63
- ```
64
-
65
- ### Message Classes
66
-
67
- #### Message
68
- Base class for message data:
69
-
70
- ```typescript
71
- import { Message } from '@memberjunction/communication-types';
72
-
73
- const message = new Message();
74
- message.From = "sender@example.com";
75
- message.To = "recipient@example.com";
76
- message.Subject = "Hello";
77
- message.Body = "Message content";
78
- message.HTMLBody = "<p>HTML content</p>";
79
-
80
- // Using templates
81
- message.BodyTemplate = templateEntity;
82
- message.SubjectTemplate = subjectTemplateEntity;
83
- message.ContextData = { name: "John", company: "Acme Corp" };
84
- ```
85
103
 
86
- #### ProcessedMessage
87
- Abstract class for messages that have been processed (templates rendered, etc.):
104
+ BaseCommunicationProvider <|-- SendGridProvider
105
+ BaseCommunicationProvider <|-- GmailProvider
106
+ BaseCommunicationProvider <|-- MSGraphProvider
107
+ BaseCommunicationProvider <|-- TwilioProvider
88
108
 
89
- ```typescript
90
- export class MyProcessedMessage extends ProcessedMessage {
91
- public async Process(forceTemplateRefresh?: boolean, contextUser?: UserInfo): Promise<{Success: boolean, Message?: string}> {
92
- // Implement template processing logic
93
- this.ProcessedBody = // processed body
94
- this.ProcessedHTMLBody = // processed HTML
95
- this.ProcessedSubject = // processed subject
96
- return { Success: true };
97
- }
98
- }
109
+ style BaseCommunicationProvider fill:#2d6a9f,stroke:#1a4971,color:#fff
110
+ style SendGridProvider fill:#b8762f,stroke:#8a5722,color:#fff
111
+ style GmailProvider fill:#2d8659,stroke:#1a5c3a,color:#fff
112
+ style MSGraphProvider fill:#2d8659,stroke:#1a5c3a,color:#fff
113
+ style TwilioProvider fill:#7c5295,stroke:#563a6b,color:#fff
99
114
  ```
100
115
 
101
- #### MessageRecipient
102
- Information about a message recipient:
116
+ #### Core Operations (Abstract -- Must Implement)
103
117
 
104
- ```typescript
105
- import { MessageRecipient } from '@memberjunction/communication-types';
118
+ | Method | Description |
119
+ |--------|-------------|
120
+ | `SendSingleMessage()` | Send a single message through the provider |
121
+ | `GetMessages()` | Retrieve messages from the provider |
122
+ | `ForwardMessage()` | Forward a message to new recipients |
123
+ | `ReplyToMessage()` | Reply to an existing message |
124
+ | `CreateDraft()` | Create a draft message (return error if unsupported) |
106
125
 
107
- const recipient = new MessageRecipient();
108
- recipient.To = "user@example.com";
109
- recipient.FullName = "John Doe";
110
- recipient.ContextData = { customField: "value" };
111
- ```
126
+ #### Extended Operations (Optional -- Override to Support)
112
127
 
113
- ## Types and Interfaces
128
+ These methods have default implementations that return "not supported" errors. Override them in providers that have full mailbox access.
114
129
 
115
- ### GetMessagesParams
116
- Parameters for retrieving messages:
130
+ | Method | Description |
131
+ |--------|-------------|
132
+ | `GetSingleMessage()` | Retrieve a single message by ID |
133
+ | `DeleteMessage()` | Delete or trash a message |
134
+ | `MoveMessage()` | Move a message to a different folder |
135
+ | `ListFolders()` | List available folders/labels |
136
+ | `MarkAsRead()` | Mark messages as read or unread |
137
+ | `ArchiveMessage()` | Archive a message |
138
+ | `SearchMessages()` | Search messages by query string |
139
+ | `ListAttachments()` | List attachments on a message |
140
+ | `DownloadAttachment()` | Download an attachment by ID |
117
141
 
118
- ```typescript
119
- type GetMessagesParams<T = Record<string, any>> = {
120
- NumMessages: number;
121
- UnreadOnly?: boolean;
122
- ContextData?: T;
123
- };
124
- ```
125
-
126
- ### GetMessagesResult
127
- Result structure for retrieved messages:
142
+ #### Capability Discovery
128
143
 
129
144
  ```typescript
130
- type GetMessagesResult<T = Record<string, any>> = {
131
- Success: boolean;
132
- ErrorMessage?: string;
133
- SourceData?: T[];
134
- Messages: GetMessageMessage[];
135
- };
136
- ```
145
+ const operations = provider.getSupportedOperations();
137
146
 
138
- ### ForwardMessageParams
139
- Parameters for forwarding messages:
140
-
141
- ```typescript
142
- type ForwardMessageParams = {
143
- MessageID: string;
144
- Message?: string;
145
- ToRecipients: string[];
146
- CCRecipients?: string[];
147
- BCCRecipients?: string[];
148
- };
147
+ if (provider.supportsOperation('SearchMessages')) {
148
+ const results = await provider.SearchMessages({ Query: 'invoice' });
149
+ }
149
150
  ```
150
151
 
151
- ### ReplyToMessageParams
152
- Parameters for replying to messages:
153
-
154
- ```typescript
155
- type ReplyToMessageParams<T = Record<string, any>> = {
156
- MessageID: string;
157
- Message: ProcessedMessage;
158
- ContextData?: T;
159
- };
160
- ```
152
+ ### Message Classes
161
153
 
162
- ### CreateDraftParams
163
- Parameters for creating draft messages:
154
+ - **Message**: Holds all data for a single communication including optional template references, CC/BCC recipients, headers, and scheduled send time.
155
+ - **ProcessedMessage**: Abstract subclass of `Message` with rendered content (`ProcessedBody`, `ProcessedHTMLBody`, `ProcessedSubject`) and a `Process()` method for template rendering.
156
+ - **MessageRecipient**: Represents a single recipient with per-recipient template context data.
157
+ - **MessageResult**: Result of a send operation including success/failure status, error details, and the processed message.
164
158
 
165
159
  ```typescript
166
- type CreateDraftParams = {
167
- Message: ProcessedMessage;
168
- ContextData?: Record<string, any>;
169
- };
170
- ```
160
+ import { Message, ProcessedMessage, MessageRecipient } from '@memberjunction/communication-types';
171
161
 
172
- ### CreateDraftResult
173
- Result structure for draft creation:
174
-
175
- ```typescript
176
- type CreateDraftResult<T = Record<string, any>> = {
177
- Success: boolean;
178
- ErrorMessage?: string;
179
- DraftID?: string; // Provider-specific draft identifier
180
- Result?: T; // Provider-specific result data
181
- };
162
+ const message = new Message();
163
+ message.From = 'sender@example.com';
164
+ message.To = 'recipient@example.com';
165
+ message.Subject = 'Hello';
166
+ message.Body = 'Plain text body';
167
+ message.HTMLBody = '<p>HTML body</p>';
168
+ message.CCRecipients = ['cc@example.com'];
169
+ message.BCCRecipients = ['bcc@example.com'];
170
+ message.Headers = { 'X-Custom': 'value' };
171
+ message.SendAt = new Date('2025-01-01');
172
+
173
+ // Template-based messages
174
+ message.BodyTemplate = templateEntity;
175
+ message.SubjectTemplate = subjectTemplateEntity;
176
+ message.ContextData = { name: 'John', company: 'Acme Corp' };
182
177
  ```
183
178
 
184
- ## Usage Examples
179
+ ### Credential Utilities
185
180
 
186
- ### Setting up the Communication Engine
181
+ The credential system supports per-request credential overrides while maintaining backward compatibility with environment variables.
187
182
 
188
183
  ```typescript
189
- import { CommunicationEngineBase } from '@memberjunction/communication-types';
190
- import { UserInfo } from '@memberjunction/core';
191
-
192
- async function initializeCommunications(user: UserInfo) {
193
- const engine = CommunicationEngineBase.Instance;
194
-
195
- // Configure the engine
196
- await engine.Config(false, user);
197
-
198
- // Access available providers
199
- const providers = engine.Providers;
200
- console.log(`Available providers: ${providers.map(p => p.Name).join(', ')}`);
201
-
202
- // Get message types for a specific provider
203
- const emailProvider = providers.find(p => p.Name === 'Email');
204
- const messageTypes = emailProvider?.MessageTypes;
205
- }
206
- ```
207
-
208
- ### Creating a Custom Communication Provider
209
-
210
- ```typescript
211
- import {
212
- BaseCommunicationProvider,
213
- ProcessedMessage,
214
- MessageResult,
215
- GetMessagesParams,
216
- GetMessagesResult
184
+ import {
185
+ ProviderCredentialsBase,
186
+ resolveCredentialValue,
187
+ validateRequiredCredentials,
188
+ resolveCredentials
217
189
  } from '@memberjunction/communication-types';
218
190
 
219
- export class CustomSMSProvider extends BaseCommunicationProvider {
220
- public async SendSingleMessage(message: ProcessedMessage): Promise<MessageResult> {
221
- try {
222
- // Implement SMS sending logic
223
- const result = await this.sendSMS(message.To, message.ProcessedBody);
224
-
225
- return {
226
- Message: message,
227
- Success: true,
228
- Error: null
229
- };
230
- } catch (error) {
231
- return {
232
- Message: message,
233
- Success: false,
234
- Error: error.message
235
- };
236
- }
237
- }
238
-
239
- public async GetMessages(params: GetMessagesParams): Promise<GetMessagesResult> {
240
- // Implement SMS retrieval logic
241
- const messages = await this.fetchSMSMessages(params.NumMessages);
242
-
243
- return {
244
- Success: true,
245
- Messages: messages.map(m => ({
246
- From: m.sender,
247
- To: m.recipient,
248
- Body: m.text,
249
- ExternalSystemRecordID: m.id
250
- }))
251
- };
252
- }
253
-
254
- public async ForwardMessage(params: ForwardMessageParams): Promise<ForwardMessageResult> {
255
- // SMS forwarding implementation
256
- return { Success: true };
257
- }
258
-
259
- public async ReplyToMessage(params: ReplyToMessageParams): Promise<ReplyToMessageResult> {
260
- // SMS reply implementation
261
- return { Success: true };
262
- }
263
-
264
- public async CreateDraft(params: CreateDraftParams): Promise<CreateDraftResult> {
265
- // SMS providers typically don't support drafts
266
- return {
267
- Success: false,
268
- ErrorMessage: 'SMS providers do not support draft messages'
269
- };
270
- }
271
-
272
- private async sendSMS(to: string, message: string): Promise<any> {
273
- // Provider-specific implementation
274
- }
275
-
276
- private async fetchSMSMessages(count: number): Promise<any[]> {
277
- // Provider-specific implementation
278
- }
279
- }
191
+ // Resolve a single credential (request value takes precedence over env fallback)
192
+ const apiKey = resolveCredentialValue(
193
+ credentials?.apiKey, // from request
194
+ process.env.SENDGRID_KEY, // environment fallback
195
+ false // disableEnvironmentFallback
196
+ );
197
+
198
+ // Validate all required fields are present
199
+ validateRequiredCredentials(
200
+ { apiKey, tenantId },
201
+ ['apiKey', 'tenantId'],
202
+ 'MyProvider'
203
+ );
204
+
205
+ // Resolve multiple fields with source tracking
206
+ const result = resolveCredentials(
207
+ requestCredentials,
208
+ envCredentials,
209
+ ['apiKey', 'secret'],
210
+ false
211
+ );
212
+ // result.source: 'request' | 'environment' | 'mixed'
213
+ // result.fieldSources: { apiKey: 'request', secret: 'environment' }
280
214
  ```
281
215
 
282
- ## Integration with MemberJunction
283
-
284
- This package integrates seamlessly with other MemberJunction packages:
216
+ ### Communication Runs and Logging
285
217
 
286
- - **@memberjunction/core**: Provides base entity functionality and metadata system integration
287
- - **@memberjunction/core-entities**: Contains the entity definitions for communication-related data
288
- - **@memberjunction/templates-base-types**: Enables template-based message content
289
- - **@memberjunction/global**: Provides utility functions and global registry
290
-
291
- ### Working with Communication Logs
292
-
293
- The engine provides methods for tracking communication activities:
218
+ The engine provides methods for tracking communication activities through database entities:
294
219
 
295
220
  ```typescript
296
- // Start a communication run
297
221
  const run = await engine.StartRun();
298
-
299
- // Log individual messages
300
222
  const log = await engine.StartLog(processedMessage, run);
301
-
302
- // Complete the run
223
+ // ... send message ...
224
+ log.Status = 'Complete';
225
+ await log.Save();
303
226
  await engine.EndRun(run);
304
227
  ```
305
228
 
229
+ ## Type Definitions
230
+
231
+ All parameter and result types used across the framework:
232
+
233
+ | Type | Purpose |
234
+ |------|---------|
235
+ | `GetMessagesParams` / `GetMessagesResult` | Message retrieval |
236
+ | `ForwardMessageParams` / `ForwardMessageResult` | Message forwarding |
237
+ | `ReplyToMessageParams` / `ReplyToMessageResult` | Message replies |
238
+ | `CreateDraftParams` / `CreateDraftResult` | Draft creation |
239
+ | `GetSingleMessageParams` / `GetSingleMessageResult` | Single message retrieval |
240
+ | `DeleteMessageParams` / `DeleteMessageResult` | Message deletion |
241
+ | `MoveMessageParams` / `MoveMessageResult` | Folder management |
242
+ | `ListFoldersParams` / `ListFoldersResult` | Folder listing |
243
+ | `MarkAsReadParams` / `MarkAsReadResult` | Read status |
244
+ | `SearchMessagesParams` / `SearchMessagesResult` | Message search |
245
+ | `ListAttachmentsParams` / `ListAttachmentsResult` | Attachment listing |
246
+ | `DownloadAttachmentParams` / `DownloadAttachmentResult` | Attachment download |
247
+ | `ProviderOperation` | Union type of all operation names |
248
+ | `MessageFolder` / `MessageAttachment` | Data structures for folders and attachments |
249
+
306
250
  ## Dependencies
307
251
 
308
- - `@memberjunction/global`: ^2.43.0
309
- - `@memberjunction/core`: ^2.43.0
310
- - `@memberjunction/templates-base-types`: ^2.43.0
311
- - `@memberjunction/core-entities`: ^2.43.0
312
- - `rxjs`: ^7.8.1
252
+ | Package | Purpose |
253
+ |---------|---------|
254
+ | `@memberjunction/core` | BaseEngine, UserInfo, logging utilities |
255
+ | `@memberjunction/core-entities` | Generated entity types for Communication metadata |
256
+ | `@memberjunction/global` | RegisterClass decorator and MJGlobal class factory |
257
+ | `@memberjunction/templates-base-types` | Template entity types for message templating |
313
258
 
314
259
  ## Development
315
260
 
316
- ### Building
317
-
318
261
  ```bash
319
- npm run build
262
+ npm run build # Compile TypeScript
263
+ npm start # Watch mode
320
264
  ```
321
-
322
- ### Development Mode
323
-
324
- ```bash
325
- npm start
326
- ```
327
-
328
- ## Extended Entity Support
329
-
330
- The package includes an extended Communication Provider entity that automatically links message types:
331
-
332
- ```typescript
333
- import { CommunicationProviderEntityExtended } from '@memberjunction/communication-types';
334
-
335
- // The extended entity automatically includes related message types
336
- const provider = await md.GetEntityObject<CommunicationProviderEntityExtended>('Communication Providers');
337
- const messageTypes = provider.MessageTypes; // Automatically populated
338
- ```
339
-
340
- ## License
341
-
342
- ISC
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@memberjunction/communication-types",
3
3
  "type": "module",
4
- "version": "4.0.0",
4
+ "version": "4.1.0",
5
5
  "description": "MemberJunction: Communication Framework Library Generic Types",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -20,10 +20,10 @@
20
20
  "typescript": "^5.9.3"
21
21
  },
22
22
  "dependencies": {
23
- "@memberjunction/global": "4.0.0",
24
- "@memberjunction/core": "4.0.0",
25
- "@memberjunction/templates-base-types": "4.0.0",
26
- "@memberjunction/core-entities": "4.0.0",
23
+ "@memberjunction/global": "4.1.0",
24
+ "@memberjunction/core": "4.1.0",
25
+ "@memberjunction/templates-base-types": "4.1.0",
26
+ "@memberjunction/core-entities": "4.1.0",
27
27
  "rxjs": "^7.8.2"
28
28
  },
29
29
  "repository": {