AI-powered email personalization tool with Gmail and Google Sheets integration for Google Workspace organizations.
- Google Cloud Apps Script: Centralized LLM API key management for team-wide use
- Google Workspace Integration: OAuth-based authentication for Gmail and Sheets APIs
- Internal Use Only: Configured for your organization's workspace members
- Smart Navigation: Auto-opens the right tab based on setup completion
- Auto-Save Configuration: All settings save automatically on blur
- Config Tab: Connect Google account, configure sheets, and select LLM model
- Context Tab: Create and edit email templates with variable placeholders
- Email Tab: Generate personalized emails, send to contacts, and track status
- Privacy Protected: Contact data never sent to AI - only your template
- Persistent Storage: Configuration and model selections saved across restarts
Prerequisites:
- Google Workspace organization
- Administrative access to deploy a Google Apps Script
Setup Steps:
-
Apps Script Configuration - See APPS_SCRIPT_SETUP.md
- Deploy the included Google Apps Script
- Grant it access to your Workspace credentials
- Distribute the Web App URL to your team members
-
Build and Distribute
npm install npm run electron:build
- Distribute the packaged app to team members
- Users will authenticate using the Web App URL on first run
Once the app is set up by your admin:
- Launch the app - It will open on the Configuration tab
- Connect Google Account:
- Enter your name and Gmail address (auto-saves on blur)
- Click "Connect Google Account"
- Paste the Apps Script Web App URL provided by your admin into the configuration field
- Authorize in your browser
- Grant permissions to the application
- Configure Integration:
- Paste your Google Sheet URL
- Test the sheet connection
- Select LLM Model:
- Click "Fetch Models" to load available Gemini models
- Select your preferred model (e.g., gemini-1.5-flash)
- Settings save automatically
- Create Template - Navigate to Context tab
- Write your email template
- Use
{{firstName}}and{{lastName}}placeholders
- Send Emails - Navigate to Email tab
- Generate personalized emails with AI
- Review, edit, and send
The app will remember your settings and automatically open the Email tab on next launch.
See USER_SETUP_GUIDE.md for detailed instructions and troubleshooting.
# Install dependencies
npm install
# Run in development mode
npm run electron:dev
# Build for production
npm run electron:build- OAuth 2.0: All Google API access via user's OAuth tokens
- Apps Script Config: Secret credentials retrieved through secure script URL
- Encrypted Storage: Configuration stored using electron-store encryption
- Content Security Policy: Strict CSP in production, relaxed for HMR in dev
- Context Isolation: Electron security best practices enabled
See SECURITY.md for detailed security architecture.
-
Main Process (
src/main/):index.ts- Electron app lifecycle and window managementconfigFetcher.ts- Local server to catch Apps Script redirectsgmail.ts- Gmail API OAuth and email sendingsheets.ts- Google Sheets API integrationsecrets.ts- Credential storage/retrieval via electron-storepreload.ts- Secure IPC bridge
-
Renderer Process (
src/renderer/):App.tsx- Main app with smart tab navigationcomponents/ConfigTab.tsx- Auto-save configuration UIcomponents/ContextTab.tsx- Template editorcomponents/EmailTab.tsx- Email generation and sendingservices/llm.ts- LLM API integration (Gemini/OpenAI)
-
Download the app:
- Go to the Releases page: https://github.com/democracy-lab/ai-mail/releases
- Look for the latest release (e.g.,
v1.0.0). - Download the
ai-mail-setup-X.X.X.exe(NSIS Installer) orai-mail-portable-X.X.X.exe(Run without installing).
-
First-time setup:
- Launch the app. The "Smart Navigation" will guide you through the initial configuration:
- User Info: Enter your name and work email.
- Google Account: Paste the admin-provided Apps Script Web App URL and click connect to securely authenticate your workspace account and pull down required configurations.
- Google Sheet: Paste the link to your contact spreadsheet.
- LLM: Select your preferred AI model (Gemini/OpenAI).
- Launch the app. The "Smart Navigation" will guide you through the initial configuration:
-
Secure API Access: The app securely fetches your LLM API Key and internal configuration through a Google Apps Script endpoint authorized by your organization's Workspace account.
-
Clone the repository:
git clone https://github.com/democracy-lab/ai-email.git cd ai-email -
Install dependencies:
npm install
-
Environment Setup:
- Follow APPS_SCRIPT_SETUP.md for configuring the environment using Google Apps Script.
-
Run in Development:
npm run dev
-
Build for Production:
- On Windows, enable Developer Mode in settings to allow symbolic links.
- Run:
npm run electron:build.
The app validates and auto-saves all settings:
- User Information: Name and Gmail address (validates email format)
- Google Account: OAuth connection with test button
- Google Sheets:
- Paste full spreadsheet URL (auto-extracts ID)
- Specify sheet tab name
- Validates required columns
- LLM Configuration:
- Fetch available models from API
- Select model (saves with cached model list)
- API key managed centrally via Apps Script
Status messages appear inline with each section showing success/error feedback.
- Write your email template in the rich text editor
- Use placeholders:
{{firstName}},{{lastName}} - Template auto-saves as you type
- Placeholders replaced locally after AI generation
Important: Only the template is sent to the LLM. Contact names are filled in afterwards, preserving privacy.
- Load Contacts: Fetches from Google Sheets via API
- Generate Email:
- Sends template to LLM
- LLM creates personalized email structure
- Placeholders replaced with contact info
- Review & Edit: Full rich-text editing before sending
- Send:
- Test button sends to yourself
- Send button uses Gmail API
- Updates sheet with status and Gmail Message ID
- Navigate: Previous/Next buttons to process multiple contacts
Required columns:
Email Address- Contact's emailFirst Name- For {{firstName}} placeholderLast Name- For {{lastName}} placeholder
Optional columns (auto-created if missing):
Team Member- Who sent the email (your name)Status- sent/skipped/errorDate Sent- TimestampGmail Message ID- For tracking
The app validates column presence and shows clear error messages if sheet structure is incorrect.
Multiple team members can use the app simultaneously:
- Each person authenticates with their own Google account
- Shared LLM API key accessed via Apps Script (requires IAM permission)
- App updates "Team Member" column after sending
- Contacts with filled "Team Member" column are skipped
- No conflicts or overwrites between users
- Electron - Desktop application framework
- React 18 - UI framework
- TypeScript - Type safety throughout
- Vite - Fast build tool with HMR
- Tailwind CSS - Utility-first styling
- react-quill - Rich text email editor
- googleapis - Gmail and Sheets API clients
- google-auth-library - OAuth 2.0 authentication
- electron-store - Encrypted local configuration
- Content Security Policy - XSS protection
Require user-provided URL during runtime inside configuration panel to fetch environments and complete setup flows via Google Apps Script.
The app requests these scopes:
https://www.googleapis.com/auth/gmail.send- Send emailshttps://www.googleapis.com/auth/gmail.readonly- Test connectionhttps://www.googleapis.com/auth/spreadsheets- Read/write sheets
- Development: Relaxed CSP allows
unsafe-evalfor Vite HMR - Production: Strict CSP with no eval, whitelisted API domains
- See SECURITY.md for details
Google Account won't connect
- Ensure you have correctly pasted your IT Admin's provided Google Apps Script URL.
- Verify OAuth consent screen is set to "Internal"
- Ensure you're signed in with a workspace account (not free Gmail)
- Ensure user is part of your Google Workspace
Can't access Apps Script
- Verify user has "Apps Script Secret Accessor" IAM role
- Check secret name is exactly
llm-api-key - Confirm
GCP_PROJECT_IDmatches your GCP project
Sheet validation fails
- Required columns must be exact:
Email Address,First Name,Last Name - Column headers must be in the first row
- Verify user's Google account has edit access to sheet
Model fetch fails
- Ensure Apps Script connection works
- Check API key in Apps Script is valid
- Try disconnecting and reconnecting Google account
LLM errors
- Verify model is selected in Configuration
- Check API key in Apps Script is valid
- For Gemini: ensure model name format is correct (e.g.,
gemini-1.5-flash)
List formatting problems
- LLM uses single newlines for list items
- Double newlines create paragraph breaks
- Check generated email preview before sending
See USER_SETUP_GUIDE.md for more troubleshooting steps.
- README.md - This file, overview and quick start
- OAUTH_SETUP.md - Complete OAuth configuration guide
- SECRET_MANAGER_SETUP.md - Apps Script setup instructions
- SECURITY.md - Security architecture and CSP details
- USER_SETUP_GUIDE.md - End-user setup and troubleshooting
- spec.md - Technical specification and architecture
MIT