Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SYJ Mail Intelligence AI

πŸ“¬ SYJ Mail Intelligence AI

Autonomous AI Email Assistant for Gmail β€” Model-Agnostic Β· Self-Hosted Β· Production-Hardened

Your inbox, triaged and drafted by AI that runs entirely on your own hardware β€” no OpenAI, no vendor lock-in, no API bill.

Phase 1 Phase 2 Phase 3 Phase 3.1 Tests License Platform

Features β€’ Architecture β€’ Quick Start β€’ Production Guide β€’ Security β€’ Author


πŸ“– What This Is

SYJ Mail Intelligence AI watches your Gmail inbox, classifies every message, scores it for importance, summarizes it, and drafts a reply in your own writing style β€” then auto-sends it only above a confidence threshold you control. Everything else waits for your one-tap approval.

It's model-agnostic by design β€” there's no OpenAI dependency anywhere in the stack. It runs entirely against local, open-weight models through Ollama (DeepSeek V3/R1, Qwen 3, Qwen Coder, Mistral, Llama 3), and swapping providers is a config change, not a code change.

This isn't a weekend script β€” it's shipped through four real phases (core pipeline β†’ dashboard β†’ production hardening β†’ an audit-driven reliability pass), each tested against live infrastructure rather than assumed to work.

Project stats

🎬 Demo: drop a short screen recording at assets/demo.gif (1280Γ—720, <10s, showing an email arriving β†’ getting classified β†’ a reply drafted) and reference it here as ![SYJ Mail Intelligence AI demo](./assets/demo.gif). Skipped in this README rather than linking a placeholder that doesn't exist yet.


✨ Key Features

  • 🧠 AI email classification β€” 22 business-relevant categories (Urgent, Client, Invoice, Security Alert, Phishing, Meeting, and more), tuned to avoid the classic false-urgency trap of marketing copy
  • πŸ“Š Importance scoring β€” 1–100 score with plain-English reasoning and automatic deadline detection
  • ✍️ Style-aware reply generation β€” drafts in your writing style, with echo/paraphrase detection that forces a stricter regeneration before ever falling back to a safe template
  • βœ… Confidence-gated approval workflow β€” auto-send, Gmail draft, or manual review, decided in plain Python (not just prompted), so a model can't talk its way past your thresholds
  • πŸ“¬ Full Gmail integration β€” polling, thread detection, draft creation, sending, archiving, read-state sync
  • πŸ”” Telegram notifications β€” with Markdown-escaping so special characters never silently break a message
  • πŸ–₯️ Next.js dashboard β€” inbox, approval queue, contact intelligence, analytics, live prompt editor, and system logs, JWT-authenticated end to end
  • πŸ” Production-grade security β€” API-key auth on every route, a server-side proxy so the key never touches the browser, rate limiting, and Postgres isolated on an internal network
  • 🧩 Truly model-agnostic β€” swap LLM_MODEL in .env to run DeepSeek, Qwen, Mistral, or Llama β€” zero code changes
  • πŸ“± Runs anywhere β€” Windows, Linux, macOS, and natively in Termux on Android

🧭 Where This Stands

Phase Status What Shipped
Phase 1 βœ… Core pipeline β€” Gmail polling, classification, importance scoring, Telegram notifications, style-learned reply drafting, the 95%/80% approval workflow. Termux-runnable, SQLite by default.
Phase 2 βœ… Next.js dashboard β€” Inbox, Important, Approval Queue, Notifications, Analytics, Contacts, Prompt Editor, Logs, Settings.
Phase 3 βœ… Production hardening β€” API-key auth, server-side dashboard proxy, rate limiting, Postgres + Alembic, Docker Compose + Nginx/HTTPS, systemd path, GitHub Actions CI, pytest suite.
Phase 3.1 βœ… Audit-driven reliability pass β€” see below.
πŸ” What Phase 3.1 actually fixed (click to expand)
  • Gmail is no longer a hard dependency to start β€” the API and dashboard run fully with zero Gmail credentials
  • The poller reconnects with capped backoff instead of crashing outright
  • A single GET /ready endpoint reports real DB + Gmail readiness
  • The AI provider is a true singleton, reusing one persistent HTTP connection instead of one per call
  • Prompt edits from the dashboard take effect without a restart
  • A failing AI call at any stage degrades to a safe default and flags the email needs_manual_review
  • Telegram notifications escape Markdown special characters instead of silently failing

