You're offline — showing cached data

Wiki

09-integrations/email
2026-06-13 07:27:03 SAST
Wiki Home → 09-integrations/email

Email Integration

Email integration connects Elmar's Microsoft 365 Outlook account to the Luci system via the MS Graph API. Emails are fetched, classified by project, summarized, and stored in a searchable SQLite database.

Components

Component Path Purpose
graph_api.py ~/workspace/scripts/graph_api.py MS Graph API client (auth, email, calendar, files)
email_sync.py ~/workspace/scripts/email_sync.py Daily email sync pipeline
email_backfill.py ~/workspace/scripts/email_backfill.py Backfill summaries for existing emails
email_attachment_sync.py ~/workspace/scripts/email_attachment_sync.py Download attachments for synced emails
email.db ~/workspace/email.db SQLite database of classified emails
email-index skill ~/.claude/skills/email-index/ Query interface for searching email.db

MS Graph API Client (graph_api.py)

Self-contained Python script with zero external dependencies (stdlib only). Handles its own OAuth via device code flow.

Authentication

Available Commands

python graph_api.py login                          # One-time auth
python graph_api.py list-messages [--since DATE]   # List emails
python graph_api.py read-message <id>              # Read full email
python graph_api.py send-message --to ... --subject ... --body ...
python graph_api.py create-reply <id> --body ...   # Draft reply
python graph_api.py send-draft <id>                # Send a draft
python graph_api.py search --query "keyword"       # Search Outlook
python graph_api.py search-files --query "..."     # OneDrive/SharePoint search
python graph_api.py calendar [--start ...] [--end ...]
python graph_api.py upload-to-onedrive <local> <remote>

email.db Schema

Column Type Notes
internet_message_id TEXT UNIQUE RFC immutable key (survives moves/archive)
conversation_id TEXT Thread grouping
subject TEXT Email subject
sender_email TEXT Sender address
sender_name TEXT Display name
received_date TEXT ISO date
project TEXT Classified project name
summary TEXT 1-2 sentence summary
confidence TEXT high/medium/low
has_attachments INTEGER 0 or 1

Daily Email Sync Pipeline

See 12-data-flows/email-pipeline for the full flow diagram.

Noise Filtering

Inbox rules are parsed from inbox-rules.md: - Sender blocklist: Exact email matches and wildcard patterns (e.g., *@zapiermail.com) - Subject skip patterns: Auto-skip emails with specific subject keywords

Project Classification

Email Backfill

email_backfill.py enriches existing email.db records that lack summaries: 1. Fetches emails without summaries from email.db 2. Reads body from Graph API by internet_message_id 3. Sends to Gemini Flash for classification + summary 4. Updates email.db with results - Rate limited: 1s between Graph API calls, batched Gemini calls

Searching Emails

Via email-index skill (recommended)

python ~/.claude/skills/email-index/query.py project "Project Heron"
python ~/.claude/skills/email-index/query.py search "MOI harith"
python ~/.claude/skills/email-index/query.py sender "stephan.spamer"
python ~/.claude/skills/email-index/query.py thread "AAQkAD..."
python ~/.claude/skills/email-index/query.py stats
python ~/.claude/skills/email-index/query.py recent --limit 10

Via Graph API (live search)

python graph_api.py search --query "subject:keyword" --top 20

When to Use What

Need Tool
Past emails by project/person email-index skill (queries email.db)
Full email body email.db lookup then graph_api.py read-message <graph-message-id>
Live inbox / new emails inbox-assist skill
Reply / draft / send inbox-assist or graph_api.py
Ad-hoc Outlook search graph_api.py search

Key Takeaways

Help