Daily Digest

The Daily Digest feature provides a consolidated view of your emails, organized by category with AI-generated summaries.


Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    DIGEST GENERATION FLOW                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚   β”‚   Fetch     │───▢│ Categorize  │───▢│  Group by       β”‚    β”‚
β”‚   β”‚   Emails    β”‚    β”‚   Each      β”‚    β”‚  Category       β”‚    β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                   β”‚              β”‚
β”‚                                                   β–Ό              β”‚
β”‚                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚                      β”‚   Render    │◀───│   Generate      β”‚    β”‚
β”‚                      β”‚   Digest    β”‚    β”‚   Summaries     β”‚    β”‚
β”‚                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Digest Structure

Categories Section

Emails grouped by type:

πŸ“‹ Need-Action (3)
β”œβ”€β”€ Meeting invite from John
β”œβ”€β”€ Urgent: Project deadline
└── Please review PR #42

πŸ“– FYI (5)
β”œβ”€β”€ Monthly report published
β”œβ”€β”€ System maintenance notice
└── ...

πŸ“° Newsletter (4)
β”œβ”€β”€ TechCrunch Daily
β”œβ”€β”€ Morning Brew
└── ...

Newsletter Summaries

Each newsletter gets an AI-generated summary:

πŸ“° TechCrunch Daily
Summary: Today's top stories include Apple's new AI features,
startup funding rounds, and regulatory updates in the EU.
Key topics: AI, Startups, Regulation

πŸ“° Morning Brew
Summary: Market updates show tech stocks rising, with focus
on Q4 earnings reports and holiday shopping trends.
Key topics: Markets, Retail, Tech

Generation Process

1. Fetch Emails

def fetch_emails(max_count: int = 10) -> list[dict]:
    """Fetch recent unread emails from Gmail."""
    query = "is:unread newer_than:1d"

    results = gmail_service.users().messages().list(
        userId='me',
        q=query,
        maxResults=max_count,
    ).execute()

    messages = results.get('messages', [])
    return [get_message_details(msg['id']) for msg in messages]

2. Categorize Each Email

def process_emails(emails: list[dict]) -> dict[str, list]:
    """Categorize emails and group by category."""
    categorized = {
        'Need-Action': [],
        'FYI': [],
        'Newsletter': [],
        'Promotional': [],
        'Social': [],
    }

    for email in emails:
        category = categorize_email(email)
        categorized[category].append(email)

    return categorized

3. Generate Summaries

def generate_category_summary(category: str, emails: list[dict]) -> str:
    """Generate AI summary for a category."""
    if not emails:
        return "No emails in this category."

    email_list = "\n".join([
        f"- {email['subject']} (from {email['from']})"
        for email in emails[:5]  # Limit for prompt size
    ])

    prompt = f"""
    Summarize these {category} emails in 2-3 sentences:

    {email_list}

    Focus on key action items or themes.
    """

    response = gemini_client.generate_content(prompt)
    return response.text

4. Newsletter Highlights

def extract_newsletter_highlights(email: dict) -> dict:
    """Extract key points from newsletter."""
    prompt = f"""
    Extract key highlights from this newsletter:

    Subject: {email['subject']}
    Content: {email['body'][:1000]}

    Return:
    - 2-3 sentence summary
    - Top 3 topics covered
    """

    response = gemini_client.generate_content(prompt)
    return parse_highlights(response.text)

Web Interface

Digest View

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ“§ Email Digest                    [Refresh]   β”‚
β”‚  Generated: Dec 22, 2024 at 9:30 AM             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                 β”‚
β”‚  πŸ“‹ Need-Action (3)                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ πŸ“Œ Meeting: Q4 Review                   β”‚   β”‚
β”‚  β”‚    From: manager@company.com            β”‚   β”‚
β”‚  β”‚    Action: Accept/Decline by EOD        β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                 β”‚
β”‚  πŸ“– FYI (5)                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ Summary: 5 informational emails about   β”‚   β”‚
β”‚  β”‚ project updates and system notices.     β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                 β”‚
β”‚  πŸ“° Newsletter (4)                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ πŸ—žοΈ TechCrunch Daily                     β”‚   β”‚
β”‚  β”‚ AI advances, startup news, EU tech laws β”‚   β”‚
β”‚  β”‚                                          β”‚   β”‚
β”‚  β”‚ πŸ—žοΈ Morning Brew                         β”‚   β”‚
β”‚  β”‚ Market rally continues, retail outlook  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Refresh Functionality

// script.js
async function refreshDigest() {
    const button = document.getElementById('refresh-btn');
    button.disabled = true;
    button.textContent = 'Refreshing...';

    try {
        const response = await fetch('/api/refresh', { method: 'POST' });
        if (response.ok) {
            location.reload();
        }
    } finally {
        button.disabled = false;
        button.textContent = 'Refresh';
    }
}

Data Persistence

Digest Storage

def save_digest(digest_data: dict) -> None:
    """Save digest to JSON file."""
    path = Path('data/digest/latest.json')

    with open(path, 'w') as f:
        json.dump({
            'generated_at': datetime.now().isoformat(),
            'data': digest_data,
        }, f, indent=2)

Cache Integration

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      CACHE INTEGRATION                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚   β”‚ New Request │─────────▢│  Digest Fresh?  β”‚                  β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚                                     β”‚                            β”‚
β”‚                            Yes      β”‚      No                    β”‚
β”‚                            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚                            β”‚                 β”‚                   β”‚
β”‚                            β–Ό                 β–Ό                   β”‚
β”‚                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
β”‚                     β”‚  Return   β”‚     β”‚ Regenerateβ”‚             β”‚
β”‚                     β”‚  Cached   β”‚     β”‚           β”‚             β”‚
β”‚                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜             β”‚
β”‚                            β–²                β”‚                    β”‚
β”‚                            β”‚                β–Ό                    β”‚
β”‚                            β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚                            └─────────│   Save    β”‚              β”‚
β”‚                                      β”‚ to Cache  β”‚              β”‚
β”‚                                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚
β”‚                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Performance

MetricValue
First run (10 emails)13-20 seconds
Cached run5-8 seconds
Page load< 1 second

Optimization Tips

Reduce Email Count

Fetch only what you need to process

Enable Caching

Avoid redundant API calls

Batch Processing

Process emails in parallel

Limit Summaries

Only summarize newsletters


Configuration

{
  "gmail_settings": {
    "max_emails_to_fetch": 10,
    "search_query": "is:unread newer_than:1d"
  },
  "digest_settings": {
    "include_promotional": false,
    "include_social": false,
    "newsletter_summary_length": 100
  }
}

Related Documentation