Covered by tests/test_pipeline_resilience.py and tests/test_provider_singleton.py.

🚧 Not yet built (by design, not by accident)
  • RAG over past sent emails
  • Redis/Celery for higher-throughput async processing
  • Multi-Gmail-account support
  • WhatsApp/Slack/Discord notification channels
  • A live Model Manager UI (today: .env + restart)

πŸ—οΈ Architecture

flowchart TD
    A[πŸ“₯ Gmail API<br/>OAuth2 Poller] -->|new message| B[βš™οΈ Pipeline Orchestrator]

    B --> C[🏷️ Classifier<br/>category · confidence · reason]
    B --> D[πŸ“Š Importance Scorer<br/>1-100 Β· sender rep Β· deadlines]
    B --> E[πŸ“ Summarizer<br/>1-line Β· detailed Β· action items]

    C --> F[✍️ Reply Generator<br/>style profile + tone selection]
    D --> F
    E --> F

    F --> G{Confidence Router}
    G -->|"β‰₯ 95%"| H[πŸš€ Auto-Send<br/>via Gmail API]
    G -->|"80–94%"| I[πŸ“‹ Gmail Draft<br/>+ Telegram approval request]
    G -->|"< 80%"| J[πŸ—‚οΈ Manual Review<br/>dashboard only]

    H --> K[πŸ”” Telegram Notification]
    I --> K
    J --> K

    K --> L[(πŸ—„οΈ Postgres / SQLite)]
    L --> M[🌐 FastAPI REST Backend]
    M --> N[πŸ–₯️ Next.js Dashboard<br/>JWT-authenticated]

    style A fill:#4285F4,color:#fff
    style H fill:#2EA44F,color:#fff
    style I fill:#F59E0B,color:#fff
    style J fill:#EF4444,color:#fff
    style N fill:#7C3AED,color:#fff
Loading

Every AI stage runs in its own try/except. A failure in classification, scoring, summarization, or reply generation never drops the email β€” it falls back to a safe default, flags the message for manual review, and logs the exact failure reason.

Request flow (dashboard β†’ backend)

sequenceDiagram
    participant Browser
    participant Dashboard as Next.js Server Proxy
    participant API as FastAPI Backend
    participant DB as Postgres / SQLite

    Browser->>Dashboard: Request (no API key attached)
    Dashboard->>API: Forwarded request + X-API-Key (server-side only)
    API->>API: Verify key
    API->>DB: Query
    DB-->>API: Result
    API-->>Dashboard: JSON response
    Dashboard-->>Browser: JSON response
Loading

The API key never reaches client-side JavaScript β€” see Security for why this matters.


🧰 Technology Stack

Layer Technology
Backend Python 3.11+, FastAPI, SQLAlchemy, Alembic, Uvicorn
AI / LLM Ollama β€” DeepSeek V3/R1, Qwen 2.5/3, Qwen Coder, Mistral, Llama 3 (fully swappable)
Frontend Next.js 14+, React, TypeScript, Tailwind CSS
Database SQLite (dev) β†’ PostgreSQL + Alembic (production)
Auth JWT (HTTP-only cookies) + API-key auth, Google OAuth2 (Gmail)
Notifications Telegram Bot API
Deployment Docker Compose + Nginx/HTTPS, or systemd (non-Docker), GitHub Actions CI

πŸ“‹ Requirements

Requirement Version / Notes
Python 3.11+
Node.js 18+ (for the dashboard)
Ollama Latest β€” local LLM inference
RAM 8 GB minimum Β· 16 GB+ recommended for 14B-class models
Disk ~10 GB free for models
Gmail account With API access enabled via Google Cloud Console

πŸš€ Quick Start

Local development β€” SQLite, no auth required.

1. Clone and set up the backend

