Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ReachInbox

AI-Powered Email Intelligence Platform - Real-time IMAP synchronization with AI categorization, Elasticsearch search, and Slack integration.

Next.js TypeScript Node.js Elasticsearch PostgreSQL Docker


πŸ“‹ Table of Contents


✨ Features

πŸ”„ Real-Time Email Synchronization

  • Multi-Account Support: Sync multiple IMAP accounts simultaneously (minimum 2 accounts)
  • Persistent IMAP Connections: Uses IMAP IDLE mode for instant email notifications (no polling/cron jobs)
  • Historical Backfill: Automatically fetches and indexes the last 30 days of emails on first sync
  • Real-time Updates: New emails appear instantly in the dashboard via WebSocket

πŸ” Advanced Search with Elasticsearch

  • Full-Text Search: Search across email subject, body, sender name, and email address
  • Locally Hosted: Docker-based Elasticsearch instance for complete data privacy
  • Powerful Filtering: Filter by account, folder (INBOX, Sent, Archive), and AI labels
  • Fast & Scalable: Elasticsearch indexing ensures sub-second search results

πŸ€– AI-Based Email Categorization

Intelligent email classification using rule-based AI with the following labels:

  • Interested 🟒 - Positive responses, meetings accepted, engagement signals
  • Meeting Booked πŸ”΅ - Calendar invites, confirmed meetings, scheduled calls
  • Not Interested ⚫ - Rejections, opt-outs, negative responses
  • Spam πŸ”΄ - Marketing emails, automated messages, suspicious content
  • Out of Office 🟑 - Auto-replies, vacation messages

πŸ”” Slack & Webhook Integration

  • Slack Notifications: Instant notifications to Slack for every "Interested" email
  • Webhook Support: Trigger external automations via webhooks for "Interested" emails
  • Configurable: Easy webhook URL configuration via environment variables

✨ AI-Powered Suggested Replies (RAG)

NEW: Intelligent reply suggestions using Retrieval-Augmented Generation with OpenAI

  • Context-Aware Responses: AI analyzes email content and retrieves relevant context from your knowledge base
  • OpenAI GPT-4o-mini: Generates professional, personalized reply suggestions
  • Vector Embeddings: Uses text-embedding-3-small for semantic similarity search
  • Knowledge Base: Store training data with context-response pairs
  • One-Click Copy: Copy suggested replies to clipboard
  • Real-Time Generation: Get AI suggestions directly in the email dashboard
  • Persistent Storage: All suggestions saved to database for tracking and analytics

Example Use Case: Job application emails

  • Training data: "Include meeting booking link: https://cal.com/example when recruiter shows interest"
  • AI automatically suggests replies with appropriate links when detecting recruitment interest
  • Professional tone maintained across all suggestions

🎨 Professional Dashboard UI

  • Modern Design: Beautiful gradient-based UI with Remix Icons
  • Real-time Stats: Live email count cards (Total, Interested, Meetings, Not Interested)
  • Live Updates: WebSocket-powered real-time email list updates
  • Color-Coded Labels: Visual categorization with professional color scheme
  • Responsive: Mobile-friendly layout with Tailwind CSS v4
  • Advanced Filtering: Filter by account, folder, and search functionality

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         Frontend (Next.js)                       β”‚
β”‚                     http://localhost:3000                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚  β”‚  Dashboard   β”‚  β”‚    Search    β”‚  β”‚   Filters    β”‚          β”‚
β”‚  β”‚  (Stats UI)  β”‚  β”‚  (Real-time) β”‚  β”‚ (Account/Folder)β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚ WebSocket + REST API
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Backend (Node.js + Express)                        β”‚
β”‚                http://localhost:4000                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚  β”‚  API Server  β”‚  β”‚  WebSocket   β”‚  β”‚ IMAP Sync    β”‚          β”‚
β”‚  β”‚  (Express)   β”‚  β”‚  (Socket.IO) β”‚  β”‚  Service     β”‚          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β”‚           β”‚                 β”‚                 β”‚                 β”‚
β”‚           β–Ό                 β–Ό                 β–Ό                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚  β”‚ AI Classifierβ”‚  β”‚   Labeler    β”‚  β”‚  Event Bus   β”‚          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό                    β–Ό                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PostgreSQL   β”‚    β”‚Elasticsearch β”‚    β”‚    Slack     β”‚
β”‚   (Prisma)   β”‚    β”‚   (Search)   β”‚    β”‚  (Webhooks)  β”‚
β”‚ localhost:5432β”‚   β”‚ localhost:9200β”‚   β”‚              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow:

  1. IMAP Service connects to Gmail accounts via IDLE mode
  2. New emails trigger events on the event bus
  3. AI Classifier analyzes and labels emails
  4. Persistence Layer stores in PostgreSQL + Elasticsearch
  5. WebSocket broadcasts to connected frontend clients
  6. Slack Integration sends notifications for interested emails
  7. Frontend receives real-time updates and displays in UI

