No description
Find a file
Jonny Nguyen 7f47ec4809 Refactor SettingsPage component for improved readability and consistency
Update formatting in SettingsPage.tsx to enhance code clarity by standardizing quotation marks and restructuring object definitions. Maintain functionality while improving overall code style and organization.
2026-06-26 23:55:39 -07:00
apps Refactor SettingsPage component for improved readability and consistency 2026-06-26 23:55:39 -07:00
docs Add Woodpecker CI/CD pipeline configuration and new chart components 2026-06-26 14:23:18 -07:00
packages/shared Enhance warmup functionality by introducing mailbox role validation for sends and replies. Implement new utility functions to check allowed warmup pairs and add corresponding tests. Update campaign stats routes and services to include a detailed warmup plan, and integrate a visual representation in the Campaign Detail page. Refactor related components and types for improved clarity and maintainability. 2026-06-26 13:56:57 -07:00
prisma Refactor project structure to support monorepo with workspaces; add API and web applications with respective configurations, dependencies, and scripts. Introduce environment variable validation and initial API setup for email warmup functionality. 2026-06-25 22:01:25 -07:00
scripts Add Woodpecker CI/CD pipeline configuration and new chart components 2026-06-26 14:23:18 -07:00
.dockerignore Update .env.example with detailed setup instructions, modify DATABASE_URL for Docker, and add new environment variables. Enhance package.json with Docker commands for easier deployment. Expand self-host hardening documentation to include Docker deployment on Ubuntu/VPS. 2026-06-26 11:18:12 -07:00
.env.example Update .env.example with new PUBLIC_BASE_URL, remove unused docker-compose.npm.yml and Caddyfile, and adjust docker-compose.yml to simplify network configuration. Revise deployment documentation to reflect changes in setup and clarify Nginx Proxy Manager integration. 2026-06-26 13:00:32 -07:00
.gitignore initial commit with working barebone prototype 2026-06-24 21:42:18 -07:00
.woodpecker.yml Add Woodpecker CI/CD pipeline configuration and new chart components 2026-06-26 14:23:18 -07:00
docker-compose.yml Update .env.example with new PUBLIC_BASE_URL, remove unused docker-compose.npm.yml and Caddyfile, and adjust docker-compose.yml to simplify network configuration. Revise deployment documentation to reflect changes in setup and clarify Nginx Proxy Manager integration. 2026-06-26 13:00:32 -07:00
Dockerfile Update .env.example with detailed setup instructions, modify DATABASE_URL for Docker, and add new environment variables. Enhance package.json with Docker commands for easier deployment. Expand self-host hardening documentation to include Docker deployment on Ubuntu/VPS. 2026-06-26 11:18:12 -07:00
package-lock.json Refactor project structure to support monorepo with workspaces; add API and web applications with respective configurations, dependencies, and scripts. Introduce environment variable validation and initial API setup for email warmup functionality. 2026-06-25 22:01:25 -07:00
package.json Update .env.example with new PUBLIC_BASE_URL, remove unused docker-compose.npm.yml and Caddyfile, and adjust docker-compose.yml to simplify network configuration. Revise deployment documentation to reflect changes in setup and clarify Nginx Proxy Manager integration. 2026-06-26 13:00:32 -07:00
prisma.config.ts initial commit with working barebone prototype 2026-06-24 21:42:18 -07:00
README.md initial commit with working barebone prototype 2026-06-24 21:42:18 -07:00
tsconfig.json initial commit with working barebone prototype 2026-06-24 21:42:18 -07:00

Warmbox

Self-hosted email warmup and deliverability engine for custom domains. Uses SMTP to send realistic B2B conversations and IMAP to rescue messages from spam folders, flag them as important, and reply — improving sender reputation over time.

Tech Stack

  • Runtime: Node.js + TypeScript + Express
  • Database: SQLite via Prisma ORM
  • Email: nodemailer (SMTP), imapflow (IMAP)
  • AI: OpenRouter (free models) for conversation generation
  • Scheduler: node-cron