git clone https://github.com/SHalimoosavi/syj-mail-intelligence-ai.git
cd syj-mail-intelligence-ai
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env

2. Add Gmail credentials

Go to Google Cloud Console β†’ APIs & Services β†’ Credentials β†’ Create OAuth client ID β†’ Desktop app, download the file, and place it in the project root as credentials.json.

3. Run the one-time OAuth flow, then start the backend

python -m app.gmail.auth    # one-time OAuth2 flow
python main.py              # starts the poller + API on :8000

4. Start the dashboard (in a second terminal)

cd dashboard
npm install
cp .env.local.example .env.local
npm run dev                 # dashboard on :3000

5. Verify it's running

curl http://localhost:8000/health

You should get a 200 OK. Open http://localhost:3000 for the dashboard.

πŸ“± Running in Termux (Android)
pkg update && pkg upgrade -y
pkg install python git nodejs -y
bash scripts/setup_termux.sh

Then follow the same steps as Quick Start above. If your phone can't comfortably run a 7B+ model, point OLLAMA_HOST at a LAN or Tailscale machine β€” most people do this, since Android backgrounding also makes Termux unsuitable for true 24/7 operation. See Making It Production-Ready for a proper deployment path.

Note: next build isn't currently supported on Android/Termux (the SWC binary isn't available for android/arm64). next dev and npx tsc --noEmit both work fine β€” run next build on Vercel, GitHub Actions, Docker, or WSL2.


πŸ› οΈ Making It Production-Ready

A step-by-step checklist, in the order you'd actually run it.

1️⃣ Generate an API key and enable production mode

python3 -c "import secrets; print(secrets.token_urlsafe(32))"

Put the output in .env as API_KEY=... and set ENVIRONMENT=production. Without this, the backend refuses to start β€” since it can send email on your behalf, it must never be reachable unauthenticated. Add the same key to dashboard/.env.local as BACKEND_API_KEY; the browser never sees it, only the dashboard's own server-side proxy does.

2️⃣ Move to Postgres

# create a database, then:
DATABASE_URL=postgresql://user:pass@host/dbname
alembic upgrade head

Run alembic upgrade head on every deploy after a model change, and alembic revision --autogenerate -m "describe the change" to create the next migration.

3️⃣ Deploy β€” pick one

Option Best for
🐳 Docker Compose (deploy/README.md) Postgres + backend + dashboard + Nginx in one docker compose up -d, HTTPS via Certbot
βš™οΈ systemd, no Docker (deploy/README-systemd.md) Same result, managed as three systemd units

Both put Nginx as the public entry point; neither exposes FastAPI or Postgres directly to the internet.

4️⃣ Set up CI

.github/workflows/ci.yml runs on every push: backend tests against a real Postgres service container, an Alembic migration check, and a full dashboard npm run build. Nothing merges if any of those fail.

5️⃣ Configure log retention

scripts/prune_logs.py prunes logs table rows older than N days (default 30). Both deploy paths install it as a scheduled job.


πŸ”’ Security

Mechanism What It Prevents
X-API-Key required on every route except /health Unauthenticated access to a service that can send email on your behalf
Server-side dashboard proxy (BACKEND_API_KEY, never NEXT_PUBLIC_) The API key ever reaching client-side JavaScript
CORS locked to CORS_ALLOW_ORIGINS Unauthorized browser-based clients
Rate limiting on approve/reject routes (slowapi) Abuse of the approval endpoints
Path-traversal-safe /prompts/{name} routes Arbitrary filesystem access via prompt names
Postgres on an internal Docker network Direct external access to the database
OAuth2-only Gmail auth, tokens never committed Plaintext credential exposure

Recommended: chmod 600 .env token.json credentials.json on any host you deploy to.


🩺 Health vs. Readiness

Endpoint Auth Purpose
GET /health None Liveness only β€” "is the process running."
GET /ready None Readiness β€” runs a real DB query and reports Gmail's connection state. Returns 503 if the database is unreachable.

Use /ready for Docker/systemd health checks and load balancer probes; use /health where you want a lightweight "process alive" check with no DB round-trip.