πŸ› οΈ Tech Stack

Frontend

  • Next.js 14.0.0 - React framework with API routes
  • TypeScript 5.9.3 - Type-safe development
  • Tailwind CSS 4.0 - Modern utility-first CSS
  • React Icons - Professional Remix icon library
  • Socket.IO Client - Real-time WebSocket communication
  • SWR - React hooks for data fetching

Backend

  • Node.js (ES Modules) - JavaScript runtime
  • Express 4.x - Web framework for REST API
  • Socket.IO 4.x - WebSocket server for real-time updates
  • ImapFlow - IMAP client with IDLE support
  • Prisma - Modern database ORM
  • Elasticsearch Client - Search engine integration
  • Pino - Fast JSON logger
  • OpenAI 6.8.1 - AI-powered reply suggestions with GPT-4o-mini and embeddings

Infrastructure

  • PostgreSQL 16 - Primary database
  • Elasticsearch 8.15.3 - Search and analytics engine
  • Kibana 8.15.3 - Elasticsearch visualization
  • Docker Compose - Container orchestration

πŸ“¦ Prerequisites

Before you begin, ensure you have the following installed:

Gmail App Password Setup

For each Gmail account you want to sync:

  1. Enable 2-Factor Authentication in your Google Account
  2. Go to: https://myaccount.google.com/apppasswords
  3. Create an App Password for "Mail"
  4. Copy the 16-character password (format: xxxx xxxx xxxx xxxx)

πŸš€ Quick Start

1️⃣ Clone the Repository

git clone https://github.com/sh3bh1t/ReachInbox.git
cd ReachInbox

2️⃣ Start Docker Services

docker compose up -d

Wait 30 seconds for Elasticsearch to initialize.

Verify services are running:

docker ps

You should see:

  • onebox_pg (PostgreSQL)
  • onebox_es (Elasticsearch)
  • onebox_kibana (Kibana)

3️⃣ Setup Backend

cd apps/imap-sync

# Install dependencies
pnpm install

# Generate Prisma client
npx prisma generate

# Run database migrations
npx prisma migrate deploy

# Start backend server
pnpm dev

Backend will start on port 4000 and immediately begin syncing emails.

4️⃣ Setup Frontend

Open a new terminal:

cd apps/web

# Install dependencies (if not already done)
pnpm install

# Start Next.js development server
pnpm dev

Frontend will start on port 3000

5️⃣ Access the Application

πŸŽ‰ Open your browser: http://localhost:3000

You should see:

  • Beautiful dashboard with gradient UI
  • Stats cards (Total, Interested, Meetings, Not Interested)
  • Real-time connection indicator (green dot = connected)
  • Email list (will populate in 1-2 minutes as sync completes)

πŸ“– Detailed Setup

Backend Configuration

Environment Variables (apps/imap-sync/.env)

NODE_ENV=development

# Account A (Gmail)
A_IMAP_HOST=imap.gmail.com
A_IMAP_PORT=993
A_IMAP_SECURE=true
A_IMAP_USER=your-email@gmail.com
A_IMAP_PASS=your-app-password
A_FOLDERS=INBOX

# Account B (Gmail)
B_IMAP_HOST=imap.gmail.com
B_IMAP_PORT=993
B_IMAP_SECURE=true
B_IMAP_USER=second-email@gmail.com
B_IMAP_PASS=second-app-password
B_FOLDERS=INBOX

# Database (update with your PostgreSQL credentials)
DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public"

# Elasticsearch
ELASTIC_URL=http://localhost:9200

# Slack Webhook (Optional)
INTERESTED_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL

