No description
Find a file
2026-06-26 13:00:32 -07:00
apps 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
docs 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
packages/shared 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
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 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
.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
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