Prévisions météo automatiques pour les voyages

Avancé

Ceci est unPersonal Productivityworkflow d'automatisation du domainecontenant 17 nœuds.Utilise principalement des nœuds comme If, Code, Wait, Telegram, HttpRequest. Envoi automatique des prévisions météorologiques des voyages vers Telegram depuis Google Calendar

Prérequis
  • Token Bot Telegram
  • Peut nécessiter les informations d'identification d'authentification de l'API cible
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": "e0abec5d9b13345e424c0dbbc512271f89fb17de3b268697e13a797de2271404"
  },
  "nodes": [
    {
      "id": "7df92b27-05c7-4c4a-9b2f-76883f0d8974",
      "name": "If1",
      "type": "n8n-nodes-base.if",
      "position": [
        624,
        -64
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8e217cc9-d842-4b92-a62b-b79e99a059df",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.sequence }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "40fe3671-d5ed-49fd-a342-f89df42f5657",
      "name": "Identifier les itinéraires",
      "type": "n8n-nodes-base.code",
      "position": [
        400,
        -64
      ],
      "parameters": {
        "jsCode": "const travelKeywords = ['trip', 'travel', 'vacation', 'flight', 'holiday'];\n\nreturn items.filter(item => {\n  const title = (item.json.summary || '').toLowerCase();\n  const description = (item.json.description || '').toLowerCase();\n\n  return travelKeywords.some(keyword => title.includes(keyword) || description.includes(keyword));\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "41df49be-15c4-4c83-8c69-6c8cc109ac34",
      "name": "Extraire les lieux",
      "type": "n8n-nodes-base.code",
      "position": [
        848,
        -64
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  const startDate = item.json.start.dateTime || item.json.start.date;\n  const endDate = item.json.end.dateTime || item.json.end.date;\n\n  // Initialize location variable\n  let location = null;\n\n  // Extract destination from summary first (e.g. \"Flight to Istanbul\")\n  const summary = (item.json.summary || '').toLowerCase();\n  const matchSummary = summary.match(/to ([a-zA-Z\\s,]+)/);\n  if (matchSummary && matchSummary[1]) {\n    location = matchSummary[1].trim();\n  }\n\n  // If no destination yet, try description (e.g. \"Flight from Mauritius (port Louis) to Istanbul\")\n  if (!location) {\n    const description = (item.json.description || '').toLowerCase();\n    // Match pattern after \"to \"\n    const matchDescription = description.match(/to ([a-zA-Z\\s,]+)/);\n    if (matchDescription && matchDescription[1]) {\n      location = matchDescription[1].trim();\n    }\n  }\n\n  // Only use the location field if above patterns fail or if location is not a \"from\" location\n  if (!location && item.json.location) {\n    const locLower = item.json.location.toLowerCase();\n    if (!locLower.startsWith('from ')) {  // Avoid departure locations starting with \"from\"\n      location = item.json.location;\n    }\n  }\n\n  // Final fallback if no location found\n  if (!location) {\n    location = null; // or 'YOUR_DEFAULT_TRIP_LOCATION'\n  }\n\n  return {\n    json: {\n      startDate,\n      endDate,\n      location\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "1c3d2277-df1f-4178-bdba-bff40a182c2d",
      "name": "Attendre",
      "type": "n8n-nodes-base.wait",
      "position": [
        1104,
        320
      ],
      "webhookId": "f1f55baf-71bd-4fc9-b81d-b3f0b8092d03",
      "parameters": {
        "resume": "specificTime",
        "dateTime": "={{ new Date(new Date($('Extract locations').item.json.startDate).getTime() - 24 * 60 * 60 * 1000).toISOString() }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "0d3f1ec2-2377-46e3-84bc-c303adddb825",
      "name": "Note adhésive4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        -400
      ],
      "parameters": {
        "width": 560,
        "height": 752,
        "content": "## How it works\nWhen a calendar event is created or updated, identified as trip, provides timely weather alerts and forecasts tailored to travel dates and locations.\n\n## Step-by-step\n\n📅 **Google Calendar Triggers** (Event Created/Updated): \nThe workflow starts immediately upon creation or update of any calendar event, enabling real-time detection of new or changed travel plans.\n\n✈ **Identify Trips & Extract Locations**: \nFilters these calendar events to detect travel-related trips by matching keywords such as \"trip,\" \"flight,\" or \"vacation\" in titles or descriptions and extract start and end dates & the trip destination.\n\n🌐 **Get Forecast & send it**: \nUsing Visual Crossing API (1000 free daily requests) fetches the detailed weather forecast and alert data for the trip location then formats the raw weather data into a readable summary 🌤️🌪🌀, and eventual severe weather alerts.\n\n📲 📧 **Send Forecast**: \nSends the forecast summary with alerts via Telegram to keep the user informed instantly.\n\n⌛**One day before the trip**: \nPauses the workflow until exactly one day before the trip start date, ensuring a timely second fetch when more accurate or updated weather data is available and the updated forecast is sent.\n\n## Optional\nYou can replace the Telegram node with email, WhatsApp, Slack, SMS notifications, or add multiple notification nodes to receive them across all desired channels."
      },
      "typeVersion": 1
    },
    {
      "id": "79b81985-724d-4208-a225-25ecde0851e7",
      "name": "Événement créé",
      "type": "n8n-nodes-base.googleCalendarTrigger",
      "position": [
        176,
        -160
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "eventCreated",
        "calendarId": {
          "__rl": true,
          "mode": "list",
          "value": "bara.razvan@gmail.com",
          "cachedResultName": "bara.razvan@gmail.com"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "38413099-7d19-4c06-bec7-a2d542607474",
      "name": "Événement mis à jour",
      "type": "n8n-nodes-base.googleCalendarTrigger",
      "position": [
        176,
        32
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "eventUpdated",
        "calendarId": {
          "__rl": true,
          "mode": "list",
          "value": "bara.razvan@gmail.com",
          "cachedResultName": "bara.razvan@gmail.com"
        }
      },
      "credentials": {},
      "typeVersion": 1
    },
    {
      "id": "1cac0052-349b-4ae2-8c4e-b1a63bd834f4",
      "name": "Envoyer la prévision",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1808,
        -64
      ],
      "webhookId": "7eb54f22-cbed-498d-b1b7-ccabe38b4a06",
      "parameters": {
        "operation": "send"
      },
      "notesInFlow": [
        {
          "note": "Sends the trip weather forecast summary to user via Telegram."
        }
      ],
      "typeVersion": 1
    },
    {
      "id": "bb15bccd-f857-4de6-907f-7a48457a125f",
      "name": "Construire l'URL d'interrogation",
      "type": "n8n-nodes-base.code",
      "position": [
        1072,
        -64
      ],
      "parameters": {
        "jsCode": "const location = encodeURIComponent($json.location);\nconst startDate = $json.startDate.split('T')[0]; // date only\nconst endDate = $json.endDate.split('T')[0]; // date only\nconst apiKey = '[your API]';\n\nconst url = `https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/${location}/${startDate}/${endDate}?unitGroup=metric&key=${apiKey}&include=days,alerts`;\n\nreturn [{ json: { url } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e29e2ff1-46fd-44c5-ab8f-02d345586e41",
      "name": "Obtenir la prévision météo mise à jour de la destination",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "One day before the trip",
      "position": [
        1328,
        320
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {}
      },
      "notesInFlow": [
        {
          "note": "Fetches weather forecast and alerts for trip location and dates from Visual Crossing."
        }
      ],
      "typeVersion": 1
    },
    {
      "id": "c69a55de-bbf3-4921-bd89-24d4b8826111",
      "name": "Note adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 240,
        "content": "## Identify \n**if** the event is a trip\n**Then** > extracting destination and period"
      },
      "typeVersion": 1
    },
    {
      "id": "50def3d9-67bc-4f5c-b2a4-18f4235fffec",
      "name": "Note adhésive8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        208
      ],
      "parameters": {
        "color": 6,
        "width": 448,
        "height": 288,
        "content": "## Update the forecast one day before the trip\nWait one day before the trip and request again the forecast"
      },
      "typeVersion": 1
    },
    {
      "id": "8aec9d53-2af5-4e3f-87a2-f0f67a2497e3",
      "name": "Note adhésive6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 672,
        "content": "## Get Forecast\n"
      },
      "typeVersion": 1
    },
    {
      "id": "57b375da-2354-4b04-a6ee-b510bed576d0",
      "name": "Note adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1536,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 256,
        "content": "## Send notification\nMake sure Telegram credentials and chat ID are set in the node."
      },
      "typeVersion": 1
    },
    {
      "id": "b4b8e95d-3ea8-4ea2-ab88-a889a74d6818",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 192,
        "height": 464,
        "content": "## Trigger:\n**EVENT**\nCreated or updated"
      },
      "typeVersion": 1
    },
    {
      "id": "5c65c141-7527-43b9-8e85-bd8f1291b54e",
      "name": "Obtenir la prévision météo de la destination",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "At the event creation/update",
      "position": [
        1296,
        -64
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {}
      },
      "notesInFlow": [
        {
          "note": "Fetches weather forecast and alerts for trip location and dates from Visual Crossing."
        }
      ],
      "typeVersion": 1
    },
    {
      "id": "b92af965-eecf-4019-b5cf-ca38e8ee9928",
      "name": "Formater le message",
      "type": "n8n-nodes-base.code",
      "position": [
        1584,
        -64
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  let forecastSummary = `Weather forecast for your trip to ${item.json.address || 'destination'} from ${item.json.days[0].datetime} to ${item.json.days[item.json.days.length - 1].datetime}:\\n`;\n\n  item.json.days.forEach(day => {\n    const precipprob = day.precipprob !== undefined ? `, Precip Prob: ${day.precipprob}%` : '';\n    const preciptype = day.preciptype ? `, Precip Type: ${day.preciptype.join(\", \")}` : '';\n    const conditions = day.conditions ? `, Conditions: ${day.conditions}` : '';\n    const description = day.description ? `,  ${day.description}` : '';\n    forecastSummary += `${day.datetime}: Max ${day.tempmax}°C, Min ${day.tempmin}°C${precipprob}${preciptype}${conditions}${description}\\n`;\n  });\n\n  if (item.json.alerts && item.json.alerts.length > 0) {\n    forecastSummary += `\\nALERTS:\\n`;\n    item.json.alerts.forEach(alert => {\n      forecastSummary += `${alert.description}\\n`;\n    });\n  }\n\n  return {\n    json: { forecastSummary }\n  };\n});\n"
      },
      "typeVersion": 2
    }
  ],
  "pinData": {},
  "connections": {
    "7df92b27-05c7-4c4a-9b2f-76883f0d8974": {
      "main": [
        [
          {
            "node": "41df49be-15c4-4c83-8c69-6c8cc109ac34",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1c3d2277-df1f-4178-bdba-bff40a182c2d": {
      "main": [
        [
          {
            "node": "e29e2ff1-46fd-44c5-ab8f-02d345586e41",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "79b81985-724d-4208-a225-25ecde0851e7": {
      "main": [
        [
          {
            "node": "40fe3671-d5ed-49fd-a342-f89df42f5657",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "38413099-7d19-4c06-bec7-a2d542607474": {
      "main": [
        [
          {
            "node": "40fe3671-d5ed-49fd-a342-f89df42f5657",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b92af965-eecf-4019-b5cf-ca38e8ee9928": {
      "main": [
        [
          {
            "node": "1cac0052-349b-4ae2-8c4e-b1a63bd834f4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "40fe3671-d5ed-49fd-a342-f89df42f5657": {
      "main": [
        [
          {
            "node": "7df92b27-05c7-4c4a-9b2f-76883f0d8974",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "41df49be-15c4-4c83-8c69-6c8cc109ac34": {
      "main": [
        [
          {
            "node": "bb15bccd-f857-4de6-907f-7a48457a125f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bb15bccd-f857-4de6-907f-7a48457a125f": {
      "main": [
        [
          {
            "node": "1c3d2277-df1f-4178-bdba-bff40a182c2d",
            "type": "main",
            "index": 0
          },
          {
            "node": "5c65c141-7527-43b9-8e85-bd8f1291b54e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5c65c141-7527-43b9-8e85-bd8f1291b54e": {
      "main": [
        [
          {
            "node": "b92af965-eecf-4019-b5cf-ca38e8ee9928",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e29e2ff1-46fd-44c5-ab8f-02d345586e41": {
      "main": [
        [
          {
            "node": "b92af965-eecf-4019-b5cf-ca38e8ee9928",
            "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é - Productivité personnelle

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œuds17
Catégorie1
Types de nœuds7
Description de la difficulté

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

Auteur
Razvan Bara

Razvan Bara

@amzneer

Whether you're launching your first product or scaling, I'll help you build an AI-powered, data-driven system that runs your business while you focus on strategic growth. Let's discuss how strategic optimization combined with business intelligence and custom AI agents can transform your operations and accelerate your success. Ready to scale smarter with AI and data? Let's talk.

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34