Workflow n8n

Automatisation Spotify avec n8n : synchronisation de playlists

Ce workflow n8n a pour objectif de synchroniser automatiquement les playlists Spotify avec une base de données Supabase. Dans un contexte où la gestion des playlists peut rapidement devenir complexe, ce workflow permet de s'assurer que toutes les musiques souhaitées sont présentes dans la playlist tout en supprimant celles qui ne le sont plus. Le processus commence par un déclencheur programmé qui s'exécute chaque jour à midi. Ensuite, il récupère un instantané de la playlist Spotify et compare cet instantané avec les données présentes dans Supabase. Si des différences sont détectées, le workflow met à jour les entrées dans la base de données en marquant les musiques à supprimer et en ajoutant de nouvelles musiques. En parallèle, il utilise des appels API vers YouTube pour rechercher des vidéos correspondantes aux musiques et les ajouter à la playlist. Les notifications peuvent également être envoyées via Discord pour informer l'utilisateur des mises à jour effectuées. Grâce à cette automatisation n8n, les utilisateurs peuvent gagner un temps précieux en évitant les mises à jour manuelles et en assurant une cohérence entre leurs différentes plateformes musicales. Ce workflow est idéal pour les créateurs de contenu et les gestionnaires de playlists qui souhaitent maintenir une présence musicale à jour et engageante. Tags clés : automatisation, Spotify, Supabase.

Catégorie: Scheduled · Tags: automatisation, Spotify, Supabase, YouTube, Discord0

Vue d'ensemble du workflow n8n

Schéma des nœuds et connexions de ce workflow n8n, généré à partir du JSON n8n.

Détail des nœuds du workflow n8n

  • Get playlist snapshot

    Récupère un instantané d'une playlist depuis Spotify.

  • Get playlist snapshot1

    Récupère un instantané d'une playlist depuis Spotify.

  • If different snapshot

    Vérifie si l'instantané récupéré est différent de l'ancien.

  • Get all musics

    Récupère toutes les musiques d'une table dans Supabase.

  • Update to_delete to true

    Met à jour le champ 'to_delete' à vrai dans Supabase.

  • Add music

    Ajoute une nouvelle musique dans une table de Supabase.

  • Compare Datasets

    Compare deux ensembles de données en fonction de champs spécifiques.

  • Spotify

    Effectue une opération sur une ressource Spotify.

  • No Operation, do nothing

    N'effectue aucune opération, servant de noeud de passage.

  • Get all musics not in youtube playlist

    Récupère toutes les musiques qui ne sont pas dans une playlist YouTube.

  • Every day at noon

    Déclenche le workflow tous les jours à midi.

  • Every day at noon + 1mn

    Déclenche le workflow tous les jours à midi plus une minute.

  • Every hour

    Déclenche le workflow chaque heure.

  • Wait 1 hour

    Met le workflow en pause pendant une heure.

  • variables

    Définit des variables dans le workflow.

  • Search video

    Recherche des vidéos sur YouTube selon des filtres spécifiés.

  • Get video duration

    Récupère la durée d'une vidéo YouTube.

  • Loop Over Items

    Divise les éléments en lots pour un traitement ultérieur.

  • If video duration ~= music duration

    Vérifie si la durée de la vidéo est approximativement égale à celle de la musique.

  • Add music to playlist

    Ajoute une musique à une playlist sur YouTube.

  • Add youtube id to row

    Ajoute l'ID YouTube à une ligne dans Supabase.

  • Discord

    Envoie un message sur Discord avec le contenu spécifié.

  • Discord1

    Envoie un message sur Discord avec le contenu spécifié.

  • Set youtube id to NOTFOUND if no matching

    Met l'ID YouTube à 'NOTFOUND' si aucune correspondance n'est trouvée.

  • Aggregate

    Effectue une agrégation sur les données selon des options spécifiées.

  • data

    Définit des données dans le workflow.

  • variables2

    Définit des variables supplémentaires dans le workflow.

  • variables1

    Définit des variables supplémentaires dans le workflow.

  • Loop Over Items1

    Divise les éléments en lots pour un traitement ultérieur.

  • data1

    Définit des données supplémentaires dans le workflow.

  • Get playlist items

    Récupère les éléments d'une playlist YouTube.

  • Playlist items to be deleted

    Compare les éléments de la playlist pour déterminer ceux à supprimer.

  • Get all musics that should be in playlist

    Récupère toutes les musiques qui devraient être dans la playlist.

  • Remove Duplicates

    Supprime les doublons dans les données.

  • Remove video from playlist

    Supprime une vidéo d'une playlist YouTube.

  • Check for deleted videos

    Vérifie les vidéos supprimées en comparant les ensembles de données.

  • Set youtube_video_id to null

    Met l'ID de la vidéo YouTube à null dans Supabase.

  • Get all musics to be deleted

    Récupère toutes les musiques à supprimer dans Supabase.

  • Delete music

    Supprime une musique de la table dans Supabase.

  • Every day at midnight

    Déclenche le workflow tous les jours à minuit.

  • variables3

    Définit des variables supplémentaires dans le workflow.

  • Reset NOTFOUND id to NULL

    Réinitialise l'ID 'NOTFOUND' à NULL dans Supabase.

  • variables4

    Définit des variables supplémentaires dans le workflow.

  • Every month

    Déclenche le workflow chaque mois.

  • Sticky Note

    Crée une note autocollante avec le contenu et les dimensions spécifiées.

  • Sticky Note1

    Crée une note autocollante avec le contenu et les dimensions spécifiées.

  • Sticky Note2

    Crée une note autocollante avec le contenu et les dimensions spécifiées.

  • Sticky Note3

    Crée une note autocollante avec le contenu et les dimensions spécifiées.

  • Sticky Note4

    Crée une note autocollante avec le contenu et les dimensions spécifiées.

