📱 Create personalized news digests with GPT-5.1, SerpAPI, and Telegram delivery

⚡ 136 views · 📱 Social Media & Email Marketing

Description

Overview

Staying up to date with fast-moving topics like AI, machine learning, or your specific industry can be overwhelming. You either drown in daily noise or miss important developments between weekly digests.

This AI News Agent workflow delivers a curated newsletter only when there’s genuinely relevant news. I use it myself for AI and n8n topics.

Key features:

In this post, I’ll walk you through the complete workflow, explain each component, and show you how to set it up yourself.

What this workflow does

At a high level, the AI News Agent:

  1. Fetches fresh news twice daily via SerpAPI’s DuckDuckGo News engine.
  2. Stores articles in a persistent data table with automatic deduplication.
  3. Filters for freshness - only considers articles newer than your last newsletter.
  4. Applies frequency guardrails - respects your min/max sending preferences.
  5. Makes an editorial decision - AI evaluates if the news is worth sending.
  6. Enriches selected articles - uses Tavily web search for fact-checking and depth.
  7. Delivers via Telegram - sends a clean, formatted newsletter.
  8. Remembers what it sent - stores each edition to prevent future repetition.

This allows you to get newsletters only when there’s genuinely relevant news - in contrast to a fixed schedule.

Requirements

To run this workflow, you need:

How it works

The workflow is organized into five logical stages.

Stage 1: Schedule & Configuration

Stage 2: Fetch & Store News

return $input.first().json.topics.split(',').map(topic => ({
  json: { topic: topic.trim() }
}));
DateTime.fromSeconds(Number($json.date), {zone: 'utc'}).toISO()

Stage 3: Filtering & Frequency Guardrails

This is where the workflow gets smart about what to consider and when to send.

$json.date_2 > ($json.createdAt_1 || DateTime.fromISO('2024-01-01T00:00:00.000Z'))

Stage 4: AI Editorial Decision

This is the core intelligence of the workflow - an AI that decides whether to send and what to include. This stage is also the actual agentic part of the workflow, where the system makes its own decisions instead of just following a fixed schedule.

You are an **AI Newsletter Editor**. Your job is to decide whether today’s newsletter edition should be sent, and to select the best articles.

You will receive a list of articles with:
'title', 'excerpt', `source`, `url`.

You will also receive content of **previously sent newsletters** (markdown).

# Your Tasks

## 1. Decide whether to send the newsletter

Output "YES" only if all of the following are satisfied **OR** the fallback rule applies:

### **Base Criteria**

1. There are **at least 3 meaningful articles**.
   *Meaningful = not trivial, not purely promotional, not clickbait, contains actual informational value.*

2. Articles must be **non-duplicate and non-overlapping**:

   * Not the same topic/headline rephrased
   * Not reporting identical events with minor variations
   * Not the same news covered by multiple sources without distinct insights

3. Articles must be **relevant to the user's topics**:
   **{{ $('Set topics and language').item.json.topics }}**

4. Articles must be **novel** relative to the **topics in previous newsletters**:

   * Compare against all previous newsletters below
   * Exclude articles that discuss topics already substantially covered

5. Articles must offer **clear value**:

   * New information
   * Impact that matters to the user
   * Insight, analysis, or meaningful expansion

### **Fallback rule: Newsletter frequency requirement**

If **at least 1 relevant article exists** *and*
the last newsletter was sent **more than {{ $('Set topics and language').item.json.maxDaysBetween }} days ago**, then you **MUST** return "YES" as a decision even if the other criteria are not completely met.

Last newsletter was sent {{ $('Get most recent newsletter').item.json.createdAt ? Math.floor($now.diff(DateTime.fromISO($('Get most recent newsletter').item.json.createdAt), 'days').days) : 999 }} days ago.

### Otherwise → "NO"

## **2. If "YES": Select Articles**

Select the **top 3–5** articles that best fulfill the criteria above.

For each selected article, output:

* **title** (rewrite for clarity, conciseness, and impact)
* **summary** (1–2 sentences; written in the output language)
* **source**
* **url**