# OpenAI API (for AI-powered suggested replies)
OPENAI_API_KEY=sk-proj-...your-api-key...
OPENAI_CHAT_MODEL=gpt-4o-mini
OPENAI_EMBED_MODEL=text-embedding-3-small

Important:

  • Replace your-email@gmail.com with your actual Gmail addresses
  • Replace your-app-password with the 16-character App Password from Google
  • Replace USER:PASSWORD@HOST:PORT/DATABASE with your PostgreSQL credentials:
    • For local Docker setup: onebox:onebox@localhost:5432/onebox
    • For custom setup: Update with your database credentials
  • OpenAI API Key: Get from https://platform.openai.com/api-keys (required for AI reply suggestions)
  • You can add more accounts by following the same pattern (C_, D_, etc.)

Database Setup

cd apps/imap-sync

# Generate Prisma client (do this after any schema changes)
npx prisma generate

# Apply migrations
npx prisma migrate deploy

# Optional: Open Prisma Studio to view data
npx prisma studio

Frontend Configuration

Environment Variables (apps/web/.env.local)

NEXT_PUBLIC_API_URL=http://localhost:4000

This tells the frontend where to find the backend API.

RAG (AI Reply Suggestions) Setup

1. Get OpenAI API Key

  1. Visit https://platform.openai.com/api-keys
  2. Create a new API key
  3. Add to apps/imap-sync/.env:
    OPENAI_API_KEY=sk-proj-...your-api-key...
    OPENAI_CHAT_MODEL=gpt-4o-mini
    OPENAI_EMBED_MODEL=text-embedding-3-small

2. Bootstrap Knowledge Base

Create your training data in apps/imap-sync/scripts/rag-bootstrap.ts:

const chunks: { text: string; source: string }[] = [
  {
    source: 'agenda',
    text: 'I am applying for a backend engineering job position. ' +
          'If the lead is interested or wants to move forward, I should share my meeting booking link: https://cal.com/example. ' +
          'My goal is to be polite, concise, and always thank them for their interest.'
  },
  {
    source: 'product',
    text: 'The product I am selling is myself as a backend engineer: experience with Node.js, TypeScript, IMAP, Elasticsearch, Prisma, and Slack/webhook integrations. ' +
          'I want to highlight reliability, clean code, and ability to ship end-to-end features.'
  },
  // Add your own context-response pairs
];

3. Generate Embeddings

cd apps/imap-sync

# Install dependencies (if not done already)
pnpm install

# Bootstrap the knowledge base with embeddings
npx tsx scripts/rag-bootstrap.ts

Output:

Embedding: agenda β†’ I am applying for a backend engineering job position...
βœ… Embedded knowledge chunk (source: agenda): I am applying for a backend engineering job position...
Embedding: product β†’ The product I am selling is myself as a backend engineer...
βœ… Embedded knowledge chunk (source: product): The product I am selling is myself as a backend engineer...
Done.

4. Test Suggested Replies

# Test with a sample email
npx tsx scripts/suggest-reply.ts

Example Output:

--- Suggested Reply ---

Thank you for your interest! I'd be happy to discuss the backend engineering role further. 

You can book a convenient time here: https://cal.com/example

Looking forward to connecting!

5. Use in Frontend

  1. Open http://localhost:3000
  2. Hover over any email
  3. Click ✨ AI Reply button
  4. Wait for AI to generate suggestion
  5. Copy suggested reply with one click

Knowledge Base Tips:

  • Add context about your business, products, or services
  • Include common objections and how to handle them
  • Store meeting links, pricing, FAQ responses
  • Update regularly based on successful email conversations
  • Use descriptive source tags for organization (e.g., 'pricing', 'objection', 'faq')

βš™οΈ Configuration

Adding More Accounts

To add additional email accounts, edit apps/imap-sync/.env:

# Account C
C_IMAP_HOST=imap.gmail.com
C_IMAP_PORT=993
C_IMAP_SECURE=true
C_IMAP_USER=third-email@gmail.com
C_IMAP_PASS=third-app-password
C_FOLDERS=INBOX,Sent

# Account D (Yahoo example)
D_IMAP_HOST=imap.mail.yahoo.com
D_IMAP_PORT=993
D_IMAP_SECURE=true
D_IMAP_USER=your-yahoo@yahoo.com
D_IMAP_PASS=your-yahoo-app-password
D_FOLDERS=INBOX