Inscris-toi pour voir l'intégralité du workflow

Inscription gratuite

S'inscrire gratuitementBesoin d'aide ?
{
  "meta": {
    "instanceId": "173bb893d2008dedab0ccfa3d7dba2c858a9076afa8f7dce6ebaa9c817262edf"
  },
  "nodes": [
    {
      "id": "c9e46f43-b159-42ca-945d-7aa8546e5fa2",
      "name": "Get playlist snapshot",
      "type": "n8n-nodes-base.spotify",
      "position": [
        380,
        1580
      ],
      "parameters": {
        "id": "={{ $json.spotify_playlist_id }}",
        "resource": "playlist",
        "operation": "get"
      },
      "typeVersion": 1
    },
    {
      "id": "73c2303e-24c2-4026-95f6-825e5d08baa4",
      "name": "Get playlist snapshot1",
      "type": "n8n-nodes-base.spotify",
      "position": [
        720,
        1580
      ],
      "parameters": {
        "id": "={{ $('variables').item.json.spotify_playlist_id }}",
        "resource": "playlist",
        "operation": "get"
      },
      "typeVersion": 1
    },
    {
      "id": "bb71003b-0945-4333-91d3-662290dfb42d",
      "name": "If different snapshot",
      "type": "n8n-nodes-base.if",
      "position": [
        900,
        1580
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2606c811-7c92-4c61-b99e-be2aaced10dd",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $('Get playlist snapshot').item.json.snapshot_id }}",
              "rightValue": "={{ $json.snapshot_id }}"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "4894d2a7-dda9-430f-849a-d2368daa0aab",
      "name": "Get all musics",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1220,
        1600
      ],
      "parameters": {
        "tableId": "={{ (() => { try { return $('variables').item.json.supabase_table_name } catch(e) {} try { return $('variables2').item.json.supabase_table_name } catch(e) {} return undefined; })() }}",
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "e854147b-a5fa-400d-8440-bda25a0226b2",
      "name": "Update to_delete to true",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1700,
        1620
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.id }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "={{ (() => { try { return $('variables').item.json.supabase_table_name } catch(e) {} try { return $('variables2').item.json.supabase_table_name } catch(e) {} return undefined; })() }}",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "to_delete",
              "fieldValue": "TRUE"
            }
          ]
        },
        "operation": "update"
      },
      "typeVersion": 1
    },
    {
      "id": "2425db39-487b-4b61-9b61-9ae00067bbca",
      "name": "Add music",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1700,
        1400
      ],
      "parameters": {
        "tableId": "={{ (() => { try { return $('variables').item.json.supabase_table_name } catch(e) {} try { return $('variables2').item.json.supabase_table_name } catch(e) {} return undefined; })() }}\n",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "id",
              "fieldValue": "={{ $json.track.id }}"
            },
            {
              "fieldId": "title",
              "fieldValue": "={{ $json.track.name }}"
            },
            {
              "fieldId": "artist",
              "fieldValue": "={{ $json.track.artists[0].name }}"
            },
            {
              "fieldId": "duration",
              "fieldValue": "={{ $json.track.duration_ms }}"
            }
          ]
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "1c28ae15-9049-4ac7-9a7f-dcd094a60ace",
      "name": "Compare Datasets",
      "type": "n8n-nodes-base.compareDatasets",
      "position": [
        1460,
        1540
      ],
      "parameters": {
        "options": {
          "skipFields": "title, artists, duration, youtube_video_id, added_at, added_by, is_local, primary_color, video_thumbnail,"
        },
        "mergeByFields": {
          "values": [
            {
              "field1": "track.id",
              "field2": "id"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "af89d454-1071-42c1-9455-d64e02ae14b7",
      "name": "Spotify",
      "type": "n8n-nodes-base.spotify",
      "position": [
        1220,
        1440
      ],
      "parameters": {
        "id": "={{ (() => { try { return $('variables').item.json.spotify_playlist_id } catch(e) {} try { return $('variables2').item.json.spotify_playlist_id } catch(e) {} return undefined; })() }}",
        "resource": "playlist",
        "operation": "getTracks",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "b924ad92-b1f2-41d5-b662-1e64ad0cc6dc",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1220,
        1800
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "2665982e-68ac-4a83-988d-78d07a0d6c75",
      "name": "Get all musics not in youtube playlist",
      "type": "n8n-nodes-base.supabase",
      "position": [
        400,
        960
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "youtube_video_id",
              "keyValue": "null",
              "condition": "is"
            },
            {
              "keyName": "to_delete",
              "keyValue": "FALSE",
              "condition": "is"
            }
          ]
        },
        "tableId": "={{ $json.supabase_table_name }}",
        "matchType": "allFilters",
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "6ea4ae11-9889-4ae2-904f-614ca4118b8a",
      "name": "Every day at noon",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        20,
        1220
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 12
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8e4b14f4-a7ec-45dd-9b24-8c86889fd135",
      "name": "Every day at noon + 1mn",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        20,
        960
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 12,
              "triggerAtMinute": 1
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "16242250-5f3f-49f9-b6cb-7302bc11765a",
      "name": "Every hour",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        20,
        1580
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6b6784ce-e236-40ca-b85c-1b0f0abdd7a5",
      "name": "Wait 1 hour",
      "type": "n8n-nodes-base.wait",
      "position": [
        560,
        1580
      ],
      "webhookId": "7d71bd21-a70a-47d5-bde5-299299fdb84e",
      "parameters": {
        "unit": "hours",
        "amount": 1
      },
      "typeVersion": 1.1
    },
    {
      "id": "746e7e33-00ba-4e92-a877-3619e14fa718",
      "name": "variables",
      "type": "n8n-nodes-base.set",
      "position": [
        200,
        1580
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "89615f0d-1f93-4416-bab4-1c69479e135e",
              "name": "spotify_playlist_id",
              "type": "string",
              "value": "4fjIxvQt8aQrQZs4XqvsmR"
            },
            {
              "id": "be22a9a9-58be-4275-aac5-c0d95ba91cfd",
              "name": "youtube_playlist_id",
              "type": "string",
              "value": "PLjmwnzu1gWRsnW6icKeUyvbaK9-Cs8oom"
            },
            {
              "id": "3536712c-8881-4089-98aa-e25516fea624",
              "name": "supabase_table_name",
              "type": "string",
              "value": "musics"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0006e12a-fea6-408d-bcf5-6d0a726322b1",
      "name": "Search video",
      "type": "n8n-nodes-base.youTube",
      "position": [
        2500,
        1420
      ],
      "parameters": {
        "limit": 5,
        "filters": {
          "q": "={{ $json.title }} {{ '-' }} {{ $json.artist }}"
        },
        "options": {},
        "resource": "video"
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "24f5a360-fa93-4942-baea-baf134dd40a3",
      "name": "Get video duration",
      "type": "n8n-nodes-base.youTube",
      "position": [
        3020,
        1420
      ],
      "parameters": {
        "part": [
          "contentDetails",
          "snippet"
        ],
        "options": {},
        "videoId": "={{ $json.id.videoId }}",
        "resource": "video",
        "operation": "get"
      },
      "typeVersion": 1
    },
    {
      "id": "2027d659-01d6-4dd0-bfdc-c92f65b021bc",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2840,
        1420
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "3e843f70-bc17-4749-86ba-11f5a0e98e7d",
      "name": "If video duration ~= music duration",
      "type": "n8n-nodes-base.if",
      "position": [
        3240,
        1420
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e8ed16f1-f0c6-4ef4-bf09-8ecb6fbf44cb",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.contentDetails.duration.match(/(\\d+)(?=[MHS])/g).reduce((acc, time, i) => acc + time * [60000, 1000, 1][i], 0) }}",
              "rightValue": "={{ $('data1').first().json.duration - 5000}}"
            },
            {
              "id": "c4317b05-69bb-4244-ac8a-4cc51113a63b",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.contentDetails.duration.match(/(\\d+)(?=[MHS])/g).reduce((acc, time, i) => acc + time * [60000, 1000, 1][i], 0) }}",
              "rightValue": "={{ $('data1').first().json.duration + 20000}}"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "a21e462c-72c9-4e77-99dc-1046acbaa998",
      "name": "Add music to playlist",
      "type": "n8n-nodes-base.youTube",
      "position": [
        3460,
        1400
      ],
      "parameters": {
        "options": {},
        "videoId": "={{ $('Get video duration').item.json.id }}",
        "resource": "playlistItem",
        "playlistId": "PLjmwnzu1gWRsnW6icKeUyvbaK9-Cs8oom"
      },
      "typeVersion": 1
    },
    {
      "id": "68fc1180-ce51-496a-909f-a652bb43febc",
      "name": "Add youtube id to row",
      "type": "n8n-nodes-base.supabase",
      "position": [
        3640,
        1400
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $('data1').first().json.id }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "={{ $('data1').first().json.supabase_table_name }}",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "youtube_video_id",
              "fieldValue": "={{ $json.snippet.resourceId.videoId }}"
            }
          ]
        },
        "operation": "update"
      },
      "typeVersion": 1
    },
    {
      "id": "3611f50e-3000-46e9-b145-109251c3a12d",
      "name": "Discord",
      "type": "n8n-nodes-base.discord",
      "position": [
        4040,
        1400
      ],
      "parameters": {
        "content": "=Added : {{ $json.title }} (https://www.youtube.com/watch?v={{ $json.youtube_video_id }})",
        "options": {},
        "authentication": "webhook"
      },
      "typeVersion": 2
    },
    {
      "id": "bd6438b2-8628-4bb9-be34-03785458f194",
      "name": "Discord1",
      "type": "n8n-nodes-base.discord",
      "position": [
        4040,
        1020
      ],
      "parameters": {
        "content": "=No match for : {{ $('data1').first().json.title }}",
        "options": {},
        "authentication": "webhook"
      },
      "typeVersion": 2
    },
    {
      "id": "97ea9e76-96a5-48de-afe3-f81dbe7e431b",
      "name": "Set youtube id to NOTFOUND if no matching",
      "type": "n8n-nodes-base.supabase",
      "position": [
        3320,
        1020
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $('data1').first().json.id }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "={{ $('data1').first().json.supabase_table_name }}",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "youtube_video_id",
              "fieldValue": "NOTFOUND"
            }
          ]
        },
        "matchType": "allFilters",
        "operation": "update"
      },
      "typeVersion": 1
    },
    {
      "id": "acb1e31e-5f17-4092-b357-b0b255a4d15f",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        3060,
        1220
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "2db8c163-bf26-445f-9339-9e387cf22286",
      "name": "If no result",
      "type": "n8n-nodes-base.if",
      "position": [
        2660,
        1420
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "49a188bb-3cc8-4a8d-babf-f591c2e72094",
              "operator": {
                "type": "object",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "5eea12d7-c313-4176-b85a-54f631e3a98f",
      "name": "data",
      "type": "n8n-nodes-base.set",
      "position": [
        1900,
        1340
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3622fecd-9a77-4cd4-ab02-6997cd83362d",
              "name": "title",
              "type": "string",
              "value": "={{ $json.title }}"
            },
            {
              "id": "76232c1e-f4de-41c4-837f-d20bd2bcfca2",
              "name": "artist",
              "type": "string",
              "value": "={{ $json.artist }}"
            },
            {
              "id": "01c3e160-f1ce-42e9-9010-a8ac806bb029",
              "name": "duration",
              "type": "number",
              "value": "={{ $json.duration }}"
            },
            {
              "id": "65f29ba5-28b4-4b50-8d38-540236229312",
              "name": "id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "d6b26130-454c-4625-bdf2-688498d61321",
              "name": "supabase_table_name",
              "type": "string",
              "value": "={{ (() => { try { return $('variables').item.json.supabase_table_name } catch(e) {} try { return $('variables1').item.json.supabase_table_name } catch(e) {} try { return $('variables2').item.json.supabase_table_name } catch(e) {} return undefined; })() }}\n"
            },
            {
              "id": "9d82b3d1-b9f9-4dc1-9e7f-ec2a3c97bfe1",
              "name": "youtube_playlist_id",
              "type": "string",
              "value": "={{ (() => { try { return $('variables').item.json.youtube_playlist_id } catch(e) {} try { return $('variables1').item.json.youtube_playlist_id } catch(e) {} try { return $('variables2').item.json.youtube_playlist_id } catch(e) {} return undefined; })() }}\n"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "73055f49-c804-4b54-a16f-c795f1295069",
      "name": "variables2",
      "type": "n8n-nodes-base.set",
      "position": [
        560,
        1220
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "89615f0d-1f93-4416-bab4-1c69479e135e",
              "name": "spotify_playlist_id",
              "type": "string",
              "value": "4fjIxvQt8aQrQZs4XqvsmR"
            },
            {
              "id": "be22a9a9-58be-4275-aac5-c0d95ba91cfd",
              "name": "youtube_playlist_id",
              "type": "string",
              "value": "PLjmwnzu1gWRsnW6icKeUyvbaK9-Cs8oom"
            },
            {
              "id": "3536712c-8881-4089-98aa-e25516fea624",
              "name": "supabase_table_name",
              "type": "string",
              "value": "musics"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "4f7da7fb-5b18-4b44-9aad-d24c2e1409cc",
      "name": "variables1",
      "type": "n8n-nodes-base.set",
      "position": [
        200,
        960
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "89615f0d-1f93-4416-bab4-1c69479e135e",
              "name": "spotify_playlist_id",
              "type": "string",
              "value": "4fjIxvQt8aQrQZs4XqvsmR"
            },
            {
              "id": "be22a9a9-58be-4275-aac5-c0d95ba91cfd",
              "name": "youtube_playlist_id",
              "type": "string",
              "value": "PLjmwnzu1gWRsnW6icKeUyvbaK9-Cs8oom"
            },
            {
              "id": "3536712c-8881-4089-98aa-e25516fea624",
              "name": "supabase_table_name",
              "type": "string",
              "value": "musics"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a814763e-d073-4984-986f-7c627bbe2269",
      "name": "Loop Over Items1",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2120,
        1400
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "5329c838-56bd-4d85-a789-7ded3a128d87",
      "name": "data1",
      "type": "n8n-nodes-base.set",
      "position": [
        2320,
        1420
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3622fecd-9a77-4cd4-ab02-6997cd83362d",
              "name": "title",
              "type": "string",
              "value": "={{ $json.title }}"
            },
            {
              "id": "76232c1e-f4de-41c4-837f-d20bd2bcfca2",
              "name": "artist",
              "type": "string",
              "value": "={{ $json.artist }}"
            },
            {
              "id": "01c3e160-f1ce-42e9-9010-a8ac806bb029",
              "name": "duration",
              "type": "number",
              "value": "={{ $json.duration }}"
            },
            {
              "id": "65f29ba5-28b4-4b50-8d38-540236229312",
              "name": "id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "d6b26130-454c-4625-bdf2-688498d61321",
              "name": "supabase_table_name",
              "type": "string",
              "value": "={{ $json.supabase_table_name }}"
            },
            {
              "id": "9d82b3d1-b9f9-4dc1-9e7f-ec2a3c97bfe1",
              "name": "youtube_playlist_id",
              "type": "string",
              "value": "={{ $json.youtube_playlist_id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "01039cab-f822-4cfc-996f-0e88923f9c14",
      "name": "Get playlist items",
      "type": "n8n-nodes-base.youTube",
      "position": [
        540,
        2600
      ],
      "parameters": {
        "options": {},
        "resource": "playlistItem",
        "operation": "getAll",
        "returnAll": true,
        "playlistId": "={{ $json.youtube_playlist_id }}"
      },
      "typeVersion": 1
    },
    {
      "id": "c12fb59f-ad15-4456-b827-f749a22f2f0c",
      "name": "Playlist items to be deleted",
      "type": "n8n-nodes-base.compareDatasets",
      "position": [
        840,
        2700
      ],
      "parameters": {
        "options": {
          "skipFields": "kind, etag, snippet, thumbnails, channelTitle, position, resourceId, contentDetails, status"
        },
        "mergeByFields": {
          "values": [
            {
              "field1": "snippet.resourceId.videoId",
              "field2": "youtube_video_id"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "57172162-a766-4c51-8249-e6e0632d1312",
      "name": "Get all musics that should be in playlist",
      "type": "n8n-nodes-base.supabase",
      "position": [
        540,
        2400
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "youtube_video_id",
              "keyValue": "={{ null }}",
              "condition": "neq"
            },
            {
              "keyName": "youtube_video_id",
              "keyValue": "NOTFOUND",
              "condition": "neq"
            }
          ]
        },
        "tableId": "={{ $json.supabase_table_name }}",
        "matchType": "allFilters",
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "88f01cff-33a2-4184-af92-80cf7dd6d28b",
      "name": "Remove Duplicates",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        1080,
        2700
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {},
        "fieldsToCompare": "different.youtube_video_id.inputB"
      },
      "typeVersion": 1.1
    },
    {
      "id": "e25d78cd-d3a9-4b24-8663-84344b6f0b68",
      "name": "Remove video from playlist",
      "type": "n8n-nodes-base.youTube",
      "position": [
        1240,
        2700
      ],
      "parameters": {
        "options": {},
        "resource": "playlistItem",
        "operation": "delete",
        "playlistItemId": "={{ $json.different.id.inputA }}"
      },
      "typeVersion": 1
    },
    {
      "id": "1420795b-fac4-47ac-8449-96ae39541c22",
      "name": "Check for deleted videos",
      "type": "n8n-nodes-base.compareDatasets",
      "position": [
        820,
        2480
      ],
      "parameters": {
        "options": {
          "skipFields": "kind, etag, snippet, thumbnails, channelTitle, position, resourceId, contentDetails, status"
        },
        "mergeByFields": {
          "values": [
            {
              "field1": "youtube_video_id",
              "field2": "contentDetails.videoId"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "fc2e2908-c491-4d45-87e4-a572a2f3e72a",
      "name": "Set youtube_video_id to null",
      "type": "n8n-nodes-base.supabase",
      "onError": "continueRegularOutput",
      "position": [
        1080,
        2440
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.id }}",
              "condition": "eq"
            },
            {
              "keyName": "youtube_video_id",
              "keyValue": "NOTFOUND",
              "condition": "neq"
            }
          ]
        },
        "tableId": "={{ $('variables3').item.json.supabase_table_name }}",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "youtube_video_id",
              "fieldValue": "={{ null }}"
            }
          ]
        },
        "matchType": "allFilters",
        "operation": "update"
      },
      "typeVersion": 1
    },
    {
      "id": "52523569-4347-477f-abe3-718b0177324a",
      "name": "Get all musics to be deleted",
      "type": "n8n-nodes-base.supabase",
      "position": [
        540,
        2820
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "to_delete",
              "keyValue": "TRUE",
              "condition": "is"
            },
            {
              "keyName": "youtube_video_id",
              "keyValue": "NOTFOUND",
              "condition": "neq"
            }
          ]
        },
        "tableId": "={{ $json.supabase_table_name }}",
        "matchType": "allFilters",
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "c1306c1e-07aa-46f9-970c-3e9ecb01638a",
      "name": "Delete music",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1400,
        2700
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "youtube_video_id",
              "keyValue": "={{ $('Get all musics to be deleted').item.json.youtube_video_id }}",
              "condition": "eq"
            },
            {
              "keyName": "to_delete",
              "keyValue": "true",
              "condition": "is"
            }
          ]
        },
        "tableId": "={{ $('variables3').item.json.supabase_table_name }}",
        "matchType": "allFilters",
        "operation": "delete"
      },
      "typeVersion": 1
    },
    {
      "id": "770083fa-6ac1-4dd9-929e-e30e933bbd95",
      "name": "Every day at midnight",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        40,
        2620
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "92e5e851-0c66-476e-bec8-a46fc96915ab",
      "name": "variables3",
      "type": "n8n-nodes-base.set",
      "position": [
        240,
        2620
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "89615f0d-1f93-4416-bab4-1c69479e135e",
              "name": "spotify_playlist_id",
              "type": "string",
              "value": "4fjIxvQt8aQrQZs4XqvsmR"
            },
            {
              "id": "be22a9a9-58be-4275-aac5-c0d95ba91cfd",
              "name": "youtube_playlist_id",
              "type": "string",
              "value": "PLjmwnzu1gWRsnW6icKeUyvbaK9-Cs8oom"
            },
            {
              "id": "3536712c-8881-4089-98aa-e25516fea624",
              "name": "supabase_table_name",
              "type": "string",
              "value": "musics"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "acde16fc-3fe3-453b-bffe-ead681e97046",
      "name": "Reset NOTFOUND id to NULL",
      "type": "n8n-nodes-base.supabase",
      "position": [
        420,
        3280
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "youtube_video_id",
              "keyValue": "NOTFOUND",
              "condition": "eq"
            }
          ]
        },
        "tableId": "={{ $json.supabase_table_name }}",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "youtube_video_id",
              "fieldValue": "={{ null }}"
            }
          ]
        },
        "operation": "update"
      },
      "typeVersion": 1
    },
    {
      "id": "62053829-3253-4a7c-b70f-ba6075df034b",
      "name": "variables4",
      "type": "n8n-nodes-base.set",
      "position": [
        220,
        3280
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "89615f0d-1f93-4416-bab4-1c69479e135e",
              "name": "spotify_playlist_id",
              "type": "string",
              "value": "4fjIxvQt8aQrQZs4XqvsmR"
            },
            {
              "id": "be22a9a9-58be-4275-aac5-c0d95ba91cfd",
              "name": "youtube_playlist_id",
              "type": "string",
              "value": "PLjmwnzu1gWRsnW6icKeUyvbaK9-Cs8oom"
            },
            {
              "id": "3536712c-8881-4089-98aa-e25516fea624",
              "name": "supabase_table_name",
              "type": "string",
              "value": "musics"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "9a205a87-f32a-49c1-8282-469777c83c9c",
      "name": "Every month",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        40,
        3280
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "months"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a40fa87c-71ae-4045-8285-91235f0cf1f0",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2040,
        780
      ],
      "parameters": {
        "color": 6,
        "width": 1780,
        "height": 980,
        "content": "# Match Spotify Tracks to YouTube Videos  \n\n## This part finds the best YouTube video for a Spotify track using the YouTube Data API v3. It searches with the track title and artist, retrieves the top 5 videos, and selects the first one with a duration within ±10% of the Spotify track length. The matched video is added to a YouTube playlist, and its ID is saved in the database.  \n\n## Operation:\n- ## Uses Spotify data (title + artist) for search.\n- ## Ensures duration accuracy (±10% tolerance).  \n- ## Automates playlist updates and database storage."
      },
      "typeVersion": 1
    },
    {
      "id": "b850a168-7fa4-417c-980c-da8fcf558cfb",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -20,
        1440
      ],
      "parameters": {
        "color": 4,
        "width": 1100,
        "height": 420,
        "content": "## Check for any modification in the spotify playlist with snapshot_id\n### If you want to change the checking interval, make sure to change the trigger AND the wait node\n"
      },
      "typeVersion": 1
    },
    {
      "id": "fe2aaa9f-e4de-4000-b535-3e351a643d01",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1360,
        1120
      ],
      "parameters": {
        "color": 3,
        "width": 960,
        "height": 1340,
        "content": "# Spotify to YouTube Playlist Synchronization\n## A workflow that maintains a YouTube playlist in sync with a Spotify playlist, featuring smart video matching and persistent synchronization.\n\n## Key Features\n- **One-way Sync**: Spotify playlist → YouTube playlist (additions and deletions\n- **Continuous Monitoring**: Automatic synchronization (every hour by default, but you can put any time you want)\n- **Smart Video Matching**: Considers video length and content relevance\n- **Auto-Recovery**: Automatically handles deleted YouTube videos\n- **Database Backup**: Persistent storage using Supabase\n\n## Prerequisites\n\n1. Supabase project with the following table structure:\n```sql\nCREATE TABLE IF NOT EXISTS musics (\n    id TEXT PRIMARY KEY,\n    title TEXT NOT NULL,\n    artist TEXT NOT NULL,\n    duration INT8 NOT NULL,\n    youtube_video_id TEXT,\n    to_delete BOOLEAN DEFAULT FALSE\n);\n```\n2. Empty YouTube playlist (recommended as duplicates are not handled)\n3. Configured credentials for YouTube, Spotify, and Supabase APIs\n4. Properly set variables in all \"variables\" nodes (variables, variables1, variables2, variables3, variables4 (all the same))\n5. Activate the workflow !\n\n## Workflow Components\n\n### Workflow 1: Main Sync Process\n1. **Change Detection**\n   - Monitors Spotify playlist for changes\n   - Compares database state with current playlist\n\n2. **Video Matching**\n   - Searches YouTube based on title, artist, and duration\n   - Evaluates top 5 results for best match\n   - Marks unmatched tracks with \"NOTFOUND\"\n   - Notifies user of successful matches and failures\n\n### Workflow 2: YouTube Maintenance\n- Monitors YouTube playlist for removed videos\n- Flags removed videos for re-search\n- Handles deletion of marked videos\n\n### Workflow 3: Recovery Process\n- Clears \"NOTFOUND\" flags periodically to re-search previously unmatched tracks\n\n## Implementation Notes\n- Workflows can be separated into different files for better monitoring\n- Recovery process ensures long-term playlist maintenance\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a86748bf-e52a-4d14-b940-d66a62de802e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1100,
        700
      ],
      "parameters": {
        "color": 5,
        "width": 920,
        "height": 1260,
        "content": "# Spotify-Database Synchronization\n\n## Operation:\n- ## Compares Spotify playlist tracks against database entries\n- ## Adds missing tracks to database\n- ## Marks database entries for deletion when removed from Spotify playlist"
      },
      "typeVersion": 1
    },
    {
      "id": "c58d3233-7059-4095-bae7-c0b451748c2f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -20,
        620
      ],
      "parameters": {
        "width": 800,
        "height": 800,
        "content": "# Daily Force Check\n\n## Forces daily comparison between Spotify playlist and database state, bypassing playlist modification checks. Essential for:\n- ## Initial setup of large playlists (manages YouTube API limits)\n- ## Processing pending tracks when playlist hasn't changed\n- ## Continuing sync attempts for unmatched tracks"
      },
      "typeVersion": 1
    },
    {
      "id": "cfea38bb-d8b2-48aa-9718-e5d2d36f52c7",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3840,
        780
      ],
      "parameters": {
        "color": 2,
        "width": 460,
        "height": 980,
        "content": "## Optional notifications (you can use the chat of your choice)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "fb6fa7af-a434-463a-a2d7-e78d0328033c",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        120
      ],
      "parameters": {
        "color": 7,
        "width": 4400,
        "height": 1880,
        "content": "# Workflow 1: Main Sync Process\n# 1. **Change Detection**\n   - ## Monitors Spotify playlist for changes\n   - ## Compares database state with current playlist\n\n# 2. **Video Matching**\n   - ## Searches YouTube based on title, artist, and duration\n   - ## Evaluates top 5 results for best match\n   - ## Marks unmatched tracks with \"NOTFOUND\"\n   - ## Notifies user of successful matches and failures"
      },
      "typeVersion": 1
    },
    {
      "id": "03e20125-37c8-4e40-98fd-9b4617eaab70",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        2200
      ],
      "parameters": {
        "color": 7,
        "width": 1740,
        "height": 800,
        "content": "# Workflow 2: YouTube Maintenance\n- ## Monitors YouTube playlist for removed videos\n- ## Flags removed videos for re-search\n- ## Handles deletion of marked videos\n"
      },
      "typeVersion": 1
    },
    {
      "id": "031c2984-96b1-4c60-9e24-a125619b204a",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        3080
      ],
      "parameters": {
        "color": 7,
        "width": 760,
        "height": 360,
        "content": "# Workflow 3: Recovery Process\n- ## Clears \"NOTFOUND\" flags periodically to re-search previously unmatched tracks"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "data": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "data1": {
      "main": [
        [
          {
            "node": "Search video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Spotify": {
      "main": [
        [
          {
            "node": "Compare Datasets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add music": {
      "main": [
        [
          {
            "node": "data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Set youtube id to NOTFOUND if no matching",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "variables": {
      "main": [
        [
          {
            "node": "Get playlist snapshot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every hour": {
      "main": [
        [
          {
            "node": "variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "variables1": {
      "main": [
        [
          {
            "node": "Get all musics not in youtube playlist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "variables2": {
      "main": [
        [
          {
            "node": "Spotify",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get all musics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "variables3": {
      "main": [
        [
          {
            "node": "Get all musics that should be in playlist",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get playlist items",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get all musics to be deleted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "variables4": {
      "main": [
        [
          {
            "node": "Reset NOTFOUND id to NULL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every month": {
      "main": [
        [
          {
            "node": "variables4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 1 hour": {
      "main": [
        [
          {
            "node": "Get playlist snapshot1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If no result": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search video": {
      "main": [
        [
          {
            "node": "If no result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get all musics": {
      "main": [
        [
          {
            "node": "Compare Datasets",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get video duration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compare Datasets": {
      "main": [
        [
          {
            "node": "Add music",
            "type": "main",
            "index": 0
          }
        ],
        [],
        [],
        [
          {
            "node": "Update to_delete to true",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items1": {
      "main": [
        [],
        [
          {
            "node": "data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every day at noon": {
      "main": [
        [
          {
            "node": "variables2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicates": {
      "main": [
        [
          {
            "node": "Remove video from playlist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get playlist items": {
      "main": [
        [
          {
            "node": "Playlist items to be deleted",
            "type": "main",
            "index": 0
          },
          {
            "node": "Check for deleted videos",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Get video duration": {
      "main": [
        [
          {
            "node": "If video duration ~= music duration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add music to playlist": {
      "main": [
        [
          {
            "node": "Add youtube id to row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add youtube id to row": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Discord",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every day at midnight": {
      "main": [
        [
          {
            "node": "variables3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get playlist snapshot": {
      "main": [
        [
          {
            "node": "Wait 1 hour",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If different snapshot": {
      "main": [
        [
          {
            "node": "Spotify",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get all musics",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get playlist snapshot1": {
      "main": [
        [
          {
            "node": "If different snapshot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every day at noon + 1mn": {
      "main": [
        [
          {
            "node": "variables1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for deleted videos": {
      "main": [
        [
          {
            "node": "Set youtube_video_id to null",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove video from playlist": {
      "main": [
        [
          {
            "node": "Delete music",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get all musics to be deleted": {
      "main": [
        [
          {
            "node": "Playlist items to be deleted",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Playlist items to be deleted": {
      "main": [
        [],
        [],
        [
          {
            "node": "Remove Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If video duration ~= music duration": {
      "main": [
        [
          {
            "node": "Add music to playlist",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get all musics not in youtube playlist": {
      "main": [
        [
          {
            "node": "data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get all musics that should be in playlist": {
      "main": [
        [
          {
            "node": "Check for deleted videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set youtube id to NOTFOUND if no matching": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Discord1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Pour qui est ce workflow ?

Ce workflow s'adresse aux créateurs de contenu, aux musiciens et aux gestionnaires de playlists qui utilisent Spotify et souhaitent automatiser la synchronisation de leurs musiques. Il est adapté aux équipes de marketing digital et aux utilisateurs ayant des compétences techniques intermédiaires.

Problème résolu

Avec ce workflow, les utilisateurs n'ont plus à se soucier de la mise à jour manuelle de leurs playlists Spotify. Il élimine les frustrations liées à la gestion des musiques, réduit le risque d'erreurs humaines lors de l'ajout ou de la suppression de titres, et garantit que les playlists restent à jour avec les dernières tendances. Les utilisateurs peuvent ainsi se concentrer sur la création de contenu plutôt que sur la gestion des playlists.

Étapes du workflow

Étape 1 : Le workflow est déclenché chaque jour à midi. Étape 2 : Il récupère un instantané de la playlist Spotify. Étape 3 : Les données de la playlist sont comparées avec celles de la base Supabase. Étape 4 : Si des différences sont trouvées, les musiques à supprimer sont marquées et les nouvelles musiques sont ajoutées. Étape 5 : Des recherches de vidéos sur YouTube sont effectuées pour chaque musique. Étape 6 : Les vidéos correspondantes sont ajoutées à la playlist YouTube. Étape 7 : Si aucune correspondance n'est trouvée, les entrées sont mises à jour dans Supabase pour indiquer qu'aucune vidéo n'a été trouvée.

Guide de personnalisation du workflow n8n

Pour personnaliser ce workflow, vous pouvez modifier les paramètres du déclencheur pour changer la fréquence d'exécution. Ajustez les identifiants de playlist Spotify et Supabase pour qu'ils correspondent à vos propres données. Vous pouvez également adapter les filtres de recherche dans le nœud 'Search video' pour cibler des vidéos spécifiques sur YouTube. Enfin, n'hésitez pas à personnaliser le contenu des messages envoyés via Discord pour qu'ils correspondent à votre style de communication.