Skip to content

Repository files navigation

Unsubly

A privacy-focused email management platform that helps users take control of their inbox by automating subscription management, creating email digests, and protecting against spam.

Features

📧 Email Management

  • Multi-Provider Support - Connect Gmail, Outlook, Yahoo, AOL, Fastmail, and iCloud accounts
  • Full Inbox Scanning - Syncs your entire inbox to find all subscriptions (not just recent emails)
  • Smart Detection - Automatically identify newsletter and marketing subscriptions
  • Browser-Automated Unsubscribe - Puppeteer-powered automation that actually clicks buttons and checks checkboxes on unsubscribe pages
  • Fresh URL Fetching - Fetches current unsubscribe URLs from email provider to avoid expired tokens
  • Cleanup Folders - After unsubscribing, move old emails to a cleanup folder for easy deletion

📊 Organization

  • Email Rollups - Consolidate newsletters into daily or weekly digests (up to 10 rollups)
  • Custom Scheduling - Choose when and how often you receive digest emails
  • Sender Management - Organize subscriptions by sender with custom preferences

🛡️ Privacy & Protection

  • Inbox Shield - Advanced spam filtering and cold email blocking
  • Do Not Disturb - Set quiet hours to focus without interruptions
  • Privacy Aliases - Generate shielded email addresses for enhanced privacy
  • Priority Senders - Whitelist important contacts

Tech Stack

Frontend

  • Next.js 14 - React framework with App Router
  • TypeScript - Type-safe development
  • Tailwind CSS - Utility-first styling
  • React Hook Form + Zod - Form validation
  • Zustand - State management
  • TanStack Query - Server state management

Backend

  • Node.js + Express - API server
  • TypeScript - Type-safe backend
  • Prisma ORM - Database management
  • PostgreSQL - Primary database
  • Redis - Caching and job queue
  • BullMQ - Background job processing
  • Puppeteer - Browser automation for unsubscribe execution
  • JWT - Authentication
  • Winston - Logging

Infrastructure

  • Docker - Containerized development
  • Turborepo - Monorepo management
  • pnpm - Fast, disk-efficient package manager

Project Structure

unsubly/
├── apps/
│   ├── web/              # Next.js frontend application
│   │   ├── src/
│   │   │   ├── app/      # App router pages
│   │   │   ├── components/
│   │   │   ├── lib/      # Utilities and API client
│   │   │   └── hooks/
│   │   └── package.json
│   │
│   └── api/              # Express backend application
│       ├── src/
│       │   ├── server.ts
│       │   ├── routes/
│       │   ├── controllers/
│       │   ├── services/
│       │   ├── workers/   # Background workers
│       │   ├── middleware/
│       │   └── prisma/    # Database schema
│       └── package.json
│
├── packages/
│   └── shared/           # Shared types and utilities
│       └── src/
│           ├── types/
│           └── constants/
│
└── docker/
    └── docker-compose.yml

Getting Started

Prerequisites

  • Node.js >= 18.0.0
  • pnpm >= 8.0.0
  • Docker and Docker Compose

Installation

  1. Clone the repository

    git clone <repository-url>
    cd unsubly
  2. Install dependencies

    pnpm install
  3. Start Docker containers

    cd docker
    docker-compose up -d
  4. Set up the database

    cd apps/api
    pnpm generate      # Generate Prisma Client
    pnpm migrate       # Run migrations
  5. Configure environment variables

    Copy .env.example to .env in apps/api/ and update values:

    cp apps/api/.env.example apps/api/.env
  6. Start development servers

    # From root directory
    pnpm run dev

Access the Application

Development

Available Scripts

Root Level

  • pnpm run dev - Start all development servers
  • pnpm run build - Build all applications
  • pnpm run lint - Lint all code
  • pnpm run clean - Clean build artifacts

Frontend (apps/web)

  • pnpm run dev - Start Next.js dev server
  • pnpm run build - Build for production
  • pnpm run start - Start production server

Backend (apps/api)

  • pnpm run dev - Start API dev server with hot reload
  • pnpm run build - Build TypeScript
  • pnpm run migrate - Run database migrations
  • pnpm run generate - Generate Prisma Client
  • pnpm run studio - Open Prisma Studio
  • pnpm run workers:dev - Start background workers

Database Management

View Database

cd apps/api
pnpm studio

Create Migration

cd apps/api
pnpm prisma migrate dev --name migration_name

Reset Database (⚠️ Deletes all data)

cd apps/api
pnpm prisma migrate reset

API Documentation

Authentication

Register