Customizing AI Classification

Edit apps/imap-sync/src/ai/rules.ts to modify classification logic:

// Example: Add custom rules for your business
if (subject.includes('partnership') || body.includes('collaborate')) {
  return { label: 'Interested', confidence: 0.9 };
}

Changing Sync Timeframe

Edit apps/imap-sync/src/imap/ImapSyncService.ts:

// Change from 30 days to 60 days
const since = new Date(Date.now() - 60 * 24 * 60 * 60 * 1000);

πŸ“± Usage

Dashboard Features

  1. Search: Type keywords to search across all emails (subject, body, sender)
  2. Filter by Account: Select specific email account from dropdown
  3. Filter by Folder: Choose INBOX, Sent, or Archive
  4. View Labels: Color-coded badges show AI categorization
  5. Real-time Updates: New emails appear automatically (watch the connection status)
  6. AI Reply Suggestions: Hover over any email to see the ✨ AI Reply button

Using AI Suggested Replies

  1. Hover over any email in the inbox
  2. Click the "✨ AI Reply" button (appears on hover)
  3. Wait 2-3 seconds while AI analyzes the email and generates suggestion
  4. Review the suggested reply in the purple gradient card
  5. Click "Copy" to copy the suggestion to clipboard
  6. Paste into your email client or modify as needed

Features:

  • ✨ Context-aware suggestions based on your knowledge base
  • πŸ“‹ One-click copy to clipboard
  • 🎨 Beautiful purple gradient UI
  • ⚑ Fast generation (2-3 seconds)
  • πŸ’Ύ All suggestions saved to database
  • πŸ”„ Re-generate anytime by clicking button again

Viewing Email Details

  • Click on any email card to see full details
  • Emails are sorted by date (newest first)
  • Today's emails show time, older emails show date

Monitoring Sync Status

Backend Terminal will show:

πŸš€ API Server running on http://localhost:4000
πŸ”Œ WebSocket ready for real-time updates
[INFO] IMAP connected: your-email@gmail.com
[INFO] Backfilling emails since 2025-10-14
[INFO] Email indexed: Re: Important Meeting
[INFO] AI Label: Interested (confidence: 0.95)

Frontend shows:

  • Green dot = WebSocket connected
  • Real-time email count in stats cards
  • New emails appear at the top automatically

πŸ“‘ API Documentation

REST Endpoints

GET /search

Search emails in Elasticsearch

Query Parameters:

  • q (string): Search query
  • account (string): Filter by account email
  • folder (string): Filter by folder name
  • size (number): Max results (default: 25)

Example:

curl "http://localhost:4000/search?q=meeting&account=user@gmail.com&size=10"

Response:

{
  "hits": [
    {
      "id": "email-id",
      "accountUser": "user@gmail.com",
      "folder": "INBOX",
      "subject": "Re: Meeting Tomorrow",
      "snippet": "Thanks for scheduling...",
      "from": {
        "name": "John Doe",
        "email": "john@example.com"
      },
      "date": "2025-11-13T10:30:00Z",
      "label": "Interested",
      "uid": 12345,
      "uidValidity": 1
    }
  ]
}

GET /accounts

Get list of all synced accounts

Example:

curl http://localhost:4000/accounts

Response:

["user1@gmail.com", "user2@gmail.com"]

POST /suggest-reply

Get AI-powered suggested reply for an email (RAG feature)

Request Body:

{
  "accountUser": "user@gmail.com",
  "folder": "INBOX",
  "uidValidity": 1,
  "uid": 12345
}

Example:

curl -X POST http://localhost:4000/suggest-reply \
  -H "Content-Type: application/json" \
  -d '{
    "accountUser": "user@gmail.com",
    "folder": "INBOX",
    "uidValidity": 1,
    "uid": 12345
  }'

Response:

{
  "suggestion": "Thank you for your interest! I'd be happy to discuss this further. You can book a time that works for you here: https://cal.com/example. Looking forward to connecting!"
}

How it works:

  1. Retrieves email from database using unique identifiers
  2. Generates embeddings for email content using OpenAI text-embedding-3-small
  3. Performs semantic similarity search against knowledge base
  4. Feeds top 3 relevant context chunks to GPT-4o-mini
  5. Generates professional, contextually-appropriate reply
  6. Stores suggestion in database for tracking

