This workflow corresponds to n8n.io template #12653 — we link there as the canonical source.
This workflow follows the Discord → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "cKm7PfdnubNOhnGevc5Jo",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Weather Monitoring Across Multiple Cities with OpenWeatherMap, GPT-4o-mini, and Discord",
"tags": [],
"nodes": [
{
"id": "a4f21274-caf1-41f4-a342-e38148ca71ee",
"name": "Main Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
-176
],
"parameters": {
"width": 500,
"height": 466,
"content": "## How it works\nThis workflow automates global weather monitoring. It triggers every 6 hours to fetch current weather, 5-day forecasts, and Air Quality Index (AQI) data for multiple cities via OpenWeatherMap. \n\nUsing custom JavaScript and OpenAI's GPT-4o-mini, it calculates a 'Comfort Index' and identifies weather risks (e.g., extreme heat or poor AQI). It then routes prioritized alerts or routine briefings to Discord, while archiving all data in Google Sheets for history.\n\n## Setup steps\n1. **Credentials:** Connect OpenWeatherMap, OpenAI, and Discord (Webhook).\n2. **Locations:** Edit the 'Set Monitoring Locations' node with your target cities' Lat/Lon.\n3. **Google Sheets:** Open the 'Log to Google Sheets' node and provide your **Spreadsheet ID** and **Sheet Name**.\n4. **Discord:** Ensure your Webhook URL is correctly configured in the Discord nodes."
},
"typeVersion": 1
},
{
"id": "21813c54-68eb-4882-b557-3f4722be704f",
"name": "Part 1 Sticky",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
288
],
"parameters": {
"color": 7,
"width": 750,
"height": 400,
"content": "## PART 1: Setup & Iteration\nTrigger the flow and define the list of cities to monitor using coordinates."
},
"typeVersion": 1
},
{
"id": "fe0b950f-be74-4a64-9f16-4aa9fe04969a",
"name": "Part 2 Sticky",
"type": "n8n-nodes-base.stickyNote",
"position": [
1360,
176
],
"parameters": {
"color": 7,
"width": 700,
"height": 600,
"content": "## PART 2: Data Collection\nFetches current weather, forecasts, and air pollution data simultaneously for each location."
},
"typeVersion": 1
},
{
"id": "911b1ce8-4bb5-4d4b-9710-e46e7d620c18",
"name": "Part 3 Sticky",
"type": "n8n-nodes-base.stickyNote",
"position": [
2112,
288
],
"parameters": {
"color": 7,
"width": 850,
"height": 400,
"content": "## PART 3: AI Analysis\nCalculates comfort metrics and uses GPT-4 to generate human-like weather briefings."
},
"typeVersion": 1
},
{
"id": "596792ac-8c33-4b63-82f1-f38d9cd1855e",
"name": "Part 4 Sticky",
"type": "n8n-nodes-base.stickyNote",
"position": [
3008,
288
],
"parameters": {
"color": 7,
"width": 750,
"height": 500,
"content": "## PART 4: Delivery & Logging\nSmart routing: sends urgent alerts or routine reports to Discord and logs results to Google Sheets."
},
"typeVersion": 1
},
{
"id": "d6aecc5b-5a8a-41d0-871f-1b7692624e27",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
608,
480
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 6
}
]
}
},
"typeVersion": 1.2
},
{
"id": "b7aa9726-4dd7-467d-89b7-1094e7fa102a",
"name": "Set Monitoring Locations",
"type": "n8n-nodes-base.set",
"position": [
832,
480
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "=[\n {\"city\": \"Tokyo\", \"lat\": \"35.6762\", \"lon\": \"139.6503\", \"timezone\": \"Asia/Tokyo\"},\n {\"city\": \"New York\", \"lat\": \"40.7128\", \"lon\": \"-74.0060\", \"timezone\": \"America/New_York\"},\n {\"city\": \"London\", \"lat\": \"51.5074\", \"lon\": \"-0.1278\", \"timezone\": \"Europe/London\"}\n]"
},
"typeVersion": 3.4
},
{
"id": "4cb7a42b-1881-4ae7-b95d-59e96ed00efc",
"name": "Split Locations",
"type": "n8n-nodes-base.splitOut",
"position": [
1040,
480
],
"parameters": {
"options": {},
"fieldToSplitOut": "="
},
"typeVersion": 1
},
{
"id": "78f0c906-08a2-4fef-9eaf-cc060b5fe1c5",
"name": "Get Current Weather",
"type": "n8n-nodes-base.openWeatherMap",
"position": [
1408,
288
],
"parameters": {
"language": "en",
"latitude": "={{ $json.lat }}",
"longitude": "={{ $json.lon }}",
"locationSelection": "coordinates"
},
"typeVersion": 1
},
{
"id": "0824a574-25b6-41cf-9a77-f065dae09522",
"name": "Get 5-Day Forecast",
"type": "n8n-nodes-base.openWeatherMap",
"position": [
1408,
480
],
"parameters": {
"language": "en",
"latitude": "={{ $json.lat }}",
"longitude": "={{ $json.lon }}",
"operation": "5DayForecast",
"locationSelection": "coordinates"
},
"typeVersion": 1
},
{
"id": "036118b6-8a52-412a-85ef-edd22de34ad4",
"name": "Get Air Quality Index",
"type": "n8n-nodes-base.httpRequest",
"position": [
1408,
672
],
"parameters": {
"url": "=http://api.openweathermap.org/data/2.5/air_pollution?lat={{ $json.lat }}&lon={{ $json.lon }}&appid={{ $credentials.openWeatherMapApi.apiKey }}",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openWeatherMapApi"
},
"typeVersion": 4.2
},
{
"id": "2c5e4dae-633c-4786-9f97-98c178afe0a8",
"name": "Merge Weather Data",
"type": "n8n-nodes-base.merge",
"position": [
1664,
384
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3
},
{
"id": "7da73045-c2a0-4c56-91dd-28bcab3f0fdd",
"name": "Merge with Air Quality",
"type": "n8n-nodes-base.merge",
"position": [
1856,
480
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3
},
{
"id": "e52a93d9-8f3d-41a9-a25f-a471ee2f4beb",
"name": "Process and Analyze Data",
"type": "n8n-nodes-base.code",
"position": [
2160,
480
],
"parameters": {
"jsCode": "const items = $input.all();\nconst results = [];\n\nfor (const item of items) {\n const current = item.json;\n \n const temp = current.main?.temp || 0;\n const humidity = current.main?.humidity || 0;\n const windSpeed = current.wind?.speed || 0;\n const weatherDesc = current.weather?.[0]?.description || 'unknown';\n const weatherMain = current.weather?.[0]?.main || 'unknown';\n \n const aqi = current.list?.[0]?.main?.aqi || 1;\n const aqiLabels = ['Good', 'Fair', 'Moderate', 'Poor', 'Very Poor'];\n const aqiLabel = aqiLabels[aqi - 1] || 'Unknown';\n \n const comfortIndex = Math.round(100 - Math.abs(temp - 22) * 2 - (humidity > 70 ? (humidity - 70) : 0));\n \n const alerts = [];\n if (temp > 35) alerts.push('\ud83d\udd25 Extreme Heat Warning');\n if (temp < 0) alerts.push('\u2744\ufe0f Freezing Temperature Alert');\n if (windSpeed > 15) alerts.push('\ud83d\udca8 High Wind Advisory');\n if (aqi >= 4) alerts.push('\ud83d\ude37 Poor Air Quality Alert');\n if (weatherMain === 'Thunderstorm') alerts.push('\u26c8\ufe0f Thunderstorm Warning');\n \n results.push({\n json: {\n city: current.name || 'Unknown',\n country: current.sys?.country || '',\n timestamp: new Date().toISOString(),\n current: {\n temperature: temp,\n feelsLike: current.main?.feels_like || temp,\n humidity: humidity,\n windSpeed: windSpeed,\n weather: weatherDesc,\n weatherMain: weatherMain\n },\n airQuality: {\n aqi: aqi,\n label: aqiLabel\n },\n analysis: {\n comfortIndex: Math.max(0, Math.min(100, comfortIndex)),\n alerts: alerts,\n hasAlerts: alerts.length > 0\n }\n }\n });\n}\n\nreturn results;"
},
"typeVersion": 2
},
{
"id": "10e3f964-ce56-44c0-9e5a-e8dad3dc9916",
"name": "Aggregate All Locations",
"type": "n8n-nodes-base.aggregate",
"position": [
2384,
480
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "f8f7eb22-4ee2-42c5-ac3d-1302ee99a4ae",
"name": "AI Weather Analysis",
"type": "n8n-nodes-base.httpRequest",
"position": [
2592,
480
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"method": "POST",
"options": {},
"jsonBody": "={\n \"model\": \"gpt-4o-mini\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a professional meteorologist. Provide: 1) Comparison of conditions, 2) Highlights/concerns, 3) Best city for outdoor activities today. Keep under 200 words with emojis.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Analyze this weather data: {{ JSON.stringify($json.data) }}\"\n }\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openAiApi"
},
"typeVersion": 4.2
},
{
"id": "b92ed99d-5dce-4119-ad5b-150aa2107462",
"name": "Format Weather Report",
"type": "n8n-nodes-base.code",
"position": [
2816,
480
],
"parameters": {
"jsCode": "const aggregatedData = $('Aggregate All Locations').first().json.data;\nconst aiAnalysis = $input.first().json.choices?.[0]?.message?.content || 'Analysis unavailable';\n\nlet report = `\ud83c\udf0d **WEATHER INTELLIGENCE REPORT**\\n`;\nreport += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n`;\n\nfor (const loc of aggregatedData) {\n report += `\ud83d\udccd **${loc.city}**\\n`;\n report += `\u251c \ud83c\udf21\ufe0f ${loc.current.temperature}\u00b0C (Comfort: ${loc.analysis.comfortIndex}/100)\\n`;\n report += `\u251c \ud83e\udec1 AQI: ${loc.airQuality.label}\\n`;\n if (loc.analysis.alerts.length > 0) report += `\u251c \u26a0\ufe0f ALERT: ${loc.analysis.alerts.join(', ')}\\n`;\n report += `\\n`;\n}\n\nreport += `\ud83e\udd16 **AI ANALYSIS**\\n${aiAnalysis}`;\n\nreturn [{\n json: {\n report: report,\n hasAlerts: aggregatedData.some(loc => loc.analysis.hasAlerts)\n }\n}];"
},
"typeVersion": 2
},
{
"id": "cd0d3a63-ea3b-4d27-b8c7-7e0e6ea16f68",
"name": "Check for Alerts",
"type": "n8n-nodes-base.if",
"position": [
3040,
480
],
"parameters": {
"options": {},
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict"
},
"conditions": [
{
"id": "alert-check",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.hasAlerts }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "d35bfe60-8c67-41f9-a84e-17b475fa53ff",
"name": "Send Discord Alert",
"type": "n8n-nodes-base.discord",
"position": [
3264,
384
],
"parameters": {
"content": "=\ud83d\udea8 **URGENT WEATHER ALERT**\\n\\n{{ $json.report }}",
"options": {},
"authentication": "webhook"
},
"typeVersion": 2
},
{
"id": "6454ab85-b90c-44a2-8220-7d8a645df915",
"name": "Send Discord Report",
"type": "n8n-nodes-base.discord",
"position": [
3264,
576
],
"parameters": {
"content": "={{ $json.report }}",
"options": {},
"authentication": "webhook"
},
"typeVersion": 2
},
{
"id": "25810664-1a4d-4ecc-bc13-0177f6071c3b",
"name": "Log to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
3504,
480
],
"parameters": {
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_SPREADSHEET_ID"
}
},
"typeVersion": 4.5
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "",
"connections": {
"Split Locations": {
"main": [
[
{
"node": "Get Current Weather",
"type": "main",
"index": 0
},
{
"node": "Get 5-Day Forecast",
"type": "main",
"index": 0
},
{
"node": "Get Air Quality Index",
"type": "main",
"index": 0
}
]
]
},
"Check for Alerts": {
"main": [
[
{
"node": "Send Discord Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Discord Report",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Set Monitoring Locations",
"type": "main",
"index": 0
}
]
]
},
"Get 5-Day Forecast": {
"main": [
[
{
"node": "Merge Weather Data",
"type": "main",
"index": 1
}
]
]
},
"Merge Weather Data": {
"main": [
[
{
"node": "Merge with Air Quality",
"type": "main",
"index": 0
}
]
]
},
"Send Discord Alert": {
"main": [
[
{
"node": "Log to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"AI Weather Analysis": {
"main": [
[
{
"node": "Format Weather Report",
"type": "main",
"index": 0
}
]
]
},
"Get Current Weather": {
"main": [
[
{
"node": "Merge Weather Data",
"type": "main",
"index": 0
}
]
]
},
"Send Discord Report": {
"main": [
[
{
"node": "Log to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Format Weather Report": {
"main": [
[
{
"node": "Check for Alerts",
"type": "main",
"index": 0
}
]
]
},
"Get Air Quality Index": {
"main": [
[
{
"node": "Merge with Air Quality",
"type": "main",
"index": 1
}
]
]
},
"Merge with Air Quality": {
"main": [
[
{
"node": "Process and Analyze Data",
"type": "main",
"index": 0
}
]
]
},
"Aggregate All Locations": {
"main": [
[
{
"node": "AI Weather Analysis",
"type": "main",
"index": 0
}
]
]
},
"Process and Analyze Data": {
"main": [
[
{
"node": "Aggregate All Locations",
"type": "main",
"index": 0
}
]
]
},
"Set Monitoring Locations": {
"main": [
[
{
"node": "Split Locations",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow provides an automated, intelligent solution for global weather monitoring. It goes beyond simple data fetching by calculating a custom "Comfort Index" and using AI to provide human-like briefings and activity recommendations. Whether you are managing remote teams…
Source: https://n8n.io/workflows/12653/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Automated garden and farm irrigation system that uses weather forecasts and evapotranspiration calculations to determine optimal watering schedules, preventing water waste while maintaining healthy pl
This workflow monitors product prices from BooksToScrape and sends alerts to a Discord channel via webhook when competitor's prices are lower than our prices. Schedule (for daily or required schedule)
AmazonLuna-Games-Fetch. Uses httpRequest, scheduleTrigger, googleSheets, stickyNote. Scheduled trigger; 16 nodes.
Automatically fetch, organize, and maintain an updated catalog of Amazon Luna – Included with Prime games.This workflow regularly queries Amazon’s official Luna endpoint, extracts complete metadata, a
AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs and upload to all social networks. Uses httpRequest, openAi, stickyNote, googleDrive. Scheduled trigger; 51 nodes.