POST /api/auth/register
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "securepassword",
  "name": "User Name"
}

Login

POST /api/auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "securepassword"
}

Get Current User

GET /api/auth/me
Authorization: Bearer <token>

Email Accounts

Connect Gmail Account

GET /api/email-accounts/gmail/auth
Authorization: Bearer <token>

List Connected Accounts

GET /api/email-accounts
Authorization: Bearer <token>

Fetch Emails from Account

GET /api/email-accounts/:accountId/emails?maxResults=10
Authorization: Bearer <token>

Disconnect Account

DELETE /api/email-accounts/:accountId
Authorization: Bearer <token>

Toggle Sync

PATCH /api/email-accounts/:accountId/sync
Authorization: Bearer <token>
Content-Type: application/json

{
  "syncEnabled": true
}

For detailed Gmail testing instructions, see TESTING_GMAIL.md.

Inbox Shield

Get Shield Settings

GET /api/shield/:emailAccountId
Authorization: Bearer <token>

Update Shield Settings

PATCH /api/shield/:emailAccountId
Authorization: Bearer <token>
Content-Type: application/json

{
  "spamFilteringEnabled": true,
  "spamThreshold": 0.7,
  "coldEmailBlockingEnabled": true,
  "coldEmailAction": "quarantine",
  "dndModeEnabled": false,
  "dndStartTime": "22:00",
  "dndEndTime": "08:00",
  "dndDays": [0, 1, 2, 3, 4, 5, 6],
  "prioritySendersEnabled": true,
  "priorityOnlyMode": false
}

Add Priority Sender

POST /api/shield/:emailAccountId/priority-senders
Authorization: Bearer <token>
Content-Type: application/json

{
  "senderEmail": "important@example.com",
  "senderDomain": "example.com"
}

Remove Priority Sender

DELETE /api/shield/:emailAccountId/priority-senders/:senderEmail
Authorization: Bearer <token>

List Priority Senders

GET /api/shield/:emailAccountId/priority-senders
Authorization: Bearer <token>

Get Spam Statistics

GET /api/shield/:emailAccountId/stats/spam
Authorization: Bearer <token>

Get Cold Email Statistics

GET /api/shield/:emailAccountId/stats/cold-email
Authorization: Bearer <token>

Batch Analyze Emails

POST /api/shield/:emailAccountId/analyze
Authorization: Bearer <token>
Content-Type: application/json

{
  "limit": 100
}

Train Classifier

POST /api/shield/classifier/train
Authorization: Bearer <token>
Content-Type: application/json

{
  "emailAccountId": "optional-account-id"
}

Get Classifier Stats

GET /api/shield/classifier/stats
Authorization: Bearer <token>

Submit Spam Feedback

POST /api/shield/feedback/:emailId
Authorization: Bearer <token>
Content-Type: application/json

{
  "isSpam": true
}

Subscription Tiers

  • Free: 10 unsubscribes, 1 email account, 1 rollup
  • Pro: Unlimited unsubscribes, 5 email accounts, 10 rollups, Inbox Shield, Aliases
  • Business: All Pro features + priority support

Database Schema

The application uses PostgreSQL with the following main tables:

  • users - User accounts and subscription tiers
  • email_accounts - Connected email accounts with OAuth tokens
  • emails - Email metadata (partitioned by month for scalability)
  • senders - Aggregated sender information and statistics
  • user_sender_preferences - User decisions for each sender
  • unsubscribe_attempts - Tracking unsubscribe execution and verification
  • rollups - Email digest configurations
  • rollup_digests - Individual digest instances
  • email_aliases - Privacy-focused shielded email addresses
  • inbox_shield_settings - Spam filtering configuration
  • priority_senders - Whitelisted important contacts
  • job_executions - Background job tracking
  • audit_logs - Security and activity audit trail

Architecture

Email Provider Integration

  • OAuth2 for Gmail and Outlook
  • IMAP/SMTP for Yahoo, AOL, Fastmail, iCloud
  • Provider abstraction layer for unified interface
  • Token refresh and management
  • Folder Management - Create labels/folders and move emails programmatically

Email Sync Process

The app performs a comprehensive inbox scan to identify all your subscriptions:

Initial Sync (First Connection)

  1. Fetches email metadata in pages of 100 from the email provider
  2. For each page, fetches individual message details in small batches (5 at a time)
  3. Adds 50ms delays between batches to respect API rate limits
  4. If rate limited, automatically waits 5 seconds and retries with doubled delays
  5. Processes each email: creates sender records, detects unsubscribe links, queues for classification
  6. Continues until entire inbox is scanned (can handle 10,000+ emails)