WebSocket Events

Client β†’ Server

// Connection (automatic via socket.io-client)
const socket = io('http://localhost:4000');

Server β†’ Client

Event: email:new Emitted when a new email is received

socket.on('email:new', (email) => {
  console.log('New email:', email.subject);
  // Update UI automatically
});

Payload:

{
  "accountUser": "user@gmail.com",
  "folder": "INBOX",
  "subject": "New Lead Inquiry",
  "from": {
    "name": "Potential Client",
    "email": "client@example.com"
  },
  "label": "Interested"
}

πŸ“ Project Structure

ReachInbox/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ imap-sync/              # Backend service
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ api/            # REST API & WebSocket
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ server.ts   # Express + Socket.IO server
β”‚   β”‚   β”‚   β”‚   └── handlers.ts # API route handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ ai/             # AI classification
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ classifier.ts
β”‚   β”‚   β”‚   β”‚   └── rules.ts    # Classification rules
β”‚   β”‚   β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”‚   β”‚   └── env.ts      # Environment config
β”‚   β”‚   β”‚   β”œβ”€β”€ consumers/
β”‚   β”‚   β”‚   β”‚   └── Labeler.ts  # AI labeling consumer
β”‚   β”‚   β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ events.ts   # Event bus
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ logger.ts   # Pino logger
β”‚   β”‚   β”‚   β”‚   └── types.ts    # TypeScript types
β”‚   β”‚   β”‚   β”œβ”€β”€ imap/           # IMAP sync logic
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ImapClient.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ImapAccount.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ImapSyncService.ts
β”‚   β”‚   β”‚   β”‚   └── parsers.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ integrations/
β”‚   β”‚   β”‚   β”‚   └── SlackInterestedSink.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ notifications/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ slack.ts
β”‚   β”‚   β”‚   β”‚   └── webhook.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ persistence/    # Database & Elasticsearch
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ PgSink.ts   # PostgreSQL sink
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ esSink.ts   # Elasticsearch sink
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ esClient.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ esBootstrap.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ prisma.ts
β”‚   β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”‚   └── index.ts        # Main entry point
β”‚   β”‚   β”œβ”€β”€ prisma/
β”‚   β”‚   β”‚   β”œβ”€β”€ schema.prisma   # Database schema
β”‚   β”‚   β”‚   └── migrations/     # Database migrations
β”‚   β”‚   β”œβ”€β”€ .env                # Environment variables
β”‚   β”‚   β”œβ”€β”€ package.json
β”‚   β”‚   └── tsconfig.json
β”‚   β”‚
β”‚   └── web/                    # Frontend (Next.js)
β”‚       β”œβ”€β”€ pages/
β”‚       β”‚   β”œβ”€β”€ _app.tsx        # App wrapper
β”‚       β”‚   β”œβ”€β”€ index.tsx       # Dashboard page
β”‚       β”‚   └── api/
β”‚       β”‚       └── search.ts   # API proxy (optional)
β”‚       β”œβ”€β”€ styles/
β”‚       β”‚   └── global.css      # Tailwind CSS
β”‚       β”œβ”€β”€ .env.local          # Frontend env vars
β”‚       β”œβ”€β”€ next.config.js
β”‚       β”œβ”€β”€ package.json
β”‚       β”œβ”€β”€ postcss.config.cjs
β”‚       └── tsconfig.json
β”‚
β”œβ”€β”€ docker-compose.yml          # Docker services
β”œβ”€β”€ .gitignore
└── README.md

πŸ”§ Troubleshooting

Docker Services Not Starting

# Check Docker is running
docker --version

# View container logs
docker logs onebox_pg
docker logs onebox_es
docker logs onebox_kibana

# Restart services
docker compose down
docker compose up -d

Elasticsearch Not Ready

Error: Connection refused or index not found

Solution:

# Check Elasticsearch health
curl http://localhost:9200/_cluster/health

# Wait for status: "yellow" or "green"

# If needed, recreate index
cd apps/imap-sync
pnpm dev  # Will auto-create index on startup

Backend Can't Connect to Gmail

Error: Authentication failed

Solution:

  1. Verify Gmail App Password is correct (16 characters, no spaces)
  2. Check 2FA is enabled on your Google Account
  3. Try generating a new App Password
  4. Check .env file for typos in email/password

