AI-Powered Information Monitoring with OpenAI, Google Sheets, Jina AI and Slack

工作流概述

这是一个包含31个节点的复杂工作流,主要用于自动化处理各种任务。

工作流源代码

下载
{
  "id": "Xk0W98z9DVrNHeku",
  "meta": {
    "instanceId": "b9faf72fe0d7c3be94b3ebff0778790b50b135c336412d28fd4fca2cbbf8d1f5",
    "templateCredsSetupCompleted": true
  },
  "name": "AI-Powered Information Monitoring with OpenAI, Google Sheets, Jina AI and Slack",
  "tags": [],
  "nodes": [
    {
      "id": "704de862-43e5-4322-ae35-45b505e68bb6",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        4220,
        380
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "",
          "name": "OpenAi Connection"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "eaae54b0-0500-47a7-ad8f-097e0882d21c",
      "name": "Basic LLM Chain",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        4180,
        -120
      ],
      "parameters": {
        "text": "={{ $json.data }}",
        "messages": {
          "messageValues": [
            {
              "message": "=You are an AI assistant responsible for summarizing articles **in English** and formatting them into Slack-compatible messages.  
Your job is to create a clear and concise summary following the guidelines below and format it in Slack-specific Markdown format.  

---

## 1. Title with Link  

- Format the article title as a **clickable link** using Slack's Markdown syntax:  
  `<URL|*Title of the article*>`.  
- The title should be clear and engaging to encourage readers to click.  

---

## 2. Section Headings  

- Use **bold text** to introduce different sections of the summary by wrapping the text with `*` symbols.  
- Ensure headings are descriptive and guide the reader through the content effectively.  

---

## 3. Key Points  

- Present key insights using **bullet points**, using the `•` symbol for listing important information.  
- Each point should be concise, informative, and directly related to the article's topic.  

---

## 4. Content Summary  

- Provide a brief but comprehensive overview of the article's content.  
- Use plain text and line breaks to separate paragraphs for improved readability.  
- Focus on the most important aspects without unnecessary details.  

---

## 5. Context and Relevance  

- Explain why the article is important and how it relates to the reader's interests.  
- Highlight its relevance to ongoing trends or industry developments.  

---

## Message Structure  

The output should follow this structured format:  

1. **Title with link** – Present the article as a clickable link formatted in Slack Markdown.  
2. **Summary sections** – Organized under clear headings to enhance readability.  
3. **Key insights** – Presented as bullet points for quick scanning.  
4. **Contextual analysis** – A brief explanation of the article's relevance and importance.  

---

## Slack Markdown Formatting Guide  

Ensure the message follows Slack's Markdown syntax for proper display:  

- **Bold text:** Use `*bold text*`.  
- **Italic text:** Use `_italic text_`.  
- **Bullet points:** Use `•` or `-` for lists.  
- **Links:** Format as `<URL|*text*>` to create clickable links.  
- **Line breaks:** Use a blank line to separate paragraphs for readability.  

---

## Example of Slack-formatted Output  

🔔 *New article from n8n Blog*  

<https://blog.n8n.io/self-hosted-ai/|*Introducing the Self-hosted AI Starter Kit: Run AI locally for privacy-first solutions*>  

*Summary of the article*  
n8n has launched the Self-hosted AI Starter Kit, a Docker Compose template designed to simplify the deployment of local AI tools. This initiative addresses the growing need for on-premise AI solutions that enhance data privacy and reduce reliance on external APIs. The starter kit includes tools like Ollama, Qdrant, and PostgreSQL, providing a foundation for building self-hosted AI workflows. While it's tailored for proof-of-concept projects, users can customize it to fit specific requirements.  

*Key Points*  
• The Self-hosted AI Starter Kit facilitates quick setup of local AI environments using Docker Compose.  
• It includes preconfigured AI workflow templates and essential tools such as Ollama, Qdrant, and PostgreSQL.  
• Running AI on-premise offers benefits like improved data privacy and cost savings by minimizing dependence on external API calls.  
• The kit is designed for easy deployment on local machines or personal cloud instances like Digital Ocean and runpod.io.  
• n8n emphasizes the flexibility of their platform, allowing integration with over 400 services, including Google, Slack, Twilio, and JIRA, to streamline AI application development.  

*Context and Relevance*  
This article introduces a practical solution for organizations and developers seeking to implement AI workflows locally. By providing a ready-to-use starter kit, n8n addresses common challenges associated with setting up and maintaining on-premise AI systems, promoting greater control over data and potential cost efficiencies.
 
---

Ensure that the message is formatted according to Slack's requirements to improve readability and engagement.  
"
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.5
    },
    {
      "id": "a3a10ccd-26f9-4b05-a79f-8754f619c153",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -840,
        120
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "54ed8957-39be-4ad4-bea7-f56308d75a91",
      "name": "RSS Read",
      "type": "n8n-nodes-base.rssFeedRead",
      "onError": "continueRegularOutput",
      "position": [
        800,
        120
      ],
      "parameters": {
        "url": "={{ $json.rss_feed_url }}",
        "options": {
          "ignoreSSL": false
        }
      },
      "executeOnce": false,
      "typeVersion": 1.1
    },
    {
      "id": "1ec53a9a-ca21-4da2-ab94-55b863a27aff",
      "name": "Relevance Classification for Topic Monitoring",
      "type": "@n8n/n8n-nodes-langchain.textClassifier",
      "position": [
        2380,
        -20
      ],
      "parameters": {
        "options": {
          "fallback": "discard"
        },
        "inputText": "={{ $json.title }}
{{ $json.contentSnippet }}",
        "categories": {
          "categories": [
            {
              "category": "relevant",
              "description": "Articles related to artificial intelligence (AI), data science, machine learning, algorithms, big data, or innovations in these fields."
            },
            {
              "category": "not_relevant",
              "description": "Articles not directly related to  artificial intelligence (AI), data science, machine learning, algorithms, big data, or innovations in these fields."
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "840431b1-cf2e-45e2-a79c-cab90f46a452",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2240,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 600,
        "height": 960,
        "content": "## LLM Call 1 - Article Topic Relevance Classification  

This **LLM call** is used to **classify** whether the articles published on the website are **relevant** to the **topics and interests** you want to monitor.  
It analyzes the **title** and the **content snippet** retrieved from the **RSS Read** node.  

In this template, the monitored articles are related to **data and AI.**  
The classification is done into **two categories**, which you should modify in the `Description` field under the **Categories** section of the node:

### Relevant  
`Description`: Articles related to **[The topics you want to monitor]**.  

### Not Relevant  
`Description`: Articles that are not directly related to **[The topics you want to monitor]**.

By default, this template monitors topics related to artificial intelligence (AI), data science, machine learning, algorithms, big data, and innovations in these fields.
"
      },
      "typeVersion": 1
    },
    {
      "id": "7dbc2246-9e1a-4c2e-a051-703e10e5fa0e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4020,
        -660
      ],
      "parameters": {
        "color": 7,
        "width": 600,
        "height": 680,
        "content": "## LLM Call 2 - Summarize and Format in Slack Markdown 

This node **uses OpenAI's GPT-4o-mini model** to **summarize the article content**, which is provided as **Markdown text** from Jina AI, and formats it in **Slack Markdown** to enhance readability within Slack.  

### Customize to fit your needs  

Here are two examples of how you can modify the **System Prompt** of this node to better suit your requirements:  

- **Language customization:**  
  You can modify the **System Prompt** to instruct the LLM to generate the summary in a specific language (e.g., French or Italian).  
  However, consider the option of adding a separate LLM node **dedicated to translation** if the model cannot handle **summarization, formatting, and translation** simultaneously while maintaining high output quality.

- **Changing the summary structure:**  
  You can adjust the prompt to modify how the summary is structured to better match your preferred format and style.
"
      },
      "typeVersion": 1
    },
    {
      "id": "b472f924-81d9-4b99-8620-d95b286800c5",
      "name": "Google Sheets - Get RSS Feed url followed",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        260,
        120
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit#gid=0",
          "cachedResultName": "rss_feed"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit?usp=drivesdk",
          "cachedResultName": "Template - AI-Powered Information Monitoring"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "id": "",
          "name": "Google Sheets account"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.5
    },
    {
      "id": "c2a571f0-614f-41cf-b0b0-db4c714a8ab8",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 960,
        "content": "## Google Sheets - Get RSS Feed URLs Followed  
This node **retrieves rows** from the Google Sheet that contains the **RSS feed URLs** you follow.  
It is configured to run only once per execution, meaning that even if the previous node outputs many items, this node will execute only once.  

You can **add more URLs** to your sheet, but keep in mind that following **more RSS feeds** will increase the **cost of LLM API usage** (e.g., OpenAI).  

You can access the **Google Sheet template** to copy and use in this workflow [here](https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/).  
(*This is the same template used in the previous node.*)

In this node, make sure to select the **\"rss_feed\"** sheet from your **copied version of the Google Sheet template**.  
This sheet contains the list of RSS feed URLs that the workflow will process."
      },
      "typeVersion": 1
    },
    {
      "id": "90e34a2f-f326-4c83-ae26-d8f38d983c21",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        620,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 960,
        "content": "## RSS Read  
This node **reads** the RSS feed.  
The RSS URL is **retrieved** from the data you have entered in **Google Sheets**, so make sure the URL provided is indeed a **valid RSS feed**.  

### What is an RSS feed?  
An **RSS feed** is a **web feed** that allows users to **automatically receive updates** from websites, such as **news sites** or **blogs**, in a **standardized format**.
"
      },
      "typeVersion": 1
    },
    {
      "id": "06c22fcc-6fb6-4646-8cd2-3e2c48a56fbc",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2940,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 960,
        "height": 500,
        "content": "## Jina AI - Read URL

This node **uses the Jina AI API** to **retrieve the content** of articles that were classified as **\"relevant\"** in the previous step.  
Since this process **involves web scraping**, ensure that it complies with the **scraping regulations** in your country.  

### What is Jina AI?  
**Jina AI** is an API that allows you to **extract webpage content** and convert it into a format that is **ready for LLM processing**, such as **Markdown**.  

You can create an account [here](https://jina.ai/) and receive **1,000,000 free tokens** for testing.  
However, the service can also be used **without an API key** (without an account), though with **reduced RPM (requests per minute)**.  
For this workflow, the default RPM limits should generally be sufficient.
"
      },
      "typeVersion": 1
    },
    {
      "id": "3f8a0ce3-d7b3-400b-bc03-1a233f441429",
      "name": "Slack1",
      "type": "n8n-nodes-base.slack",
      "position": [
        4940,
        -120
      ],
      "webhookId": "",
      "parameters": {
        "text": "={{ $json.text }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0898R9G7JP",
          "cachedResultName": "topic-monitoring"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "id": "",
          "name": "slack-topic-monitoring"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "6920300f-fd0e-41dc-adf6-ed5a3a267b3f",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -460,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 960,
        "content": "## Google Sheets - Get Article Monitored Database  
This node **retrieves rows** from the Google Sheet that contains articles **already monitored and summarized** by the workflow.  
Depending on the RSS feed you monitor, **URLs may remain in the feed for a long time**, and you don't want to monitor the same URL **twice**.  
You can find the **Google Sheet template** that you can copy and use in this workflow [here](https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit?gid=1966921272#gid=1966921272).

In this node, make sure to select the **\"article_database\"** sheet from your **copied version of the Google Sheet template**.  
This sheet is used to store and manage the articles processed by the workflow.


---

## Set Field - existing_url  

This node sets the **\"existing_url\"** field with the value from **\"article_url\"** in the Google Sheets database.  
During the **first execution** of the workflow, this field will be **empty**, as no articles are present in Google Sheets yet.  
An error may occur in this case; however, the workflow will **continue running** without interruption.
"
      },
      "typeVersion": 1
    },
    {
      "id": "204aab36-1081-4d6e-b3a3-2fc03b6a1a10",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1180,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 980,
        "height": 960,
        "content": "## Code Node to Filter Existing URLs

This code node filters URLs that have **not yet been summarized by AI.**  
It outputs:

- A **list of URLs** following the RSS Read schema if new URLs are found.
- An item called **\"message\"** with the value **\"No new articles found\"** if no new articles are available in your RSS feed.

---

## IF Node

The condition for this node is: `{{ $json.message }}` *not equal to* **\"No new articles found\"**.

- **False** → The workflow executes the \"No Operation, do nothing\" node.
- **True** → The workflow proceeds to process the new articles for your web development industry monitoring.
"
      },
      "typeVersion": 1
    },
    {
      "id": "ef83c5f9-12a7-4924-9356-d1307fc8f279",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2940,
        60
      ],
      "parameters": {
        "color": 7,
        "width": 960,
        "height": 580,
        "content": "## Set Fields - Not Relevant Articles  

This node prepares the data to be added to the Google Sheet by defining the following fields:  

- **`article_url`** – The article's URL.
- **`summarized`** – Always set to `\"NO (not relevant)\"`, as it belongs to the **\"not_relevant\"** path.  
- **`website`** – The website where the article URL was published.  
- **`fetched_at`** – The timestamp when the URL was processed by the workflow.  
  > *(Note: This timestamp reflects when the scenario was triggered, as obtained from the **Schedule Trigger** node, not the exact fetch time.)*  
- **`publish_date`** – The date the article was published.  

---

## Google Sheets - Add Not Relevant Articles

This node adds the prepared data to the **\"article_database\"** sheet in your copied Google Sheet template.  
Ensure that you select the **\"article_database\"** sheet when configuring this node.  
"
      },
      "typeVersion": 1
    },
    {
      "id": "10af053d-23f6-416b-9fe2-874dfc2ec7aa",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4020,
        80
      ],
      "parameters": {
        "color": 5,
        "width": 600,
        "height": 440,
        "content": "## OpenAI Chat Model  

This node specifies the **AI model** to be used for processing.  
The default model is **GPT-4o-mini**, which has been **tested** and proven to perform well for this task.  

**GPT-4o-mini** is a **cost-efficient** model, offering a good balance between **performance and affordability**, making it suitable for regular usage without incurring high costs.
"
      },
      "typeVersion": 1
    },
    {
      "id": "67e6b0f9-32fc-4dcf-ae1b-effe11b31cd1",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4680,
        -640
      ],
      "parameters": {
        "color": 7,
        "width": 600,
        "height": 680,
        "content": "## Slack - Send Article Summary  

This node **posts the message** to the designated Slack channel, containing the **output generated by the LLM.**  

For better organization and accessibility, it is recommended to use a **dedicated Slack channel** specifically for topic monitoring.  
This ensures that team members can easily access relevant summaries without cluttering other discussions.  


### Why not use Slack Tool Calling?  

After extensive testing, the output from the previous node has proven to be **highly effective**, making it unnecessary to use **tool calling** or an **AI agent.** 😀  
Keeping things simple **streamlines the workflow** and reduces complexity.
"
      },
      "typeVersion": 1
    },
    {
      "id": "afe7643d-618b-4798-851e-b8b9d024e792",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4700,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 1260,
        "height": 560,
        "content": "## Set Fields - Relevant Articles  

This node prepares the data to be added to the Google Sheet by defining the following fields:  

- **`article_url`** – The article's URL.  
- **`summarized`** – Always set to `\"YES\"`, as it follows the **\"relevant\"** path.  
- **`summary`** – The article summary that was posted to Slack.  
- **`website`** – The source website where the article was published.  
- **`fetched_at`** – The timestamp indicating when the URL was processed by the workflow.  
  > *(Note: This timestamp reflects when the data was added to Google Sheets, not the actual fetch time.)*  
- **`publish_date`** – The date the article was published.  

---

## Google Sheets - Add Relevant Articles

This node adds the prepared data to the **\"article_database\"** sheet in your copied Google Sheet template.  
Make sure to select the **\"article_database\"** sheet when configuring this node.  
"
      },
      "typeVersion": 1
    },
    {
      "id": "e87619df-48e3-4ef8-83c7-1695746e2b92",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1000,
        -280
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 600,
        "content": "## Scheduler 
This **trigger** is a **scheduler** that defines **how often the workflow is executed**.  
By default, the **template is set to every 1 hour**, meaning the workflow will check **every hour** if **new articles** have been added to the **RSS feed** you follow.
"
      },
      "typeVersion": 1
    },
    {
      "id": "e2bcd684-abd9-4f47-bf4c-12eac379432d",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1900,
        -720
      ],
      "parameters": {
        "color": 6,
        "width": 780,
        "height": 1300,
        "content": "# Workflow Overview

## Check Legal Regulations:
This workflow involves scraping, so ensure you comply with the legal regulations in your country before getting started. Better safe than sorry!

## 📌 Purpose  
This workflow enables **automated and AI-driven topic monitoring**, delivering **concise article summaries** directly to a **Slack channel** in a structured and easy-to-read format.  
It allows users to stay informed on specific topics of interest effortlessly, without manually checking multiple sources, ensuring a **time-efficient and focused** monitoring experience.  

**To get started, copy the Google Sheets template required for this workflow from [here](https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY).**  


## 🎯 Target Audience  
This workflow is designed for:  
- **Industry professionals** looking to track key developments in their field.  
- **Research teams** who need up-to-date insights on specific topics.  
- **Companies** aiming to keep their teams informed with relevant content.  

## ⚙️ How It Works  
1. **Trigger:** A **Scheduler** initiates the workflow at regular intervals (default: every hour).  
2. **Data Retrieval:**  
   - RSS feeds are fetched using the **RSS Read** node.  
   - Previously monitored articles are checked in **Google Sheets** to avoid duplicates.  
3. **Content Processing:**  
   - The article relevance is assessed using **OpenAI (GPT-4o-mini)**.  
   - Relevant articles are scraped using **Jina AI** to extract content.  
   - Summaries are generated and formatted for Slack.  
4. **Output:**  
   - Summaries are posted to the specified Slack channel.  
   - Article metadata is stored in **Google Sheets** for tracking.  

## 🛠️ Key APIs and Nodes Used  
- **Scheduler Node:** Triggers the workflow periodically.  
- **RSS Read:** Fetches the latest articles from defined RSS feeds.  
- **Google Sheets:** Stores monitored articles and manages feed URLs.  
- **OpenAI API (GPT-4o-mini):** Classifies article relevance and generates summaries.  
- **Jina AI API:** Extracts the full content of relevant articles.  
- **Slack API:** Posts formatted messages to Slack channels.  

---

This workflow provides an **efficient and intelligent way** to stay informed about your topics of interest, directly within Slack.
"
      },
      "typeVersion": 1
    },
    {
      "id": "d72f505d-2bbf-41db-b404-8a61b8c21452",
      "name": "Google Sheets - Get article monitored database",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -400,
        120
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1966921272,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit#gid=1966921272",
          "cachedResultName": "article_database"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit?usp=drivesdk",
          "cachedResultName": "Template - AI-Powered Information Monitoring"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "id": "",
          "name": "Google Sheets account"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.5,
      "alwaysOutputData": true
    },
    {
      "id": "08eae799-2682-4d49-81fa-2127a65d887b",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        1280,
        120
      ],
      "parameters": {
        "jsCode": "// Retrieve data from RSS feed and Google Sheets
const rssItems = items; // Contains RSS articles
const sheetItems = $items(\"Set field - existing_url\", 0);

// Extract the links of articles present in Google Sheets
const existingUrls = sheetItems.map(entry => entry.json.existing_url);

// Filter RSS articles to keep only those not present in Google Sheets
const newArticles = rssItems.filter(rssItem => {
    return !existingUrls.includes(rssItem.json.link);
});

// If new articles are found, return them
if (newArticles.length > 0) {
    return newArticles;
}

// If no new articles, return an informational message
return [{ json: { message: \"No new articles found.\" } }];

"
      },
      "typeVersion": 2
    },
    {
      "id": "9f2d2c87-460b-4872-9538-519d26524475",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1960,
        240
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "e9ebbce6-a3b4-4f89-9908-3d9b2dd42f44",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        1640,
        120
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bad6fc33-2e1e-4169-9893-d284c6c68288",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.message }}",
              "rightValue": "No new articles found."
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6e2c820d-27da-4d3b-844c-581fb266e04a",
      "name": "Jina AI - Read URL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3240,
        -120
      ],
      "parameters": {
        "url": "=https://r.jina.ai/{{ $json.link }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "3f942518-f75b-4d03-9cd1-b275ad3b91cd",
      "name": "Set field - existing_url",
      "type": "n8n-nodes-base.set",
      "onError": "continueRegularOutput",
      "position": [
        -180,
        120
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "07799638-55d7-42a9-b1f7-fea762cfa2f1",
              "name": "existing_url",
              "type": "string",
              "value": "={{ $json.article_url.extractUrl() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4,
      "alwaysOutputData": true
    },
    {
      "id": "baef0ff9-8bf5-4ecf-9300-0adbad0d1a07",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2400,
        300
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "",
          "name": "OpenAi Connection"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "ccbfe5fc-2e87-4fff-b23d-0c4c6ebd3648",
      "name": "Set fields - Not relevant articles",
      "type": "n8n-nodes-base.set",
      "position": [
        3060,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3fbf5256-f06b-450a-adf7-65591a19c7dd",
              "name": "article_url",
              "type": "string",
              "value": "={{ $json.link }}"
            },
            {
              "id": "02f506cf-28fe-46ef-b97e-7ec938805151",
              "name": "summarized",
              "type": "string",
              "value": "NO (not relevant)"
            },
            {
              "id": "552efef4-63cb-448b-bb0c-30ae9666f310",
              "name": "website",
              "type": "string",
              "value": "={{ $('Google Sheets - Get RSS Feed url followed').item.json.website }}"
            },
            {
              "id": "096acb35-4e9e-48fd-8e61-8ceb525591fa",
              "name": "fetched_at",
              "type": "string",
              "value": "={{$now}}"
            },
            {
              "id": "427243d1-01c4-458a-9626-75366e4264cd",
              "name": "publish_date",
              "type": "string",
              "value": "={{ $('Relevance Classification for Topic Monitoring').item.json.pubDate.toDateTime().format('yyyy-MM-dd') }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0dbcc872-9afa-4e2c-be24-82d3a2457dd0",
      "name": "Google Sheets - Add relevant articles",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3480,
        480
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "article_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "article_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "summarized",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "summarized",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "website",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "website",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "fetched_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "fetched_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "publish_date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "publish_date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1966921272,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit#gid=1966921272",
          "cachedResultName": "article_database"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit?usp=drivesdk",
          "cachedResultName": "Template - AI-Powered Information Monitoring"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "id": "",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "0c7024b6-dfac-4e97-9d42-198fff6bcc47",
      "name": "Google Sheets - Add relevant article",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5660,
        520
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "article_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "article_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "summarized",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "summarized",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "website",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "website",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "fetched_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "fetched_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "publish_date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "publish_date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1966921272,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit#gid=1966921272",
          "cachedResultName": "article_database"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F2FzWt9FMkA5V5i9d_hBJRahLDvxs3DQBOLkLYowXbY/edit?usp=drivesdk",
          "cachedResultName": "Template - AI-Powered Information Monitoring"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "id": "",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "e1266606-eaee-4077-be7e-6f08ae9bae39",
      "name": "Set Fields - Relevant Articles",
      "type": "n8n-nodes-base.set",
      "position": [
        4900,
        520
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3fbf5256-f06b-450a-adf7-65591a19c7dd",
              "name": "article_url",
              "type": "string",
              "value": "={{ $('Relevance Classification for Topic Monitoring').item.json.link }}"
            },
            {
              "id": "02f506cf-28fe-46ef-b97e-7ec938805151",
              "name": "summarized",
              "type": "string",
              "value": "YES"
            },
            {
              "id": "e23059bd-8bb2-439a-85bd-f9e191930d1e",
              "name": "summary",
              "type": "string",
              "value": "={{ $json.text }}"
            },
            {
              "id": "552efef4-63cb-448b-bb0c-30ae9666f310",
              "name": "website",
              "type": "string",
              "value": "={{ $('Google Sheets - Get RSS Feed url followed').item.json.website }}"
            },
            {
              "id": "096acb35-4e9e-48fd-8e61-8ceb525591fa",
              "name": "fetched_at",
              "type": "string",
              "value": "={{$now}}"
            },
            {
              "id": "427243d1-01c4-458a-9626-75366e4264cd",
              "name": "publish_date",
              "type": "string",
              "value": "={{ $('Relevance Classification for Topic Monitoring').item.json.pubDate.toDateTime().format('yyyy-MM-dd') }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "dcc84e7c-aa42-4d0f-8522-84fdf8bea0bc",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Relevance Classification for Topic Monitoring",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RSS Read": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Slack1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Set Fields - Relevant Articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Google Sheets - Get article monitored database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Jina AI - Read URL": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Relevance Classification for Topic Monitoring",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Set field - existing_url": {
      "main": [
        [
          {
            "node": "Google Sheets - Get RSS Feed url followed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Fields - Relevant Articles": {
      "main": [
        [
          {
            "node": "Google Sheets - Add relevant article",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set fields - Not relevant articles": {
      "main": [
        [
          {
            "node": "Google Sheets - Add relevant articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets - Add relevant article": {
      "main": [
        []
      ]
    },
    "Google Sheets - Get RSS Feed url followed": {
      "main": [
        [
          {
            "node": "RSS Read",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Relevance Classification for Topic Monitoring": {
      "main": [
        [
          {
            "node": "Jina AI - Read URL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set fields - Not relevant articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets - Get article monitored database": {
      "main": [
        [
          {
            "node": "Set field - existing_url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

功能特点

  • 自动检测新邮件
  • AI智能内容分析
  • 自定义分类规则
  • 批量处理能力
  • 详细的处理日志

技术分析

节点类型及作用

  • @N8N/N8N Nodes Langchain.Lmchatopenai
  • @N8N/N8N Nodes Langchain.Chainllm
  • Scheduletrigger
  • Rssfeedread
  • @N8N/N8N Nodes Langchain.Textclassifier

复杂度评估

配置难度:
★★★★☆
维护难度:
★★☆☆☆
扩展性:
★★★★☆

实施指南

前置条件

  • 有效的Gmail账户
  • n8n平台访问权限
  • Google API凭证
  • AI分类服务订阅

配置步骤

  1. 在n8n中导入工作流JSON文件
  2. 配置Gmail节点的认证信息
  3. 设置AI分类器的API密钥
  4. 自定义分类规则和标签映射
  5. 测试工作流执行
  6. 配置定时触发器(可选)

关键参数

参数名称 默认值 说明
maxEmails 50 单次处理的最大邮件数量
confidenceThreshold 0.8 分类置信度阈值
autoLabel true 是否自动添加标签

最佳实践

优化建议

  • 定期更新AI分类模型以提高准确性
  • 根据邮件量调整处理批次大小
  • 设置合理的分类置信度阈值
  • 定期清理过期的分类规则

安全注意事项

  • 妥善保管API密钥和认证信息
  • 限制工作流的访问权限
  • 定期审查处理日志
  • 启用双因素认证保护Gmail账户

性能优化

  • 使用增量处理减少重复工作
  • 缓存频繁访问的数据
  • 并行处理多个邮件分类任务
  • 监控系统资源使用情况

故障排除

常见问题

邮件未被正确分类

检查AI分类器的置信度阈值设置,适当降低阈值或更新训练数据。

Gmail认证失败

确认Google API凭证有效且具有正确的权限范围,重新进行OAuth授权。

调试技巧

  • 启用详细日志记录查看每个步骤的执行情况
  • 使用测试邮件验证分类逻辑
  • 检查网络连接和API服务状态
  • 逐步执行工作流定位问题节点

错误处理

工作流包含以下错误处理机制:

  • 网络超时自动重试(最多3次)
  • API错误记录和告警
  • 处理失败邮件的隔离机制
  • 异常情况下的回滚操作