Spotify Sync Liked Songs to Playlist
工作流概述
这是一个包含40个节点的复杂工作流,主要用于自动化处理各种任务。
工作流源代码
{
"id": "gemC8tYGZk3LtBHG",
"meta": {
"instanceId": "14252f55409b74bfbc2ebbc1f88f70ee3158c04314bae8b95b4a969a5a5972e3",
"templateCredsSetupCompleted": false
},
"name": "Spotify Sync Liked Songs to Playlist",
"tags": [
{
"id": "TYGC4owzlQuowxvB",
"name": "Spotify",
"createdAt": "2024-03-14T16:54:47.712Z",
"updatedAt": "2024-03-14T16:54:47.712Z"
}
],
"nodes": [
{
"id": "7767a08e-43f0-4c07-968c-06dab188bf86",
"name": "Start",
"type": "n8n-nodes-base.manualTrigger",
"position": [
160,
220
],
"parameters": {},
"typeVersion": 1
},
{
"id": "9193f532-335e-4a6a-886e-64849f6fab55",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
180,
-100
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.1
},
{
"id": "41cffeb0-9dd5-4f71-8519-19f7339e2102",
"name": "Sort first added to first item",
"type": "n8n-nodes-base.sort",
"position": [
1480,
-60
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"fieldName": "added_at"
}
]
}
},
"typeVersion": 1
},
{
"id": "ed77edb1-25d4-4330-a6ad-3864117172e3",
"name": "Gotify Send deleted n from x",
"type": "n8n-nodes-base.gotify",
"position": [
3540,
220
],
"parameters": {
"message": "=### Sync of Lieblingssongs to {{ $('Edit set Vars').item.json.varplaylistto }} finished.
#### Deleted {{ $json.count_del }} Songs in {{ (($now.toUnixInteger()-$('Edit set intern vars').item.json.timestart)/60).toFixed(1) }} Minutes from {{ $('Edit set Vars').item.json.varplaylistto }}.",
"options": {
"contentType": "text/markdown"
},
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "f9e03838-03ea-44de-b3d5-6adb94f2324b",
"name": "Loop delete old",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2560,
300
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "2aa10aab-fd65-4be3-95da-2471bacde57c",
"name": "Spotify delete old",
"type": "n8n-nodes-base.spotify",
"position": [
2820,
320
],
"parameters": {
"id": "={{ $('Set pluri').item.json.setpluri }}",
"trackID": "={{ $json.track.uri }}",
"resource": "playlist",
"operation": "delete"
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "71a4391d-280b-4cbc-be5b-16f9bb02c161",
"name": "Edit set Vars",
"type": "n8n-nodes-base.set",
"position": [
480,
100
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "1bacf493-c2bf-47f8-bcb4-a83010d8da57",
"name": "varplaylistto",
"type": "string",
"value": "CHANGE MEEEEEEEEE"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "b0f18395-2bee-4e92-8905-a2faf8b8617b",
"name": "Edit success to del",
"type": "n8n-nodes-base.set",
"position": [
3180,
240
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "2aab653d-b7ee-4d50-b8e5-fcae0c0da1f4",
"name": "del",
"type": "string",
"value": "={{ $json.success }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "d205de9e-fefd-4a9b-933b-932e19873ee3",
"name": "Filter Playlist x",
"type": "n8n-nodes-base.filter",
"position": [
1480,
160
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0665f0f3-fb32-4391-b1a9-ce1dee887392",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.name }}",
"rightValue": "={{ $('Edit set Vars').item.json.varplaylistto }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "5f81aa3f-631d-41c8-aaf7-0bced69ecb7a",
"name": "Compare Datasets",
"type": "n8n-nodes-base.compareDatasets",
"position": [
2260,
20
],
"parameters": {
"options": {},
"mergeByFields": {
"values": [
{
"field1": "track.uri",
"field2": "track.uri"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "7c86ca31-1e78-47d2-8c97-b796aa9b3eff",
"name": "count added",
"type": "n8n-nodes-base.summarize",
"position": [
3320,
-280
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "added"
}
]
}
},
"typeVersion": 1
},
{
"id": "80e6c5f5-6ca1-44a5-8f6a-2181854f3ad8",
"name": "Loop add missing",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2560,
-240
],
"parameters": {
"options": {}
},
"executeOnce": false,
"typeVersion": 3
},
{
"id": "399c4489-82d3-4ca4-b875-5a3988cc1e56",
"name": "Spotify add Missing to x",
"type": "n8n-nodes-base.spotify",
"position": [
2740,
-200
],
"parameters": {
"id": "={{ $json.setpluri }}",
"trackID": "={{ $json.track.uri }}",
"resource": "playlist",
"additionalFields": {}
},
"retryOnFail": true,
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "598693f1-9716-45b7-a53b-d4b16a9dbd5d",
"name": "Edit snapshot to added",
"type": "n8n-nodes-base.set",
"position": [
3160,
-280
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "2aab653d-b7ee-4d50-b8e5-fcae0c0da1f4",
"name": "added",
"type": "string",
"value": "={{ $json.snapshot_id }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "29b6f2c3-7c03-4c22-9c40-12224adc36a9",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2480,
-380
],
"parameters": {
"color": 7,
"width": 552.0433138756023,
"height": 424.7557420711291,
"content": "### Spotify add all missing song from your Liked Songs to the Playlist."
},
"typeVersion": 1
},
{
"id": "2e6b61ee-67dd-473f-aca6-4bf81d348474",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
2480,
140
],
"parameters": {
"color": 7,
"width": 526.4961431470259,
"height": 334.0270849934536,
"content": "### Spotify remove all songs that aren't in your Liked Songs anymore."
},
"typeVersion": 1
},
{
"id": "a7a32504-0805-4898-a054-3a9d1cbfdf00",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
120,
-180
],
"parameters": {
"color": 7,
"width": 208.40632224018503,
"height": 218.09160104224037,
"content": "Run the workflow every 24h at 0 o'clock"
},
"typeVersion": 1
},
{
"id": "240bb516-434c-4050-af5c-8ecf3c270077",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1280,
-202
],
"parameters": {
"color": 7,
"width": 961.006341450897,
"height": 611.5473181162548,
"content": "## Compare the content of your Liked Songs and the target Playlist "
},
"typeVersion": 1
},
{
"id": "cd4fe1c5-88da-4925-b95e-a03c9cfb14fc",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
420,
-80
],
"parameters": {
"color": 3,
"width": 365.4656320955345,
"height": 271.1720790719926,
"content": "# Edit here!"
},
"typeVersion": 1
},
{
"id": "aa447ed6-9522-4f25-b0b6-7c8592b3d71a",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
-20
],
"parameters": {
"width": 362.28928697919184,
"height": 267.99573395564994,
"content": "## Change the value to the name of your target playlist."
},
"typeVersion": 1
},
{
"id": "a7fd9f12-3f06-4613-9797-2cd754af4e44",
"name": "Cound deleted",
"type": "n8n-nodes-base.summarize",
"position": [
3320,
231
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "del"
}
]
}
},
"typeVersion": 1
},
{
"id": "ebdc4b9d-09a9-4a41-b2a3-f9488decafd7",
"name": "Sort",
"type": "n8n-nodes-base.sort",
"position": [
2100,
160
],
"parameters": {
"options": {
"disableDotNotation": false
},
"sortFieldsUi": {
"sortField": [
{
"fieldName": "added_at"
}
]
}
},
"typeVersion": 1
},
{
"id": "1285f8fd-423a-418f-9ba0-b2e43f3f55d7",
"name": "Set pluri",
"type": "n8n-nodes-base.set",
"position": [
1680,
160
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f1589697-556f-451d-aada-55d2b0892eb2",
"name": "setpluri",
"type": "string",
"value": "={{ $json.uri }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "55e994d9-cb66-4a30-9cda-ec373f5135a7",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
1700,
-60
],
"parameters": {
"mode": "combine",
"options": {},
"combinationMode": "multiplex"
},
"typeVersion": 2.1
},
{
"id": "83e47b30-dc30-4978-9de4-087f711f05b3",
"name": "Gotify",
"type": "n8n-nodes-base.gotify",
"position": [
3520,
-300
],
"parameters": {
"message": "=### Sync of Liked Songs to {{ $('Edit set Vars').item.json.varplaylistto }} finished.
#### Added {{ $('count added').item.json.count_added }} Songs in {{ (($now.toUnixInteger()-$('Edit set intern vars').item.json.timestart)/60).toFixed(1) }} Minutes to {{ $('Edit set Vars').item.json.varplaylistto }}.",
"options": {
"contentType": "text/markdown"
},
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "d58f4a88-d760-4d6f-a43f-d38575b5fa64",
"name": "Edit set intern vars",
"type": "n8n-nodes-base.set",
"position": [
880,
80
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "88b47bd3-d1b6-4c7d-bec2-1606d8c39bde",
"name": "timestart",
"type": "string",
"value": "={{ $now.toUnixInteger()}}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "5bfaaa09-5310-49af-be6b-df0495eebefc",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
-150
],
"parameters": {
"color": 3,
"width": 326.5743290776694,
"height": 513.8509299486715,
"content": "# Edit here!"
},
"typeVersion": 1
},
{
"id": "0e47be4b-668b-4167-a191-2680f5750798",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1080,
-87
],
"parameters": {
"width": 331.1762445648999,
"height": 481.41944245487934,
"content": "### You need to add your own spotify account here."
},
"typeVersion": 1
},
{
"id": "b15d1e35-03bc-4ee9-b425-38b73f832807",
"name": "END",
"type": "n8n-nodes-base.noOp",
"position": [
2580,
0
],
"parameters": {},
"typeVersion": 1
},
{
"id": "2ea585b8-645b-499d-8bef-9579f7283a38",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
3140,
131
],
"parameters": {
"color": 5,
"width": 322.2176178216457,
"height": 271.6789308744022,
"content": "## (Optional)
### Count the number of songs that were deleted"
},
"typeVersion": 1
},
{
"id": "bec19dea-11f6-4ac3-96c2-5b0b13079cab",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
3120,
-400
],
"parameters": {
"color": 5,
"width": 322.2176178216457,
"height": 271.6789308744022,
"content": "## (Optional)
### Count the number of songs that were added"
},
"typeVersion": 1
},
{
"id": "44731884-1a40-49ca-bdc8-08f135e97fba",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1840,
37
],
"parameters": {
"color": 3,
"width": 210.26363071246638,
"height": 252.15185862696416,
"content": "# Edit here!"
},
"typeVersion": 1
},
{
"id": "e9654402-2c58-458e-a235-ed1dd09bbc61",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
1800,
100
],
"parameters": {
"width": 223.1734532257829,
"height": 240.4901386983871,
"content": "### You need to add your own spotify account here."
},
"typeVersion": 1
},
{
"id": "2d924a96-a313-448d-b563-abd4c56e8af9",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
2800,
180
],
"parameters": {
"color": 3,
"width": 210.26363071246638,
"height": 252.15185862696416,
"content": "# Edit here!"
},
"typeVersion": 1
},
{
"id": "9cbe2e02-7e5d-47b8-a333-5d09767790d6",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
2760,
240
],
"parameters": {
"width": 223.1734532257829,
"height": 240.4901386983871,
"content": "### You need to add your own spotify account here."
},
"typeVersion": 1
},
{
"id": "f1d30def-79d5-4efe-9f24-d36866e971ee",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"position": [
2740,
-340
],
"parameters": {
"color": 3,
"width": 210.26363071246638,
"height": 252.15185862696416,
"content": "# Edit here!"
},
"typeVersion": 1
},
{
"id": "957dc82b-6fe0-4018-add9-d904b8a1af9f",
"name": "Sticky Note15",
"type": "n8n-nodes-base.stickyNote",
"position": [
2700,
-280
],
"parameters": {
"width": 223.1734532257829,
"height": 240.4901386983871,
"content": "### You need to add your own spotify account here."
},
"typeVersion": 1
},
{
"id": "b63c2dcc-da0c-4074-bfa5-69aaeaa9e1db",
"name": "Spotify get Liked Songs",
"type": "n8n-nodes-base.spotify",
"position": [
1160,
-20
],
"parameters": {
"resource": "library",
"returnAll": true
},
"typeVersion": 1
},
{
"id": "808389ac-65a8-444f-99a7-08eab4b48b3e",
"name": "Spotify get all playlists",
"type": "n8n-nodes-base.spotify",
"position": [
1160,
200
],
"parameters": {
"resource": "playlist",
"operation": "getUserPlaylists",
"returnAll": true
},
"typeVersion": 1
},
{
"id": "6232b653-27ba-4986-9f53-b5d9dfa2e6b8",
"name": "Spotify get Tracks of X",
"type": "n8n-nodes-base.spotify",
"position": [
1880,
160
],
"parameters": {
"id": "={{ $json.setpluri }}",
"resource": "playlist",
"operation": "getTracks",
"returnAll": true
},
"typeVersion": 1,
"alwaysOutputData": false
}
],
"active": false,
"pinData": {},
"settings": {
"timezone": "Europe/Berlin",
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1",
"saveManualExecutions": true
},
"versionId": "04d88525-7f76-435b-b70c-a7ace2517815",
"connections": {
"Sort": {
"main": [
[
{
"node": "Compare Datasets",
"type": "main",
"index": 1
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Compare Datasets",
"type": "main",
"index": 0
}
]
]
},
"Start": {
"main": [
[
{
"node": "Edit set Vars",
"type": "main",
"index": 0
}
]
]
},
"Set pluri": {
"main": [
[
{
"node": "Spotify get Tracks of X",
"type": "main",
"index": 0
},
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"count added": {
"main": [
[
{
"node": "Gotify",
"type": "main",
"index": 0
}
]
]
},
"Cound deleted": {
"main": [
[
{
"node": "Gotify Send deleted n from x",
"type": "main",
"index": 0
}
]
]
},
"Edit set Vars": {
"main": [
[
{
"node": "Edit set intern vars",
"type": "main",
"index": 0
}
]
]
},
"Loop delete old": {
"main": [
[
{
"node": "Edit success to del",
"type": "main",
"index": 0
}
],
[
{
"node": "Spotify delete old",
"type": "main",
"index": 0
}
]
]
},
"Compare Datasets": {
"main": [
[
{
"node": "Loop add missing",
"type": "main",
"index": 0
}
],
[
{
"node": "END",
"type": "main",
"index": 0
}
],
[
{
"node": "END",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop delete old",
"type": "main",
"index": 0
}
]
]
},
"Loop add missing": {
"main": [
[
{
"node": "Edit snapshot to added",
"type": "main",
"index": 0
}
],
[
{
"node": "Spotify add Missing to x",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Edit set Vars",
"type": "main",
"index": 0
}
]
]
},
"Filter Playlist x": {
"main": [
[
{
"node": "Set pluri",
"type": "main",
"index": 0
}
]
]
},
"Spotify delete old": {
"main": [
[
{
"node": "Loop delete old",
"type": "main",
"index": 0
}
]
]
},
"Edit success to del": {
"main": [
[
{
"node": "Cound deleted",
"type": "main",
"index": 0
}
]
]
},
"Edit set intern vars": {
"main": [
[
{
"node": "Spotify get Liked Songs",
"type": "main",
"index": 0
},
{
"node": "Spotify get all playlists",
"type": "main",
"index": 0
}
]
]
},
"Edit snapshot to added": {
"main": [
[
{
"node": "count added",
"type": "main",
"index": 0
}
]
]
},
"Spotify get Liked Songs": {
"main": [
[
{
"node": "Sort first added to first item",
"type": "main",
"index": 0
}
]
]
},
"Spotify get Tracks of X": {
"main": [
[
{
"node": "Sort",
"type": "main",
"index": 0
}
]
]
},
"Spotify add Missing to x": {
"main": [
[
{
"node": "Loop add missing",
"type": "main",
"index": 0
}
]
]
},
"Spotify get all playlists": {
"main": [
[
{
"node": "Filter Playlist x",
"type": "main",
"index": 0
}
]
]
},
"Sort first added to first item": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
}
}
}
功能特点
- 自动检测新邮件
- AI智能内容分析
- 自定义分类规则
- 批量处理能力
- 详细的处理日志
技术分析
节点类型及作用
- Manualtrigger
- Scheduletrigger
- Sort
- Gotify
- Splitinbatches
复杂度评估
配置难度:
维护难度:
扩展性:
实施指南
前置条件
- 有效的Gmail账户
- n8n平台访问权限
- Google API凭证
- AI分类服务订阅
配置步骤
- 在n8n中导入工作流JSON文件
- 配置Gmail节点的认证信息
- 设置AI分类器的API密钥
- 自定义分类规则和标签映射
- 测试工作流执行
- 配置定时触发器(可选)
关键参数
| 参数名称 | 默认值 | 说明 |
|---|---|---|
| maxEmails | 50 | 单次处理的最大邮件数量 |
| confidenceThreshold | 0.8 | 分类置信度阈值 |
| autoLabel | true | 是否自动添加标签 |
最佳实践
优化建议
- 定期更新AI分类模型以提高准确性
- 根据邮件量调整处理批次大小
- 设置合理的分类置信度阈值
- 定期清理过期的分类规则
安全注意事项
- 妥善保管API密钥和认证信息
- 限制工作流的访问权限
- 定期审查处理日志
- 启用双因素认证保护Gmail账户
性能优化
- 使用增量处理减少重复工作
- 缓存频繁访问的数据
- 并行处理多个邮件分类任务
- 监控系统资源使用情况
故障排除
常见问题
邮件未被正确分类
检查AI分类器的置信度阈值设置,适当降低阈值或更新训练数据。
Gmail认证失败
确认Google API凭证有效且具有正确的权限范围,重新进行OAuth授权。
调试技巧
- 启用详细日志记录查看每个步骤的执行情况
- 使用测试邮件验证分类逻辑
- 检查网络连接和API服务状态
- 逐步执行工作流定位问题节点
错误处理
工作流包含以下错误处理机制:
- 网络超时自动重试(最多3次)
- API错误记录和告警
- 处理失败邮件的隔离机制
- 异常情况下的回滚操作