Building a Serverless AI Tech-News Bot with Node.js, Gemini and GitHub Actions
DEV Community

Building a Serverless AI Tech-News Bot with Node.js, Gemini and GitHub Actions

I wanted to build a project that combined several technologies into one practical automation pipeline: Node.js, Web scraping, RSS, Offline NLP, Generative AI, Telegram, Discord, GitHub Actions, Vercel. The result is the Chaos Routine Bot, a serverless technology-news agent that runs every morning and generates an AI-assisted briefing. GitHub repository: https://github.com/starJeet000/Telegram-News-Scraper-Bot

Architecture

The high-level pipeline is:

News Sources │
 ▼ Random Source Selection │
 ▼ Tech Relevance Filter │
 ▼ Fetch HTML │
 ▼ Readability + JSDOM │
 ▼ Clean Article │
 ▼ Compromise NLP │
 ▼ Core Facts │
 ▼ Gemini 2.5 Flash │
 ┌───────┴────────┐
 ▼▼ TelegramDiscord │
 └───────┬────────┘
 ▼ JSON + RSS + Dashboard │
 ▼ Vercel

1. Collecting News

The scraper supports multiple technology sources. The current source pool includes: Hacker News, Reddit, Lobste.rs, Dev.to, InfoQ, BleepingComputer, Krebs on Security, TechCrunch AI, MIT Technology Review AI, ServeTheHome, Phoronix, TechXplore, ScienceDaily Nanotechnology, Ars Technica.
The scraper randomly selects two sources for each execution. For Reddit, it also randomly selects one subreddit from communities such as: r/programming, r/netsec, r/artificial, r/webdev, r/sysadmin.

2. Filtering Before Processing

The project doesn't blindly process every title. The scraper has a negative keyword list and a technology whitelist. For example, terms related to unrelated categories can cause a title to be rejected, while terms such as: code, software, hardware, linux, api, security, cyber, gpu, cpu, cloud, llm, kernel, framework help identify technology-related content. The filtering happens before the article reaches the extraction and AI stages.

3. Extracting Clean Article Content

A raw webpage contains far more than the article. The project uses:

import { JSDOM } from 'jsdom';
import { Readability } from '@mozilla/readability';

The HTML is loaded into JSDOM and then processed through Mozilla Readability. This produces a cleaner article representation.

4. Offline NLP

After extracting the article text, the project uses Compromise. The current implementation takes the first three sentences from the processed article:

const docNLP = nlp(article.textContent);
const sentences = docNLP.sentences().out('array').slice(0, 3);

Those sentences become the factual input for the AI stage. This is an important architectural choice. Instead of sending the entire article to an LLM, the pipeline first creates a compact representation.

5. Gemini Synthesis

Gemini 2.5 Flash is used to generate the final briefing. The project gives the model a specific persona: an exhausted senior software engineer drinking their fourth cup of coffee. The prompt asks Gemini to create a few short, sarcastic paragraphs around the collected technology stories. This produces a consistent editorial style without requiring the scraper itself to generate prose.

6. Graceful AI Fallback

The application checks whether a Gemini API key exists. If it doesn't, it returns the offline summaries instead. The Gemini request is also wrapped in error handling. If the request fails, the application again falls back to the offline NLP output. So the architecture is:

Gemini │
 ┌──────┴──────┐
 │ │
 Success Failure │
 │ ▼ ▼
 AI briefing NLP facts

This prevents the AI service from becoming the only path to a usable result.

7. Telegram Delivery

The Telegram module uses the Telegram Bot API. The generated message is sent using Markdown formatting. The project also disables webpage previews to avoid unnecessary visual clutter in the Telegram channel.

8. Discord Delivery

The main pipeline also supports sending the same briefing to a Discord webhook. That makes the generated content available across multiple messaging platforms.

9. Generating a Static API and RSS Feed

The project doesn't stop after sending a Telegram message. It creates:

  • public/briefing.json
  • public/rss.xml

The JSON contains information such as:

  • update timestamp
  • generated briefing
  • source
  • title
  • URL
  • extracted facts

The RSS feed packages the generated briefing for RSS readers.

10. GitHub Actions Automation

The GitHub Actions workflow runs at: 02:30 UTC which corresponds to: 08:00 IST.
The workflow uses Node.js 20 and executes:

npm ci
npm start

It then deploys the generated output using the Vercel CLI. This removes the need for a permanently running server.

11. Environment Variables

The workflow keeps credentials in GitHub Actions secrets. The project expects values such as:

  • GEMINI_API_KEY
  • TELEGRAM_BOT_TOKEN
  • TELEGRAM_CHAT_ID
  • DISCORD_WEBHOOK_URL
  • VERCEL_TOKEN
  • VERCEL_ORG_ID
  • VERCEL_PROJECT_ID

The important rule here is simple: Never commit real API keys or bot tokens to Git.

12. Why This Architecture?

The project could have been much simpler: RSS → Gemini → Telegram. But that would make every component dependent on the next one. Instead, the pipeline separates responsibilities:

Scraping
 ↓
Filtering
 ↓
Extraction
 ↓
NLP
 ↓
AI
 ↓
Fallback
 ↓
Distribution
 ↓
Deployment

That makes it easier to debug and gives the system a useful fallback path.

Lessons From the Project

A few ideas I took away from building this:

  1. AI doesn't need to process raw data. Preprocessing can significantly simplify what reaches the model.
  2. External APIs should not become single points of failure. The offline NLP fallback keeps the application functional when Gemini isn't available.
  3. Automation can replace an always-on server. For workloads that run once or a few times per day, GitHub Actions can be a practical execution layer.
  4. One pipeline can have multiple outputs. The same generated data can power:
    • Telegram
    • Discord
    • JSON
    • RSS
    • Web dashboard

Final Architecture

The complete system can be summarized as:

GitHub Actions
 ↓
Node.js
 ↓
News Sources
 ↓
Filtering
 ↓
Readability
 ↓
Offline NLP
 ↓
Gemini
 ↓
Telegram + Discord
 ↓
JSON + RSS
 ↓
Vercel

The complete source code is available here: https://github.com/starJeet000/Telegram-News-Scraper-Bot
If you're experimenting with Node.js + AI + web scraping + automation, this is a useful pattern to explore: use traditional software engineering to prepare and control the data, then use the LLM for the part it is actually good at-synthesis.

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.