Quick Start

1. Install dependencies

npm install

2. Configure environment

cp .env.example .env

Generate an encryption key:

openssl rand -hex 32

Set these in .env:

Variable Description
DATABASE_URL SQLite path, e.g. file:./prisma/dev.db (configured in prisma.config.ts)
ENCRYPTION_KEY 64-char hex string (32 bytes) for AES-256-GCM password encryption
AI_API_KEY API key from OpenRouter (free tier works)
AI_BASE_URL Default https://openrouter.ai/api/v1
AI_MODEL Default openrouter/free (auto-picks a free model)
API_KEY Optional API key for REST auth (x-api-key header)
PORT HTTP port (default 3000)

Get a free AI API key (OpenRouter)

Email generation only needs a small, fast language model — not GPT-4 class reasoning.

  1. Sign up at openrouter.ai
  2. Go to openrouter.ai/keys and create an API key
  3. Paste it into .env as AI_API_KEY

Recommended free models (set AI_MODEL in .env):

Model Notes
openrouter/free Auto-selects an available free model (default)
google/gemma-2-9b-it:free Good quality, reliable JSON
meta-llama/llama-3.2-3b-instruct:free Fast, lightweight

You do not need an OpenAI account.

3. Run database migrations

npm run db:migrate

4. Start the server

npm run dev

The API and cron jobs start together. Default schedules:

  • Dispatcher: every 15 minutes — sends warmup emails
  • Rescuer: every 10 minutes — rescues spam, replies to inbox
  • Ramp: midnight daily — increases currentRamp per inbox

5. Add mailboxes

You need at least 2 active inboxes for warmup to work. Warmbox randomly pairs senders and receivers from your pool.

SMTP/IMAP settings by provider

Every inbox needs 4 connection fields plus credentials:

Field What it is
smtpHost / smtpPort Where to send mail
imapHost / imapPort Where to read mail (spam rescue + replies)
username Usually the full email address
password App password (not your login password)
Gmail (including Google Workspace custom domains)

If hello@fillcareapp.com is hosted on Google Workspace, use Gmail servers:

Field Value
smtpHost smtp.gmail.com
smtpPort 587
imapHost imap.gmail.com
imapPort 993

App password setup:

  1. Enable 2-Step Verification on the Google account
  2. Go to myaccount.google.com/apppasswords
  3. Create an app password for "Mail" → copy the 16-character code
  4. Use that code as password in Warmbox
Yahoo Mail
Field Value
smtpHost smtp.mail.yahoo.com
smtpPort 587
imapHost imap.mail.yahoo.com
imapPort 993

App password: Yahoo Account Security → Generate app password.

Outlook / Hotmail / Live.com (@live.com, @outlook.com, @hotmail.com)
Field Value
smtpHost smtp-mail.outlook.com
smtpPort 587
imapHost outlook.office365.com
imapPort 993

App password: Microsoft Account Security → Advanced security → App passwords. IMAP must be enabled in Outlook settings.

Custom domain (cPanel / generic hosting)

If hello@fillcareapp.com is on cPanel or similar (not Google/Microsoft), check your host's email docs. Common pattern:

Field Value
smtpHost mail.fillcareapp.com or smtp.fillcareapp.com
smtpPort 587 (or 465 for SSL)
imapHost mail.fillcareapp.com or imap.fillcareapp.com
imapPort 993

Ask your DNS/hosting provider if unsure — look for "IMAP/SMTP settings" in cPanel → Email Accounts.

Example: FillCare + personal accounts

Add hello@fillcareapp.com as your primary warmup domain (industry: Childcare), then add 45 Gmail/Yahoo/Live accounts as the reply pool.

1. Primary domain (FillCare)

curl -X POST http://localhost:3000/api/inboxes \
  -H "Content-Type: application/json" \
  -d '{
    "email": "hello@fillcareapp.com",
    "smtpHost": "smtp.gmail.com",
    "smtpPort": 587,
    "imapHost": "imap.gmail.com",
    "imapPort": 993,
    "username": "hello@fillcareapp.com",
    "password": "hkem mfmi bkmg bqyw",
    "industry": "Childcare",
    "dailyLimit": 40,
    "currentRamp": 5
  }'

