Notification automatisée des abonnements YouTube, intégrant RSS et e-mail

Avancé

Ceci est unOtherworkflow d'automatisation du domainecontenant 18 nœuds.Utilise principalement des nœuds comme If, Filter, YouTube, SplitOut, EmailSend. Notifications automatisées des abonnements YouTube, intégrant le flux RSS et l'e-mail

Prérequis
  • Peut nécessiter les informations d'identification d'authentification de l'API cible

Catégorie

Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "meta": {
    "instanceId": "4a8c4d3ed2f4423694f8ac022d1c321551900c7ab47e0c03549acecec1ab4a89",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "a5292068-5ace-4372-9869-46100ae81b8f",
      "name": "Obtenir les détails de la vidéo",
      "type": "n8n-nodes-base.youTube",
      "notes": "Make a call to the YouTube API so that we have the thumbnail for the email and the duration to filter out shorts.",
      "position": [
        1000,
        -60
      ],
      "parameters": {
        "part": [
          "contentDetails",
          "snippet",
          "id"
        ],
        "options": {},
        "videoId": "={{ $json.id.replace(\"yt:video:\", \"\") }}",
        "resource": "video",
        "operation": "get"
      },
      "credentials": {
        "youTubeOAuth2Api": {
          "id": "5lD8Hahvq4r7Og0F",
          "name": "YouTube account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b9eb34aa-90c4-492a-a33e-37a32812fa32",
      "name": "Déclencheur planifié",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -840,
        -160
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 1,
              "triggerAtMinute": 47
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8f0dbe74-53e5-4b14-86f6-eb0f502c8471",
      "name": "Filtrer les shorts",
      "type": "n8n-nodes-base.if",
      "notes": "Sometime, some live broadcasts that are then posted as regular videos do not have a duration. That is why we check if `duration` is present in `contentDetails`.",
      "position": [
        1180,
        -60
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "5342ecc0-d764-4bef-8161-d1f571fcb931",
              "operator": {
                "type": "string",
                "operation": "notExists",
                "singleValue": true
              },
              "leftValue": "={{ $json.contentDetails.duration }}",
              "rightValue": "\"duration\""
            },
            {
              "id": "b82e3373-a28b-49bd-afa0-4f48cafe2bfe",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ Duration.fromISO($json.contentDetails.duration).as('seconds') }}",
              "rightValue": 61
            }
          ]
        }
      },
      "notesInFlow": false,
      "typeVersion": 2
    },
    {
      "id": "14d54ed0-f5c0-4992-af56-0af2d8973963",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -900,
        -340
      ],
      "parameters": {
        "color": 7,
        "width": 220,
        "height": 460,
        "content": "### Default frequency: every hour\nChanging it here is enough if you want to check for new videos at a higher or lower frequency. You don't have to edit anything else."
      },
      "typeVersion": 1
    },
    {
      "id": "c4acbb10-1f57-4934-a324-f26d0532767c",
      "name": "Note adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -660,
        -340
      ],
      "parameters": {
        "color": 5,
        "width": 880,
        "height": 460,
        "content": "### Get my subscriptions from the YouTube Data v3 API\nYou can expect to use 1 quota per 50 subscriptions per run, which is well within the 10 000/req a day allowed by default."
      },
      "typeVersion": 1
    },
    {
      "id": "4ae2d2f3-53b5-4431-90d8-06e41a6950e2",
      "name": "Note adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        -160
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "height": 280,
        "content": "### Get the 15 latest videos of each channel with RSS\nUsing the YouTube API instead would cost too many quotas to make it viable."
      },
      "typeVersion": 1
    },
    {
      "id": "48894d79-7e59-49fc-beb5-445fb5ca2ff6",
      "name": "Note adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        940,
        -160
      ],
      "parameters": {
        "color": 3,
        "width": 400,
        "height": 280,
        "content": "### Call YouTube's API for more data\nWe need the thumbnails for the email and the duration to filter out shorts."
      },
      "typeVersion": 1
    },
    {
      "id": "e3da3f97-138c-481e-a763-9a3c9e402928",
      "name": "Note adhésive4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1360,
        -160
      ],
      "parameters": {
        "color": 6,
        "width": 260,
        "height": 280,
        "content": "### Configure your email here\nTo go to the video from the email, simply click on the thumbnail."
      },
      "typeVersion": 1
    },
    {
      "id": "0d092c3d-b2e1-4468-a044-c6cf0f37672b",
      "name": "Obtenir les 15 dernières vidéos de chaque chaîne",
      "type": "n8n-nodes-base.rssFeedRead",
      "notes": "YouTube provides an RSS feed for each channel with the 15 latest videos.\nWe use this instead of the YouTube Data v3 API, as search requests cost a lot of \"quota points\" and would easily put us over the daily limit with just one workflow run.",
      "position": [
        540,
        -60
      ],
      "parameters": {
        "url": "=https://www.youtube.com/feeds/videos.xml?channel_id={{ $json.snippet.resourceId.channelId }}",
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "34823384-d8a5-415a-87ff-203d65aa9a75",
      "name": "Obtenir mes abonnements",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Get subscriptions from YouTube Data v3 API",
      "position": [
        -600,
        -160
      ],
      "parameters": {
        "url": "https://www.googleapis.com/youtube/v3/subscriptions",
        "options": {
          "pagination": {
            "pagination": {
              "parameters": {
                "parameters": [
                  {
                    "name": "pageToken",
                    "value": "={{ $response.body.nextPageToken }}"
                  }
                ]
              },
              "completeExpression": "={{ !('nextPageToken' in $response.body) }}",
              "paginationCompleteWhen": "other"
            }
          }
        },
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "mine",
              "value": "true"
            },
            {
              "name": "part",
              "value": "snippet,contentDetails"
            },
            {
              "name": "maxResults",
              "value": "50"
            }
          ]
        },
        "nodeCredentialType": "youTubeOAuth2Api"
      },
      "credentials": {
        "youTubeOAuth2Api": {
          "id": "5lD8Hahvq4r7Og0F",
          "name": "YouTube account"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "534e38f3-ac40-4194-8821-5926ee581605",
      "name": "Vérifier les erreurs",
      "type": "n8n-nodes-base.if",
      "position": [
        -400,
        -160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5972ff90-aa5a-470c-aa96-87138eb60565",
              "operator": {
                "type": "object",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.error }}",
              "rightValue": "error"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2d872c0f-30b9-4ffc-aba0-6644bf05d7bb",
      "name": "Conserver uniquement les chaînes avec des vidéos non visionnées",
      "type": "n8n-nodes-base.filter",
      "notes": "It's not a perfect indicator for new videos but helps reduce the amount of channels to process.",
      "position": [
        40,
        -60
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "4734ee8c-1655-47be-bd45-a9527aee2833",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.contentDetails.newItemCount }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c7bd97ec-47c1-40b4-955d-bf89d3cde330",
      "name": "Conserver uniquement les vidéos publiées depuis la dernière exécution",
      "type": "n8n-nodes-base.filter",
      "notes": "We dynamically figure out the last run's execution time through the settings of the \"Schedule Trigger\" node.",
      "position": [
        740,
        -60
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "65d905a2-c89e-41f3-a2cf-0d1a76c48d8e",
              "operator": {
                "type": "dateTime",
                "operation": "after"
              },
              "leftValue": "={{ $json.pubDate.toDateTime() }}",
              "rightValue": "={{ \n  $('Schedule Trigger').item.json.timestamp.toDateTime().minus(\n    $('Schedule Trigger').params.rule.interval[0].hoursInterval,\n    $('Schedule Trigger').params.rule.interval[0].field\n  ).toISO()\n}}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "72341b1f-a391-4210-b3ca-4e74ae1f2e1b",
      "name": "Envoyer un email pour chaque nouvelle vidéo",
      "type": "n8n-nodes-base.emailSend",
      "notes": "The expression in the HTML for the thumbnail simply selects the last element of the thumbnails array so that we get the best possible resolution thumbnail available.",
      "position": [
        1440,
        -60
      ],
      "webhookId": "44bf0e95-98e5-4b5b-a7c5-c802379ab3b0",
      "parameters": {
        "html": "=<h1 style=\"text-align: center;\">{{ $json.snippet.title }}</h1>\n<a href=\"https://www.youtube.com/watch?v={{ $json.id }}\">\n  <img src=\"{{ $json.snippet.thumbnails[Object.keys($json.snippet.thumbnails)[Object.keys($json.snippet.thumbnails).length - 1]].url }}\" alt=\"Watch on YouTube\" style=\"width:100%; height:auto; max-width:640px; display:block; margin: 10px auto;\">\n</a>",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.snippet.channelTitle }}",
        "toEmail": "My Name <to@email.com>",
        "fromEmail": "YouTube <from@email.com>"
      },
      "credentials": {
        "smtp": {
          "id": "ThrKm6bLUg1owKn1",
          "name": "SMTP account"
        }
      },
      "notesInFlow": false,
      "typeVersion": 2.1
    },
    {
      "id": "b82cfbd5-71e3-418f-9b6d-6d0ec007733a",
      "name": "Si la requête HTTP a échoué, lever l'erreur",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        -180,
        -260
      ],
      "parameters": {
        "errorMessage": "=Status code: {{ $json.error.code }}\nMessage: {{ $json.error.message }}"
      },
      "typeVersion": 1
    },
    {
      "id": "e89eca92-896f-46b5-8a4b-149d51682faa",
      "name": "Séparer les abonnements pour traitement individuel",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -180,
        -60
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "items"
      },
      "typeVersion": 1
    },
    {
      "id": "0e00fda6-1489-4c1a-8205-22e620a554c5",
      "name": "Note adhésive5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        -240
      ],
      "parameters": {
        "width": 220,
        "height": 360,
        "content": "## Manually filter out channels\nTo find the channel ID of a channel, click on the description → Share channel → Copy channel ID"
      },
      "typeVersion": 1
    },
    {
      "id": "bcc2e57c-23b2-42b7-81ab-cdd88b70b8a3",
      "name": "Filtrer les chaînes",
      "type": "n8n-nodes-base.filter",
      "notes": "Optional step",
      "position": [
        300,
        -60
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b27b14a9-c86c-4ebd-8a0f-4e7db722796e",
              "operator": {
                "type": "array",
                "operation": "notContains",
                "rightType": "any"
              },
              "leftValue": "={{[\n  \"exampleChannelId1\",\n  \"exampleChannelId2\"\n]}}",
              "rightValue": "={{ $json.snippet.resourceId.channelId }}"
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 2.2
    }
  ],
  "pinData": {},
  "connections": {
    "534e38f3-ac40-4194-8821-5926ee581605": {
      "main": [
        [
          {
            "node": "b82cfbd5-71e3-418f-9b6d-6d0ec007733a",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "e89eca92-896f-46b5-8a4b-149d51682faa",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b9eb34aa-90c4-492a-a33e-37a32812fa32": {
      "main": [
        [
          {
            "node": "34823384-d8a5-415a-87ff-203d65aa9a75",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8f0dbe74-53e5-4b14-86f6-eb0f502c8471": {
      "main": [
        [
          {
            "node": "72341b1f-a391-4210-b3ca-4e74ae1f2e1b",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "a5292068-5ace-4372-9869-46100ae81b8f": {
      "main": [
        [
          {
            "node": "8f0dbe74-53e5-4b14-86f6-eb0f502c8471",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bcc2e57c-23b2-42b7-81ab-cdd88b70b8a3": {
      "main": [
        [
          {
            "node": "0d092c3d-b2e1-4468-a044-c6cf0f37672b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "34823384-d8a5-415a-87ff-203d65aa9a75": {
      "main": [
        [
          {
            "node": "534e38f3-ac40-4194-8821-5926ee581605",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "72341b1f-a391-4210-b3ca-4e74ae1f2e1b": {
      "main": [
        []
      ]
    },
    "0d092c3d-b2e1-4468-a044-c6cf0f37672b": {
      "main": [
        [
          {
            "node": "c7bd97ec-47c1-40b4-955d-bf89d3cde330",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2d872c0f-30b9-4ffc-aba0-6644bf05d7bb": {
      "main": [
        [
          {
            "node": "bcc2e57c-23b2-42b7-81ab-cdd88b70b8a3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c7bd97ec-47c1-40b4-955d-bf89d3cde330": {
      "main": [
        [
          {
            "node": "a5292068-5ace-4372-9869-46100ae81b8f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e89eca92-896f-46b5-8a4b-149d51682faa": {
      "main": [
        [
          {
            "node": "2d872c0f-30b9-4ffc-aba0-6644bf05d7bb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - Autres

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds18
Catégorie1
Types de nœuds10
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34