You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
1 week ago | |
|---|---|---|
| app | 1 week ago | |
| .env.example | 1 week ago | |
| .gitignore | 1 week ago | |
| README.md | 1 week ago | |
| requirements.txt | 1 week ago | |
README.md
Personal Gmail + Calendar Agent
This project runs a small local API service that:
- scans new Gmail inbox messages
- classifies emails with an LLM as
LINKEDIN,ADVERTISING, orOTHER - moves LinkedIn emails to a
LinkedInlabel/folder - moves advertising emails to an
Advertisinglabel/folder - exposes a secure availability endpoint powered by Google Calendar free/busy
1) Prerequisites
- Python 3.11+
- A Google account
- An OpenAI-compatible API key for the LLM classifier
- A Google Cloud project with:
- Gmail API enabled
- Google Calendar API enabled
- OAuth consent configured
- OAuth Client ID of type Desktop app
2) Google OAuth setup
- In Google Cloud Console, create a desktop OAuth client.
- Download the client JSON file.
- Save it in this project as
credentials.json.
The first run opens a browser window for consent and creates token.json.
3) Install and configure
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
Edit .env and set:
AGENT_API_KEYto a strong secret for agent-to-agent callsLLM_API_KEYand optionalLLM_MODEL/LLM_BASE_URL- optional scan frequency and Gmail query
4) Run
uvicorn app.main:app --reload
At startup, the scheduler runs every GMAIL_SCAN_INTERVAL_MINUTES.
5) API usage
Health check
curl http://127.0.0.1:8000/health
Manual Gmail scan
curl -X POST "http://127.0.0.1:8000/scan?max_results=100" \
-H "X-API-Key: your-secret"
Availability for other AI agents
curl -X POST "http://127.0.0.1:8000/availability" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret" \
-d '{
"start": "2026-03-09T09:00:00+01:00",
"end": "2026-03-09T10:00:00+01:00",
"calendar_ids": ["primary"]
}'
If available is true, there are no busy slots in that range.
Classification behavior
- LLM classification is used for each email (
LINKEDIN,ADVERTISING,OTHER). - LinkedIn has priority over advertising inside the classifier prompt.
- Set
LLM_FALLBACK_TO_RULES=trueonly if you want rules-based backup when LLM calls fail. - Every scanned message gets an
AgentProcessedlabel to avoid reprocessing loops.
Notes
- Gmail "folders" are labels. This agent creates:
LinkedInAdvertisingAgentProcessed
- Messages classified as LinkedIn/Advertising are removed from
INBOX(moved out of inbox).