Incremental Sync (Subsequent Syncs)

  • Only fetches emails newer than the last sync
  • Limited to 200 most recent emails per sync
  • Runs automatically every 15 minutes via background workers

Rate Limit Protection

  • Gmail: Batched requests with automatic retry and exponential backoff
  • Outlook: Respects Microsoft Graph API limits
  • IMAP: Connection pooling with provider-specific limits

Performance

  • Initial sync of ~10,000 emails takes approximately 7-10 minutes
  • Incremental syncs complete in seconds
  • Progress is logged for monitoring

Background Processing

  • BullMQ with Redis for job queues
  • Workers for email scanning, unsubscribe execution, and rollup generation
  • Retry logic with exponential backoff
  • Job monitoring and error handling

Security

  • JWT-based authentication with HTTP-only cookies
  • OAuth tokens encrypted at rest (AES-256)
  • Rate limiting on all endpoints
  • Input validation with Zod
  • SQL injection prevention (Prisma parameterized queries)
  • XSS prevention
  • CSRF protection
  • Secure password hashing (bcrypt with 12 salt rounds)

Scalability

  • Stateless API servers for horizontal scaling
  • Database partitioning for large datasets
  • Redis caching for frequently accessed data
  • Email metadata in PostgreSQL, bodies in S3
  • Read replicas for query distribution

Roadmap

Phase 1: Foundation ✅

  • Monorepo setup with Turborepo
  • Next.js frontend with Tailwind CSS
  • Express backend with TypeScript
  • PostgreSQL + Redis infrastructure
  • User authentication (JWT)
  • Database schema design

Phase 2: Email Integration ✅

  • Gmail OAuth2 integration
  • Provider abstraction layer
  • OAuth token management and refresh
  • Email account management API
  • Email fetching with pagination
  • Outlook/Microsoft Graph API integration
  • Generic IMAP provider (Yahoo, AOL, Fastmail, iCloud)
  • Token encryption (AES-256-GCM)
  • Email scanning background workers
  • Rate limiting and retry logic
  • Frontend account connection UI

Phase 3: Subscription Management ✅

  • Subscription detection algorithm
  • List-Unsubscribe header parsing
  • Email body unsubscribe link extraction
  • Browser-automated unsubscribe with Puppeteer
    • Checkbox detection and automatic checking
    • Button pattern detection (Unsubscribe, Confirm, Save Preferences, etc.)
    • CAPTCHA and login detection with manual fallback
    • Success/failure detection from page content
  • Fresh URL fetching from email provider before unsubscribe
  • Body link prioritization over header links (more reliable, don't expire)
  • Verification and retry logic
  • Sender tracking and statistics
  • Subscriptions management UI with real-time stats updates
  • Full inbox scanning with pagination (syncs entire mailbox)
  • Gmail API rate limit handling with batched requests and auto-retry
  • Cleanup folder feature (move unsubscribed sender emails to "Unsubly Cleanup")
  • Bulk unsubscribe with batch cleanup support
  • Search and filter subscriptions by name, email, or domain
  • Keep workflow for subscription triage (mark to keep, then bulk unsubscribe the rest)

Phase 4: Email Rollups

  • Rollup configuration UI
  • Digest generation service
  • Responsive email templates
  • Scheduling system
  • Sender-to-rollup assignment

Phase 5: Inbox Shield

  • Spam score calculation
  • Machine learning classifier (Naive Bayes)
  • Cold email detection
  • Do Not Disturb mode
  • Priority senders system

Phase 6: Privacy Aliases

  • Domain and MX record setup (configurable via ALIAS_DOMAIN env var)
  • Alias generation service (random and custom prefix aliases)
  • Email forwarding infrastructure (webhook endpoints for Postmark/SendGrid)
  • Usage tracking and analytics (received, forwarded, blocked counts)
  • Auto-disable features (blockAfterFirstSender, autoDisableDate)

See Privacy Aliases Setup Guide for domain configuration.

Phase 7: Payment Integration

  • Stripe checkout integration
  • Subscription management
  • Feature gating by tier
  • Webhook handlers
  • Billing portal

Phase 8: Production Readiness

  • Comprehensive testing (unit, integration, E2E)
  • Security audit
  • Performance optimization
  • Error tracking (Sentry)
  • Monitoring and alerting
  • CI/CD pipeline
  • Documentation

Contributing

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

License

Private - All Rights Reserved

Support

For issues or questions, please open an issue on GitHub.

About

Privacy-focused email management platform

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages