Installation
This guide walks you through setting up DelightBridge from scratch, including database setup, Google OAuth configuration, environment variables, and deployment options.Prerequisites
Before you begin, ensure you have:- Node.js 20+ and pnpm installed
- A Neon DB account (or any PostgreSQL database)
- A Google Cloud Platform project with OAuth credentials
- An Anthropic API key
- (Optional) A Vercel account for deployment
Step 1: Clone and install dependencies
Step 2: Set up the database
DelightBridge uses Neon DB (serverless PostgreSQL) with Drizzle ORM.Create a Neon DB project
- Go to console.neon.tech
- Click “New Project”
- Choose a region close to your users
- Copy the connection string (starts with
postgresql://)
Push the database schema
Drizzle will create all tables automatically:This creates the following tables:
users— Workspace members with authentication infoworkspace_members— Email allowlist for logingmail_accounts— Services (Gmail accounts) with OAuth tokenscategories— Service-specific email categoriesemail_threads— Email conversationsemails— Individual messages within threadsdrafts— AI-generated reply drafts
You can view and edit your database using Drizzle Studio:This opens a web UI at
https://local.drizzle.studio.Step 3: Configure Google OAuth
DelightBridge uses Google OAuth for two purposes:- App authentication (NextAuth): Who can log in to the workspace
- Service Gmail connection: Which Gmail accounts to sync
Create OAuth credentials
- Go to Google Cloud Console
- Create a new project or select an existing one
- Navigate to APIs & Services > Credentials
- Click “Create Credentials” > “OAuth 2.0 Client ID”
- Choose “Web application”
Configure authorized redirect URIs
Add the following redirect URIs:For local development:For production (replace with your domain):
Enable Gmail API
- In Google Cloud Console, go to APIs & Services > Library
- Search for “Gmail API”
- Click “Enable”
Step 4: Configure NextAuth
NextAuth handles user authentication and sessions.Generate AUTH_SECRET
Generate a random secret for session encryption:Add it to
.env.local:.env.local
Step 5: Configure Anthropic API
DelightBridge uses Claude Sonnet 4 for draft generation.Get an Anthropic API key
- Go to console.anthropic.com
- Sign up or log in
- Navigate to API Keys
- Click “Create Key”
- Copy the key (starts with
sk-ant-)
Step 6: Configure Vercel Cron (optional)
For automatic Gmail sync every 5 minutes, set up Vercel Cron.Generate a cron secret
.env.local:.env.local
CRON_SYNC_MAX_ACCOUNTS limits how many services are synced per cron run (prevents timeout).Step 7: Complete environment configuration
Your final.env.local should include all of these variables:
.env.local
Step 8: Run locally
Step 9: Deploy to Vercel (optional)
Add environment variables
In the Vercel dashboard:
- Go to Settings > Environment Variables
- Add all variables from
.env.local - Make sure to add them for Production, Preview, and Development environments
Update OAuth redirect URIs
Go back to Google Cloud Console and add your Vercel domain to the authorized redirect URIs:
Step 10: Seed initial data (optional)
For testing, you can seed the database with sample data:- Sample services (Noji, AnkiPro)
- Categories for each service
- Mock email threads
Database schema reference
Here’s an overview of the database tables:users
Stores authenticated workspace members.
| Column | Type | Description |
|---|---|---|
id | text | Primary key (e.g., user-123) |
googleId | text | Google OAuth sub (unique) |
email | text | User email (unique) |
name | text | Display name |
picture | text | Profile picture URL |
permission | enum | view, edit, send, or admin |
createdAt | timestamp | Account creation time |
workspace_members
Email allowlist for login (invite-only).
| Column | Type | Description |
|---|---|---|
email | text | Primary key |
permission | enum | Default permission level |
createdAt | timestamp | When added |
gmail_accounts
Services (Gmail accounts).
| Column | Type | Description |
|---|---|---|
id | text | Primary key (e.g., service-123) |
name | text | Service name (e.g., “Noji”) |
email | text | Connected Gmail address |
color | text | Brand color (hex) |
signature | text | HTML email signature |
document | text | Reference docs (Markdown) |
accessToken | text | OAuth access token |
refreshToken | text | OAuth refresh token |
lastHistoryId | text | Gmail sync cursor |
createdAt | timestamp | Service creation time |
categories
Service-specific email categories.
| Column | Type | Description |
|---|---|---|
id | text | Primary key |
accountId | text | Foreign key to gmail_accounts |
name | text | Category name |
color | text | Background color (hex) |
textColor | text | Text color (hex) |
email_threads
Email conversations.
| Column | Type | Description |
|---|---|---|
id | text | Primary key |
accountId | text | Foreign key to gmail_accounts |
gmailThreadId | text | Gmail thread ID |
subject | text | Email subject |
customerEmail | text | Customer email address |
customerName | text | Customer name |
categoryId | text | Auto-assigned category |
status | enum | inbox, sent, or archived |
detectedLanguage | text | Language code (e.g., en) |
isRead | boolean | Read status |
lastMessageAt | timestamp | Last message time |
createdAt | timestamp | Thread creation time |
emails
Individual messages within threads.
| Column | Type | Description |
|---|---|---|
id | text | Primary key |
threadId | text | Foreign key to email_threads |
gmailMessageId | text | Gmail message ID |
fromEmail | text | Sender email |
fromName | text | Sender name |
toEmail | text | Recipient email |
body | text | HTML body |
direction | enum | inbound or outbound |
sentAt | timestamp | Message timestamp |
createdAt | timestamp | DB creation time |
drafts
AI-generated reply drafts.
| Column | Type | Description |
|---|---|---|
id | text | Primary key |
threadId | text | Foreign key to email_threads (unique) |
subject | text | Reply subject |
content | text | HTML body |
translation | text | Korean translation |
status | enum | pending, ready, sent, or skipped |
sentAt | timestamp | When sent |
updatedAt | timestamp | Last edit time |
Project structure
Available commands
Next steps
Quickstart
Follow the quickstart guide to connect your first service and generate a draft
Team Collaboration
Add team members and configure permissions
Gmail Integration
Learn about automatic sync, manual triggers, and troubleshooting
API Reference
Explore the REST API endpoints
Troubleshooting
Database connection fails
Database connection fails
- Check DATABASE_URL: Ensure it’s a valid PostgreSQL connection string
- Check SSL mode: Neon requires
?sslmode=requireat the end of the URL - Check IP allowlist: Some databases restrict connections by IP
OAuth redirect mismatch
OAuth redirect mismatch
- Check redirect URIs: Make sure all URIs are added in Google Cloud Console
- Check protocol: Use
http://for localhost andhttps://for production - Check trailing slashes: Google is strict about exact URI matches
Build errors
Build errors
- Check Node version: Use Node 20+
- Clear cache: Run
rm -rf .next node_modules pnpm-lock.yaml && pnpm install - Check TypeScript: Run
pnpm buildto see type errors
Environment variables not loading
Environment variables not loading
- Restart dev server:
.env.localchanges require a restart - Check file name: It must be exactly
.env.local(not.env) - Check deployment platform: Add variables in Vercel/Railway dashboard