Spotify DJ AI
中級
これはMiscellaneous分野の自動化ワークフローで、12個のノードを含みます。主にCode, Spotify, ManualTrigger, SplitInBatchesなどのノードを使用。 自動Spotifyプレイリスト整理ツール - 人気順で音楽をキューにする
前提条件
- •特別な前提条件なし、インポートしてすぐに使用可能
カテゴリー
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
"id": "Q7bb75lt3cXobMuU",
"meta": {
"instanceId": "93a2dbaed1b1d92e0b6ebb49a18663033f61e6c9c2b71ef1849cf7de2fad9f23",
"templateCredsSetupCompleted": true
},
"name": "Spotify DJ AI",
"tags": [],
"nodes": [
{
"id": "cc585aa3-5d73-4032-adf7-e7a40e050963",
"name": "「Execute workflow」クリック時",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-336,
-16
],
"parameters": {},
"typeVersion": 1
},
{
"id": "0f1db10b-3c41-449c-aa59-bf19929f3ac6",
"name": "ユーザーのプレイリストを取得",
"type": "n8n-nodes-base.spotify",
"position": [
-64,
-16
],
"parameters": {
"resource": "playlist",
"operation": "getUserPlaylists",
"returnAll": true
},
"typeVersion": 1
},
{
"id": "d7083e5b-9233-4177-afea-a64f801a7698",
"name": "キューに曲を追加",
"type": "n8n-nodes-base.spotify",
"position": [
1296,
0
],
"parameters": {
"id": "=spotify:track:{{ $json.id }}"
},
"typeVersion": 1
},
{
"id": "9b6865cb-44ef-4c3e-a03d-0f81eafd6241",
"name": "URIまたはIDでプレイリストのトラックを取得",
"type": "n8n-nodes-base.spotify",
"position": [
496,
-16
],
"parameters": {
"id": "{{ $json.uri }}",
"resource": "playlist",
"operation": "get"
},
"typeVersion": 1
},
{
"id": "eb38ca65-09e1-4440-a426-57e11268ed28",
"name": "アイテムをループ処理",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1008,
-16
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "11b1ab8e-f4ed-4a61-92b3-74286425f878",
"name": "クリーンアップと重複排除",
"type": "n8n-nodes-base.code",
"position": [
224,
-16
],
"parameters": {
"jsCode": "// 1) items[0].json might be an array of playlists\n// 2) or each item in items[] might already represent a playlist (items[].json)\nconst source = Array.isArray(items[0]?.json)\n ? items[0].json // Case 1: The first item's JSON is already an array → use it directly\n : items.map(i => i.json); // Case 2: Each item is a separate playlist → collect them all\n\n// Keep only the relevant fields: name, uri, and total track count\nconst minimal = source\n .map(p => ({\n name: p?.name, // Playlist name\n uri: p?.uri, // Spotify URI (unique identifier)\n total: p?.tracks?.total ?? null, // Total number of tracks (null if not available)\n }))\n .filter(p => p.name && p.uri); // Exclude incomplete entries\n\n// Deduplicate by URI (optional but recommended)\nconst seen = new Set();\nconst dedup = minimal.filter(p => (\n seen.has(p.uri) // If we've already seen this URI → skip it\n ? false\n : (seen.add(p.uri), true) // Otherwise, mark as seen and keep it\n));\n\n// Return the result formatted for n8n\nreturn dedup.map(j => ({ json: j })); // n8n expects an array of { json: ... } objects"
},
"typeVersion": 2
},
{
"id": "71d6e171-5d97-45b6-b462-39f6502ae39c",
"name": "プレイリスト再編成ツール",
"type": "n8n-nodes-base.code",
"position": [
752,
-16
],
"parameters": {
"jsCode": "// ID cible pris dynamiquement depuis le 1er item\nconst targetId = items[0]?.json?.id;\n\nconst processedPlaylists = new Set(); // évite de retraiter la même playlist\nconst seenTrackIds = new Set(); // évite les doublons de tracks\nconst out = [];\n\nfor (const item of items) {\n const pl = item.json;\n if (!pl || pl.id !== targetId) continue;\n\n // Si on a déjà traité cette playlist, on skip\n if (processedPlaylists.has(pl.id)) continue;\n processedPlaylists.add(pl.id);\n\n const tracks = pl?.tracks?.items ?? [];\n for (const t of tracks) {\n const tr = t?.track;\n const tid = tr?.id;\n if (!tid) continue; // skip si pas d'id (local/null)\n if (seenTrackIds.has(tid)) continue; // déjà vu → skip\n seenTrackIds.add(tid);\n\n out.push({\n playlistId: pl.id,\n playlistName: pl.name,\n id: tid,\n name: tr?.name,\n popularity: tr?.popularity ?? -1,\n artists: (tr?.artists ?? []).map(a => a.name).join(\", \"),\n album: tr?.album?.name,\n added_at: t.added_at,\n url: tr?.external_urls?.spotify,\n });\n }\n}\n\n// Tri ASC popularité (valeurs manquantes en fin)\nout.sort((a, b) => {\n const pa = a.popularity ?? -1;\n const pb = b.popularity ?? -1;\n if (pa === -1 && pb !== -1) return 1;\n if (pb === -1 && pa !== -1) return -1;\n return pa - pb;\n});\n\n// Format n8n\nreturn out.map(j => ({ json: j }));"
},
"typeVersion": 2
},
{
"id": "13679add-3de9-4411-932f-f34818ce9f6f",
"name": "付箋",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
-128
],
"parameters": {
"height": 368,
"content": "## This node retrieve all your playlist"
},
"typeVersion": 1
},
{
"id": "db178070-9da6-443a-b4ad-553ea73a724b",
"name": "付箋1",
"type": "n8n-nodes-base.stickyNote",
"position": [
128,
-208
],
"parameters": {
"width": 288,
"height": 448,
"content": "## This node clean and deduplicate the previous output. \n\n**It displays a list of all your playlists with their ids**"
},
"typeVersion": 1
},
{
"id": "68cbf32b-8650-493c-8fb3-99cd1395d50a",
"name": "付箋2",
"type": "n8n-nodes-base.stickyNote",
"position": [
432,
-128
],
"parameters": {
"width": 224,
"height": 368,
"content": "## This node extract all the song\n"
},
"typeVersion": 1
},
{
"id": "3f9a5db7-9e26-498a-9ca1-b3285f60eb41",
"name": "付箋3",
"type": "n8n-nodes-base.stickyNote",
"position": [
688,
-192
],
"parameters": {
"width": 224,
"height": 432,
"content": "## This node reorganize your playlist sorting by popularity"
},
"typeVersion": 1
},
{
"id": "4b587aaa-af95-4bb2-9cf1-b48d50ff40ca",
"name": "付箋4",
"type": "n8n-nodes-base.stickyNote",
"position": [
928,
-192
],
"parameters": {
"width": 544,
"height": 432,
"content": "## This loop add songs in queue so you can enjoy it for your evening :)"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "4c44b96e-1190-4e31-86aa-47231c0e6d86",
"connections": {
"eb38ca65-09e1-4440-a426-57e11268ed28": {
"main": [
[],
[
{
"node": "d7083e5b-9233-4177-afea-a64f801a7698",
"type": "main",
"index": 0
}
]
]
},
"11b1ab8e-f4ed-4a61-92b3-74286425f878": {
"main": [
[
{
"node": "9b6865cb-44ef-4c3e-a03d-0f81eafd6241",
"type": "main",
"index": 0
}
]
]
},
"71d6e171-5d97-45b6-b462-39f6502ae39c": {
"main": [
[
{
"node": "eb38ca65-09e1-4440-a426-57e11268ed28",
"type": "main",
"index": 0
}
]
]
},
"d7083e5b-9233-4177-afea-a64f801a7698": {
"main": [
[
{
"node": "eb38ca65-09e1-4440-a426-57e11268ed28",
"type": "main",
"index": 0
}
]
]
},
"0f1db10b-3c41-449c-aa59-bf19929f3ac6": {
"main": [
[
{
"node": "11b1ab8e-f4ed-4a61-92b3-74286425f878",
"type": "main",
"index": 0
}
]
]
},
"9b6865cb-44ef-4c3e-a03d-0f81eafd6241": {
"main": [
[
{
"node": "71d6e171-5d97-45b6-b462-39f6502ae39c",
"type": "main",
"index": 0
}
]
]
},
"cc585aa3-5d73-4032-adf7-e7a40e050963": {
"main": [
[
{
"node": "0f1db10b-3c41-449c-aa59-bf19929f3ac6",
"type": "main",
"index": 0
}
]
]
}
}
}よくある質問
このワークフローの使い方は?
上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。
このワークフローはどんな場面に適していますか?
中級 - その他
有料ですか?
このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。
関連ワークフロー
GPT-5 nanoとYoast SEOでWordPress SEO最適化を自動化
GPT-5 nanoとYoast SEOを使って、WordPressのSEO最適化を自動化
Set
Code
Gmail
+
Set
Code
Gmail
35 ノードOriol Seguí
その他
Google MapsレビューをGoogleスプレッドシートに同期
SerpApiを利用したGoogle MapsレビューからGoogle表格への同期
If
Set
Code
+
If
Set
Code
22 ノードSerpApi
市場調査
複数のExcelファイルをサマリページ付きのマルチシートファイルにマージ
複数のExcelファイルをサマリーページ付きのマルチシートファイルに結合
Code
Aggregate
Manual Trigger
+
Code
Aggregate
Manual Trigger
11 ノードSimone
その他
Google GeminiとGoogleスプレッドシートを使用したShopify製品AIブログジェネレーター
GPT-4oとGoogleシートを使用したShopify製品AIブログジェネレーター
If
Code
Limit
+
If
Code
Limit
22 ノードMANISH KUMAR
その他
タロットカード占い
GPT と Blooio に基づく iMessage タロット占いシステム
If
Code
Webhook
+
If
Code
Webhook
19 ノードDavid Harvey
その他
あなたのブログのトピックです
GPT、Leonardo AI、WordPressを使って自動のにブログ記事を生成して投稿する
If
Code
Wait
+
If
Code
Wait
26 ノードDean Gallop
コンテンツ作成
ワークフロー情報
難易度
中級
ノード数12
カテゴリー1
ノードタイプ5
作成者
Arthur Dimeglio
@wakizaraFormer data engineer, now full-time automation creator. I design systems that create, talk, and think
外部リンク
n8n.ioで表示 →
このワークフローを共有