A backend system that connects to Gmail, stores sent emails with embeddings, and generates AI-powered draft replies using Groq API that match your writing style.
- Gmail OAuth2 Integration: Secure authentication with Gmail
- Email Fetching: Retrieve inbox and sent emails
- Embedding Storage: Store sent emails with vector embeddings for style matching
- AI Draft Generation: Generate contextual email drafts using Groq API
- Style Matching: Uses similarity search to match your past email writing style
npm install
# or
pnpm installCreate a .env.local file in the root directory and add the following variables:
# Gmail OAuth2 Credentials
GMAIL_CLIENT_ID=your_gmail_client_id_here
GMAIL_CLIENT_SECRET=your_gmail_client_secret_here
GMAIL_REDIRECT_URI=http://localhost:3000/api/auth/gmail/callback
# Groq API Key
GROQ_API_KEY=your_groq_api_key_here
# Embedding API Key (Optional - leave empty for free Hugging Face API)
EMBEDDING_API_KEY=
# Frontend URL
NEXT_PUBLIC_APP_URL=http://localhost:3000- Go to Google Cloud Console
- Create a new project or select an existing one
- Enable the Gmail API
- Go to "Credentials" → "Create Credentials" → "OAuth 2.0 Client ID"
- Set application type to "Web application"
- Add authorized redirect URI:
http://localhost:3000/api/auth/gmail/callback(or your production URL) - Copy the Client ID and Client Secret to your
.env.local
- Go to Groq Console
- Sign up or log in
- Navigate to API Keys section
- Create a new API key
- Copy it to your
.env.local
- Free Option: Leave
EMBEDDING_API_KEYempty to use Hugging Face's free Inference API - OpenAI Option: Provide an OpenAI API key (starts with
sk-) for OpenAI embeddings - Hugging Face Option: Provide a Hugging Face API key for authenticated requests
The backend includes several optimizations for fast embedding generation:
- Batch Processing: Embeddings are generated in parallel batches (default: 10 at a time)
- Background Processing: Use
/api/emails/syncto process emails in the background - Rate Limiting: Automatic delays between batches to respect API rate limits
- Error Handling: Failed embeddings don't block the entire process
- Caching: Already processed emails are skipped
For the first time setup with many sent emails, use the sync endpoint:
POST /api/emails/sync?maxResults=500This will:
- Fetch all sent emails
- Process them in the background (returns immediately)
- Generate embeddings asynchronously
- Store them for future draft generation
Check sync status:
GET /api/emails/syncGet the OAuth2 authorization URL for Gmail authentication.
Response:
{
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth?..."
}OAuth callback endpoint. Handles the redirect from Google after authentication.
Query Parameters:
code: Authorization code from Googleerror: Error message if authentication failed
Response: Redirects to frontend with ?auth=success or ?auth=error
Clear stored authentication tokens.
Response:
{
"success": true,
"message": "Logged out successfully"
}Fetch emails from Gmail.
Query Parameters:
type:"inbox"(default) or"sent"maxResults: Number of emails to fetch (default: 50)
Response:
{
"emails": [
{
"id": "email_id",
"threadId": "thread_id",
"subject": "Email subject",
"from": "sender@example.com",
"to": "recipient@example.com",
"date": "Date string",
"body": "Email body text",
"snippet": "Email snippet",
"labels": ["INBOX", "UNREAD"]
}
],
"count": 10
}Get a specific email by ID.
Response:
{
"email": {
"id": "email_id",
"subject": "Email subject",
"from": "sender@example.com",
"to": "recipient@example.com",
"date": "Date string",
"body": "Email body text",
"snippet": "Email snippet"
}
}Generate an AI draft reply for a specific email.
Response:
{
"draft": "Generated draft reply text...",
"emailId": "email_id",
"subject": "Re: Original subject"
}Background sync endpoint for bulk processing sent emails with embeddings.
Query Parameters:
maxResults: Number of sent emails to process (default: 100)
Response:
{
"message": "Email processing started in background",
"queued": 50,
"total": 100
}Usage: Call this endpoint once after initial Gmail connection to process all sent emails in the background.
Get sync status and statistics.
Response:
{
"totalStored": 150,
"sentWithEmbeddings": 100,
"lastSync": 1704067200000
}- Frontend calls
GET /api/auth/gmailto get authorization URL - User is redirected to Google to authorize
- Google redirects back to
/api/auth/gmail/callbackwith authorization code - Backend exchanges code for access/refresh tokens
- Tokens are stored locally in
data/tokens.json
- Sent Emails: When fetched, sent emails are stored in
data/emails.jsonwith embeddings - Received Emails: Inbox emails are stored without embeddings (for reference only)
- Embeddings are generated using Hugging Face (free) or OpenAI API
- User requests a draft for an incoming email
- System generates embedding for the incoming email
- Finds most similar past sent emails using cosine similarity
- Uses Groq API to generate a draft that matches the user's writing style
- Returns plain text draft ready for review
├── app/
│ └── api/
│ ├── auth/
│ │ ├── gmail/
│ │ │ ├── route.ts # Get auth URL
│ │ │ └── callback/
│ │ │ └── route.ts # OAuth callback
│ │ └── logout/
│ │ └── route.ts # Logout
│ └── emails/
│ ├── route.ts # Fetch emails
│ └── [id]/
│ └── draft/
│ └── route.ts # Generate draft
├── lib/
│ ├── gmail.ts # Gmail API utilities
│ ├── embeddings.ts # Embedding generation
│ ├── similarity.ts # Similarity search
│ ├── ai-draft.ts # AI draft generation
│ └── storage.ts # Local storage
└── data/ # Generated at runtime
├── emails.json # Stored emails with embeddings
└── tokens.json # OAuth tokens
The backend uses file-based storage (JSON files) in the data/ directory:
data/emails.json: Stores all emails with embeddingsdata/tokens.json: Stores OAuth2 tokens
Note: For production, consider migrating to a proper database (PostgreSQL, MongoDB, etc.) for better performance and scalability.
All endpoints return appropriate HTTP status codes:
200: Success400: Bad request (missing parameters)401: Unauthorized (not authenticated)404: Not found500: Server error
Error responses include a details field with more information.
Run the development server:
npm run dev
# or
pnpm devThe API will be available at http://localhost:3000/api/...
- Database: Replace file-based storage with a proper database
- Token Refresh: Implement automatic token refresh for expired access tokens
- Rate Limiting: Add rate limiting to prevent API abuse
- Error Logging: Implement proper error logging and monitoring
- Security: Ensure
.env.localanddata/directory are in.gitignore - CORS: Configure CORS if frontend is on a different domain
- Ensure all Gmail environment variables are set in
.env.local
- User needs to complete OAuth flow first by calling
/api/auth/gmail
- User needs to send some emails first so the system can learn their writing style
- Check your
EMBEDDING_API_KEYif using a paid service - Free Hugging Face API may have rate limits
- Verify your
GROQ_API_KEYis correct - Check Groq API status and rate limits