Backend-only, Telegram-operated Gmail assistant for inbox triage, digesting, and draft suggestion under strict manual-send control.
This system never sends emails automatically.
- No email send endpoint is exposed.
- No
send_emailtool exists in backend services. - Drafts can be generated and created in Gmail, but final send happens manually by the user in Gmail.
[Telegram User]
|
| Bot commands + inline callbacks
v
[Telegram Bot API] -> [FastAPI Backend /telegram/webhook]
|-- /auth/* -> Google OAuth flow
|-- /emails/* -> Gmail sync + stored email retrieval + analysis
|-- /digests/* -> digest generation + Telegram dispatch
|-- /actions/* -> approve/reject/execute suggested actions
|-- /drafts/* -> draft generation + create Gmail draft (no send)
|-- /telegram/* -> webhook + Telegram test endpoint
|
+--> [SQLAlchemy + Alembic] -> [Postgres]
+--> [Celery Worker + Beat] <-> [Redis]
+--> [OpenAI API (structured outputs)]
+--> [Gmail API (read + draft only)]
- Backend: Python + FastAPI
- Database: Postgres
- ORM/Migrations: SQLAlchemy + Alembic
- Background Jobs: Redis + Celery
- AI: OpenAI API (structured JSON outputs)
- Email: Gmail API (read + draft only)
- Operations: Telegram Bot API
- Copy env template:
cp .env.example .env(PowerShell:Copy-Item .env.example .env)
- Fill required values in
.env:- Google OAuth credentials
- OpenAI API key
- Telegram bot token (+ optional bot username)
- Telegram webhook base URL + secret token
- Database URL
- Install backend dependencies:
cd backend && pip install -r requirements.txt
- Copy and configure env:
Copy-Item .env.example .env- Keep
DATABASE_URLpointed to your existing cloud Postgres. - Set
TELEGRAM_WEBHOOK_BASE_URL=https://<your-stable-tunnel-domain>. - Set
GOOGLE_REDIRECT_URI=https://<your-stable-tunnel-domain>/auth/google/callback. - Keep
TELEGRAM_WEBHOOK_SECRET_TOKENset.
- Start API, worker, and Redis:
docker compose up -d --build
- Verify local health:
curl.exe -sS http://localhost:8000/health
- Set
CLOUDFLARED_TUNNEL_TOKENin.env. - Start tunnel profile:
docker compose --profile tunnel up -d
- Install
cloudflaredand run (admin terminal):cloudflared.exe service install <TUNNEL_TOKEN>
- This enables tunnel auto-start on reboot.
- Containers use
restart: unless-stoppedindocker-compose.yml. - Enable Docker Desktop auto-start on login.
- Ensure your tunnel client (Docker profile or Windows service) auto-starts.
Notes:
- Backend startup runs
alembic upgrade headautomatically by default (RUN_DB_MIGRATIONS_ON_STARTUP=true). - Set
RUN_DB_MIGRATIONS_ON_STARTUP=falseif you manage migrations separately in your deploy pipeline.
- Open chat with your bot and send
/start. - Send
/connectand click Connect Gmail. - Complete Google OAuth consent in browser.
- Google calls back to
GET /auth/google/callbackand the backend auto-links yourtelegram_chat_id. - Operate through Telegram:
/status/today/ask <question>/followups/due-today/schedule country <country>/schedule count <1-3>/schedule times <8am,1pm[,6pm]>/schedule status/schedule on/schedule off
- Set
TELEGRAM_WEBHOOK_BASE_URLto your public HTTPS backend URL. - Backend startup auto-registers webhook at:
<TELEGRAM_WEBHOOK_BASE_URL>/telegram/webhook
- Localhost is not reachable by Telegram unless exposed via secure tunnel/reverse proxy.
- Telegram webhook delivery requires HTTPS and supported ports (
443,80,88,8443). - Verify webhook status:
curl.exe -sS "https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/getWebhookInfo"- Start local stack and tunnel, then confirm:
curl.exe -sS http://localhost:8000/healthcurl.exe -sS https://<your-stable-tunnel-domain>/health
- Check webhook now targets desktop domain:
curl.exe -sS "https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/getWebhookInfo"- Confirm
urlishttps://<your-stable-tunnel-domain>/telegram/webhook.
- Run Telegram checks:
/start,/status,/today
- Run OAuth check:
/connect, complete login, verify callback success page and chat link.
- Disable/scale down Render service after verification to avoid dual-processing.
GET /healthPOST /auth/google/startGET /auth/google/callbackPOST /emails/syncGET /emailsGET /emails/{email_id}POST /emails/{email_id}/analysePOST /digests/generateGET /digests/latestPOST /digests/{digest_id}/send-telegramPOST /actions/{action_id}/approvePOST /actions/{action_id}/rejectPOST /drafts/generatePOST /drafts/{draft_id}/create-in-gmailPOST /telegram/webhookPOST /telegram/test
- The assistant extracts commitments/tasks from analyzed emails and stores open follow-up items.
- Use
/followupsto list unresolved follow-up items. - Use
/due-todayto show follow-ups due in your current timezone day. - Optional proactive reminders:
FOLLOWUP_REMINDERS_ENABLED=trueFOLLOWUP_REMINDER_LEAD_MINUTES=60FOLLOWUP_REMINDER_COOLDOWN_HOURS=6
- Do not commit
.env. - Use env vars only; no hardcoded secrets.
- Restrict OAuth scopes to Gmail read/draft workflows.
- Keep audit log (
agent_actions) for AI suggestions and decisions. - Enforce manual approval for actionable suggestions.
- Maintain explicit prohibition on automatic email sending.