@memberjunction/communication-ms-graph 5.0.0 → 5.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.
Files changed (2) hide show
  1. package/README.md +251 -0
  2. package/package.json +9 -9
package/README.md ADDED
@@ -0,0 +1,251 @@
1
+ # @memberjunction/communication-ms-graph
2
+
3
+ Microsoft Graph (Office 365 / Exchange Online) provider for the MemberJunction Communication Framework. This provider enables full mailbox operations -- sending, receiving, searching, managing folders, attachments, drafts, and more -- through the Microsoft Graph API with Azure AD application authentication.
4
+
5
+ ## Architecture
6
+
7
+ ```mermaid
8
+ graph TD
9
+ subgraph msgraph["@memberjunction/communication-ms-graph"]
10
+ MSP["MSGraphProvider"]
11
+ AUTH["Auth Module\n(ClientSecretCredential)"]
12
+ CFG["Config Module\n(Environment Variables)"]
13
+ CRED["MSGraphCredentials"]
14
+ end
15
+
16
+ subgraph azure["Azure / Microsoft"]
17
+ AAD["Azure AD\n(OAuth2 Client Credentials)"]
18
+ GRAPH["Microsoft Graph API\n(/users/email/...)"]
19
+ MAIL["Exchange Online\nMailbox"]
20
+ end
21
+
22
+ subgraph base["@memberjunction/communication-types"]
23
+ BCP["BaseCommunicationProvider"]
24
+ end
25
+
26
+ BCP --> MSP
27
+ MSP --> AUTH
28
+ MSP --> CFG
29
+ MSP --> CRED
30
+ AUTH --> AAD
31
+ MSP --> GRAPH
32
+ GRAPH --> MAIL
33
+
34
+ style msgraph fill:#2d6a9f,stroke:#1a4971,color:#fff
35
+ style azure fill:#7c5295,stroke:#563a6b,color:#fff
36
+ style base fill:#2d8659,stroke:#1a5c3a,color:#fff
37
+ ```
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ npm install @memberjunction/communication-ms-graph
43
+ ```
44
+
45
+ ## Configuration
46
+
47
+ Set the following environment variables:
48
+
49
+ ```env
50
+ AZURE_TENANT_ID=your-azure-tenant-id
51
+ AZURE_CLIENT_ID=your-azure-app-client-id
52
+ AZURE_CLIENT_SECRET=your-azure-app-client-secret
53
+ AZURE_ACCOUNT_EMAIL=mailbox@yourdomain.com
54
+ ```
55
+
56
+ ### Required Azure AD App Permissions (Application type)
57
+
58
+ | Permission | Operations |
59
+ |-----------|------------|
60
+ | `Mail.Send` | SendSingleMessage, ForwardMessage, ReplyToMessage |
61
+ | `Mail.Read` | GetMessages, GetSingleMessage, SearchMessages, ListFolders, ListAttachments, DownloadAttachment |
62
+ | `Mail.ReadWrite` | CreateDraft, DeleteMessage, MoveMessage, MarkAsRead, ArchiveMessage |
63
+ | `User.Read.All` | GetServiceAccount (user lookup, optional) |
64
+
65
+ ## Supported Operations
66
+
67
+ This provider supports all 14 operations defined in `BaseCommunicationProvider`:
68
+
69
+ | Operation | Description |
70
+ |-----------|-------------|
71
+ | `SendSingleMessage` | Send email via Graph API |
72
+ | `GetMessages` | Retrieve messages with filtering and header extraction |
73
+ | `GetSingleMessage` | Retrieve a single message by ID |
74
+ | `ForwardMessage` | Forward email to new recipients |
75
+ | `ReplyToMessage` | Reply to an existing email thread |
76
+ | `CreateDraft` | Create a draft message in the mailbox |
77
+ | `DeleteMessage` | Move to Deleted Items or permanently delete |
78
+ | `MoveMessage` | Move message to a different mail folder |
79
+ | `ListFolders` | List mail folders with optional message counts |
80
+ | `MarkAsRead` | Mark messages as read or unread (batch) |
81
+ | `ArchiveMessage` | Move message to Archive folder |
82
+ | `SearchMessages` | Full-text search with KQL syntax and date filtering |
83
+ | `ListAttachments` | List attachments on a message |
84
+ | `DownloadAttachment` | Download attachment content as base64/Buffer |
85
+
86
+ ## Usage
87
+
88
+ ### Sending Email
89
+
90
+ ```typescript
91
+ import { CommunicationEngine } from '@memberjunction/communication-engine';
92
+ import { Message } from '@memberjunction/communication-types';
93
+
94
+ const engine = CommunicationEngine.Instance;
95
+ await engine.Config(false, contextUser);
96
+
97
+ const message = new Message();
98
+ message.From = 'user@yourdomain.com';
99
+ message.To = 'recipient@example.com';
100
+ message.Subject = 'Hello from MS Graph';
101
+ message.HTMLBody = '<h1>Hello</h1><p>Sent via Microsoft Graph.</p>';
102
+ message.ContextData = { saveToSentItems: true };
103
+
104
+ const result = await engine.SendSingleMessage(
105
+ 'Microsoft Graph',
106
+ 'Standard Email',
107
+ message
108
+ );
109
+ ```
110
+
111
+ ### Per-Request Credentials
112
+
113
+ Override credentials on a per-request basis for multi-tenant scenarios:
114
+
115
+ ```typescript
116
+ import { MSGraphCredentials } from '@memberjunction/communication-ms-graph';
117
+
118
+ const result = await engine.SendSingleMessage(
119
+ 'Microsoft Graph',
120
+ 'Standard Email',
121
+ message,
122
+ undefined,
123
+ false,
124
+ {
125
+ tenantId: 'customer-tenant-id',
126
+ clientId: 'customer-app-id',
127
+ clientSecret: 'customer-secret',
128
+ accountEmail: 'user@customer.com'
129
+ } as MSGraphCredentials
130
+ );
131
+ ```
132
+
133
+ ### Reading Messages
134
+
135
+ ```typescript
136
+ const provider = engine.GetProvider('Microsoft Graph');
137
+
138
+ const result = await provider.GetMessages({
139
+ NumMessages: 10,
140
+ UnreadOnly: true,
141
+ IncludeHeaders: true,
142
+ ContextData: {
143
+ ReturnAsPlainText: true,
144
+ MarkAsRead: true
145
+ }
146
+ });
147
+
148
+ result.Messages.forEach(msg => {
149
+ console.log(`${msg.From}: ${msg.Subject}`);
150
+ console.log(`Thread: ${msg.ThreadID}`);
151
+ });
152
+ ```
153
+
154
+ ### Searching Messages
155
+
156
+ MS Graph supports KQL (Keyword Query Language) for search:
157
+
158
+ ```typescript
159
+ const result = await provider.SearchMessages({
160
+ Query: 'invoice',
161
+ FromDate: new Date('2025-01-01'),
162
+ MaxResults: 25,
163
+ FolderID: 'inbox-folder-id'
164
+ });
165
+ ```
166
+
167
+ ### Creating Drafts
168
+
169
+ ```typescript
170
+ const result = await engine.CreateDraft(message, 'Microsoft Graph', contextUser);
171
+ if (result.Success) {
172
+ console.log(`Draft ID: ${result.DraftID}`);
173
+ }
174
+ ```
175
+
176
+ ### Managing Folders
177
+
178
+ ```typescript
179
+ // List top-level folders
180
+ const folders = await provider.ListFolders({ IncludeCounts: true });
181
+ folders.Folders.forEach(f => {
182
+ console.log(`${f.Name}: ${f.MessageCount} total, ${f.UnreadCount} unread`);
183
+ });
184
+
185
+ // List subfolders
186
+ const subfolders = await provider.ListFolders({
187
+ ParentFolderID: 'parent-folder-id',
188
+ IncludeCounts: true
189
+ });
190
+
191
+ // Move a message
192
+ await provider.MoveMessage({
193
+ MessageID: 'msg-id',
194
+ DestinationFolderID: 'folder-id'
195
+ });
196
+
197
+ // Archive a message
198
+ await provider.ArchiveMessage({ MessageID: 'msg-id' });
199
+ ```
200
+
201
+ ### Downloading Attachments
202
+
203
+ ```typescript
204
+ const attachments = await provider.ListAttachments({ MessageID: 'msg-id' });
205
+ for (const att of attachments.Attachments) {
206
+ const download = await provider.DownloadAttachment({
207
+ MessageID: 'msg-id',
208
+ AttachmentID: att.ID
209
+ });
210
+ // download.Content is a Buffer
211
+ // download.ContentBase64 is the raw base64 string
212
+ }
213
+ ```
214
+
215
+ ## Client Caching
216
+
217
+ The provider caches Microsoft Graph `Client` instances per credential set for performance. Environment credential clients are shared across all calls; per-request credential clients are cached by `tenantId:clientId`.
218
+
219
+ ## System Folder Mapping
220
+
221
+ | Exchange Display Name | SystemFolderType |
222
+ |----------------------|-----------------|
223
+ | Inbox | `inbox` |
224
+ | Sent Items | `sent` |
225
+ | Drafts | `drafts` |
226
+ | Deleted Items | `trash` |
227
+ | Junk Email | `spam` |
228
+ | Archive | `archive` |
229
+ | Other folders | `other` |
230
+
231
+ ## HTML to Text Conversion
232
+
233
+ When `ReturnAsPlainText` is set in `ContextData`, the provider uses the `html-to-text` library to convert HTML email bodies to plain text with 130-character word wrap.
234
+
235
+ ## Dependencies
236
+
237
+ | Package | Purpose |
238
+ |---------|---------|
239
+ | `@memberjunction/communication-types` | Base provider class and type definitions |
240
+ | `@memberjunction/core` | Logging utilities |
241
+ | `@memberjunction/global` | RegisterClass decorator |
242
+ | `@microsoft/microsoft-graph-client` | Microsoft Graph SDK |
243
+ | `@azure/identity` | Azure AD ClientSecretCredential |
244
+ | `html-to-text` | HTML to plain text conversion |
245
+
246
+ ## Development
247
+
248
+ ```bash
249
+ npm run build # Compile TypeScript
250
+ npm run clean # Remove dist directory
251
+ ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@memberjunction/communication-ms-graph",
3
3
  "type": "module",
