AutomationFlowsAI & RAG › Generate News Cards From Spotify Emotions with Llm, Google News and…

Generate News Cards From Spotify Emotions with Llm, Google News and…

Original n8n title: Generate News Cards From Spotify Emotions with Llm, Google News and Apitemplate.io

Bynoda @shusaku on n8n.io

Title: Spotify Emotion-to-News Card Generator (APITemplate.io + Slack)

Cron / scheduled trigger★★★★☆ complexityAI-powered21 nodesAgentSpotifyOpenRouter ChatRSS Feed ReadApi Template IoSlack
AI & RAG Trigger: Cron / scheduled Nodes: 21 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #10267 — we link there as the canonical source.

This workflow follows the Agent → OpenRouter Chat recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "OMGFOlTIKsAAAwUG",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Spotify Emotion-to-News Card Generator (APITemplate.io + Slack)",
  "tags": [],
  "nodes": [
    {
      "id": "773130e9-c130-4276-b4f5-6fa0cd79ba91",
      "name": "Emotion Analyzer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        304,
        -16
      ],
      "parameters": {
        "text": "=You are an emotion analyst.\nGiven the following song title and artist, infer the main emotion it conveys \n(e.g., joyful, nostalgic, melancholic, energetic, angry, romantic).\nReturn JSON.\n\nInput:\n\"{{ $json.track.name }} - {{ $json.track.album.artists[0].name }}\"\n\nOutput:\n{\n  \"emotion\": \"nostalgic\",\n  \"reason\": \"The song's tone and lyrics evoke reflection and memory.\"\n}\n",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "734a0e4f-1a01-4bfd-8877-4629ef89d1a4",
      "name": "Start on Schedule (Cron)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -144,
        -16
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3c9cf5ff-747e-436c-b47d-8d55b2fdde40",
      "name": "Fetch Spotify Recently Played",
      "type": "n8n-nodes-base.spotify",
      "position": [
        80,
        -16
      ],
      "parameters": {
        "operation": "recentlyPlayed"
      },
      "credentials": {
        "spotifyOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e051c66b-fdfb-4ef7-860a-9a14c9c29f9e",
      "name": "LLM: Infer Emotion from Track",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        384,
        208
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ee6e19e5-8843-4669-87e6-432d0c944db7",
      "name": "For Each Track (Batch)",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        656,
        -16
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "282fbf38-97c2-4510-bed4-08072dea9f71",
      "name": "Build Google News RSS Query",
      "type": "n8n-nodes-base.set",
      "position": [
        880,
        -16
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{\n  (() => {\n    const raw =\n      $json.emotion ||\n      (JSON.parse($json.output || '{}').emotion) ||\n      'music';\n    const clean = String(raw).replace(/\\s+/g,' ').replace(/\\u3000/g,' ').trim();\n    const base = 'https://news.google.com/rss/search?hl=en-US&gl=US&ceid=US%3Aen&q=';\n    return { feedUrl: base + encodeURIComponent(clean) }; // \u2190 \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3067\u8fd4\u3059\n  })()\n}}\n"
      },
      "typeVersion": 3.4
    },
    {
      "id": "1636d83b-5ff3-4360-b70c-c469691e7d15",
      "name": "Fetch Google News RSS",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        1104,
        -16
      ],
      "parameters": {
        "url": "={{\n  (() => {\n    const emotionRaw =\n      $json.emotion ||\n      (JSON.parse($json.output || '{}').emotion) ||\n      'music';\n\n    const q = encodeURIComponent(String(emotionRaw).trim());\n    const url = `https://news.google.com/rss/search?hl=en-US&gl=US&ceid=US%3Aen&q=${q}`;\n    return url.trim();\n  })()\n}}\n",
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "89aab605-b6bb-4206-8866-c6bb97f269e5",
      "name": "Pick Top News & Format",
      "type": "n8n-nodes-base.code",
      "position": [
        1328,
        -16
      ],
      "parameters": {
        "jsCode": "return items.slice(0, 1);"
      },
      "typeVersion": 2
    },
    {
      "id": "20707f6c-fbec-45a8-94e0-a42574e9c90e",
      "name": "Generate News Card (APITemplate)",
      "type": "n8n-nodes-base.apiTemplateIo",
      "position": [
        1552,
        -16
      ],
      "parameters": {
        "overridesJson": "={{ JSON.stringify([\n  { \"name\": \"text_emotion\", \"text\": $json.emotion ?? \"neutral\" },\n  { \"name\": \"text_url\",     \"text\": $json.link ?? \"https://example.com\" },\n  { \"name\": \"text_1\",       \"text\": $json.contentSnippet ?? \"Unknown source\" },\n  { \"name\": \"text_2\",       \"text\": $json.title ?? \"No title\" }\n]) }}\n",
        "jsonParameters": true,
        "imageTemplateId": "="
      },
      "credentials": {
        "apiTemplateIoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "abed781e-894c-4239-8f89-34532fe17022",
      "name": "Post to Slack (Title + Link + Card URL)",
      "type": "n8n-nodes-base.slack",
      "position": [
        1776,
        -16
      ],
      "parameters": {
        "text": "={{\n  $(\"Pick Top News & Format\").item.json.title + \"\\n\" +\n  $(\"Pick Top News & Format\").item.json.link + \"\\n\" +\n  \"\ud83d\udcf0 \u30cb\u30e5\u30fc\u30b9\u30ab\u30fc\u30c9\\n\" +\n  ( $(\"Generate News Card (APITemplate)\").item.json.download_url_png || $(\"Generate News Card (APITemplate)\").item.json.download_url )\n}}\n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "CKUCBTG0H",
          "cachedResultName": "general"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "259a3bb9-d297-442c-b998-ea7aed02d1d1",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1072,
        -352
      ],
      "parameters": {
        "width": 416,
        "height": 1344,
        "content": "## \ud83d\udcc4 Workflow Overview\n\nTitle: Spotify Emotion-to-News Card Generator (APITemplate.io + Slack)\n\n## What it does:\nThis workflow analyzes the emotion of your recently played Spotify track using OpenRouter (LLM), fetches a related trending Google News article, generates a visual news card with APITemplate.io, and posts it to Slack.\n\n## \ud83d\udc65 Who\u2019s it for\n\nMusic lovers, marketers, and developers who want to automatically turn their listening mood into a visual daily digest or Slack update.\n\n## \u2699\ufe0f How it works\n\nSpotify Trigger \u2014 Fetch your recently played tracks.\n\nLLM (Emotion Analyzer) \u2014 Infer the main emotion from the track title and artist.\n\nGoogle News Query \u2014 Build an RSS URL based on the emotion keyword.\n\nRSS Reader \u2014 Retrieve trending news headlines.\n\nAPITemplate.io \u2014 Render the top article into an image card.\n\nSlack \u2014 Post title, link, and card image into your channel.\n\n## \ud83e\uddf0 Requirements\n\nSpotify API credentials\n\nOpenRouter API key\n\nAPITemplate.io account (with template ID)\n\nSlack OAuth2 connection\n\n## \ud83e\ude84 How to customize\n\nReplace the APITemplate.io template ID with your own.\n\nAdjust the RSS URL language (hl=en-US \u2192 hl=ja-JP for Japanese news).\n\nModify the Slack message text for your preferred channel tone.\n\n## \u26a0\ufe0f Disclaimer\n\nIf you use community nodes (LangChain), this template is for self-hosted n8n only."
      },
      "typeVersion": 1
    },
    {
      "id": "930501ea-23fc-4014-b2e1-8547d609680e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -240
      ],
      "parameters": {
        "color": 7,
        "content": "## Start on Schedule (Cron)\n\u201cTriggers this workflow on a fixed schedule. You can adjust interval in node settings.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "4b84f0fc-1f3f-4ebf-934e-3092759aae9f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        192
      ],
      "parameters": {
        "color": 7,
        "height": 176,
        "content": "## Fetch Spotify Recently Played\n\u201cRetrieves your last played Spotify tracks. Requires Spotify OAuth2 credentials.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "8fe180e8-594c-470b-9b1d-fa754582ae19",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        -208
      ],
      "parameters": {
        "color": 7,
        "height": 128,
        "content": "## Emotion Analyzer\n\u201cUses LLM (OpenRouter) to infer the dominant emotion from song title and artist.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "7017bd67-3219-492c-9334-16883310c843",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        160
      ],
      "parameters": {
        "color": 7,
        "height": 176,
        "content": "## For Each Track (Batch)\n\u201cProcesses each track individually for emotion-to-news mapping.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "c0ad00c2-c320-41c2-ad1e-982c192fc81c",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        816,
        -256
      ],
      "parameters": {
        "color": 7,
        "height": 176,
        "content": "## Build Google News RSS Query\n\u201cConverts emotion into a Google News RSS query string. Modify hl and gl for language/country.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "ab9563f1-d47a-49fc-ba02-149b251e8a0e",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1056,
        160
      ],
      "parameters": {
        "color": 7,
        "content": "## Fetch Google News RSS\n\u201cReads top articles matching the emotion keyword.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "1d92ea4b-bba2-4be9-8401-1174cbefef9a",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        -240
      ],
      "parameters": {
        "color": 7,
        "content": "## Pick Top News & Format\n\u201cSelects the first article from RSS feed and prepares title/link/snippet.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "afe292e6-24aa-42c8-9de5-e1d78b7acf30",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1504,
        176
      ],
      "parameters": {
        "color": 7,
        "height": 208,
        "content": "## Generate News Card (APITemplate)\n\u201cCreates a news card image using APITemplate.io. Replace template ID with yours.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "9914e9fa-6135-40ce-abf3-053a3c798c03",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1712,
        -208
      ],
      "parameters": {
        "color": 7,
        "content": "## Post to Slack (Title + Link + Card URL)\n\u201cPosts the generated card, title, and link to Slack. Unfurling disabled for clean appearance.\u201d"
      },
      "typeVersion": 1
    },
    {
      "id": "842092ca-795b-4330-b1c8-b83b6c8652e8",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        -304
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 752,
        "content": "## Setup (Step-by-Step)\n\nGoal: Analyze your recent Spotify listening history, infer the emotional tone, and generate a matching news image card that\u2019s automatically posted to Slack.\nPrerequisites: n8n (Cloud or Self-hosted), and active accounts for Spotify, Slack, APITemplate.io, and OpenRouter.\n\n1) Create Credentials (Required)\n\nSpotify OAuth2 \u2014 Go to Settings \u2192 Credentials \u2192 New \u2192 Spotify OAuth2, create a credential, and assign it to the \u201cFetch Spotify Recently Played\u201d node.\n\nSlack OAuth2 \u2014 Create it under Settings \u2192 Credentials, and assign it to \u201cPost to Slack.\u201d\n\nAPITemplate.io \u2014 Create it under Settings \u2192 Credentials, and assign it to \u201cGenerate News Card (APITemplate).\u201d\n\nOpenRouter API (LLM) \u2014 Create it under Settings \u2192 Credentials, and assign it to \u201cInfer Emotion from Track (LLM).\u201d\nIf you\u2019re concerned about Cloud compatibility, refer to the \u201cSelf-host / Cloud\u201d alternative described below."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b0b1e713-4148-491c-ba26-71d4520280bf",
  "connections": {
    "Emotion Analyzer": {
      "main": [
        [
          {
            "node": "For Each Track (Batch)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Google News RSS": {
      "main": [
        [
          {
            "node": "Pick Top News & Format",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "For Each Track (Batch)": {
      "main": [
        [],
        [
          {
            "node": "Build Google News RSS Query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pick Top News & Format": {
      "main": [
        [
          {
            "node": "Generate News Card (APITemplate)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start on Schedule (Cron)": {
      "main": [
        [
          {
            "node": "Fetch Spotify Recently Played",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Google News RSS Query": {
      "main": [
        [
          {
            "node": "Fetch Google News RSS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Spotify Recently Played": {
      "main": [
        [
          {
            "node": "Emotion Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LLM: Infer Emotion from Track": {
      "ai_languageModel": [
        [
          {
            "node": "Emotion Analyzer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Generate News Card (APITemplate)": {
      "main": [
        [
          {
            "node": "Post to Slack (Title + Link + Card URL)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to Slack (Title + Link + Card URL)": {
      "main": [
        []
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Title: Spotify Emotion-to-News Card Generator (APITemplate.io + Slack)

Source: https://n8n.io/workflows/10267/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This workflow acts as a specialized market analyst for Japan's "Furusato Nozei" (Hometown Tax) system. It automates the process of monitoring related news, validating keyword popularity via search tre

HTTP Request, RSS Feed Read, Agent +2
AI & RAG

This workflow is for beauty salons who want consistent, high‑quality social media content without writing every post manually. It also suits agencies and automation builders who manage multiple beauty

Telegram, Google Sheets Trigger, Agent +26
AI & RAG

Who Is This For?

Telegram, Google Sheets Trigger, Lm Chat Mistral Cloud +17
AI & RAG

This n8n template transforms your daily meeting preparation by automatically researching attendees and generating comprehensive briefing documents. Every weekday morning, it analyzes your calendar eve

Google Calendar, Slack, Agent +7
AI & RAG

Ghost-Automated-Blog-System. Uses scheduleTrigger, rssFeedRead, httpRequest, airtable. Scheduled trigger; 38 nodes.

RSS Feed Read, HTTP Request, Airtable +5