@memberjunction/communication-gmail
v4.3.0
Published
Gmail/Google Suite provider for MemberJunction Communication framework
Keywords
Readme
@memberjunction/communication-gmail
Gmail / Google Workspace provider for the MemberJunction Communication Framework. This provider enables full mailbox operations -- sending, receiving, searching, managing labels, attachments, drafts, and more -- through the Gmail API with OAuth2 authentication.
Architecture
graph TD
subgraph gmail["@memberjunction/communication-gmail"]
GP["GmailProvider"]
AUTH["Auth Module\n(OAuth2 Client)"]
CFG["Config Module\n(Environment Variables)"]
CRED["GmailCredentials"]
end
subgraph google["Google APIs"]
OAUTH["Google OAuth2"]
GAPI["Gmail API v1\n(/users/me/...)"]
MAILBOX["Gmail Mailbox"]
end
subgraph base["@memberjunction/communication-types"]
BCP["BaseCommunicationProvider"]
end
BCP --> GP
GP --> AUTH
GP --> CFG
GP --> CRED
AUTH --> OAUTH
GP --> GAPI
GAPI --> MAILBOX
style gmail fill:#2d6a9f,stroke:#1a4971,color:#fff
style google fill:#7c5295,stroke:#563a6b,color:#fff
style base fill:#2d8659,stroke:#1a5c3a,color:#fffInstallation
npm install @memberjunction/communication-gmailConfiguration
Set the following environment variables:
GMAIL_CLIENT_ID=your-oauth2-client-id
GMAIL_CLIENT_SECRET=your-oauth2-client-secret
GMAIL_REDIRECT_URI=your-redirect-uri
GMAIL_REFRESH_TOKEN=your-refresh-token
[email protected] # optional default senderRequired OAuth2 Scopes
https://www.googleapis.com/auth/gmail.sendhttps://www.googleapis.com/auth/gmail.readonlyhttps://www.googleapis.com/auth/gmail.modifyhttps://www.googleapis.com/auth/gmail.compose
Obtaining OAuth2 Credentials
- Go to the Google Cloud Console
- Create or select a project and enable the Gmail API
- Create OAuth 2.0 Client ID credentials
- Configure the OAuth consent screen
- Use the OAuth2 flow to obtain a refresh token with the required scopes
Supported Operations
This provider supports all 14 operations defined in BaseCommunicationProvider:
| Operation | Gmail Implementation |
|-----------|---------------------|
| SendSingleMessage | Send via users.messages.send |
| GetMessages | List and fetch with Gmail search query support |
| GetSingleMessage | Fetch single message by ID |
| ForwardMessage | Reconstruct and send as RFC 822 attachment |
| ReplyToMessage | Send in same thread via threadId |
| CreateDraft | Create via users.drafts.create |
| DeleteMessage | Trash or permanently delete |
| MoveMessage | Add/remove labels via users.messages.modify |
| ListFolders | List labels with optional message/unread counts |
| MarkAsRead | Add/remove UNREAD label (batch) |
| ArchiveMessage | Remove INBOX label |
| SearchMessages | Gmail query syntax with date filters |
| ListAttachments | Parse message parts recursively for attachments |
| DownloadAttachment | Download via users.messages.attachments.get |
Usage
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 = '[email protected]';
message.To = '[email protected]';
message.Subject = 'Hello from Gmail';
message.HTMLBody = '<h1>Hello</h1>';
message.CCRecipients = ['[email protected]'];
const result = await engine.SendSingleMessage('Gmail', 'Email', message);Per-Request Credentials
Override credentials for multi-user scenarios:
import { GmailCredentials } from '@memberjunction/communication-gmail';
const result = await provider.SendSingleMessage(processedMessage, {
clientId: 'other-client-id',
clientSecret: 'other-secret',
redirectUri: 'other-redirect',
refreshToken: 'user-specific-refresh-token'
} as GmailCredentials);Retrieving Messages
const provider = engine.GetProvider('Gmail');
const result = await provider.GetMessages({
NumMessages: 10,
UnreadOnly: true,
ContextData: {
query: 'from:[email protected]', // Gmail search syntax
MarkAsRead: true
}
});
result.Messages.forEach(msg => {
console.log(`${msg.From}: ${msg.Subject}`);
console.log(`Thread: ${msg.ThreadID}`);
});Creating Drafts
const result = await provider.CreateDraft({ Message: processedMessage });
if (result.Success) {
console.log(`Draft ID: ${result.DraftID}`);
// Draft appears in Gmail drafts folder
}Searching with Gmail Query Syntax
const result = await provider.SearchMessages({
Query: 'has:attachment',
FromDate: new Date('2025-01-01'),
ToDate: new Date('2025-06-01'),
FolderID: 'INBOX', // Gmail label ID
MaxResults: 50
});Managing Labels (Folders)
const folders = await provider.ListFolders({ IncludeCounts: true });
folders.Folders.forEach(f => {
console.log(`${f.Name} (${f.ID}): ${f.MessageCount} messages`);
console.log(` System: ${f.IsSystemFolder}, Type: ${f.SystemFolderType}`);
});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 base64 string
// download.Filename, download.ContentType available
}Gmail Label Mapping
Gmail uses labels instead of traditional folders. The provider maps system labels to standard folder types:
| Gmail Label | SystemFolderType |
|-------------|-----------------|
| INBOX | inbox |
| SENT | sent |
| DRAFT | drafts |
| TRASH | trash |
| SPAM | spam |
| User labels | undefined |
Client Caching
The provider caches Gmail API client instances for performance. Environment credential clients are shared across all calls; per-request credential clients are cached by a key derived from clientId and refreshToken.
Security Considerations
- Store refresh tokens securely and never commit them to version control
- Request only the minimum required OAuth2 scopes
- Use secure methods to manage environment variables in production
- Regularly rotate client secrets and monitor API usage
Dependencies
| Package | Purpose |
|---------|---------|
| @memberjunction/communication-types | Base provider class and type definitions |
| @memberjunction/core | Logging utilities |
| @memberjunction/global | RegisterClass decorator |
| googleapis | Google APIs Node.js client |
| dotenv | Environment variable loading |
| env-var | Environment variable validation |
Development
npm run build # Compile TypeScript
npm run clean # Remove dist directory