mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-09 22:31:10 +00:00
docs: gmail connector (#690)
This commit is contained in:
parent
7972e543c4
commit
0d82ac3238
4 changed files with 487 additions and 3 deletions
433
apps/docs/connectors/gmail.mdx
Normal file
433
apps/docs/connectors/gmail.mdx
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
---
|
||||
title: "Gmail Connector"
|
||||
description: "Sync email threads from Gmail with real-time Pub/Sub webhooks and incremental sync"
|
||||
icon: "mail"
|
||||
---
|
||||
|
||||
Connect Gmail to automatically sync email threads into your supermemory knowledge base. Supports real-time updates via Google Cloud Pub/Sub webhooks and incremental synchronization.
|
||||
|
||||
<Note>
|
||||
**Scale Plan Required:** The Gmail connector is available on Scale and Enterprise plans only.
|
||||
</Note>
|
||||
|
||||
## Quick Setup
|
||||
|
||||
### 1. Create Gmail Connection
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```typescript
|
||||
import Supermemory from 'supermemory';
|
||||
|
||||
const client = new Supermemory({
|
||||
apiKey: process.env.SUPERMEMORY_API_KEY!
|
||||
});
|
||||
|
||||
const connection = await client.connections.create('gmail', {
|
||||
redirectUrl: 'https://yourapp.com/auth/gmail/callback',
|
||||
containerTags: ['user-123', 'gmail-sync'],
|
||||
documentLimit: 5000,
|
||||
metadata: {
|
||||
source: 'gmail',
|
||||
department: 'support'
|
||||
}
|
||||
});
|
||||
|
||||
// Redirect user to Google OAuth
|
||||
window.location.href = connection.authLink;
|
||||
console.log('Auth expires in:', connection.expiresIn);
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```python
|
||||
from supermemory import Supermemory
|
||||
import os
|
||||
|
||||
client = Supermemory(api_key=os.environ.get("SUPERMEMORY_API_KEY"))
|
||||
|
||||
connection = client.connections.create(
|
||||
'gmail',
|
||||
redirect_url='https://yourapp.com/auth/gmail/callback',
|
||||
container_tags=['user-123', 'gmail-sync'],
|
||||
document_limit=5000,
|
||||
metadata={
|
||||
'source': 'gmail',
|
||||
'department': 'support'
|
||||
}
|
||||
)
|
||||
|
||||
# Redirect user to Google OAuth
|
||||
print(f'Redirect to: {connection.auth_link}')
|
||||
print(f'Expires in: {connection.expires_in}')
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="cURL">
|
||||
```bash
|
||||
curl -X POST "https://api.supermemory.ai/v3/connections/gmail" \
|
||||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"redirectUrl": "https://yourapp.com/auth/gmail/callback",
|
||||
"containerTags": ["user-123", "gmail-sync"],
|
||||
"documentLimit": 5000,
|
||||
"metadata": {
|
||||
"source": "gmail",
|
||||
"department": "support"
|
||||
}
|
||||
}'
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 2. Handle OAuth Callback
|
||||
|
||||
After user grants permissions, Google redirects to your callback URL. The connection is automatically established and the initial sync begins.
|
||||
|
||||
### 3. Check Connection Status
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```typescript
|
||||
// Get connection details
|
||||
const connection = await client.connections.getByTags('gmail', {
|
||||
containerTags: ['user-123', 'gmail-sync']
|
||||
});
|
||||
|
||||
console.log('Connected email:', connection.email);
|
||||
console.log('Connection created:', connection.createdAt);
|
||||
|
||||
// List synced email threads
|
||||
const documents = await client.documents.list({
|
||||
containerTags: ['user-123', 'gmail-sync']
|
||||
});
|
||||
|
||||
console.log(`Synced ${documents.memories.length} email threads`);
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```python
|
||||
# Get connection details
|
||||
connection = client.connections.get_by_tags(
|
||||
'gmail',
|
||||
container_tags=['user-123', 'gmail-sync']
|
||||
)
|
||||
|
||||
print(f'Connected email: {connection.email}')
|
||||
print(f'Connection created: {connection.created_at}')
|
||||
|
||||
# List synced email threads
|
||||
documents = client.documents.list(
|
||||
container_tags=['user-123', 'gmail-sync']
|
||||
)
|
||||
|
||||
print(f'Synced {len(documents.memories)} email threads')
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="cURL">
|
||||
```bash
|
||||
# Get connections by provider and tags
|
||||
curl -X POST "https://api.supermemory.ai/v3/connections/list" \
|
||||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"containerTags": ["user-123", "gmail-sync"],
|
||||
"provider": "gmail"
|
||||
}'
|
||||
|
||||
# List synced email threads
|
||||
curl -X POST "https://api.supermemory.ai/v3/documents/list" \
|
||||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"containerTags": ["user-123", "gmail-sync"],
|
||||
"source": "gmail"
|
||||
}'
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## What Gets Synced
|
||||
|
||||
### Email Threads
|
||||
|
||||
Gmail threads (conversations) are synced as individual documents with all messages included:
|
||||
|
||||
- **Thread content** converted to structured markdown
|
||||
- **All messages** within each thread preserved in order
|
||||
- **Message metadata**: subject, from, to, cc, bcc, date
|
||||
- **HTML content** converted to clean markdown
|
||||
- **Attachment metadata**: filename, mime type, size (attachments are referenced, not stored)
|
||||
|
||||
### Document Metadata
|
||||
|
||||
Each synced thread includes searchable metadata:
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `type` | Always `gmail_thread` |
|
||||
| `subject` | Email subject line |
|
||||
| `threadId` | Gmail thread ID |
|
||||
| `from` | Sender email address |
|
||||
| `to` | Recipient email addresses |
|
||||
| `date` | Date of first message |
|
||||
| `messageCount` | Number of messages in thread |
|
||||
| `attachmentCount` | Number of attachments (if any) |
|
||||
| `attachmentNames` | List of attachment filenames |
|
||||
|
||||
You can filter searches using these metadata fields:
|
||||
|
||||
```typescript
|
||||
const results = await client.search.documents({
|
||||
q: "project update",
|
||||
containerTags: ['user-123'],
|
||||
filters: JSON.stringify({
|
||||
AND: [
|
||||
{ key: "type", value: "gmail_thread", negate: false },
|
||||
{ key: "from", value: "team@company.com", negate: false }
|
||||
]
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
## Connection Management
|
||||
|
||||
### List All Connections
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```typescript
|
||||
// List all connections for specific container tags
|
||||
const connections = await client.connections.list({
|
||||
containerTags: ['user-123']
|
||||
});
|
||||
|
||||
connections.forEach(conn => {
|
||||
console.log(`Provider: ${conn.provider}`);
|
||||
console.log(`ID: ${conn.id}`);
|
||||
console.log(`Email: ${conn.email}`);
|
||||
console.log(`Created: ${conn.createdAt}`);
|
||||
console.log(`Document limit: ${conn.documentLimit}`);
|
||||
console.log('---');
|
||||
});
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```python
|
||||
# List all connections for specific container tags
|
||||
connections = client.connections.list(
|
||||
container_tags=['user-123']
|
||||
)
|
||||
|
||||
for conn in connections:
|
||||
print(f'Provider: {conn.provider}')
|
||||
print(f'ID: {conn.id}')
|
||||
print(f'Email: {conn.email}')
|
||||
print(f'Created: {conn.created_at}')
|
||||
print(f'Document limit: {conn.document_limit}')
|
||||
print('---')
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="cURL">
|
||||
```bash
|
||||
# List all connections for specific container tags
|
||||
curl -X POST "https://api.supermemory.ai/v3/connections/list" \
|
||||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"containerTags": ["user-123"]
|
||||
}'
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Delete Connection
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```typescript
|
||||
// Delete by connection ID
|
||||
const result = await client.connections.deleteByID('connection_id_123');
|
||||
console.log('Deleted connection:', result.id);
|
||||
|
||||
// Delete by provider and container tags
|
||||
const providerResult = await client.connections.deleteByProvider('gmail', {
|
||||
containerTags: ['user-123']
|
||||
});
|
||||
console.log('Deleted Gmail connection:', providerResult.id);
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```python
|
||||
# Delete by connection ID
|
||||
result = client.connections.delete_by_id('connection_id_123')
|
||||
print(f'Deleted connection: {result.id}')
|
||||
|
||||
# Delete by provider and container tags
|
||||
provider_result = client.connections.delete_by_provider(
|
||||
'gmail',
|
||||
container_tags=['user-123']
|
||||
)
|
||||
print(f'Deleted Gmail connection: {provider_result.id}')
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="cURL">
|
||||
```bash
|
||||
# Delete by connection ID
|
||||
curl -X DELETE "https://api.supermemory.ai/v3/connections/connection_id_123" \
|
||||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY"
|
||||
|
||||
# Delete by provider and container tags
|
||||
curl -X DELETE "https://api.supermemory.ai/v3/connections/gmail" \
|
||||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"containerTags": ["user-123"]
|
||||
}'
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
Deleting a connection will:
|
||||
- Stop all future syncs from Gmail
|
||||
- Remove the OAuth authorization
|
||||
- Keep existing synced documents in supermemory (they won't be deleted)
|
||||
</Note>
|
||||
|
||||
### Manual Sync
|
||||
|
||||
Trigger a manual synchronization:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```typescript
|
||||
// Trigger sync for Gmail connections
|
||||
await client.connections.import('gmail');
|
||||
|
||||
// Trigger sync for specific container tags
|
||||
await client.connections.import('gmail', {
|
||||
containerTags: ['user-123']
|
||||
});
|
||||
|
||||
console.log('Manual sync initiated');
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```python
|
||||
# Trigger sync for Gmail connections
|
||||
client.connections.import_('gmail')
|
||||
|
||||
# Trigger sync for specific container tags
|
||||
client.connections.import_(
|
||||
'gmail',
|
||||
container_tags=['user-123']
|
||||
)
|
||||
|
||||
print('Manual sync initiated')
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="cURL">
|
||||
```bash
|
||||
# Trigger sync for all Gmail connections
|
||||
curl -X POST "https://api.supermemory.ai/v3/connections/gmail/import" \
|
||||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY"
|
||||
|
||||
# Trigger sync for specific container tags
|
||||
curl -X POST "https://api.supermemory.ai/v3/connections/gmail/import" \
|
||||
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"containerTags": ["user-123"]
|
||||
}'
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Sync Mechanism
|
||||
|
||||
Gmail connector supports multiple sync methods:
|
||||
|
||||
| Feature | Behavior |
|
||||
|---------|----------|
|
||||
| **Real-time sync** | Via Google Cloud Pub/Sub webhooks (7-day expiry, auto-renewed) |
|
||||
| **Scheduled sync** | Every 4 hours |
|
||||
| **Manual sync** | On-demand via API |
|
||||
| **Incremental sync** | Uses Gmail `historyId` to fetch only changed threads |
|
||||
|
||||
### How Real-time Sync Works
|
||||
|
||||
1. When a connection is created, supermemory registers a Gmail API "watch" subscription
|
||||
2. Gmail sends notifications to a Google Cloud Pub/Sub topic when emails change
|
||||
3. supermemory receives these notifications and fetches updated threads
|
||||
4. Watch subscriptions expire after 7 days and are automatically renewed
|
||||
|
||||
<Note>
|
||||
Real-time sync monitors the **INBOX** label. Emails in other labels are synced via scheduled/manual sync.
|
||||
</Note>
|
||||
|
||||
## Permissions & Scopes
|
||||
|
||||
The Gmail connector requests the following OAuth scopes:
|
||||
|
||||
| Scope | Purpose |
|
||||
|-------|---------|
|
||||
| `gmail.readonly` | Read-only access to Gmail messages and threads |
|
||||
| `userinfo.email` | Access to user's email address for connection identification |
|
||||
|
||||
<Warning>
|
||||
**Read-only Access:** The Gmail connector only reads emails. It cannot send, delete, or modify any emails in the user's account.
|
||||
</Warning>
|
||||
|
||||
## Limitations
|
||||
|
||||
<Warning>
|
||||
**Important Limitations:**
|
||||
- **Plan requirement**: Requires Scale Plan or Enterprise Plan
|
||||
- **INBOX only** for real-time sync: Only INBOX label triggers real-time updates; other labels sync via scheduled sync
|
||||
- **Watch expiration**: Gmail watch subscriptions expire after 7 days (automatically renewed by supermemory)
|
||||
- **Document limit**: Default limit is 10,000 threads per connection (configurable via `documentLimit` parameter)
|
||||
- **Attachments**: Attachment metadata is stored, but attachment content is not downloaded
|
||||
- **Rate limits**: Gmail API rate limits may affect sync speed for accounts with many emails
|
||||
</Warning>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### OAuth Fails or Missing Refresh Token
|
||||
|
||||
If OAuth fails or the connection stops syncing:
|
||||
|
||||
1. Delete the existing connection
|
||||
2. Create a new connection
|
||||
3. Ensure the user completes the full OAuth flow with consent
|
||||
|
||||
```typescript
|
||||
// Re-create connection to get fresh tokens
|
||||
await client.connections.deleteByProvider('gmail', {
|
||||
containerTags: ['user-123']
|
||||
});
|
||||
|
||||
const newConnection = await client.connections.create('gmail', {
|
||||
redirectUrl: 'https://yourapp.com/auth/gmail/callback',
|
||||
containerTags: ['user-123']
|
||||
});
|
||||
|
||||
// User must re-authenticate
|
||||
window.location.href = newConnection.authLink;
|
||||
```
|
||||
|
||||
### Emails Not Syncing in Real-time
|
||||
|
||||
If real-time sync isn't working:
|
||||
|
||||
- Scheduled sync (every 4 hours) and manual sync still work
|
||||
- Real-time sync requires supermemory's Pub/Sub infrastructure
|
||||
- Check if the connection was created recently (watch registration happens on creation)
|
||||
- Trigger a manual sync to verify the connection is working
|
||||
|
||||
### Permission Denied Errors
|
||||
|
||||
If you see permission errors:
|
||||
|
||||
- Ensure the user granted the required Gmail scopes during OAuth
|
||||
- Verify your organization has Scale Plan or Enterprise Plan access
|
||||
- Check if the user revoked app access in their Google Account settings
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
title: "Connectors Overview"
|
||||
description: "Integrate Google Drive, Notion, OneDrive, GitHub and Web Crawler to automatically sync documents into your knowledge base"
|
||||
description: "Integrate Google Drive, Gmail, Notion, OneDrive, GitHub and Web Crawler to automatically sync documents into your knowledge base"
|
||||
sidebarTitle: "Overview"
|
||||
icon: "layers"
|
||||
---
|
||||
|
||||
Connect external platforms to automatically sync documents into Supermemory. Supported connectors include Google Drive, Notion, OneDrive, GitHub and Web Crawler with real-time synchronization and intelligent content processing.
|
||||
Connect external platforms to automatically sync documents into supermemory. Supported connectors include Google Drive, Gmail, Notion, OneDrive, GitHub and Web Crawler with real-time synchronization and intelligent content processing.
|
||||
|
||||
## Supported Connectors
|
||||
|
||||
|
|
@ -16,6 +16,12 @@ Connect external platforms to automatically sync documents into Supermemory. Sup
|
|||
Real-time sync via webhooks. Supports shared drives, nested folders, and collaborative documents.
|
||||
</Card>
|
||||
|
||||
<Card title="Gmail" icon="mail" href="/connectors/gmail">
|
||||
**Email Threads**
|
||||
|
||||
Real-time sync via Pub/Sub webhooks. Syncs threads with full conversation history and metadata.
|
||||
</Card>
|
||||
|
||||
<Card title="Notion" icon="notion" href="/connectors/notion">
|
||||
**Pages, Databases, Blocks**
|
||||
|
||||
|
|
@ -218,6 +224,7 @@ graph TD
|
|||
| Provider | Real-time Sync | Scheduled Sync | Manual Sync |
|
||||
|----------|---------------|----------------|-------------|
|
||||
| **Google Drive** | ✅ Webhooks (7-day expiry) | ✅ Every 4 hours | ✅ On-demand |
|
||||
| **Gmail** | ✅ Pub/Sub (7-day expiry) | ✅ Every 4 hours | ✅ On-demand |
|
||||
| **Notion** | ✅ Webhooks | ✅ Every 4 hours | ✅ On-demand |
|
||||
| **OneDrive** | ✅ Webhooks (30-day expiry) | ✅ Every 4 hours | ✅ On-demand |
|
||||
| **GitHub** | ✅ Webhooks | ✅ Every 4 hours | ✅ On-demand |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "Connector Troubleshooting"
|
||||
sidebarTitle: "Troubleshooting"
|
||||
description: "Diagnose and resolve common issues with Google Drive, Notion, and OneDrive connectors"
|
||||
description: "Diagnose and resolve common issues with Google Drive, Gmail, Notion, and OneDrive connectors"
|
||||
icon: "wrench"
|
||||
---
|
||||
|
||||
|
|
@ -182,6 +182,49 @@ Business accounts may have additional restrictions:
|
|||
- Some SharePoint sites may be restricted
|
||||
- Compliance policies may block certain files
|
||||
|
||||
### Gmail
|
||||
|
||||
**Real-time Sync Not Working**
|
||||
|
||||
If emails aren't syncing in real-time but scheduled/manual sync works:
|
||||
|
||||
1. Real-time sync uses Google Cloud Pub/Sub webhooks
|
||||
2. Watch subscriptions expire after 7 days (supermemory auto-renews)
|
||||
3. Only INBOX label triggers real-time updates
|
||||
4. Trigger a manual sync to verify the connection is healthy:
|
||||
|
||||
```typescript
|
||||
await client.connections.import('gmail', {
|
||||
containerTags: ['user-123']
|
||||
});
|
||||
```
|
||||
|
||||
**Missing Refresh Token**
|
||||
|
||||
If Gmail stops syncing after initial setup:
|
||||
|
||||
1. The user may have revoked app access in Google Account settings
|
||||
2. Delete and recreate the connection
|
||||
3. Ensure user completes full OAuth consent flow
|
||||
|
||||
```typescript
|
||||
// Re-authenticate to get fresh tokens
|
||||
await client.connections.deleteByProvider('gmail', {
|
||||
containerTags: ['user-123']
|
||||
});
|
||||
|
||||
const newConnection = await client.connections.create('gmail', {
|
||||
redirectUrl: 'https://yourapp.com/callback',
|
||||
containerTags: ['user-123']
|
||||
});
|
||||
```
|
||||
|
||||
**Scale Plan Required Error**
|
||||
|
||||
Gmail connector requires Scale Plan or Enterprise Plan. If you see access errors:
|
||||
- Verify your organization has the required plan
|
||||
- Contact support to upgrade your plan
|
||||
|
||||
|
||||
## Best Practices
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@
|
|||
"pages": [
|
||||
"connectors/notion",
|
||||
"connectors/google-drive",
|
||||
"connectors/gmail",
|
||||
"connectors/onedrive",
|
||||
"connectors/s3",
|
||||
"connectors/github",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue