This workflow follows the Google Sheets → 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 →
{
"name": "Weather Bot - Alert Monitor",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 30
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-500,
-20
],
"id": "0480dcfd-592d-41a2-8105-0efdaa8cafe9",
"name": "Schedule Trigger"
},
{
"parameters": {
"authentication": "serviceAccount",
"documentId": {
"__rl": true,
"value": "1TI7vysDQJULYNJmFvJtpTBBnUQV50HKs75a3bI91ZVo",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Users",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1TI7vysDQJULYNJmFvJtpTBBnUQV50HKs75a3bI91ZVo/edit#gid=0"
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.6,
"position": [
-280,
-20
],
"id": "23c90828-e3dc-4035-af62-1db277522686",
"name": "Get All Users",
"credentials": {
"googleApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Get ALL input items from the previous node.\n// This gives you an array of n8n item objects (e.g., [{ json: {...} }, { json: {...} }])\nconst allInputItems = $input.all();\n\n// Map these n8n item objects to extract their 'json' payload,\n// resulting in a clean array of your user data objects.\n// This ensures 'users' is always an array, whether there's 1, 3, or 0 input items.\nconst users = allInputItems.map(item => item.json);\n\n// Filter the users based on the conditions\nconst activeUsers = users.filter(user =>\n user.location && user.lat && user.lon\n);\n\n// Map the filtered activeUsers to the desired output format\nreturn activeUsers.map(user => ({\n json: {\n userId: user.user_id,\n location: user.location,\n lat: user.lat,\n lon: user.lon,\n chatId: user.user_id // Assuming user_id is the correct chatId\n }\n}));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-60,
-20
],
"id": "55edc8b3-546f-448f-97bf-577a5d9e4925",
"name": "Filter Active Users"
},
{
"parameters": {
"url": "https://api.openweathermap.org/data/2.5/weather",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "lat",
"value": "={{ $json.lat }}"
},
{
"name": "lon",
"value": "={{ $json.lon }}"
},
{
"name": "appid",
"value": "[your weather API]"
},
{
"name": "units",
"value": "metric"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
460,
20
],
"id": "f3668a07-9d2b-4b40-b232-dde7eee9170f",
"name": "Weather Alerts API"
},
{
"parameters": {
"mode": "combine",
"combineBy": "combineByPosition",
"options": {}
},
"type": "n8n-nodes-base.merge",
"typeVersion": 3.1,
"position": [
720,
-160
],
"id": "af6e8102-65d0-48c0-a17b-b795847ba93d",
"name": "Merge"
},
{
"parameters": {
"jsCode": "// Get ALL input items from the previous node.\n// Each item will be an n8n item object, containing the weather data and user details\nconst inputItems = $input.all();\n\n// You need to map each input item to an output item.\n// This ensures each weather data block is processed independently.\nreturn inputItems.map(item => {\n // Extract the actual weather data object and user details for the current item\n const weather = item.json;\n const locationName = item.json.location || weather.name || 'Your Location'; // Prioritize passed-through location, fallback to weather.name\n\n // This variable correctly holds the userId (which you're using as chatId) for the CURRENT item\n const userIdForChat = item.json.userId || ''; // Or item.json.chatId if that's the field name\n\n\n // Safely access weather properties\n const temp = weather.main?.temp;\n const windSpeed = (weather.wind?.speed || 0) * 3.6; // m/s to km/h, default 0\n const condition = weather.weather[0]?.main;\n const description = weather.weather[0]?.description;\n\n let alerts = [];\n\n // Temperature alerts\n if (temp !== undefined) {\n if (temp < -5) {\n alerts.push('\ud83e\udd76 Extreme Cold Warning: Temperature below -5\u00b0C');\n }\n if (temp > 35) {\n alerts.push('\ud83d\udd25 Heat Warning: Temperature above 35\u00b0C');\n }\n }\n\n // Wind alerts\n if (windSpeed > 50) {\n alerts.push('\ud83d\udca8 High Wind Warning: Wind speed above 50 km/h');\n }\n\n // Weather condition alerts\n if (condition === 'Thunderstorm') {\n alerts.push('\u26c8\ufe0f Thunderstorm Alert: Take shelter indoors');\n }\n if (condition === 'Snow') {\n alerts.push('\u2744\ufe0f Snow Alert: Drive carefully and dress warmly');\n }\n\n // If no alerts, return null for this item\n if (alerts.length === 0) {\n return null;\n }\n\n const message = `\u26a0\ufe0f WEATHER ALERT for ${locationName}\n\n${alerts.join('\\n')}\n\nCurrent conditions: ${Math.round(temp || 0)}\u00b0C, ${description || 'N/A'}\n\nStay safe! \ud83d\ude4f`;\n\n // Return a new n8n item for each processed weather data that generated an alert\n return {\n json: {\n // FIX: Use the userIdForChat variable which is specific to the current item\n chatId: userIdForChat,\n message: message\n }\n };\n}).filter(Boolean); // .filter(Boolean) will remove any null items from the array"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1040,
-20
],
"id": "bf0887c0-efbf-4deb-b4b6-65b187894d6d",
"name": "Check Alert Conditions",
"alwaysOutputData": false
},
{
"parameters": {
"chatId": "={{ $json.chatId }}",
"text": "={{ $json.message }}",
"additionalFields": {}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1320,
-20
],
"id": "be38674c-aa8f-4a6f-ad24-39c48d92e84e",
"name": "Send Alert",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "610674d7-abdc-420c-b17c-a28e99ef9b09",
"leftValue": "={{ $json.userId }}",
"rightValue": "",
"operator": {
"type": "number",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
220,
60
],
"id": "1bccd19f-ff14-45ec-bbab-4dfa2688e4c2",
"name": "Is There Active Users"
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Get All Users",
"type": "main",
"index": 0
}
]
]
},
"Get All Users": {
"main": [
[
{
"node": "Filter Active Users",
"type": "main",
"index": 0
}
]
]
},
"Filter Active Users": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
},
{
"node": "Is There Active Users",
"type": "main",
"index": 0
}
]
]
},
"Weather Alerts API": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Check Alert Conditions",
"type": "main",
"index": 0
}
]
]
},
"Check Alert Conditions": {
"main": [
[
{
"node": "Send Alert",
"type": "main",
"index": 0
}
]
]
},
"Is There Active Users": {
"main": [
[
{
"node": "Weather Alerts API",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "102d1fdf-8672-4b6d-8859-c8a8140d2b54",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "Q3XzfXtAjifX8MZ1",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Weather Bot - Alert Monitor. Uses googleSheets, httpRequest, telegram. Scheduled trigger; 8 nodes.
Source: https://github.com/SAMURAI711/telegram-weather-alert-bot/blob/0df2cb09f542bbd86f989b41d0a4e8ee0a1b7345/n8n-workflows/alert-monitor.json — 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.
⚠️ Heads up: this is satire. The "Hell Yeah!" workflow is a parody of "automate your whole life with AI agents" grindset content. The API endpoints are fictional and the function nodes are illustrativ
This workflow tracks a configurable crypto watchlist using the CoinGecko API, sends Telegram alerts when price, % change, or volume-spike conditions are met (with optional RSI filtering), optionally l
This workflow continuously monitors the Meta Ads Library for new creatives from a specific competitor pages, logs them into Google Sheets, and sends a concise Telegram notification with the number of
> n8n, Binance API, Google Sheets, Slack, Telegram, Jira & Email
This workflow is ideal for marketers, product managers, competitive intelligence teams, and anyone who needs to track changes on web pages — whether it's competitor pricing, job postings, policy updat