Production-ready FastAPI service that monitors Gmail, classifies incoming messages with Groq-first LLM routing plus local safety rules, auto-replies to safe messages, and sends risky messages to Telegram for approval.
app/gmail: Gmail OAuth, unread email reader, threaded reply sender.app/integrations: shared Google OAuth plus Google Calendar scheduling services.app/ai: Groq-first classifier/provider routing, deterministic risk engine, local reply safety validation.app/services: Inbox orchestration, duplicate prevention, approval workflow.app/telegram: Telegram Bot API approval notifications and callback support.app/memory: sender history and trust scoring.app/database.py: SQLite persistence for emails, decisions, approvals, sender memory, and action logs.app/main.py: FastAPI app, health checks, Telegram webhook, APScheduler polling.
The first database backend is SQLite. The service layer only depends on the Database adapter, so it can later be swapped for PostgreSQL without changing Gmail, AI, or Telegram modules.
The agent never auto-replies to noreply, newsletter, promotional, spam, or phishing-like messages. It requires approval for legal, financial, HR, angry, sensitive, attachment-bearing, low-confidence, unknown, or high-risk messages. Duplicate email IDs and duplicate approval callbacks are blocked in the database.
Groq is the default LLM provider for intent, urgency, tone, summary, confidence, and suggested reply generation. Deterministic local risk scoring and reply validation are always applied before and after model output, so no paid OpenAI API is required for safety or production operation. OpenAI remains an optional adapter only if explicitly configured.
cd "/Users/143ns/BTECH/PORTFOLIO/EMail Automator"
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .envFill .env with Groq, Gmail, and Telegram values. OpenAI is optional.
Run tests:
pytest -qRun locally:
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000Or:
python -m app.mainLocal development starts with ENABLE_INBOX_MONITOR=false by default, so /health works before Gmail, Groq, and Telegram credentials are configured. Set ENABLE_INBOX_MONITOR=true after .env, Gmail OAuth, Groq, and Telegram are ready.
Health check:
curl http://127.0.0.1:8000/health
curl http://localhost:8000/healthExpected response:
{"status":"ok"}Production diagnostics:
curl https://<render-url>/
curl https://<render-url>/health
curl https://<render-url>/status
curl -H "X-Diagnostics-Secret: <DIAGNOSTICS_SECRET>" https://<render-url>/diagnostics/gmail/diagnostics/gmail verifies the mounted Gmail client secret, token file, required scopes, Gmail profile access, and unread inbox query without returning email bodies or subjects.
- Go to Google Cloud Console.
- Create a project and enable the Gmail API and Google Calendar API.
- Configure OAuth consent screen.
- Create an OAuth Client ID for a desktop app.
- Download it as
client_secret.json. - Generate the shared Gmail + Calendar token:
python scripts/generate_google_token.pyThis creates token.json using the existing client_secret.json. The legacy command below is kept for compatibility and now requests the same shared scopes:
python scripts/generate_gmail_token.pyTo intentionally force a fresh consent screen after adding Calendar scopes, run:
python scripts/generate_google_token.py --force- On Render, upload
client_secret.jsonandtoken.jsonas secret files.
Required shared Google scopes:
https://www.googleapis.com/auth/gmail.modifyhttps://www.googleapis.com/auth/gmail.sendhttps://www.googleapis.com/auth/calendarhttps://www.googleapis.com/auth/calendar.events
Enable Calendar features with:
GOOGLE_CALENDAR_ENABLED=true
GOOGLE_CALENDAR_ID=primary
Seno uses the same token for Gmail and Calendar. If token.json is missing, invalid, expired without a refresh token, or missing Calendar scopes, the shared Google auth loader regenerates it from client_secret.json.
- Message
@BotFather. - Create a bot and copy the token into
TELEGRAM_BOT_TOKEN. - Get your chat ID by messaging the bot, then visiting:
https://api.telegram.org/bot<token>/getUpdates
- Set
TELEGRAM_CHAT_ID. - After deployment, configure the webhook:
curl "https://api.telegram.org/bot<token>/setWebhook?url=https://<render-url>/telegram/webhook&secret_token=<TELEGRAM_WEBHOOK_SECRET>"Create a Groq API key and set:
LLM_PROVIDER=groq
GROQ_API_KEY=...
GROQ_MODEL=llama-3.3-70b-versatile
Optional OpenAI adapter:
LLM_PROVIDER=openai
OPENAI_API_KEY=...
OPENAI_MODEL=gpt-4.1-mini
- Push this repository to GitHub.
- Create a new Render Blueprint from
render.yaml. - Add secret environment variables:
GROQ_API_KEYTELEGRAM_BOT_TOKENTELEGRAM_CHAT_IDDIAGNOSTICS_SECRET
- Add secret files:
/etc/secrets/client_secret.json/etc/secrets/token.json
- Deploy.
- Confirm
https://<render-url>/healthreturns{"status":"ok"}. - Set the Telegram webhook as shown above.
Render restarts the service automatically after crashes. APScheduler resumes polling on process startup. The SQLite disk at /data preserves processed message IDs, approvals, and memory.
docker build -t autonomous-gmail-ai-agent .
docker run --env-file .env -p 8000:8000 autonomous-gmail-ai-agentSee .env.example for all supported variables. In production, these are required:
GROQ_API_KEYGMAIL_CLIENT_SECRETS_FILEGMAIL_TOKEN_FILETELEGRAM_BOT_TOKENTELEGRAM_CHAT_ID
- Gmail or Calendar auth fails: regenerate the shared
token.jsonlocally withpython scripts/generate_google_token.py, then redeploy the updated secret file. - Telegram buttons do nothing: verify webhook URL,
TELEGRAM_WEBHOOK_SECRET, and Render logs. - Duplicate replies: check
emailsandapprovalstables. Gmail message IDs are primary keys and approval rows are unique by Gmail ID. - Groq outage or missing provider key: messages fall back to approval-required mode; local risk/safety rules still run.
- Render restarts: inspect action logs and service logs. The agent is designed to continue after restart without reprocessing stored Gmail IDs.
- PostgreSQL adapter with migrations.
- Gmail push notifications via Pub/Sub instead of polling.
- Admin UI for approvals and audit history.
- Per-sender custom reply style memory.
- Vector memory for long-running relationships.