If FillCare email is not on Google Workspace, swap smtpHost/imapHost to your host's values (see table above).

2. Gmail account

curl -X POST http://localhost:3000/api/inboxes \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@gmail.com",
    "smtpHost": "smtp.gmail.com",
    "smtpPort": 587,
    "imapHost": "imap.gmail.com",
    "imapPort": 993,
    "username": "you@gmail.com",
    "password": "your-gmail-app-password",
    "industry": "SaaS"
  }'

3. Yahoo account

curl -X POST http://localhost:3000/api/inboxes \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@yahoo.com",
    "smtpHost": "smtp.mail.yahoo.com",
    "smtpPort": 587,
    "imapHost": "imap.mail.yahoo.com",
    "imapPort": 993,
    "username": "you@yahoo.com",
    "password": "your-yahoo-app-password",
    "industry": "Marketing"
  }'

4. Live.com / Outlook account

curl -X POST http://localhost:3000/api/inboxes \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@live.com",
    "smtpHost": "smtp-mail.outlook.com",
    "smtpPort": 587,
    "imapHost": "outlook.office365.com",
    "imapPort": 993,
    "username": "you@live.com",
    "password": "your-microsoft-app-password",
    "industry": "Finance"
  }'

Repeat for each additional Gmail/Yahoo/Live account. Mixing providers is fine — Warmbox only needs them all in the same pool.

6. Test connections

After adding each inbox, verify SMTP + IMAP:

curl -X POST http://localhost:3000/api/inboxes/{id}/test

A successful response looks like:

{
  "ok": true,
  "smtp": { "ok": true },
  "imap": { "ok": true }
}

If either fails, double-check the app password and that IMAP is enabled on the account.

7. Monitor logs

curl http://localhost:3000/api/logs

Watch for status progression: sentrescued_from_spamrepliedcomplete.

API Reference

All endpoints under /api accept optional x-api-key header when API_KEY is set.

Method Path Description
POST /api/inboxes Create inbox
GET /api/inboxes List inboxes
GET /api/inboxes/:id Get inbox
PATCH /api/inboxes/:id Update inbox
DELETE /api/inboxes/:id Delete inbox
POST /api/inboxes/:id/test Test SMTP + IMAP
GET /api/logs List warmup logs (?status=&inboxId=&page=&limit=)
GET /api/settings Get settings
PATCH /api/settings Update settings
GET /health Health check

Project Structure

src/
├── config.ts              # Environment validation
├── index.ts               # Express + scheduler bootstrap
├── jobs/
│   ├── dispatcher.job.ts  # Sends warmup emails
│   ├── rescuer.job.ts     # Spam rescue + replies
│   └── scheduler.ts       # Cron wiring
├── lib/                   # Prisma, logger, inbox guard
├── middleware/            # Auth, error handling
├── models/                # Enums, types
├── routes/                # REST endpoints
└── services/
    ├── ai.service.ts      # OpenRouter conversation generator
    ├── crypto.service.ts  # AES-256-GCM encryption
    ├── email.service.ts   # SMTP via nodemailer
    ├── imap.service.ts    # IMAP via imapflow
    └── settings.service.ts
prisma/
└── schema.prisma          # Database schema

How It Works

  1. Dispatcher picks random sender/receiver pairs from active inboxes, generates a B2B email via AI, and sends via SMTP.
  2. Rescuer scans spam folders ([Gmail]/Spam, Junk, Spam) for warmup emails, moves them to INBOX, flags them as read/starred/important.
  3. Rescuer also processes unread warmup emails already in INBOX, generates contextual AI replies, and sends them back.
  4. Failed IMAP/SMTP connections mark the inbox as error and skip it until credentials are fixed.

Production

npm run build
npm start

Use a process manager (systemd, PM2) and back up the SQLite database file regularly.

License

MIT