使用OpenWeather、表格和Telegram的植物护理提醒
高级
这是一个Personal Productivity领域的自动化工作流,包含 27 个节点。主要使用 If, Set, Code, Merge, Webhook 等节点。 使用OpenWeather、表格和Telegram的植物护理提醒
前置要求
- •HTTP Webhook 端点(n8n 会自动生成)
- •Telegram Bot Token
- •可能需要目标 API 的认证凭证
- •Google Sheets API 凭证
使用的节点 (27)
分类
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "0867aa2e4fb4e86d170a6ca997a164fd02d27420eb0e7cb54482c4b03d1672ac"
},
"nodes": [
{
"id": "23904e88-dc72-4e65-ad85-c4bec858bf1d",
"name": "计划触发器",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1424,
144
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.2
},
{
"id": "2992a320-5790-4bc4-b1bb-f1d9ba49afb8",
"name": "读取植物数据",
"type": "n8n-nodes-base.googleSheets",
"position": [
-880,
160
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit#gid=0",
"cachedResultName": "plants"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit?usp=drivesdk",
"cachedResultName": "Plants Scheudle"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "x23VLPzDtSY8QGZL",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "85ab0cc8-f43a-4001-bf29-b3810e79fa43",
"name": "读取设置",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1248,
144
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 278009058,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit#gid=278009058",
"cachedResultName": "settings"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit?usp=drivesdk",
"cachedResultName": "Plants Scheudle"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "x23VLPzDtSY8QGZL",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "b254e202-8293-41ed-998c-064da1ae6953",
"name": "判断到期任务",
"type": "n8n-nodes-base.code",
"position": [
-736,
160
],
"parameters": {
"jsCode": "// Input: items from \"Read plants\" (one per row)\n// Output:\n// - $json.due: array de { plant_id, plant, action, reason, lat, lon, thirst_level, indoor, weather_delay }\n// - $json.toCheckWeather: array {lat, lon}\n// Frecuencys: \"7d\", \"2w\", \"1m\" or number of days.\n\nfunction parseFreq(f) {\n if (!f) return null;\n if (typeof f === 'number') return f;\n const m = String(f).trim().match(/^(\\d+)\\s*([dwm])?$/i);\n if (!m) return null;\n const n = parseInt(m[1], 10);\n const unit = (m[2] || 'd').toLowerCase();\n if (unit === 'd') return n;\n if (unit === 'w') return n * 7;\n if (unit === 'm') return n * 30; \n return n;\n}\n\nfunction daysBetween(a, b) {\n const A = new Date(a + 'T00:00:00');\n const B = new Date(b + 'T00:00:00');\n return Math.floor((B - A) / (1000*60*60*24));\n}\n\nconst today = new Date().toISOString().slice(0,10); // YYYY-MM-DD\nconst due = [];\nconst toCheckWeather = [];\nconst coordSet = new Set();\n\nfor (const item of items) {\n const r = item.json;\n\n const actions = [\n { key: 'water', lastKey: 'last_water', freqKey: 'water_freq' },\n { key: 'fertilize', lastKey: 'last_fert', freqKey: 'fert_freq' },\n ];\n\n for (const a of actions) {\n const freqDays = parseFreq(r[a.freqKey]);\n if (!freqDays) continue;\n\n const last = r[a.lastKey] ? String(r[a.lastKey]).slice(0,10) : null;\n const elapsed = last ? daysBetween(last, today) : Infinity;\n\n if (elapsed >= freqDays) {\n const entry = {\n plant_id: r.id,\n plant: r.plant,\n action: a.key,\n reason: last ? `due after ${elapsed}d` : 'no last date',\n lat: r.lat ? Number(r.lat) : null,\n lon: r.lon ? Number(r.lon) : null,\n weather_delay: String(r.weather_delay || '').toLowerCase() === 'true',\n thirst_level: (r.thirst_level || 'med').toLowerCase(),\n indoor: (r.indoor || '').toLowerCase(),\n };\n\n if (a.key === 'water' && entry.weather_delay && entry.lat && entry.lon) {\n const key = `${entry.lat},${entry.lon}`;\n if (!coordSet.has(key)) {\n coordSet.add(key);\n toCheckWeather.push({ lat: entry.lat, lon: entry.lon });\n }\n }\n\n due.push(entry);\n }\n }\n}\n\nreturn [{ json: { today, due, toCheckWeather } }];\n"
},
"typeVersion": 2
},
{
"id": "28ac4c1e-0df8-463b-ae4a-0b93767d54a5",
"name": "OpenWeather请求",
"type": "n8n-nodes-base.httpRequest",
"position": [
-368,
-48
],
"parameters": {
"url": "https://api.openweathermap.org/data/2.5/forecast",
"options": {},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "lat",
"value": "={{ $json.due[0].lat }}"
},
{
"name": "lon",
"value": "={{ $json.due[0].lon }}"
},
{
"name": "appid",
"value": "{YOU_API_CREDENTIAL}"
},
{
"name": "units",
"value": "metric"
},
{
"name": "cnt",
"value": "16"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "d826a674-b889-4360-8225-33d66f9e2fd3",
"name": "天气判断门",
"type": "n8n-nodes-base.code",
"position": [
160,
128
],
"parameters": {
"jsCode": "// WeatherGate (single-input, merged)\n// Upstream: Merge (Combine) of DecideDue+OpenWeather, each tagged with json.source = \"decide\" | \"weather\"\n\nfunction rainScore(forecast) {\n const now = Date.now() / 1000, win = 24 * 3600;\n let recent = 0, upcoming = 0;\n const list = (forecast && forecast.list) || [];\n for (const e of list) {\n const t = e.dt, mm = e.rain && e.rain['3h'] ? e.rain['3h'] : 0;\n if (typeof t !== 'number') continue;\n if (t < now && (now - t) <= win) recent += mm;\n if (t >= now && (t - now) <= win) upcoming += mm;\n }\n return { recent, upcoming };\n}\nconst coordKey = (lat, lon) => {\n const la = Number(lat), lo = Number(lon);\n if (!Number.isFinite(la) || !Number.isFinite(lo)) return null;\n return `${la.toFixed(4)},${lo.toFixed(4)}`;\n};\n\n// Read everything from single input\nconst all = $input.all();\nconst decide = all.find(i => (i.json?.source || '').toLowerCase() === 'decide')?.json || {};\nconst weatherItems = all.filter(i => (i.json?.source || '').toLowerCase() === 'weather')\n .map(i => i.json?.body ?? i.json ?? {});\n\n// Normalize controller\nconst today = decide.today || new Date().toISOString().slice(0,10);\nconst due = Array.isArray(decide.due) ? decide.due : [];\n\n// Build coord → rain map\nconst wxMap = new Map();\nfor (const w of weatherItems) {\n const lat = w?.city?.coord?.lat ?? w?.coord?.lat ?? w?.lat;\n const lon = w?.city?.coord?.lon ?? w?.coord?.lon ?? w?.lon;\n const k = coordKey(lat, lon);\n if (!k) continue;\n if (!wxMap.has(k)) wxMap.set(k, { ...rainScore(w), raw: w });\n}\n\n// Decide skip / send\nconst out = [];\nfor (const d of due) {\n const act = d.action;\n const lat = d.lat ?? d.latitude ?? null;\n const lon = d.lon ?? d.longitude ?? null;\n const indoor = String(d.indoor || '').toLowerCase();\n const thirst = String(d.thirst_level || 'med').toLowerCase();\n const weatherDelay = String(d.weather_delay || '').toLowerCase() === 'true';\n let note = d.reason || '';\n let skip = false;\n\n if (act === 'water' && weatherDelay && lat != null && lon != null) {\n let recentThresh = 2, upcomingThresh = 3;\n if (thirst === 'low') { recentThresh = 1; upcomingThresh = 2; }\n if (thirst === 'high') { recentThresh = 4; upcomingThresh = 6; }\n const wx = wxMap.get(coordKey(lat, lon));\n if (wx) {\n if (wx.recent >= recentThresh) {\n skip = true;\n note += (note ? ' | ' : '') + `skipped: ${wx.recent.toFixed(1)}mm rain last 24h`;\n } else if (wx.upcoming >= upcomingThresh && indoor !== 'indoor') {\n skip = true;\n note += (note ? ' | ' : '') + `delayed: ${wx.upcoming.toFixed(1)}mm rain next 24h`;\n }\n }\n }\n\n if (!skip) {\n out.push({\n json: {\n plant_id: d.plant_id || d.id || d.plantId,\n plant: d.plant || d.name || d.title,\n action: act,\n message: `Time to ${act} **${d.plant || d.name || d.title || 'your plant'}** (${note || 'due today'}).`,\n updateFlags: { [`last_${act}`]: today }\n }\n });\n }\n}\n\nif (!out.length) {\n return [{ json: { noop: true, reason: 'no-due-or-all-skipped', today, dueCount: due.length } }];\n}\nreturn out;\n"
},
"typeVersion": 2,
"alwaysOutputData": false
},
{
"id": "0d5b4179-9bf1-4561-bcf6-4dc573f1638b",
"name": "如果",
"type": "n8n-nodes-base.if",
"position": [
352,
128
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "92cacd6e-b0be-463c-a4ca-06825687e5db",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{$json.noop}}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "3328bf71-4472-448e-88f6-820a46165ed4",
"name": "设置天气标签",
"type": "n8n-nodes-base.set",
"position": [
-176,
-48
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "bcb7280e-507a-45ea-8079-82375f9877d6",
"name": "source",
"type": "string",
"value": "weather"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "f39035b3-88ba-48e7-a587-eda013331af9",
"name": "设置决策标签",
"type": "n8n-nodes-base.set",
"position": [
-272,
144
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "33207508-c616-4ea7-bda8-a8f850bf1cd6",
"name": "today",
"type": "string",
"value": "={{ $json.today }}"
},
{
"id": "cc174303-762a-40b6-93d0-81c3f8cf4335",
"name": "due",
"type": "array",
"value": "={{ $json.due }}"
},
{
"id": "6e51c675-ee89-40d1-be4e-32ddf11cff58",
"name": "toCheckWeather",
"type": "array",
"value": "={{ $json.toCheckWeather }}"
},
{
"id": "70f07a8d-0d66-48bd-8485-648f3920d720",
"name": "source",
"type": "string",
"value": "decide"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "747d8bc2-a6c3-404e-a384-1940681154fc",
"name": "合并",
"type": "n8n-nodes-base.merge",
"position": [
0,
128
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "94f8f534-8a6a-4a49-bc4a-343562d5f7f5",
"name": "¿有待处理任务?",
"type": "n8n-nodes-base.if",
"position": [
-560,
160
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b2fea9f1-257b-4d5f-a581-fc6ef90e46b6",
"operator": {
"type": "array",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.due }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "28b3d293-2286-4b4f-af0b-5a11c72301c0",
"name": "发送无到期任务最终消息",
"type": "n8n-nodes-base.telegram",
"position": [
544,
16
],
"webhookId": "d544aed5-6ced-4da8-be90-6cdce70fd07c",
"parameters": {
"text": "=No plants due today ✅",
"chatId": "{YOUR_CHAT_ID}",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"id": "qxlsxJ9bb8CDTLtP",
"name": "Telegram InputChatBot"
}
},
"typeVersion": 1.2
},
{
"id": "5278b601-64f0-4498-b850-93738850a108",
"name": "休假模式",
"type": "n8n-nodes-base.if",
"position": [
-1104,
144
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f259e344-e664-4d16-8ac8-9b7ab3156965",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.vacation_mode }}",
"rightValue": "on"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "7a476e7d-f7a9-48ab-afde-3dbd938dc685",
"name": "发送无到期任务最终消息1",
"type": "n8n-nodes-base.telegram",
"position": [
-272,
320
],
"webhookId": "d544aed5-6ced-4da8-be90-6cdce70fd07c",
"parameters": {
"text": "=“No plants due today ✅”",
"chatId": "{YOUR_CHAT_ID}",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"id": "qxlsxJ9bb8CDTLtP",
"name": "Telegram InputChatBot"
}
},
"typeVersion": 1.2
},
{
"id": "facb0a87-1ae1-4a4b-acba-a7262ed6fbd7",
"name": "发送到期任务",
"type": "n8n-nodes-base.telegram",
"position": [
560,
224
],
"webhookId": "3e39865b-8f51-4542-9a65-082e587bc0a9",
"parameters": {
"text": "={{ $json.message }}",
"chatId": "{YOUR_CHAT_ID}",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "Mark as done",
"additionalFields": {
"url": "=https://{YOUR_PROJECT_URL}.app.n8n.cloud/webhook/plant-confirm?plant={{ $('WeatherGate').item.json.plant_id }}&action={{ $('WeatherGate').item.json.action }}"
}
}
]
}
}
]
},
"additionalFields": {
"parse_mode": "HTML",
"disable_web_page_preview": true
}
},
"credentials": {
"telegramApi": {
"id": "qxlsxJ9bb8CDTLtP",
"name": "Telegram InputChatBot"
}
},
"typeVersion": 1.2
},
{
"id": "1200e7e5-8f18-4e63-8459-af24d888ee90",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-1408,
720
],
"webhookId": "2214b310-4a8f-46da-8822-aec26a3e24a2",
"parameters": {
"path": "plant-confirm",
"options": {},
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "fd6774ba-a9c6-4600-a75a-d2a04106d384",
"name": "准备数据",
"type": "n8n-nodes-base.code",
"position": [
-1232,
720
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Mode: Run once for each item\n\nconst q = $json.query || {}; // comes from the Webhook node\nconst id = (q.plant || '').toString().trim();\nconst action = ((q.action || 'water') + '').toLowerCase();\nconst today = new Date().toISOString().slice(0,10);\n\nconst allowed = ['water', 'fertilize', 'repot'];\nif (!id || !allowed.includes(action)) {\n return { json: { ok: false, error: 'Missing/invalid id or action', debug: $json } };\n}\n\nreturn {\n json: {\n ok: true,\n id,\n action,\n today,\n columnToUpdate: `last_${action}` // e.g. last_water\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "7e0b8569-ed69-4a6b-bbed-b569b31a85c7",
"name": "追加日志",
"type": "n8n-nodes-base.googleSheets",
"position": [
-672,
720
],
"parameters": {
"columns": {
"value": {
"ts": "={{$now}}",
"action": "={{ $('Prepare Data').item.json.action }}",
"plant_id": "={{$json[\"id\"]}}",
"message_id": "={{$json[\"id\"]}}-{{ $('Prepare Data').item.json.action }}-{{$now}}"
},
"schema": [
{
"id": "ts",
"type": "string",
"display": true,
"required": false,
"displayName": "ts",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "plant_id",
"type": "string",
"display": true,
"required": false,
"displayName": "plant_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "action",
"type": "string",
"display": true,
"required": false,
"displayName": "action",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "message_id",
"type": "string",
"display": true,
"required": false,
"displayName": "message_id",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 129180157,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit#gid=129180157",
"cachedResultName": "log"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit?usp=drivesdk",
"cachedResultName": "Plants Scheudle"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "x23VLPzDtSY8QGZL",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "32d4b3dd-f0dd-4f4f-a0b5-4c746dcffeb0",
"name": "响应 Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-176,
720
],
"parameters": {
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "text/html; charset=utf-8"
}
]
}
},
"respondWith": "text",
"responseBody": "={{$json.body}}"
},
"typeVersion": 1.4
},
{
"id": "dd65ee94-3590-455a-9534-40161d9141d0",
"name": "HTML",
"type": "n8n-nodes-base.code",
"position": [
-336,
720
],
"parameters": {
"jsCode": "// Modo: Run once for each item\nconst id = ($json.id || '').toString();\nconst action = ($json.action || '').toString().toLowerCase();\nconst today = ($json.today || new Date().toISOString().slice(0,10)).toString();\nconst col = ($json.columnToUpdate || '').toString();\n\n// Mapa de acciones (infinitivo → pasado)\nconst pastMap = { water: 'Watered', fertilize: 'Fertilized', repot: 'Repotted' };\nconst verbPast = pastMap[action] || action;\n\nconst html = `<!doctype html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>${verbPast} • ${id}</title>\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n <style>\n body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;margin:0;background:#f6f7fb;color:#111}\n .wrap{max-width:640px;margin:40px auto;padding:0 16px}\n .card{background:#fff;border-radius:14px;box-shadow:0 6px 24px rgba(0,0,0,.08);padding:22px}\n h1{margin:0 0 10px;font-size:22px}\n .ok{display:inline-block;background:#22c55e;color:#fff;padding:6px 10px;border-radius:999px;font-weight:600;margin-bottom:12px}\n .kv{margin-top:8px;line-height:1.7}\n .kv b{display:inline-block;width:160px}\n .foot{color:#666;margin-top:16px;font-size:13px}\n </style>\n</head>\n<body>\n <div class=\"wrap\">\n <div class=\"card\">\n <div class=\"ok\">✅ Recorded</div>\n <h1>${verbPast}</h1>\n <div class=\"kv\">\n <div><b>Plant ID</b> ${id}</div>\n <div><b>Action</b> ${verbPast}</div>\n <div><b>Updated field</b> ${col}</div>\n <div><b>Date</b> ${today}</div>\n </div>\n <p class=\"foot\">You can close this tab now.</p>\n </div>\n </div>\n</body>\n</html>`;\n\nreturn [{ json: { body: html } }];\n"
},
"typeVersion": 2
},
{
"id": "7fe9d87e-612d-4af5-8693-9e85b74895c4",
"name": "编辑字段",
"type": "n8n-nodes-base.set",
"position": [
-512,
720
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6bc3bfe1-df8a-4506-bc9e-3df97e22cf17",
"name": "id",
"type": "string",
"value": "={{ $('Prepare Data').item.json.id }}"
},
{
"id": "912b2d24-c7c6-47c4-afba-1cf9e3ab6c39",
"name": "action",
"type": "string",
"value": "={{ $('Prepare Data').item.json.action }}"
},
{
"id": "418ec865-7eaa-4dd5-b5f3-10c83d7ee1f2",
"name": "today",
"type": "string",
"value": "={{ $('Prepare Data').item.json.today }}"
},
{
"id": "c23125fc-54a7-41c8-a0dd-88443c34095a",
"name": "columnToUpdate",
"type": "string",
"value": "={{ $('Prepare Data').item.json.columnToUpdate }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "17a256b5-2768-40d4-bc45-15ab858dcdcc",
"name": "更新浇水",
"type": "n8n-nodes-base.googleSheets",
"position": [
-864,
608
],
"parameters": {
"columns": {
"value": {
"id": "={{ $json.id }}",
"last_water": "={{ $json.today }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "id",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "plant",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "plant",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "species",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "species",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "indoor",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "indoor",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lat",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "lat",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lon",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "lon",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_water",
"type": "string",
"display": true,
"required": false,
"displayName": "last_water",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "water_freq",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "water_freq",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_fert",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "last_fert",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "fert_freq",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "fert_freq",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_repot",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "last_repot",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "repot_freq",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "repot_freq",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "weather_delay",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "weather_delay",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "thirst_level",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "thirst_level",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit#gid=0",
"cachedResultName": "plants"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit?usp=drivesdk",
"cachedResultName": "Plants Scheudle"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "x23VLPzDtSY8QGZL",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "feb23de6-b31d-4473-9500-d889ec5f9c94",
"name": "更新施肥",
"type": "n8n-nodes-base.googleSheets",
"position": [
-864,
816
],
"parameters": {
"columns": {
"value": {
"id": "={{ $json.id }}",
"last_fert": "={{ $json.today }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "id",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "plant",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "plant",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "species",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "species",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "indoor",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "indoor",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lat",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "lat",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lon",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "lon",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_water",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "last_water",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "water_freq",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "water_freq",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_fert",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "last_fert",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "fert_freq",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "fert_freq",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_repot",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "last_repot",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "repot_freq",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "repot_freq",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "weather_delay",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "weather_delay",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "thirst_level",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "thirst_level",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit#gid=0",
"cachedResultName": "plants"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZjZAoHTvqzNeqtxqsgshe4YhU07Ad5DEC5SLEdiK_Lk/edit?usp=drivesdk",
"cachedResultName": "Plants Scheudle"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "x23VLPzDtSY8QGZL",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "baff37f4-df01-4765-88ee-f9a1a94e6361",
"name": "如果1",
"type": "n8n-nodes-base.if",
"position": [
-1056,
720
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c00fadf4-2b6f-4084-9566-a40071ea4868",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.action }}",
"rightValue": "water"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d164e45f-f4c9-47ea-b017-65b68a10b41d",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1488,
560
],
"parameters": {
"width": 1504,
"height": 432,
"content": "## 子工作流 Webhook"
},
"typeVersion": 1
},
{
"id": "ee91e133-02bd-4dbd-9ac3-e249dee9a1c5",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1488,
-112
],
"parameters": {
"color": 6,
"width": 2288,
"height": 656,
"content": "## 主工作流"
},
"typeVersion": 1
},
{
"id": "20e8fbbc-bfbf-452c-a17c-08a18e0344c6",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2048,
-112
],
"parameters": {
"color": 3,
"width": 544,
"height": 1296,
"content": "## 🌱 设置与配置指南"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"If": {
"main": [
[
{
"node": "Send Final Message No Dues",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Dues",
"type": "main",
"index": 0
}
]
]
},
"If1": {
"main": [
[
{
"node": "Update Water",
"type": "main",
"index": 0
}
],
[
{
"node": "Update Fert",
"type": "main",
"index": 0
}
]
]
},
"HTML": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "WeatherGate",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Prepare Data",
"type": "main",
"index": 0
}
]
]
},
"DecideDue": {
"main": [
[
{
"node": "¿Pending task?",
"type": "main",
"index": 0
}
]
]
},
"Append Log": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "HTML",
"type": "main",
"index": 0
}
]
]
},
"Read plants": {
"main": [
[
{
"node": "DecideDue",
"type": "main",
"index": 0
}
]
]
},
"Update Fert": {
"main": [
[
{
"node": "Append Log",
"type": "main",
"index": 0
}
]
]
},
"WeatherGate": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Prepare Data": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"Update Water": {
"main": [
[
{
"node": "Append Log",
"type": "main",
"index": 0
}
]
]
},
"Read settings": {
"main": [
[
{
"node": "Vacation Mode",
"type": "main",
"index": 0
}
]
]
},
"Set DecideTag": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Vacation Mode": {
"main": [
[],
[
{
"node": "Read plants",
"type": "main",
"index": 0
}
]
]
},
"Set Weather Tag": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"¿Pending task?": {
"main": [
[
{
"node": "OpenWeather request",
"type": "main",
"index": 0
},
{
"node": "Set DecideTag",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Final Message No Dues1",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Read settings",
"type": "main",
"index": 0
}
]
]
},
"OpenWeather request": {
"main": [
[
{
"node": "Set Weather Tag",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 个人效率
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
来自多个招聘网站的求职自动化
使用 5 个招聘平台和 AI 简历生成器自动化求职与申请
If
Set
Code
+14
34 节点Gerald Denor
个人效率
每日WhatsApp摘要与群组级别控制
WhatsApp群组摘要工作流
If
Set
Code
+13
39 节点Luís Philipe Trindade
个人效率
使用GPT-4o、WordPress和LinkedIn发布自动化RSS内容到博客文章
使用GPT-4o、WordPress和LinkedIn发布自动化RSS内容到博客文章
If
Set
Code
+21
40 节点Immanuel
人工智能
在可视化参考库中探索n8n节点
在可视化参考库中探索n8n节点
If
Ftp
Set
+93
113 节点I versus AI
其他
灵活新闻聚合器 - 多源集成、AI分析和可设置频道
多源新闻策展系统,集成Mistral AI分析、摘要和自定义频道
If
Set
Xml
+32
120 节点Hybroht
内容创作
使用Gemini、语音和图像生成构建多模态Telegram AI助手
使用Gemini、语音和图像生成构建多模态Telegram AI助手
If
Set
Code
+19
95 节点Iniyavan JC
个人效率
工作流信息
难度等级
高级
节点数量27
分类1
节点类型11
作者
Adrian
@nafriExperienced tech professional with 10+ years in Big Data, AI, and automation, former bootcamp director, and passionate about innovation and strategic growth.
外部链接
在 n8n.io 查看 →
分享此工作流