Autonomous AI News Agent Development by Arya AAutonomous AI News Agent Development by Arya A

Autonomous AI News Agent Development

Arya A

Arya A

AI Tech Digest Agent

Your twice-daily 3-minute AI briefing. Read less, know more. πŸŽ™οΈ A fully autonomous AI agent that fetches, ranks, summarizes, and delivers the top 5 AI tech stories β€” as a formatted Telegram message and a human-quality voice briefing β€” in English or Hindi, twice a day.

Table of Contents

Project Overview

AI Tech Digest is a production-grade autonomous news agent built with LangGraph. Every day it:
Pulls fresh articles from 12 high-signal RSS sources (OpenAI Blog, Google AI, Microsoft AI, Meta AI, TensorFlow, ArXiv, Hacker News, TechCrunch, and more)
Runs each article through an LLM-powered scoring pipeline β€” scoring innovation, impact, and credibility
Selects the Top 5 stories with category-diversity enforcement (no single topic dominates)
Translates the digest to Hindi using the same LLM
Generates human-quality voice briefings in both English (Ava Neural) and Hindi (Madhur Neural)
Delivers the text digest + audio to each subscriber on Telegram twice a day (AM and PM cycle)
Never repeats a story β€” permanently tracking every sent article via MongoDB

Architecture


Tech Stack

Layer Technology Purpose AI Orchestration LangGraph Stateful, multi-node AI pipeline LLM Groq API β€” llama-3.3-70b-versatile Article scoring, summarization, translation RSS Parsing feedparser + requests Fetching articles from 12 sources Text-to-Speech edge-tts β€” Microsoft Neural Voice briefings in EN & HI Telegram python-telegram-bot v22 Delivery, bot commands, inline keyboards Database MongoDB + PyMongo Subscribers + deduplication ledger Scheduling Custom IST Loop / schedule Hourly daemon runner & job scheduler Frontend Next.js 16 + Tailwind CSS + Framer Motion Landing page Language Python 3.12+ Core backend Caching File-based JSON 22-hour LLM response cache

Complete Workflow

Step 1 β€” User Subscribes


Step 2 β€” Scheduler Wakes Up (Every Hour)


Step 3 β€” LangGraph Pipeline (Runs Twice Per Day)


Module Breakdown

graph.py β€” The Orchestrator

Defines the LangGraph StateGraph with a shared State TypedDict that flows through all 4 nodes. Each node reads from and writes to this shared state, keeping the pipeline clean and testable in isolation.

fetch_news.py β€” The Ingestion Layer

12 RSS Sources with per-source credibility weights (1.2x–1.8x) and daily caps
Reddit Integration via the JSON API, filtering posts by minimum upvote score (80+)
Title Fingerprinting: Strips stopwords, takes first 6 meaningful words to create a semantic key β€” catches the same story published on multiple outlets
Age Filtering: Lab blogs allowed up to 7 days old; news sites capped at 2 days

summarize.py β€” The Intelligence Layer

Single LLM prompt per article β€” scoring + summarization + categorization in one call (minimizes token usage on Groq free tier)
Parallel processing via ThreadPoolExecutor(max_workers=4) β€” 4x faster than sequential
rank_and_diversify(): Three-pass selection ensuring the daily digest is never dominated by a single topic or source

cache.py β€” The Cost Shield

A simple JSON file cache with a 22-hour TTL. Stores both kept and rejected articles (rejected are stored as {} sentinel values). This prevents re-spending tokens on articles already evaluated. Capped at 500 entries with auto-eviction.

db.py β€” The Database Layer

Four MongoDB collections:
subscribers: Stores chat_id, username, language, delivery_time, active flag
history: Permanent ledger β€” every sent article's URL and title fingerprint are stored here forever. Never expires.
daily_digests: Stores the raw text content of the generated digests for each date and language.
digest_audio: GridFS collections (digest_audio.files and digest_audio.chunks) storing the binary voice notes (.mp3 files) for each digest.

voice_engine.py β€” The Audio Layer

Language-aware script builder: Generates fully localized scripts β€” Hindi scripts use native Hindi intros (ΰ€Έΰ₯ΰ€ͺΰ₯ΰ€°ΰ€­ΰ€Ύΰ€€...), transitions (ΰ€…ΰ€—ΰ€²ΰ₯€ ΰ€–ΰ€¬ΰ€°...), and outros
_clean_for_speech(): Strips URLs, emojis, category labels, markdown syntax, and score tags that sound awkward when read aloud
Threading safety: Uses threading.Thread to run asyncio.run() safely if called from within an existing event loop (avoids RuntimeError: no running event loop)

telegram_bot.py β€” The Delivery Layer

Two modes: --send (broadcast) and --bot (interactive registration)
Emoji-based parser: Parses digest files using Unicode emoji codepoints (πŸ“°, 🧠, πŸ‘‰) instead of English strings β€” ensures both EN and HI digests are parsed correctly
MarkdownV2 escaping: All dynamic text is escaped before sending via Telegram's strict MarkdownV2 parser
Guard clauses: All handlers check for None on update.message, update.effective_user, etc.

scheduler.py β€” The Background Worker

Runs an hourly loop (utilizes the schedule library when run as a standalone script).
Lazy Initialization: Only runs the expensive pipeline if the digest files don't yet exist for today.
7-day cleanup: Automatically deletes digest and audio files older than 7 days to prevent disk exhaustion.

run.py β€” The Unified Entry Point

Runs the Telegram Bot (main thread) + Scheduler (daemon thread using a custom, drift-free IST time-check loop) in one process for single-server cloud deployment.

Deduplication System

The system uses a layered, three-level deduplication strategy:

Voice Engine

