{
  "id": "Yo7sHkx1CGYo7hCC",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Telegram bot that summarizes articles with AI",
  "tags": [
    {
      "id": "T3xhK1cIuPex0boX",
      "name": "Templates",
      "createdAt": "2025-09-03T11:06:03.839Z",
      "updatedAt": "2025-09-03T11:06:03.839Z"
    }
  ],
  "nodes": [
    {
      "id": "ce04c36f-596a-445b-906a-5fd5c51900c1",
      "name": "After message is received",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        1184,
        -112
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.2
    },
    {
      "id": "7056604f-5185-4c80-b82a-b6599b41a56b",
      "name": "Check if URL",
      "type": "n8n-nodes-base.filter",
      "position": [
        1408,
        -112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "url-check",
              "operator": {
                "type": "string",
                "operation": "regex"
              },
              "leftValue": "={{ $json.message.text }}",
              "rightValue": "^https?://"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "3a8db721-345e-41c1-887a-9fc6bf5051f6",
      "name": "Extract URL",
      "type": "n8n-nodes-base.set",
      "position": [
        1680,
        -112
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "url-extract",
              "name": "url",
              "type": "string",
              "value": "={{ $json.message.text }}"
            },
            {
              "id": "chat-id",
              "name": "chat_id",
              "type": "number",
              "value": "={{ $json.message.chat.id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "56578477-9406-40ef-9e29-f306416f42ea",
      "name": "Fetch Article Markdown",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        1904,
        -112
      ],
      "parameters": {
        "url": "=https://r.jina.ai/{{ $json.url }}",
        "options": {}
      },
      "typeVersion": 4.1
    },
    {
      "id": "872e133e-6c0d-4bd7-9dd7-792d9a51190b",
      "name": "Summarize Article",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "onError": "continueErrorOutput",
      "maxTries": 2,
      "position": [
        2176,
        -128
      ],
      "parameters": {
        "text": "=Extract from this article and respond in the SAME LANGUAGE as the article:\n\n{{ $json.data }}\n\nReturn JSON with: title (string), summary (1 sentence), key_points (array of 3-5 strings)\n\nIMPORTANT: If article is in Spanish, respond in Spanish. If English, respond in English. Match the article's language.",
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 1.4,
      "alwaysOutputData": false
    },
    {
      "id": "bbb97241-521c-4ddd-b00a-23b15e52a1b5",
      "name": "Send Summary to Telegram",
      "type": "n8n-nodes-base.telegram",
      "maxTries": 2,
      "position": [
        2784,
        -192
      ],
      "parameters": {
        "text": "=\ud83d\udcf0 Article summary\n\nTitle: {{ $json.output.title }}\n\n\ud83d\udca1 Summary: {{ $json.output.summary }}\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udccc Key points:\n\n1\ufe0f\u20e3 {{ $json.output.key_points[0] }}\n\n2\ufe0f\u20e3 {{ $json.output.key_points[1] }}\n\n3\ufe0f\u20e3 {{ $json.output.key_points[2] }}\n\n{{ $json.output.key_points[3] ? '4\ufe0f\u20e3 ' + $json.output.key_points[3] : '' }}\n\n{{ $json.output.key_points[4] ? '5\ufe0f\u20e3 ' + $json.output.key_points[4] : '' }}\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udd17 {{ $('Extract URL').item.json.url }}",
        "chatId": "={{ $('Extract URL').item.json.chat_id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "retryOnFail": true,
      "typeVersion": 1.2
    },
    {
      "id": "3791d353-17a4-4b45-b383-e608a737f6a2",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        688,
        -384
      ],
      "parameters": {
        "width": 380,
        "height": 943,
        "content": "## Article summarizer bot\n\nSend any URL to your Telegram bot and get an AI summary instantly.\n\nWhat it does\n\n- Receives URLs via Telegram\n- Fetches clean article content (removes ads, navbars)\n- Generates AI summary \n- Sends formatted summary back to Telegram\n\n\nHow to set up\n\n1. **Create Telegram bot**\n   - Message @BotFather on Telegram\n   - Run /newbot and follow prompts\n   - Copy your bot token\n   - Add credentials to n8n\n\n2. **Get API keys** (optional but recommended)\n   - Jina AI: Sign up at jina.ai/reader  \n   - Add keys to nodes\n\n3. **Configure AI model and output parser format**\n\n\nRequirements\n\n- Telegram bot token\n- OpenRouter API key or any other LLM you have\n\n\nHow to customize\n\n- Change summary format: Edit prompt in \"Summarize Article\" node\n- Update Output Parser schema (title, tags, etc)\n- Save to database: Enable Google Sheets node or add Notion/Airtable\n- Different language: Modify prompt to force specific language"
      },
      "typeVersion": 1
    },
    {
      "id": "5c537825-51b3-4d0b-ad60-7bce7ea7895a",
      "name": "Save to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "disabled": true,
      "position": [
        2784,
        -384
      ],
      "parameters": {
        "columns": {
          "value": {
            "URL": "={{ $('Extract URL').item.json.url }}",
            "Date": "={{ $now.format('YYYY-MM-DD HH:mm') }}",
            "Title": "={{ $json.output.title }}",
            "Summary": "={{ $json.output.summary }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "4d67dfb6-490c-4627-b06e-6ba64cc59102",
      "name": "Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        2336,
        272
      ],
      "parameters": {
        "autoFix": true,
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"title\": {\n      \"type\": \"string\",\n      \"description\": \"The article title\"\n    },\n    \"summary\": {\n      \"type\": \"string\",\n      \"description\": \"One sentence summary\"\n    },\n    \"key_points\": {\n      \"type\": \"array\",\n      \"description\": \"3-5 key takeaways\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    }\n  },\n  \"required\": [\"title\", \"summary\", \"key_points\"]\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "02fa1407-ebcd-4cc8-8fda-9de6fd1a3628",
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        2096,
        256
      ],
      "parameters": {
        "model": "anthropic/claude-3.5-haiku",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8d160193-d474-4434-8691-51c7f7796d8f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1344,
        -320
      ],
      "parameters": {
        "color": 7,
        "height": 336,
        "content": "## Filter URLs\n\nOnly processes messages that start with http:// or https://\n\nNon-URL messages are ignored."
      },
      "typeVersion": 1
    },
    {
      "id": "8528f480-c1a5-4455-a8cf-6e75be2f06e5",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1872,
        -400
      ],
      "parameters": {
        "color": 7,
        "height": 432,
        "content": "## Fetch article\n\nUses Jina AI to convert webpage to clean markdown.\n\nRemoves navigation, ads, and clutter automatically.\n\nIf fetch fails, sends error message."
      },
      "typeVersion": 1
    },
    {
      "id": "d78eb2c2-26d3-449b-82b5-3fa9a6f6d655",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2144,
        -400
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 432,
        "content": "##  AI summary\n\nSends markdown to llm model via OpenRouter.\n\nReturns structured JSON with:\n- Title\n- One-sentence summary  \n- 3-5 key points\n\nMatches the article's original language."
      },
      "typeVersion": 1
    },
    {
      "id": "6adb92e2-d30a-41ef-8e9b-8570bdb22f99",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2944,
        -256
      ],
      "parameters": {
        "color": 7,
        "height": 240,
        "content": "## Send summary\n\nFormats the summary with emojis and sends to Telegram.\n\nOptionally saves to Google Sheets for tracking."
      },
      "typeVersion": 1
    },
    {
      "id": "7f10167e-3e09-4808-97fc-7e0fd056c095",
      "name": "Notify an error while fetching",
      "type": "n8n-nodes-base.telegram",
      "maxTries": 2,
      "position": [
        2048,
        528
      ],
      "parameters": {
        "text": "\u274c Failed to fetch article\n\nThe URL couldn't be processed. Possible reasons:\n\u2022 Paywall or login required\n\u2022 Invalid URL\n\u2022 Website blocking bots\n\u2022 Connection timeout",
        "chatId": "={{ $('Extract URL').item.json.chat_id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "retryOnFail": true,
      "typeVersion": 1.2
    },
    {
      "id": "dc78430c-9f60-4b09-a49b-ef126acc8e3b",
      "name": "Notify an error while summarizing",
      "type": "n8n-nodes-base.telegram",
      "maxTries": 2,
      "position": [
        2784,
        0
      ],
      "parameters": {
        "text": "\u274c Failed to summarize article\n\nThe AI couldn't process this content. Try a different URL or contact support.",
        "chatId": "={{ $('Extract URL').item.json.chat_id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "retryOnFail": true,
      "typeVersion": 1.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9d2f4076-a67d-4c25-b56c-1cf5aeb029b1",
  "connections": {
    "Extract URL": {
      "main": [
        [
          {
            "node": "Fetch Article Markdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if URL": {
      "main": [
        [
          {
            "node": "Extract URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Summarize Article",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Summarize Article": {
      "main": [
        [
          {
            "node": "Send Summary to Telegram",
            "type": "main",
            "index": 0
          },
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify an error while summarizing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Summarize Article",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Output Parser",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Article Markdown": {
      "main": [
        [
          {
            "node": "Summarize Article",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify an error while fetching",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "After message is received": {
      "main": [
        [
          {
            "node": "Check if URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}