All summaries **must** be written in:
**{{ $('Set topics and language').item.json.language }}**

---

# **Output Format (JSON)**

{
  "decision": "YES or NO",
  "articles": [
    {
      "title": "...",
      "summary": "...",
      "source": "...",
      "url": "..."
    }
  ]
}

When "decision": "NO", return an empty array for "articles".

# **Article Input**

Use these articles:

{{
  $json.results.map(
   article =>
    `Title: ${article.title_2}
     Excerpt: ${article.excerpt_2}
     Source: ${article.source_2}
     URL: ${article.url_2}`
  ).join('\n---\n')
}}

You must also consider the topics already covered in previous newsletters to avoid repetition:

{{ $json.newsletters.map(x => `Newsletter: ${x.content}`).join('\n---\n') }}

The AI outputs structured JSON:

{
  "decision": "YES",
  "articles": [
    {
      "title": "...",
      "summary": "...",
      "source": "...",
      "url": "..."
    }
  ]
}

Stage 5: Content Enrichment & Delivery

You are a research writer that updates short news summaries into concise, factual articles.

**Input:**
Title: {{ $json["title"] }}
Summary: {{ $json["summary"] }}
Source: {{ $json["source"] }}
Original URL: {{ $json["url"] }}
Language: {{ $('Set topics and language').item.json.language }}

**Instructions:**

1. Use **Tavily Search** to gather 2–3 reliable, recent, and relevant sources on this topic.
2. Update the **title** if a more accurate or engaging one exists.
3. Write **1–2 sentences** summarizing the topic, combining the original summary and information from the new sources.
4. Return the original source name and url as well.

**Output (JSON):**

{
  "title": "final article title",
  "content": "concise 1–2 sentence article content",
  "source": "the name of the original source",
  "url": "the url of the original source"
}

**Rules:**

* Ensure the topic is relevant, informative, and timely.
* Translate the article if necessary to comply with the desired language {{ $('Set topics and language').item.json.language }}.

The Output Parser enforces the JSON schema with title, content, source, and url fields.

$json.output.map(article => {
  const title = JSON.stringify(article.title).slice(1, -1);
  const content = JSON.stringify(article.content).slice(1, -1);
  const source = JSON.stringify(article.source).slice(1, -1);
  const url = JSON.stringify(article.url).slice(1, -1);
  return `*${title}*\n${content}\nSource: [${source}](${url})`;
}).join('\n\n')

Why this workflow is powerful

Configuration guide

To customize this workflow for your needs:

  1. Topics and language
    Open Set topics and language and modify:

    • topics: your interests (e.g., machine learning, startups, TypeScript)
    • language: your preferred output language
  2. Frequency settings

    • minDaysBetween: minimum days between newsletters (0 = no limit)
    • maxDaysBetween: maximum gap before forcing a send
    • For very high-volume topics (such as "AI"), expect the workflow to send almost every time once minDaysBetween has passed, because the content-quality criteria are usually met.
  3. Schedule
    Modify the Schedule Trigger cron expression. Default runs twice daily at 9:00 am and 5:00 pm; adjust to your preference.

  4. Telegram
    Update the chatId in the Telegram node to your chat/channel.

  5. Credentials
    Set up credentials for: SerpAPI (httpQueryAuth), Tavily, OpenAI, Telegram.

Next steps and improvements

Here are concrete directions to take this workflow further:

Wrap-up

This AI News Agent workflow represents a significant evolution from simple scheduled newsletters. By adding intelligent send decisions, historical deduplication, and frequency guardrails, you get a newsletter that respects the quality of available news.

I use this workflow myself to stay informed on AI and automation topics without the overload of daily news or the delayed delivery caused by a fixed newsletter schedule.

Need help with your automations? Contact me here.

đź”— Nodes Used

HTTP Request, Telegram, Schedule Trigger, Filter, AI Agent, OpenAI Chat Model

📥 Import

Download workflow.json and import into n8n: Workflow menu → Import from File

📖 Importing guide · 🔑 Credential setup