4
- "version": "5.0.0",
4
+ "version": "5.2.0",
5
5
  "description": "MemberJunction: Microsoft Graph Provider for the MJ Communication Framework",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -23,14 +23,14 @@
23
23
  "dependencies": {
24
24
  "@azure/identity": "^4.13.0",
25
25
  "@azure/msal-node": "^5.0.3",
26
- "@memberjunction/ai": "5.0.0",
27
- "@memberjunction/ai-provider-bundle": "5.0.0",
28
- "@memberjunction/aiengine": "5.0.0",
29
- "@memberjunction/communication-types": "5.0.0",
30
- "@memberjunction/core": "5.0.0",
31
- "@memberjunction/core-entities": "5.0.0",
32
- "@memberjunction/global": "5.0.0",
33
- "@memberjunction/sqlserver-dataprovider": "5.0.0",
26
+ "@memberjunction/ai": "5.2.0",
27
+ "@memberjunction/ai-provider-bundle": "5.2.0",
28
+ "@memberjunction/aiengine": "5.2.0",
29
+ "@memberjunction/communication-types": "5.2.0",
30
+ "@memberjunction/core": "5.2.0",
31
+ "@memberjunction/core-entities": "5.2.0",
32
+ "@memberjunction/global": "5.2.0",
33
+ "@memberjunction/sqlserver-dataprovider": "5.2.0",
34
34
  "@microsoft/microsoft-graph-client": "^3.0.7",
35
35
  "@microsoft/microsoft-graph-types": "^2.43.1",
36
36
  "@types/html-to-text": "^9.0.4",