{"slug": "daily-summary-agent", "title": "Daily-summary-agent", "summary": "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.", "body_md": "*This is a # I Built a Private AI Agent That Reads My Slack & Gmail Every Morning — Runs 100% on My Laptop\n\nNo API keys. No cloud. No monthly bill. Just Hermes3 running locally, summarizing my entire day before I drink my first coffee.\n\nEvery morning I opened **47 Slack messages** and **23 emails** and spent 40 minutes figuring out what actually needed my attention.\n\nThe obvious fix? Ask ChatGPT or Claude to summarize them.\n\nBut 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.\n\nSo I built my own. Fully local. Fully private. Free forever.\n\nA Python agent that:\n\nEvery morning at 9 AM, this runs automatically and gives me:\n\n```\n🔴 URGENT — ACTION NEEDED\n- Production server throwing 503s (#dev) — Ravi needs help\n- Client contract must be signed by EOD — priya@client.com\n\n💬 IMPORTANT DISCUSSIONS  \n- Q3 roadmap debate ongoing in #product\n- Partnership proposal from Zoho needs response\n\n📢 FYI — ANNOUNCEMENTS\n- Monday is a public holiday (HR, #general)\n\n🗑️ LOW PRIORITY\n- 3 newsletters, 2 LinkedIn notifications\n```\n\nIn under 60 seconds. On my machine. No data leaving my laptop.\n\nThis is the question worth answering properly.\n\n| ChatGPT / Claude API | Hermes3 (Local) | |\n|---|---|---|\n| Your data | Sent to their servers | Never leaves your machine |\n| Cost | ~$30–50/month at scale | Free forever |\n| Customization | Prompt only | Fine-tune on your own data |\n| Internet required | Always | Never |\n| Speed | Network latency | Pure local speed |\n| Restrictions | Content policies | Full control |\n\n**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.\n\n```\nSlack API  +  Gmail API\n       ↓\n   Python agent\n       ↓\n  Ollama (local runner)\n       ↓\n   Hermes3 (LLM)\n       ↓\n Smart grouped summary\n# Install Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# Pull and run Hermes3 (4.7GB download)\nollama run hermes3\n```\n\nTest it works:\n\n```\ncurl http://localhost:11434/api/generate \\\n  -d '{\"model\": \"hermes3\", \"prompt\": \"Say hello\", \"stream\": false}'\ndaily-summary-agent/\n├── slack_reader.py\n├── gmail_reader.py\n├── summarizer.py\n├── main.py\n├── credentials.json     ← Gmail OAuth file\n└── .env\npython\n# slack_reader.py\nimport os\nfrom datetime import datetime\nfrom slack_sdk import WebClient\nfrom dotenv import load_dotenv\n\nload_dotenv()\nclient = WebClient(token=os.environ[\"SLACK_BOT_TOKEN\"])\n\ndef get_today_messages():\n    all_messages = {}\n    oldest = datetime.now().replace(hour=0, minute=0, second=0).timestamp()\n\n    result = client.conversations_list(types=\"public_channel,private_channel\")\n\n    for ch in result[\"channels\"]:\n        if not ch.get(\"is_member\"):\n            continue\n        try:\n            history = client.conversations_history(\n                channel=ch[\"id\"], oldest=oldest, limit=100\n            )\n            messages = [\n                m[\"text\"] for m in history[\"messages\"]\n                if m.get(\"text\") and not m.get(\"bot_id\")\n            ]\n            if messages:\n                all_messages[ch[\"name\"]] = messages\n        except Exception as e:\n            print(f\"Skipping #{ch['name']}: {e}\")\n\n    return all_messages\npython\n# gmail_reader.py\nimport os\nfrom datetime import datetime\nfrom google.oauth2.credentials import Credentials\nfrom google_auth_oauthlib.flow import InstalledAppFlow\nfrom google.auth.transport.requests import Request\nfrom googleapiclient.discovery import build\n\nSCOPES = [\"https://www.googleapis.com/auth/gmail.readonly\"]\n\ndef get_gmail_service():\n    creds = None\n    if os.path.exists(\"token.json\"):\n        creds = Credentials.from_authorized_user_file(\"token.json\", SCOPES)\n    if not creds or not creds.valid:\n        if creds and creds.expired and creds.refresh_token:\n            creds.refresh(Request())\n        else:\n            flow = InstalledAppFlow.from_client_secrets_file(\"credentials.json\", SCOPES)\n            creds = flow.run_local_server(port=0)\n        with open(\"token.json\", \"w\") as f:\n            f.write(creds.to_json())\n    return build(\"gmail\", \"v1\", credentials=creds)\n\ndef get_today_emails():\n    service = get_gmail_service()\n    today = datetime.now().strftime(\"%Y/%m/%d\")\n    results = service.users().messages().list(\n        userId=\"me\", q=f\"after:{today}\", maxResults=50\n    ).execute()\n\n    emails = []\n    for msg in results.get(\"messages\", []):\n        data = service.users().messages().get(\n            userId=\"me\", id=msg[\"id\"], format=\"full\"\n        ).execute()\n        headers = data[\"payload\"][\"headers\"]\n        emails.append({\n            \"subject\": next((h[\"value\"] for h in headers if h[\"name\"] == \"Subject\"), \"\"),\n            \"from\": next((h[\"value\"] for h in headers if h[\"name\"] == \"From\"), \"\"),\n            \"snippet\": data.get(\"snippet\", \"\")\n        })\n    return emails\n```\n\nThis is where the magic happens. The prompt design is everything:\n\n``` python\n# summarizer.py\nimport requests\n\ndef summarize(slack_data, email_data):\n    prompt = \"\"\"You are a smart executive assistant. \nAnalyze these messages and group them into exactly 4 sections:\n\n🔴 URGENT — ACTION NEEDED (deadlines, outages, decisions needed today)\n💬 IMPORTANT DISCUSSIONS (ongoing debates, replies needed soon)  \n📢 FYI — ANNOUNCEMENTS (good to know, no action needed)\n🗑️ LOW PRIORITY (newsletters, notifications, can ignore)\n\nFor each item write: channel/sender — one line summary.\nBe ruthlessly concise. Max 10 words per item.\n\n=== SLACK ===\\n\"\"\"\n\n    for channel, msgs in slack_data.items():\n        prompt += f\"\\n#{channel}:\\n\" + \"\\n\".join(f\"- {m}\" for m in msgs)\n\n    prompt += \"\\n\\n=== EMAILS ===\\n\"\n    for e in email_data:\n        prompt += f\"- From: {e['from']} | {e['subject']} | {e['snippet'][:100]}\\n\"\n\n    prompt += \"\\n\\nNow give the grouped summary:\"\n\n    response = requests.post(\"http://localhost:11434/api/generate\", json={\n        \"model\": \"hermes3\",\n        \"prompt\": prompt,\n        \"stream\": False\n    })\n    return response.json()[\"response\"]\npython\n# main.py\nfrom slack_reader import get_today_messages\nfrom gmail_reader import get_today_emails\nfrom summarizer import summarize\nfrom datetime import datetime\n\ndef run_agent():\n    print(f\"\\n🤖 Daily Brief — {datetime.now().strftime('%B %d, %Y %I:%M %p')}\")\n    print(\"=\" * 50)\n    print(\"📥 Reading Slack...\")\n    slack = get_today_messages()\n    print(\"📧 Reading Gmail...\")\n    emails = get_today_emails()\n    print(\"🧠 Thinking with Hermes3...\\n\")\n    summary = summarize(slack, emails)\n    print(summary)\n    with open(\"daily_summary.txt\", \"w\") as f:\n        f.write(summary)\n    return summary\n\nif __name__ == \"__main__\":\n    run_agent()\n# Run at 9 AM every weekday\ncrontab -e\n\n# Add this line:\n0 9 * * 1-5 cd /path/to/daily-summary-agent && python3 main.py >> summary.log 2>&1\n```\n\nBefore connecting Slack/Gmail, test Hermes summarization with fake data:\n\n``` python\n# test_summarizer.py\nfrom summarizer import summarize\n\nfake_slack = {\n    \"dev\": [\"Server is down! 503 errors since 8am\", \"PR #234 needs review\"],\n    \"general\": [\"Team lunch at 1pm\", \"Please fill the feedback form\"]\n}\n\nfake_emails = [\n    {\"from\": \"boss@company.com\", \"subject\": \"Q3 Report Due Today\", \"snippet\": \"Submit by EOD\"},\n    {\"from\": \"newsletter@medium.com\", \"subject\": \"Top AI stories\", \"snippet\": \"Weekly digest...\"}\n]\n\nprint(summarize(fake_slack, fake_emails))\n```\n\nRun it:\n\n```\npython3 test_summarizer.py\n```\n\nNo Slack token, no Gmail auth needed. Just Hermes running locally. ✅\n\n```\n🔴 URGENT — ACTION NEEDED\n• #dev — Server down, 503s since 8am, fix immediately\n• boss@company.com — Q3 report due today EOD\n\n💬 IMPORTANT DISCUSSIONS\n• #product — Q3 roadmap priorities debated, needs decision\n• partnerships@zoho.com — Integration call request this week\n\n📢 FYI — ANNOUNCEMENTS  \n• #general — Monday public holiday, no standups\n• HR — Feedback form deadline Friday\n\n🗑️ LOW PRIORITY\n• medium.com — Weekly AI newsletter\n• linkedin.com — 3 connection requests\n```\n\n40 minutes of inbox anxiety → 60 seconds of clarity. Every morning.\n\nThings I'm adding next:\n\n`pyttsx3`\n\nWe'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.\n\nThe 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.\n\nEvery workflow you currently do with a cloud API, ask yourself: *does this data need to leave my machine?*\n\nOften the answer is no.\n\n*Built this over a weekend. Still running every morning. Zero cloud costs.*\n\n*Have questions or improvements? Drop them in the comments — happy to help you set it up.*\n\n**Tags:** `#ai`\n\n`#python`\n\n`#productivity`\n\n`#ollama`\n\n`#opensource`\n\nsubmission for the [Hermes Agent Challenge](https://dev.to/challenges/hermes-agent-2026-05-15): Write About Hermes Agent*", "url": "https://wpnews.pro/news/daily-summary-agent", "canonical_source": "https://dev.to/muthukumar_pattan_00/daily-summary-agent-5ece", "published_at": "2026-05-31 06:13:46+00:00", "updated_at": "2026-05-31 06:41:44.180560+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "ai-products", "large-language-models", "ai-startups"], "entities": ["Hermes3", "Slack", "Gmail", "ChatGPT", "Claude", "Zoho", "Ravi", "Priya"], "alternates": {"html": "https://wpnews.pro/news/daily-summary-agent", "markdown": "https://wpnews.pro/news/daily-summary-agent.md", "text": "https://wpnews.pro/news/daily-summary-agent.txt", "jsonld": "https://wpnews.pro/news/daily-summary-agent.jsonld"}}