The voice engine produces two distinct audio styles:
English (Ava Neural β€” en-US-AvaNeural)

Hindi (Madhur Neural β€” hi-IN-MadhurNeural)

Telegram Bot

User Commands

Command Description /start Subscribe and set language + delivery time preferences /stop Unsubscribe (sets active: False in DB) /latest Get today's digest immediately on demand /help Show all available commands

Registration Flow


Scheduler

The scheduler architecture follows a "Lazy Initialization" model:

Landing Page

Built with: Next.js 16 (App Router), Tailwind CSS, Framer Motion, shadcn/ui
Sections:
Hero: Animated rotating headline words (noise β†’ hype β†’ scrolling β†’ FOMO)
Features: Bento-grid layout with 6 feature cards
How It Works: 4-step card layout with animated zigzag connectors
Sample Digest: 3D scroll animation showing a real Telegram message mockup
FAQ: Accordion with 5 questions including bilingual support info
CTA: Full-width indigo section with Telegram subscribe button
All "Subscribe" buttons link directly to https://t.me/aitechdigest_bot.

Difficulties Faced & How We Solved Them

1. Achieving Zero-Cost Scaling

The Problem: Delivering daily AI news and audio to thousands of users typically incurs massive LLM API and TTS generation costs.
The Solution:
Implemented "lazy initialization" and aggressive caching so LLM text and edge-tts audio generate only once per day per language.
Built a layered deduplication system (In-Session, Cross-Day DB, and Same-Day JSON Cache) to prevent wasting tokens.
Embedded a lightweight HTTP server in the backend, enabling the bot to run entirely on Render's Free Web Service tier.

2. Crafting a Readable Telegram Delivery Format

The Problem: Dense AI news (with context, summaries, and impact statements) easily turns into an unreadable wall of text on mobile screens. Additionally, character limits truncated summaries and Telegram's MarkdownV2 parser easily broke.
The Solution:
Removed all character truncation limits and stripped distracting emojis from the body text.
Switched to a clean, spacious bullet-point layout with intentional line breaks between each story component (Source, Summary, Context, Impact).
Added dynamic escaping for all special characters to safely satisfy Telegram's MarkdownV2 constraints.

3. Delivering Authentic Multilingual Audio

The Problem: While translating text to Hindi was straightforward, generating the voice briefing resulted in awkward "Hinglish" (the TTS model reading hardcoded English transitions like "First up..." with a thick Hindi accent).
The Solution:
Built a language-aware Voice Engine that uses entirely separate template dictionaries for English and Hindi.
Injected native Hindi intros ("ΰ€Έΰ₯ΰ€ͺΰ₯ΰ€°ΰ€­ΰ€Ύΰ€€!"), transitions ("ΰ€…ΰ€—ΰ€²ΰ₯€ ΰ€–ΰ€¬ΰ€°..."), and outros when Hindi is selected.
Ensured the final audio feels like a seamless, high-quality local broadcast.

4. Refining the Mobile Web Experience

The Problem: The Next.js landing page suffered from critical overlap and alignment issues on small mobile screens (e.g., the "Subscribe Free" button crashing into the Dark Mode toggle, uncentered Hero buttons, and wrapping FAQ text).
The Solution:
Hid redundant CTA buttons in the mobile navbar, relying instead on the massive Hero CTA.
Forced flex containers to full width with explicit center alignments for the Hero buttons.
Locked the FAQ accordion components to a strict left-aligned text constraint to prevent them from inheriting parent centering rules.

5. Server Timezone Shifts & On-Demand Delivery

The Problem:
Render servers default to UTC, causing the scheduler to wake up 5.5 hours late for Indian Standard Time (IST) users.
Additionally, since the scheduler uses "lazy initialization" to save costs, the /latest command failed to retrieve today's news if there were no scheduled deliveries earlier that morning.
The Solution:
Configured scheduler.py to evaluate the current time and dates using the ZoneInfo("Asia/Kolkata") timezone.
Replaced the schedule library's startup-offset dependent loop in run.py with a direct, custom IST time-check loop. This reads time explicitly using ZoneInfo("Asia/Kolkata") and triggers hourly_job exactly at :00 IST, completely bypassing system timezone or container boot timing offsets.
Upgraded the /latest Telegram command to dynamically trigger ensure_digest_generated() on demand if the local text files are missing.
Added a hybrid MongoDB GridFS storage strategy to save generated text digests and voice notes in the database so that they are not lost during container redeployments.

Setup & Installation

Prerequisites

Python 3.12+
MongoDB (local or Atlas)
Groq API Key (free tier available)
Telegram Bot Token (from @BotFather)

Local Setup


Deployment

Component Platform Command Database MongoDB Atlas (M0 Free) Connect via Atlas URI Backend Bot Render (Web Service) python run.py Frontend Vercel Root directory: landing/

Render Configuration

Build Command: pip install -r requirements.txt
Start Command: python run.py
Instance Type: Free (Web Service)
Important: We integrated a lightweight HTTP health-check server inside run.py so it cleanly binds to Render's $PORT, allowing the entire backend to run on the Free Web Service tier instead of requiring a paid Background Worker.
Add all 3 environment variables in Render's dashboard.
Tip: Use a free service like cron-job.org to ping your Render URL every 10 minutes to keep the bot awake 24/7!

Vercel Configuration

Set Root Directory to landing/ during import
Framework auto-detected as Next.js
No environment variables needed

Environment Variables

Create a .env file in the project root:

Project Structure


Built with ❀️ by Ayush Aryan β€” Making AI news accessible to everyone, one briefing at a time.
Like this project

Posted Aug 9, 2026

Developed an autonomous AI news agent delivering top AI stories via Telegram.