Error: Connection timeout

Solution:

  1. Check firewall settings
  2. Verify port 993 is not blocked
  3. Try different network (some corporate networks block IMAP)

Frontend Shows "No Emails"

Checklist:

  1. βœ… Backend is running (http://localhost:4000/accounts returns accounts)
  2. βœ… Elasticsearch has emails (curl http://localhost:9200/emails/_count)
  3. βœ… WebSocket is connected (green dot in UI)
  4. βœ… Wait 1-2 minutes for initial sync to complete

Debug:

# Check backend logs for sync progress
cd apps/imap-sync
pnpm dev

# Check Elasticsearch count
curl http://localhost:9200/emails/_count

# Test API directly
curl http://localhost:4000/search?size=5

Port Already in Use

Error: EADDRINUSE: address already in use

Solution:

# Find process using port 4000
netstat -ano | findstr :4000

# Kill the process (Windows)
taskkill /PID <PID> /F

# Or change port in .env
PORT=4001

Database Migration Errors

# Reset database (WARNING: deletes all data)
cd apps/imap-sync
npx prisma migrate reset

# Regenerate client
npx prisma generate

# Reapply migrations
npx prisma migrate deploy

πŸ§ͺ Development

Running Tests

# Backend tests
cd apps/imap-sync
pnpm test

# Frontend tests
cd apps/web
pnpm test

Database Management

# Open Prisma Studio (visual database editor)
cd apps/imap-sync
npx prisma studio

# Create new migration
npx prisma migrate dev --name your_migration_name

# View database directly
psql postgresql://onebox:onebox@localhost:5432/onebox

Viewing Logs

# Backend logs (pretty printed)
cd apps/imap-sync
pnpm dev

# Elasticsearch logs
docker logs onebox_es

# PostgreSQL logs
docker logs onebox_pg

Production Build

# Backend
cd apps/imap-sync
pnpm build
pnpm start

# Frontend
cd apps/web
pnpm build
pnpm start

🌟 Features Implemented

  • Multi-account IMAP synchronization (2+ accounts)
  • Real-time email sync using IMAP IDLE (no polling)
  • 30-day historical email backfill
  • Elasticsearch integration for full-text search
  • PostgreSQL storage for reliable persistence
  • AI-based email categorization (5 labels)
  • Slack notifications for interested emails
  • Webhook integration for automation
  • WebSocket real-time updates to frontend
  • Professional dashboard UI with Tailwind CSS v4
  • Search by subject, body, sender
  • Filter by account and folder
  • Color-coded label visualization
  • Real-time stats cards
  • Responsive mobile-friendly design
  • REST API for email search
  • Docker-based infrastructure
  • TypeScript throughout
  • Event-driven architecture
  • Prisma ORM for type-safe database queries

πŸš€ Deployment

Production Checklist

  1. Environment Variables:

    • Set NODE_ENV=production
    • Use secure passwords
    • Configure production Slack webhooks
    • Update NEXT_PUBLIC_API_URL to production URL
  2. Database:

    • Use managed PostgreSQL (AWS RDS, DigitalOcean, etc.)
    • Run migrations: npx prisma migrate deploy
    • Set up automated backups
  3. Elasticsearch:

    • Use managed Elasticsearch (Elastic Cloud, AWS OpenSearch)
    • Configure authentication
    • Set up index lifecycle policies
  4. Backend:

    • Build: pnpm build
    • Use process manager (PM2, systemd)
    • Set up monitoring and logging
    • Configure rate limiting
  5. Frontend:

    • Build: pnpm build
    • Deploy to Vercel, Netlify, or custom server
    • Configure CDN for static assets

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development Workflow

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the ISC License.


πŸ‘¨β€πŸ’» Author

sh3bh1t


πŸ™ Acknowledgments

  • Next.js team for the amazing React framework
  • Prisma for the excellent ORM
  • Elastic for Elasticsearch
  • The open-source community

πŸ“ž Support

If you encounter any issues or have questions:

  1. Check the Troubleshooting section
  2. Search existing GitHub Issues
  3. Create a new issue with detailed information

Built with ❀️ using TypeScript, Next.js, and Node.js

About

please wait for some time for backend server responses to load on frontend as backend is hosted using render's free tier which is known to be a bit slow

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages