cd /news/ai-agents/daily-summary-agent Β· home β€Ί topics β€Ί ai-agents β€Ί article
[ARTICLE Β· art-19004] src=dev.to pub= topic=ai-agents verified=true sentiment=↑ positive

Daily-summary-agent

A developer built a fully local AI agent that reads Slack messages and Gmail emails every morning and generates a prioritized daily summary using the Hermes3 open-source model running on Ollama. The agent, which processes 47 Slack messages and 23 emails in under 60 seconds, never sends data to external servers and requires no API keys or internet connection. The project demonstrates a private, cost-free alternative to cloud-based summarization tools for startups concerned about data security.

read6 min publishedMay 31, 2026

*This is a # I Built a Private AI Agent That Reads My Slack & Gmail Every Morning β€” Runs 100% on My Laptop

No API keys. No cloud. No monthly bill. Just Hermes3 running locally, summarizing my entire day before I drink my first coffee.

Every morning I opened 47 Slack messages and 23 emails and spent 40 minutes figuring out what actually needed my attention.

The obvious fix? Ask ChatGPT or Claude to summarize them.

But wait β€” that means sending every private Slack message, every client email, every internal discussion to someone else's server. For a startup, that's a non-starter.

So I built my own. Fully local. Fully private. Free forever.

A Python agent that:

Every morning at 9 AM, this runs automatically and gives me:

πŸ”΄ URGENT β€” ACTION NEEDED
- Production server throwing 503s (#dev) β€” Ravi needs help
- Client contract must be signed by EOD β€” priya@client.com

πŸ’¬ IMPORTANT DISCUSSIONS  
- Q3 roadmap debate ongoing in #product
- Partnership proposal from Zoho needs response

πŸ“’ FYI β€” ANNOUNCEMENTS
- Monday is a public holiday (HR, #general)

πŸ—‘οΈ LOW PRIORITY
- 3 newsletters, 2 LinkedIn notifications

In under 60 seconds. On my machine. No data leaving my laptop.

This is the question worth answering properly.

ChatGPT / Claude API Hermes3 (Local)
Your data Sent to their servers Never leaves your machine
Cost ~$30–50/month at scale Free forever
Customization Prompt only Fine-tune on your own data
Internet required Always Never
Speed Network latency Pure local speed
Restrictions Content policies Full control

Hermes3 is an open-source model by Nous Research, built on LLaMA 3. It's specifically fine-tuned to be excellent at instruction-following and summarization β€” exactly what this agent needs.

Slack API  +  Gmail API
       ↓
   Python agent
       ↓
  Ollama (local runner)
       ↓
   Hermes3 (LLM)
       ↓
 Smart grouped summary
curl -fsSL https://ollama.com/install.sh | sh

ollama run hermes3

Test it works:

curl http://localhost:11434/api/generate \
  -d '{"model": "hermes3", "prompt": "Say hello", "stream": false}'
daily-summary-agent/
β”œβ”€β”€ slack_reader.py
β”œβ”€β”€ gmail_reader.py
β”œβ”€β”€ summarizer.py
β”œβ”€β”€ main.py
β”œβ”€β”€ credentials.json     ← Gmail OAuth file
└── .env
python
import os
from datetime import datetime
from slack_sdk import WebClient
from dotenv import load_dotenv

load_dotenv()
client = WebClient(token=os.environ["SLACK_BOT_TOKEN"])

def get_today_messages():
    all_messages = {}
    oldest = datetime.now().replace(hour=0, minute=0, second=0).timestamp()

    result = client.conversations_list(types="public_channel,private_channel")

    for ch in result["channels"]:
        if not ch.get("is_member"):
            continue
        try:
            history = client.conversations_history(
                channel=ch["id"], oldest=oldest, limit=100
            )
            messages = [
                m["text"] for m in history["messages"]
                if m.get("text") and not m.get("bot_id")
            ]
            if messages:
                all_messages[ch["name"]] = messages
        except Exception as e:
            print(f"Skipping #{ch['name']}: {e}")

    return all_messages
python
import os
from datetime import datetime
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build

SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]

def get_gmail_service():
    creds = None
    if os.path.exists("token.json"):
        creds = Credentials.from_authorized_user_file("token.json", SCOPES)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
            creds = flow.run_local_server(port=0)
        with open("token.json", "w") as f:
            f.write(creds.to_json())
    return build("gmail", "v1", credentials=creds)

def get_today_emails():
    service = get_gmail_service()
    today = datetime.now().strftime("%Y/%m/%d")
    results = service.users().messages().list(
        userId="me", q=f"after:{today}", maxResults=50
    ).execute()

    emails = []
    for msg in results.get("messages", []):
        data = service.users().messages().get(
            userId="me", id=msg["id"], format="full"
        ).execute()
        headers = data["payload"]["headers"]
        emails.append({
            "subject": next((h["value"] for h in headers if h["name"] == "Subject"), ""),
            "from": next((h["value"] for h in headers if h["name"] == "From"), ""),
            "snippet": data.get("snippet", "")
        })
    return emails

This is where the magic happens. The prompt design is everything:

import requests

def summarize(slack_data, email_data):
    prompt = """You are a smart executive assistant. 
Analyze these messages and group them into exactly 4 sections:

πŸ”΄ URGENT β€” ACTION NEEDED (deadlines, outages, decisions needed today)
πŸ’¬ IMPORTANT DISCUSSIONS (ongoing debates, replies needed soon)  
πŸ“’ FYI β€” ANNOUNCEMENTS (good to know, no action needed)
πŸ—‘οΈ LOW PRIORITY (newsletters, notifications, can ignore)

For each item write: channel/sender β€” one line summary.
Be ruthlessly concise. Max 10 words per item.

=== SLACK ===\n"""

    for channel, msgs in slack_data.items():
        prompt += f"\n#{channel}:\n" + "\n".join(f"- {m}" for m in msgs)

    prompt += "\n\n=== EMAILS ===\n"
    for e in email_data:
        prompt += f"- From: {e['from']} | {e['subject']} | {e['snippet'][:100]}\n"

    prompt += "\n\nNow give the grouped summary:"

    response = requests.post("http://localhost:11434/api/generate", json={
        "model": "hermes3",
        "prompt": prompt,
        "stream": False
    })
    return response.json()["response"]
python
from slack_reader import get_today_messages
from gmail_reader import get_today_emails
from summarizer import summarize
from datetime import datetime

def run_agent():
    print(f"\nπŸ€– Daily Brief β€” {datetime.now().strftime('%B %d, %Y %I:%M %p')}")
    print("=" * 50)
    print("πŸ“₯ Reading Slack...")
    slack = get_today_messages()
    print("πŸ“§ Reading Gmail...")
    emails = get_today_emails()
    print("🧠 Thinking with Hermes3...\n")
    summary = summarize(slack, emails)
    print(summary)
    with open("daily_summary.txt", "w") as f:
        f.write(summary)
    return summary

if __name__ == "__main__":
    run_agent()
crontab -e

0 9 * * 1-5 cd /path/to/daily-summary-agent && python3 main.py >> summary.log 2>&1

Before connecting Slack/Gmail, test Hermes summarization with fake data:

from summarizer import summarize

fake_slack = {
    "dev": ["Server is down! 503 errors since 8am", "PR #234 needs review"],
    "general": ["Team lunch at 1pm", "Please fill the feedback form"]
}

fake_emails = [
    {"from": "boss@company.com", "subject": "Q3 Report Due Today", "snippet": "Submit by EOD"},
    {"from": "newsletter@medium.com", "subject": "Top AI stories", "snippet": "Weekly digest..."}
]

print(summarize(fake_slack, fake_emails))

Run it:

python3 test_summarizer.py

No Slack token, no Gmail auth needed. Just Hermes running locally. βœ…

πŸ”΄ URGENT β€” ACTION NEEDED
β€’ #dev β€” Server down, 503s since 8am, fix immediately
β€’ boss@company.com β€” Q3 report due today EOD

πŸ’¬ IMPORTANT DISCUSSIONS
β€’ #product β€” Q3 roadmap priorities debated, needs decision
β€’ partnerships@zoho.com β€” Integration call request this week

πŸ“’ FYI β€” ANNOUNCEMENTS  
β€’ #general β€” Monday public holiday, no standups
β€’ HR β€” Feedback form deadline Friday

πŸ—‘οΈ LOW PRIORITY
β€’ medium.com β€” Weekly AI newsletter
β€’ linkedin.com β€” 3 connection requests

40 minutes of inbox anxiety β†’ 60 seconds of clarity. Every morning.

Things I'm adding next:

pyttsx3

We're in a moment where running a capable LLM locally is genuinely possible for any developer. Hermes3 on a MacBook M-series is fast, smart, and completely private.

The real unlock isn't just summarization. It's your own AI that knows your context, your team, your language β€” without sending that context to anyone else.

Every workflow you currently do with a cloud API, ask yourself: does this data need to leave my machine?

Often the answer is no.

Built this over a weekend. Still running every morning. Zero cloud costs.

Have questions or improvements? Drop them in the comments β€” happy to help you set it up.

Tags: #ai

#python

#productivity

#ollama

#opensource

submission for the Hermes Agent Challenge: Write About Hermes Agent*

── more in #ai-agents 4 stories Β· sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/daily-summary-agent] indexed:0 read:6min 2026-05-31 Β· β€”