Skip to main content

Daily Digest

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

Overviewโ€‹

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โ€‹

Performanceโ€‹

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

Optimization Tipsโ€‹

  1. Reduce email count: Fetch only what you need
  2. Enable caching: Avoid redundant API calls
  3. Batch processing: Process emails in parallel
  4. 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
}
}