@memberjunction/communication-ms-graph
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.
Architecture
Section titled “Architecture”graph TD
subgraph msgraph["@memberjunction/communication-ms-graph"]
MSP["MSGraphProvider"]
AUTH["Auth Module\n(ClientSecretCredential)"]
CFG["Config Module\n(Environment Variables)"]
CRED["MSGraphCredentials"]
end
subgraph azure["Azure / Microsoft"]
AAD["Azure AD\n(OAuth2 Client Credentials)"]
GRAPH["Microsoft Graph API\n(/users/email/...)"]
MAIL["Exchange Online\nMailbox"]
end
subgraph base["@memberjunction/communication-types"]
BCP["BaseCommunicationProvider"]
end
BCP --> MSP
MSP --> AUTH
MSP --> CFG
MSP --> CRED
AUTH --> AAD
MSP --> GRAPH
GRAPH --> MAIL
style msgraph fill:#2d6a9f,stroke:#1a4971,color:#fff
style azure fill:#7c5295,stroke:#563a6b,color:#fff
style base fill:#2d8659,stroke:#1a5c3a,color:#fff
Installation
Section titled “Installation”npm install @memberjunction/communication-ms-graphConfiguration
Section titled “Configuration”Set the following environment variables:
AZURE_TENANT_ID=your-azure-tenant-idAZURE_CLIENT_ID=your-azure-app-client-idAZURE_CLIENT_SECRET=your-azure-app-client-secretAZURE_ACCOUNT_EMAIL=mailbox@yourdomain.comRequired Azure AD App Permissions (Application type)
Section titled “Required Azure AD App Permissions (Application type)”| Permission | Operations |
|---|---|
Mail.Send | SendSingleMessage, ForwardMessage, ReplyToMessage |
Mail.Read | GetMessages, GetSingleMessage, SearchMessages, ListFolders, ListAttachments, DownloadAttachment |
Mail.ReadWrite | CreateDraft, DeleteMessage, MoveMessage, MarkAsRead, ArchiveMessage |
User.Read.All | GetServiceAccount (user lookup, optional) |
Supported Operations
Section titled “Supported Operations”This provider supports all 14 operations defined in BaseCommunicationProvider:
| Operation | Description |
|---|---|
SendSingleMessage | Send email via Graph API |
GetMessages | Retrieve messages with filtering and header extraction |
GetSingleMessage | Retrieve a single message by ID |
ForwardMessage | Forward email to new recipients |
ReplyToMessage | Reply to an existing email thread |
CreateDraft | Create a draft message in the mailbox |
DeleteMessage | Move to Deleted Items or permanently delete |
MoveMessage | Move message to a different mail folder |
ListFolders | List mail folders with optional message counts |
MarkAsRead | Mark messages as read or unread (batch) |
ArchiveMessage | Move message to Archive folder |
SearchMessages | Full-text search with KQL syntax and date filtering |
ListAttachments | List attachments on a message |
DownloadAttachment | Download attachment content as base64/Buffer |
Sending Email
Section titled “Sending Email”import { CommunicationEngine } from '@memberjunction/communication-engine';import { Message } from '@memberjunction/communication-types';
const engine = CommunicationEngine.Instance;await engine.Config(false, contextUser);
const message = new Message();message.From = 'user@yourdomain.com';message.To = 'recipient@example.com';message.Subject = 'Hello from MS Graph';message.HTMLBody = '<h1>Hello</h1><p>Sent via Microsoft Graph.</p>';message.ContextData = { saveToSentItems: true };
const result = await engine.SendSingleMessage( 'Microsoft Graph', 'Standard Email', message);Per-Request Credentials
Section titled “Per-Request Credentials”Override credentials on a per-request basis for multi-tenant scenarios:
import { MSGraphCredentials } from '@memberjunction/communication-ms-graph';
const result = await engine.SendSingleMessage( 'Microsoft Graph', 'Standard Email', message, undefined, false, { tenantId: 'customer-tenant-id', clientId: 'customer-app-id', clientSecret: 'customer-secret', accountEmail: 'user@customer.com' } as MSGraphCredentials);Reading Messages
Section titled “Reading Messages”const provider = engine.GetProvider('Microsoft Graph');
const result = await provider.GetMessages({ NumMessages: 10, UnreadOnly: true, IncludeHeaders: true, ContextData: { ReturnAsPlainText: true, MarkAsRead: true }});
result.Messages.forEach(msg => { console.log(`${msg.From}: ${msg.Subject}`); console.log(`Thread: ${msg.ThreadID}`);});Searching Messages
Section titled “Searching Messages”MS Graph supports KQL (Keyword Query Language) for search:
const result = await provider.SearchMessages({ Query: 'invoice', FromDate: new Date('2025-01-01'), MaxResults: 25, FolderID: 'inbox-folder-id'});Creating Drafts
Section titled “Creating Drafts”const result = await engine.CreateDraft(message, 'Microsoft Graph', contextUser);if (result.Success) { console.log(`Draft ID: ${result.DraftID}`);}Managing Folders
Section titled “Managing Folders”// List top-level foldersconst folders = await provider.ListFolders({ IncludeCounts: true });folders.Folders.forEach(f => { console.log(`${f.Name}: ${f.MessageCount} total, ${f.UnreadCount} unread`);});
// List subfoldersconst subfolders = await provider.ListFolders({ ParentFolderID: 'parent-folder-id', IncludeCounts: true});
// Move a messageawait provider.MoveMessage({ MessageID: 'msg-id', DestinationFolderID: 'folder-id'});
// Archive a messageawait provider.ArchiveMessage({ MessageID: 'msg-id' });Downloading Attachments
Section titled “Downloading Attachments”const attachments = await provider.ListAttachments({ MessageID: 'msg-id' });for (const att of attachments.Attachments) { const download = await provider.DownloadAttachment({ MessageID: 'msg-id', AttachmentID: att.ID }); // download.Content is a Buffer // download.ContentBase64 is the raw base64 string}Client Caching
Section titled “Client Caching”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.
System Folder Mapping
Section titled “System Folder Mapping”| Exchange Display Name | SystemFolderType |
|---|---|
| Inbox | inbox |
| Sent Items | sent |
| Drafts | drafts |
| Deleted Items | trash |
| Junk Email | spam |
| Archive | archive |
| Other folders | other |
HTML to Text Conversion
Section titled “HTML to Text Conversion”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.
Dependencies
Section titled “Dependencies”| Package | Purpose |
|---|---|
@memberjunction/communication-types | Base provider class and type definitions |
@memberjunction/core | Logging utilities |
@memberjunction/global | RegisterClass decorator |
@microsoft/microsoft-graph-client | Microsoft Graph SDK |
@azure/identity | Azure AD ClientSecretCredential |
html-to-text | HTML to plain text conversion |
Development
Section titled “Development”npm run build # Compile TypeScriptnpm run clean # Remove dist directory