AI DJ:基于Linkup和GPT4的文本转Spotify歌单生成器
高级
这是一个Content Creation、Multimodal AI领域的自动化工作流,包含 17 个节点。主要使用 Set、Form、Spotify、SplitOut、FormTrigger 等节点。 AI DJ:基于Linkup和GPT4的文本转Spotify歌单生成器
前置要求
- •可能需要目标 API 的认证凭证
- •OpenAI API Key
使用的节点 (17 个)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"nodes": [
{
"id": "cad152e6-b878-4ecc-9d6c-c35cd456881c",
"name": "获取音轨 ID",
"type": "n8n-nodes-base.set",
"position": [
2464,
1072
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a35cb340-5917-4981-9627-6c6189a0a0f4",
"name": "Track ID",
"type": "string",
"value": "={{ $json.id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "fa700f73-8477-46fe-b037-0eddd4634977",
"name": "创建播放列表",
"type": "n8n-nodes-base.spotify",
"notes": "Create a blank playlist with the chosen name.",
"position": [
1568,
1072
],
"parameters": {
"name": "={{ $json.output.playlistName }}",
"resource": "playlist",
"operation": "create",
"additionalFields": {
"public": true
}
},
"credentials": {
"spotifyOAuth2Api": {
"id": "cF3ccMo4DndHdIe1",
"name": "Spotify account"
}
},
"notesInFlow": true,
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "9a95a7c1-b655-4078-88ba-1cc5eefd9fbe",
"name": "分离音轨",
"type": "n8n-nodes-base.splitOut",
"position": [
2016,
1072
],
"parameters": {
"options": {},
"fieldToSplitOut": "Tracks"
},
"typeVersion": 1
},
{
"id": "f8503606-eaf1-484f-9bf4-260f1dbce716",
"name": "获取音轨数组",
"type": "n8n-nodes-base.set",
"position": [
1792,
1072
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c03ede2c-3d1a-4b94-ba72-d9ac518300d3",
"name": "Tracks",
"type": "array",
"value": "={{ $('Ideate playlist').item.json.output.tracks }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "5462894f-ddfe-4e80-a5af-07d57b39d9dd",
"name": "添加音轨到播放列表",
"type": "n8n-nodes-base.spotify",
"position": [
2688,
1072
],
"parameters": {
"id": "=spotify:playlist:{{ $('Create playlist').first().json.id }}",
"trackID": "=spotify:track:{{ $json[\"Track ID\"] }}",
"resource": "playlist",
"additionalFields": {}
},
"credentials": {
"spotifyOAuth2Api": {
"id": "cF3ccMo4DndHdIe1",
"name": "Spotify account"
}
},
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "8363b3a8-710f-42a6-b977-7ba7b4fc3076",
"name": "获取最终播放列表",
"type": "n8n-nodes-base.spotify",
"position": [
2256,
1360
],
"parameters": {
"id": "=spotify:playlist:{{ $('Create playlist').item.json.id }}",
"resource": "playlist",
"operation": "get"
},
"credentials": {
"spotifyOAuth2Api": {
"id": "cF3ccMo4DndHdIe1",
"name": "Spotify account"
}
},
"executeOnce": true,
"typeVersion": 1
},
{
"id": "660044f8-d9e3-4b7a-b5ec-9100d315d87f",
"name": "搜索音轨",
"type": "n8n-nodes-base.spotify",
"position": [
2240,
1072
],
"parameters": {
"limit": 1,
"query": "={{ $json.artist }} - {{ $json.title }}",
"filters": {},
"resource": "track",
"operation": "search"
},
"credentials": {
"spotifyOAuth2Api": {
"id": "cF3ccMo4DndHdIe1",
"name": "Spotify account"
}
},
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "749dd63f-a0cc-449f-9289-c3628bfdcbbf",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
848,
912
],
"parameters": {
"color": 5,
"width": 652,
"height": 756,
"content": "## AI 代理规划播放列表"
},
"typeVersion": 1
},
{
"id": "0bcc422d-d223-409b-b13c-e4be95f4dc0e",
"name": "便签 6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1984,
912
],
"parameters": {
"color": 7,
"width": 840,
"height": 320,
"content": "## 对于每个音轨"
},
"typeVersion": 1
},
{
"id": "f63a650e-3612-4bc0-bb4a-94d804d86459",
"name": "表单提交时",
"type": "n8n-nodes-base.formTrigger",
"position": [
640,
1072
],
"webhookId": "440aeb02-ea99-4b63-be29-c093786684ce",
"parameters": {
"options": {
"path": "spotify-playlist-generator",
"customCss": ":root {\n /* Fonts */\n --font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n --font-weight-normal: 400;\n --font-weight-bold: 700;\n\n /* Font sizes */\n --font-size-body: 14px;\n --font-size-label: 16px;\n --font-size-test-notice: 14px;\n --font-size-input: 16px;\n --font-size-header: 24px;\n --font-size-paragraph: 16px;\n --font-size-link: 14px;\n --font-size-error: 14px;\n --font-size-html-h1: 36px;\n --font-size-html-h2: 28px;\n --font-size-html-h3: 22px;\n --font-size-html-h4: 18px;\n --font-size-html-h5: 16px;\n --font-size-html-h6: 14px;\n --font-size-subheader: 18px;\n\n /* Colours – Dark Theme */\n --color-background: #191414; /* Spotify dark background */\n --color-card-bg: #212121; /* Dark card background */\n --color-card-border: #2a2a2a;\n --color-card-shadow: rgba(0, 0, 0, 0.6);\n\n --color-header: #FFFFFF;\n --color-label: #EAEAEA;\n --color-input-bg: #212121; /* ✅ Dark background for inputs */\n --color-input-text: #FFFFFF; /* ✅ White text */\n --color-input-border: #444444;\n --color-focus-border: #1DB954;\n\n --color-link: #1DB954;\n --color-link-hover: #1AA34A;\n --color-header-subtext: #B3B3B3;\n\n --color-submit-btn-bg: #1DB954;\n --color-submit-btn-text: #FFFFFF;\n --color-submit-btn-hover: #1AA34A;\n\n --color-clear-button-bg: #333333;\n --color-clear-button-text: #FFFFFF;\n\n --color-test-notice-text: #FFFFFF;\n --color-test-notice-bg: #2a2a2a;\n --color-test-notice-border: #3a3a3a;\n\n --color-error: #E22134;\n --color-required: #1DB954;\n\n --color-html-text: #EAEAEA;\n --color-html-link: #1DB954;\n\n /* Border Radii */\n --border-radius-card: 8px;\n --border-radius-input: 4px;\n --border-radius-clear-btn: 50%;\n --card-border-radius: 8px;\n\n /* Spacing */\n --padding-container-top: 32px;\n --padding-card: 24px;\n --padding-test-notice-vertical: 16px;\n --padding-test-notice-horizontal: 24px;\n --margin-bottom-card: 24px;\n --padding-form-input: 12px;\n --card-padding: 24px;\n --card-margin-bottom: 24px;\n\n /* Dimensions */\n --container-width: 480px;\n --submit-btn-height: 48px;\n --checkbox-size: 20px;\n\n /* Other visuals */\n --box-shadow-card: 0px 4px 16px rgba(0, 0, 0, 0.6);\n --opacity-placeholder: 0.8;\n}\n\n/* Inputs */\ninput, textarea {\n background-color: var(--color-input-bg);\n color: var(--color-input-text);\n border: 1px solid var(--color-input-border);\n border-radius: var(--border-radius-input);\n padding: var(--padding-form-input);\n}\n\ninput:focus, textarea:focus {\n outline: none;\n border-color: var(--color-focus-border);\n box-shadow: 0 0 0 2px rgba(29, 185, 84, 0.3); /* Spotify green glow */\n}\n\n/* Placeholder styling */\n::placeholder {\n font-family: system-ui, sans-serif;\n font-size: 0.9em;\n font-weight: 400;\n color: #B3B3B3; /* ✅ More readable grey */\n opacity: 1;\n}",
"buttonLabel": "Generate the playlist",
"appendAttribution": false
},
"formTitle": "Spotify playlist AI generator",
"formFields": {
"values": [
{
"fieldType": "textarea",
"fieldLabel": "Playlist request",
"placeholder": "=Describe the playlist you'd like, its style, artists, mood, anything",
"requiredField": true
},
{
"fieldType": "number",
"fieldLabel": "Number of tracks",
"placeholder": "How many tracks to include",
"requiredField": true
}
]
},
"responseMode": "lastNode"
},
"typeVersion": 2.3
},
{
"id": "32bcb9a6-89d3-4aa6-a38f-459cbef72398",
"name": "OpenAI 聊天模型",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
896,
1296
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "dMiSy27YCK6c6rra",
"name": "Duv's OpenAI"
}
},
"typeVersion": 1.2
},
{
"id": "5ae73327-327c-4add-8068-f0e202101577",
"name": "网络查询以查找音轨",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1136,
1312
],
"parameters": {
"url": "https://api.linkup.so/v1/search",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "q",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters0_Value', `The tracks research query.\n(e.g. \"12 tracks released in 2010 in Spain on the topic of passionate love, RNB style\" or \"10 most famous Daft Punk tracks\" ...)`, 'string') }}"
},
{
"name": "depth",
"value": "deep"
},
{
"name": "outputType",
"value": "structured"
},
{
"name": "structuredOutputSchema",
"value": "={\n \"type\": \"object\",\n \"properties\": {\n \"tracks\": {\n \"type\": \"array\",\n \"description\": \"A list of music tracks included in the selection\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"description\": \"The title of the track\"\n },\n \"artist\": {\n \"type\": \"string\",\n \"description\": \"The artist or group who performed the track\"\n },\n \"explanation\": {\n \"type\": \"string\",\n \"description\": \"A 1-line explanation of why this track was chosen\"\n }\n }\n }\n }\n }\n}"
},
{
"name": "includeImages",
"value": "false"
}
]
},
"genericAuthType": "httpBearerAuth",
"toolDescription": "=Call this tool with a specific query to get a list of recommended tracks to include in the playlist."
},
"credentials": {
"httpBearerAuth": {
"id": "W7AgeoVOv60DlvyS",
"name": "Linkup - web search AI"
}
},
"typeVersion": 4.2
},
{
"id": "4733dee8-34fd-4e20-b91a-e5f5a16abb42",
"name": "构思播放列表",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1056,
1072
],
"parameters": {
"text": "=# Playlist guidelines\n\n{{ $json['Playlist request'] }}\n\n\n# Number of songs to include\n\n{{ $json['Number of tracks'] }}",
"options": {
"systemMessage": "=# Role\n\nYou are a very experienced DJ and your task is to create a playlist of {{ $json['Number of tracks'] }} tracks and give it a name, based on the user message which contains the playlist instructions and number of tracks to include. \n\n# How to find the {{ $json['Number of tracks'] }} tracks to include within a playlist\n\nYou'll recommend an interesting and relevant mix of tracks, exactly {{ $json['Number of tracks'] }} tracks - ideally not from the same artist (except if the instructions tell so), nailing implementing the instructions given by the user message.\n\nTo achieve that, you'll call the tool \"Web query to find tracks\" with a query you'll craft - this tool has web access and knows all tracks so you can pass queries and it will return track suggestions. Run this tool only once.\nYou'll then be able to make your selection based on those recommendations.\n\nFor each track you will (and this will be detailed later) provide the artist name and the title of the track.\n\n\n# How to craft the playlist title\n\nBased on the user message and the songs to fit into the playlist, the playlist name should be between 5 and 9 words and perfectly fit for a playlist name.\nIt is possible that the user message contains more direct instructions for the title.\n\n# Strict output format:\n\nHere's an example of your output so you have a good idea of the schema of the JSON output and a little idea of how the values can look like in the case of a 5-track playlist (but adapt the values to the user message!):\n\n\n{\n \"playlistName\":\"Summer dancing with a Spritz and attitude\",\n \"tracks\":[\n {\n \"artist\":\"David Guetta, Sia\",\n \"title\":\"Beautiful People\"\n },\n {\n \"artist\":\"Ed Sheeran\",\n \"title\":\"Azizam\"\n },\n {\n \"artist\":\"Doechii\",\n \"title\":\"Anxiety\"\n },\n {\n \"artist\":\"OneRepublic\",\n \"title\":\"Nobody (from Kaiju No.8)\"\n },\n {\n \"artist\":\"The Weeknd\",\n \"title\":\"Cry For Me\"\n }\n ]\n}\n\n\n"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "d370dbad-7b59-4e88-ab36-5058112af9ab",
"name": "结构化输出解析器",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1360,
1312
],
"parameters": {
"jsonSchemaExample": "{\n \"playlistName\":\"Summer dancing with a Spritz and attitude\",\n \"tracks\":[\n {\n \"artist\":\"David Guetta, Sia\",\n \"title\":\"Beautiful People\"\n },\n {\n \"artist\":\"Ed Sheeran\",\n \"title\":\"Azizam\"\n },\n {\n \"artist\":\"Doechii\",\n \"title\":\"Anxiety\"\n },\n {\n \"artist\":\"OneRepublic\",\n \"title\":\"Nobody (from Kaiju No.8)\"\n },\n {\n \"artist\":\"The Weeknd\",\n \"title\":\"Cry For Me\"\n }\n ]\n}\n"
},
"typeVersion": 1.3
},
{
"id": "90f4b20f-4e85-4069-9d1e-e54c41778ac7",
"name": "打开播放列表",
"type": "n8n-nodes-base.form",
"position": [
2464,
1360
],
"webhookId": "d417cf9e-4774-4400-a5b1-93369a236547",
"parameters": {
"options": {},
"operation": "completion",
"redirectUrl": "={{ $json.external_urls.spotify }}",
"respondWith": "redirect"
},
"typeVersion": 2.3
},
{
"id": "277b77d3-8f2f-462c-9dd0-71704acd4256",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
1056,
1280
],
"parameters": {
"color": 6,
"height": 368,
"content": ""
},
"typeVersion": 1
},
{
"id": "3f440854-0af9-4676-93c8-1674255c5d66",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
48,
720
],
"parameters": {
"width": 528,
"height": 960,
"content": ""
},
"typeVersion": 1
}
],
"connections": {
"Get track IDs": {
"main": [
[
{
"node": "Add track to playlist",
"type": "main",
"index": 0
}
]
]
},
"Create playlist": {
"main": [
[
{
"node": "Get tracks array",
"type": "main",
"index": 0
}
]
]
},
"Ideate playlist": {
"main": [
[
{
"node": "Create playlist",
"type": "main",
"index": 0
}
]
]
},
"Get tracks array": {
"main": [
[
{
"node": "Split out tracks",
"type": "main",
"index": 0
}
]
]
},
"Search the track": {
"main": [
[
{
"node": "Get track IDs",
"type": "main",
"index": 0
}
]
]
},
"Split out tracks": {
"main": [
[
{
"node": "Search the track",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Ideate playlist",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"On form submission": {
"main": [
[
{
"node": "Ideate playlist",
"type": "main",
"index": 0
}
]
]
},
"Add track to playlist": {
"main": [
[
{
"node": "Get the final playlist",
"type": "main",
"index": 0
}
]
]
},
"Get the final playlist": {
"main": [
[
{
"node": "Opening the playlist",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Ideate playlist",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Web query to find tracks": {
"ai_tool": [
[
{
"node": "Ideate playlist",
"type": "ai_tool",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
这是一个高级难度的工作流,适用于Content Creation、Multimodal AI等场景。适合高级用户,包含 16+ 个节点的复杂工作流
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用Lookio和OpenAI GPT从知识源创建基于事实的文章
使用Lookio和OpenAI GPT从知识源创建基于事实的文章
Set
Split Out
Aggregate
+7
19 节点Guillaume Duvernay
Content Creation
使用AI规划、Linkup搜索和GPT-5创建研究支持的文章
使用AI规划、Linkup搜索和GPT-5创建研究支持的文章
Set
Split Out
Aggregate
+7
19 节点Guillaume Duvernay
Content Creation
生成长文档
使用GPT-5和Google Docs从简单标题生成长篇文档
Set
Form
Split Out
+8
14 节点Nghia Nguyen
Content Creation
使用 Nano Banana 和 Telegram 将产品照片转换为专业级视觉效果
使用 Nano Banana 和 Telegram 将产品照片转换为专业级视觉效果
If
Set
Wait
+10
21 节点Sulieman Said
Content Creation
使用OpenAI和Firecrawl从产品URL创建AI生成的Meta广告活动
使用OpenAI和Firecrawl从产品URL创建AI生成的Meta广告活动
If
Set
Code
+15
40 节点Adam Crafts
Content Creation
WordPress博客自动化专业版(深度研究)v2.1市场
使用GPT-4o、Perplexity AI和多语言支持自动化SEO优化的博客创建
If
Set
Xml
+27
125 节点Daniel Ng
Content Creation