πŸ§ͺ Testing

pip install -r requirements.txt -r requirements-dev.txt
pytest tests/ -v

19 tests, covering:

  • βœ… Approval-threshold logic (auto-send vs. approval-queue vs. draft-only, including exact boundaries)
  • βœ… API-key enforcement end-to-end
  • βœ… AI-provider singleton behavior
  • βœ… Per-stage AI failure isolation in the pipeline
  • βœ… Telegram Markdown escaping

Runs against SQLite locally and against real Postgres in CI.


βš™οΈ Configuration β€” Swapping Models

LLM_PROVIDER=ollama
LLM_MODEL=deepseek-r1:14b        # or qwen2.5:14b, qwen2.5-coder:14b, mistral, llama3.1
LLM_FALLBACK_MODEL=qwen2.5:7b    # used if the primary model errors or times out

No OpenAI dependency exists anywhere in the codebase β€” every model runs locally through Ollama.


βœ… Approval Workflow

Confidence Action
β‰₯ 95% Auto-send reply via Gmail API
80–94% Draft created, Telegram approval request sent, waits for your review
< 80% Draft only, saved to the database, never sent, never touches Gmail

Enforced in plain Python (app/workflows/pipeline.py::_handle_reply_confidence) β€” not just prompted β€” so a model misreporting its own confidence can't bypass it.


πŸ—ΊοΈ Roadmap

  1. πŸ”Ž RAG over past sent emails (sqlite-vec or Chroma, Ollama embeddings β€” no OpenAI)
  2. ⚑ Redis + Celery for real async/concurrent processing at higher volume
  3. πŸ“§ Multi-Gmail-account support
  4. πŸ’¬ WhatsApp / Slack / Discord / Desktop notification channels
  5. πŸŽ›οΈ Live Model Manager in the dashboard (swap LLM_MODEL without a restart)

πŸ‘€ Behind the Code

Syed Ali Hasan Moosavi

Founder & Managing Director β€” Sayanjali Nexus Private Limited

GitHub Portfolio X

A solo, full-stack technical founder building across AI/SaaS, cybersecurity, blockchain, and business automation β€” end to end, from backend architecture to deployment to the docs you're reading right now. Core stack: Python, FastAPI, Next.js, React, TypeScript, PostgreSQL, Docker.

This project reflects a broader building philosophy: no phase is marked "done" until it's been run against real infrastructure β€” a live Postgres instance, a live Docker-equivalent stack, an actual main.py run with credentials deliberately removed. If this README says something is tested, it's because it was tested.


🧰 Other Tools & Projects by SYJ

Project What It Is
SYJ GST Invoice Reconciliation Production-ready GST invoice reconciliation engine β€” duplicate detection, GSTIN matching, multi-sheet Excel reporting. 137 tests, ~90% coverage.
SYJ NexusIntel AI Multi-tenant enterprise SaaS β€” CRM, revenue intelligence, RBAC, subscriptions, audit logging.
SYJ Media Tools Social media downloader β€” GitHub Pages frontend, FastAPI + yt-dlp backend.
Sayanjali OSINT β€” Sentinel Intelligence Threat intelligence aggregation from VirusTotal, Shodan, AbuseIPDB, AlienVault OTX.
NexusRank AI AI-powered SEO/GEO SaaS β€” async FastAPI backend, multi-provider AI integration, Stripe billing.
Real Estate CRM SaaS Multi-tenant AI-powered CRM with WhatsApp automation.
SYJ MOMENTUM Unified B2B automation β€” WhatsApp, LinkedIn outreach, review monitoring, GST compliance.

Full, up-to-date list: github.com/SHalimoosavi?tab=repositories


πŸ“„ License

MIT License β€” see LICENSE.


Model-agnostic. Self-hosted. Actually tested against real infrastructure.

Built to run anywhere. Shipped like a product.

About

AI-powered Gmail intelligence platform that automatically classifies emails, prioritizes messages, generates summaries and smart replies using local LLMs (Ollama), with a FastAPI backend, Next.js dashboard.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages