惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tailwind CSS Blog
J
Java Code Geeks
博客园_首页
Google Online Security Blog
Google Online Security Blog
Hugging Face - Blog
Hugging Face - Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
Intezer
P
Palo Alto Networks Blog
V
Vulnerabilities – Threatpost
雷峰网
雷峰网
O
OpenAI News
SecWiki News
SecWiki News
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
N
News | PayPal Newsroom
Project Zero
Project Zero
Forbes - Security
Forbes - Security
IT之家
IT之家
A
Arctic Wolf
WordPress大学
WordPress大学
Jina AI
Jina AI
T
Tor Project blog
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
博客园 - 聂微东
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Privacy International News Feed
Cloudbric
Cloudbric
G
GRAHAM CLULEY
博客园 - 叶小钗
H
Hacker News: Front Page
腾讯CDC
量子位
Help Net Security
Help Net Security
人人都是产品经理
人人都是产品经理
C
Cyber Attacks, Cyber Crime and Cyber Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
爱范儿
爱范儿
L
Lohrmann on Cybersecurity
Hacker News - Newest:
Hacker News - Newest: "LLM"
Recorded Future
Recorded Future
C
CERT Recently Published Vulnerability Notes

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
ChronoAgent: I Built an Agent That Reads My WhatsApp So I Stop Missing Deadlines
Kanak Waradk · 2026-04-24 · via DEV Community

This is a submission for the OpenClaw Challenge.

What I Built

I'm a second year computer engineering student.I often joke that my degree runs on Whatsapp.Often most students dont attend lectures but just see what someone has uploaded on whatsapp and do their work from there. I'm going to be honest with you about something embarrassing: I missed a lab submission last semester not because I didn't do the work, but because the deadline came through a WhatsApp group at 11 PM and I just didn't see it in time.

The professor sent a reminder email three days before. Someone in the group chat forwarded it with "guys don't forget!!". Someone else sent a voice note I never opened. By the time I remembered, the portal was closed.

This is not a unique experience. If you're a student in India — or honestly anyone whose professional life runs partially through WhatsApp — you know that deadlines don't live in one place. They're fragmented across group chats, Gmail threads, DMs, and the occasional Instagram message from a friend who remembered you hadn't registered for something yet.

The "fix" people suggest is: "just use Google Calendar." Sure. Do you manually create an event every time someone texts you about something? I don't. Nobody does.

So here comes our hero of the story OpenClaw.

How I Used OpenClaw

I've played with n8n, with custom Python cron scripts, with Zapier. None of them had native WhatsApp access without either paying for a business API (which requires a separate phone number and a whole approval process) or running a fragile Selenium scraper.

OpenClaw has WhatsApp built into its Gateway via Baileys. One command, one QR scan. Done. The agent immediately has access to every message I receive, treated as a first-class channel.

The other thing that made OpenClaw the right fit was Standing Orders. This is not a feature you'd expect to care about until you actually use it. The idea is simple: you write a file called AGENTS.md in your workspace and the agent reads it every session. You define programs — "here's what you're authorized to do, here's when to do it, here's when to stop and ask me."

For OpenClaw, the Standing Order looks roughly like this:

## Program: WhatsApp Deadline Monitor

**Authority:** Read all inbound WhatsApp messages. Extract and store deadline/event data.
Send review messages back to the user for ambiguous extractions.
**Trigger:** Every inbound WhatsApp message
**Approval gate:** Auto-write calendar for confidence ≥ 0.80. Request approval below that.
**Escalation:** If extraction fails 3 times in a row, alert me and pause.

Enter fullscreen mode Exit fullscreen mode

This single file is why it is an agent and not a script. It has defined scope, defined escalation rules, defined approval gates. It knows when to act and when to ask. I wrote those rules once and now they govern every message that comes through, forever, without me thinking about it again.

Demo

So I built ChronoAgent.

ChronoAgent runs in the background on my laptop as an OpenClaw Gateway daemon. It has a WhatsApp channel connected (OpenClaw supports this natively through Baileys — no external service, no webhook nonsense, just scan a QR code). Every message that comes in gets silently processed. If it contains a deadline, a due date, a meeting, an exam — it gets extracted, deduplicated, and written to Google Calendar automatically.

I don't prompt it. I don't open a chat window. It just runs.

When it adds something to my calendar, it sends me a message back: "📅 Added: Assignment 3 submission on April 28, 11:59 PM". I can reply NO to undo it. That's the entire user interaction for 80% of cases.

For things it's less sure about — "sometime next week we should meet bro" — it holds the event in a pending queue and asks me to confirm with a YES or NO reply. No calendar write until I say so.

IT'S ALIVE

Source code and setup instructions: github.com/Labreo/openclaw-calendar-agent

What I Learned

Here's the mistake I almost made: trying to have the LLM do everything.

My first draft had the LLM reading messages, extracting dates, checking the calendar for duplicates, deciding whether to write, writing the event, formatting the confirmation message — all in one big chain of reasoning.

It was slow. It was expensive. And it hallucinated duplicates constantly.

The version that actually works is much dumber-looking on the surface, but it's solid:

Incoming Message
    │
    ▼
[Python: normalize to standard envelope]
{ source, sender, timestamp, raw_text }
    │
    ▼
[LLM: ONLY job is translation]
Input: raw text + today's date
Output: JSON array of extracted events with confidence scores
    │
    ▼
[Python: resolve relative dates]
"next Friday" → 2026-04-25T00:00:00
    │
    ▼
[Python: deduplicate]
Fuzzy title match + date proximity + semantic similarity
    │
    ▼
[Confidence router]
≥ 0.80 → write to calendar, notify me
0.50–0.79 → pending queue, ask me
< 0.50 → silent discard

Enter fullscreen mode Exit fullscreen mode

The LLM's job is exactly one thing: read messy human text and output clean structured JSON. That's it. Every other decision in the pipeline is deterministic Python.

Architecture Diagram

The extraction prompt that actually worked

Getting the LLM to reliably output JSON (and only JSON) took more iteration than I expected. The trick was treating the model like a data parser in the system prompt, not like a conversationalist:

EXTRACTION_SYSTEM_PROMPT = """You are a deadline and event extraction engine.
Your ONLY output is a valid JSON array. No prose. No markdown. No explanation.

Given a message, extract every actionable deadline, due date, meeting, or event.
For each item output:
{
  "title": string,
  "date_raw": string,       // verbatim from the message
  "date_iso": string|null,  // resolved ISO 8601 if possible, else null
  "confidence": float,      // 0.0 to 1.0
  "source_quote": string,   // the exact fragment that contains the deadline
  "event_type": string      // deadline | meeting | exam | submission | event | other
}

Confidence guide:
  1.0  — explicit date + time + clear action
  0.85 — explicit date, no time
  0.70 — relative date that can be resolved
  0.55 — vague but likely actionable
  0.30 — might be an event, very unclear
  0.10 — references a past deadline

If NO events found, return: []
Today's date is injected in the user message."""

Enter fullscreen mode Exit fullscreen mode

The source_quote field was an afterthought that turned out to be the most useful field in the whole schema. Every Google Calendar event created by ChronoAgent has the original message fragment in its description. When I look at a calendar event three weeks later and don't remember what it's about, I can see "Original: 'bro the quiz is moved to Thursday 10am right?' — Source: WhatsApp, Sender: Abdullah". That's enough context.

Reading Emails

The deduplication problem

This was the hardest part of the whole project by a significant margin.

The naive approach: ask the LLM "is this event already in my calendar?" Tried it. Terrible. Slow, expensive, and the model would confidently say "no duplicate found" when there obviously was one.

The approach that works is a 2-out-of-3 vote between three deterministic checks:

  1. Fuzzy title match (Levenshtein ratio ≥ 0.85)
  2. Date proximity (within ±24 hours)
  3. Semantic similarity (cosine similarity using a local sentence-transformers model, threshold 0.80)
def is_duplicate(candidate, existing, embeddings_cache):
    votes = 0

    # Check 1: title similarity
    if lev_ratio(candidate["title"].lower(), existing["title"].lower()) >= 0.85:
        votes += 1

    # Check 2: date proximity
    if candidate.get("date_iso") and existing.get("date_iso"):
        a = datetime.fromisoformat(candidate["date_iso"])
        b = datetime.fromisoformat(existing["date_iso"])
        if abs((a - b).total_seconds()) <= 86400:  # 24 hours
            votes += 1

    # Check 3: semantic similarity
    vec_a = get_or_compute_embedding(candidate["title"], embeddings_cache)
    vec_b = get_or_compute_embedding(existing["title"], embeddings_cache)
    if cosine_similarity(vec_a, vec_b) >= 0.80:
        votes += 1

    return votes >= 2

Enter fullscreen mode Exit fullscreen mode

"Assignment 3 due Friday" and "A3 submission end of week" — different titles, so Levenshtein fails. But they're semantically similar and the dates are within 24 hours, so they correctly merge as duplicates.

The semantic model I used (all-MiniLM-L6-v2) is 80MB and runs locally. No API call, no cost, ~10ms inference time. The LLM is completely out of the loop for dedup.

The 3 AM quota problem (a real thing that happened)

Midway through building this, I burnt through my initial API credits testing the extraction pipeline on WhatsApp group traffic. A college group chat is... a lot of messages. Most of them "ok", "haha", "send notes pls" — but the extraction call fires on all of them before it knows they're non-events.

I had two options: add pre-filtering, or switch to a cheaper model.

I did both. Added a simple length and keyword pre-filter that drops messages under 15 words with no date-adjacent terms before they even hit the LLM. Dropped API usage by about 70% immediately.

Then switched from Claude Sonnet to Gemini 2.5 Flash for the extraction step. Flash is significantly cheaper for this kind of structured output task and the JSON reliability was equivalent in my testing. I still use Claude for anything that requires more complex reasoning — the confidence routing logic and the digest generation — but for the high-volume extraction pass, Flash works well.

The lesson: the best agentic systems aren't the ones throwing the strongest model at every task. They're the ones with smart orchestration about when to call what.

What "passive operation" actually means in practice

The phrase "runs in the background" is easy to say and actually kind of hard to build well.

OpenClaw's Gateway is a daemon — you run openclaw onboard --install-daemon and it sets up a launchd/systemd service that starts automatically on login and stays running. The WhatsApp channel maintains a persistent Baileys session. Cron jobs handle the Gmail polling every 4 hours.

The Standing Order hook fires on every inbound WhatsApp message without any scheduler. The agent just... responds to events. It's not polling. It's not a loop. It's closer to how a web server handles requests — always listening, processes when something arrives, goes quiet otherwise.

The Gmail part is a Python script (ingest_email.py) that the OpenClaw cron calls every 4 hours:

openclaw cron add \
  --name email-ingestion \
  --cron "0 */4 * * *" \
  --timeout-seconds 120 \
  --message "Execute email ingestion per standing orders. Run ingest_email.py, process queue, run extraction and dedup on each envelope, route by confidence, write calendar entries, report summary."

Enter fullscreen mode Exit fullscreen mode

The cron message references the Standing Order rather than duplicating the logic. The agent reads its AGENTS.md, knows the full procedure, and executes it. I don't need to write a long prompt into the cron command because the authority is already defined.

What I'd build next if I had more time

The biggest gap right now is thread context. When someone says "bro don't forget about the thing on Friday" — that's a 0.3 confidence extraction at best. But if I had the last 5 messages of that WhatsApp thread, I'd probably know what "the thing" is.

OpenClaw's session history tools make this possible but I didn't have time to implement it cleanly before the deadline. It's the next feature.

The other thing is cross-source entity resolution. Right now if the same event appears in email and WhatsApp, the dedup engine usually catches it. But it runs independently per message — there's no weekly "let me look at everything I've collected and find clusters" pass. I have a consolidation script written but not wired into the cron yet.

ClawCon Michigan

I didn't attend ClawCon Michigan this time around, but building ChronoAgent has made me want to.

The honest summary

ChronoAgent is not a product. It's a personal tool I built because I was genuinely failing at calendar management and the existing solutions didn't work for how I actually communicate (mostly WhatsApp, some email, basically no structured calendar input).

OpenClaw made the WhatsApp part possible without fighting through Business API approvals. The Standing Orders made the "passive, always-on, doesn't need prompting" part possible without writing a custom daemon. The exec tool made it easy to keep the heavy lifting in plain Python scripts that I can test independently.

The thing I keep coming back to from this project: the right job for the LLM in an agentic system is usually much smaller than you initially think. Translation, intent recognition, natural language output — yes. Calendar math, deduplication logic, date resolution — no. The moment I moved those out of the LLM and into deterministic code, the whole system became faster, cheaper, and more reliable.

Since I set it up, I've had zero missed deadline incidents. That's the only metric that matters.