Last active
December 26, 2025 03:59
-
-
Save kkdai/1fa447799a498be089ad56fe95e80a3a to your computer and use it in GitHub Desktop.
N8N 發送 Google Sheet 的資訊
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "nodes": [ | |
| { | |
| "parameters": { | |
| "content": "## ⏰ 定時觸發\n\n每天早上 6:00 執行", | |
| "height": 264, | |
| "width": 220, | |
| "color": 5 | |
| }, | |
| "type": "n8n-nodes-base.stickyNote", | |
| "typeVersion": 1, | |
| "position": [ | |
| -16, | |
| 0 | |
| ], | |
| "id": "4c18ee39-7a7c-473c-916f-7b8bbc93e158", | |
| "name": "Sticky Note - Trigger" | |
| }, | |
| { | |
| "parameters": { | |
| "content": "## 📊 讀取 Google Sheets\n\n篩選 sent=FALSE 的前 10 筆", | |
| "height": 712, | |
| "width": 280, | |
| "color": 4 | |
| }, | |
| "type": "n8n-nodes-base.stickyNote", | |
| "typeVersion": 1, | |
| "position": [ | |
| 224, | |
| 0 | |
| ], | |
| "id": "21b488f5-989f-4036-a787-fc54313fc42e", | |
| "name": "Sticky Note - Read Sheets" | |
| }, | |
| { | |
| "parameters": { | |
| "content": "## 📱 發送 LINE\n\n組合 Flex Message 並發送\n(含摘要統計 Bubble)", | |
| "height": 568, | |
| "width": 400, | |
| "color": 6 | |
| }, | |
| "type": "n8n-nodes-base.stickyNote", | |
| "typeVersion": 1, | |
| "position": [ | |
| 704, | |
| 0 | |
| ], | |
| "id": "d8b3f009-f029-4b1b-8f9d-91ce7ca327dc", | |
| "name": "Sticky Note - LINE" | |
| }, | |
| { | |
| "parameters": { | |
| "content": "## ✅ 更新狀態\n\n將已發送的文章標記為 sent=TRUE", | |
| "height": 568, | |
| "width": 260, | |
| "color": 7 | |
| }, | |
| "type": "n8n-nodes-base.stickyNote", | |
| "typeVersion": 1, | |
| "position": [ | |
| 1120, | |
| 0 | |
| ], | |
| "id": "02956191-b410-4553-995d-236f0df8dbb8", | |
| "name": "Sticky Note - Update" | |
| }, | |
| { | |
| "parameters": { | |
| "content": "## 🔀 檢查是否有文章\n\n有文章 → 發送\n無文章 → 跳過或通知", | |
| "height": 264, | |
| "width": 200, | |
| "color": 3 | |
| }, | |
| "type": "n8n-nodes-base.stickyNote", | |
| "typeVersion": 1, | |
| "position": [ | |
| 524, | |
| 0 | |
| ], | |
| "id": "sticky-check-articles", | |
| "name": "Sticky Note - Check" | |
| }, | |
| { | |
| "parameters": { | |
| "content": "## ⚙️ 設定說明\n\n使用前請先設定:\n1. Google Sheets Credentials\n2. LINE Channel Access Token (Header Auth)\n3. 替換 YOUR_LINE_USER_ID\n4. 替換 Google Sheets 文件 ID", | |
| "height": 200, | |
| "width": 300, | |
| "color": 1 | |
| }, | |
| "type": "n8n-nodes-base.stickyNote", | |
| "typeVersion": 1, | |
| "position": [ | |
| -16, | |
| 300 | |
| ], | |
| "id": "sticky-setup-guide", | |
| "name": "Sticky Note - Setup" | |
| }, | |
| { | |
| "parameters": { | |
| "rule": { | |
| "interval": [ | |
| { | |
| "field": "hours", | |
| "hoursInterval": 24 | |
| } | |
| ] | |
| } | |
| }, | |
| "type": "n8n-nodes-base.scheduleTrigger", | |
| "typeVersion": 1.2, | |
| "position": [ | |
| 16, | |
| 112 | |
| ], | |
| "id": "e9dfe487-7395-4a3b-9b20-f80ef199aec8", | |
| "name": "每日 6:00 觸發" | |
| }, | |
| { | |
| "parameters": { | |
| "documentId": { | |
| "__rl": true, | |
| "value": "YOUR_GOOGLE_SHEET_ID", | |
| "mode": "id" | |
| }, | |
| "sheetName": { | |
| "__rl": true, | |
| "value": "RSS_Feeds", | |
| "mode": "name" | |
| }, | |
| "options": {} | |
| }, | |
| "type": "n8n-nodes-base.googleSheets", | |
| "typeVersion": 4.5, | |
| "position": [ | |
| 288, | |
| 112 | |
| ], | |
| "id": "69721bfa-0fdd-4a4c-83e5-c87c67d4fd5c", | |
| "name": "Read Google Sheets" | |
| }, | |
| { | |
| "parameters": { | |
| "conditions": { | |
| "options": { | |
| "caseSensitive": false, | |
| "leftValue": "", | |
| "typeValidation": "loose", | |
| "version": 2 | |
| }, | |
| "conditions": [ | |
| { | |
| "id": "filter-sent", | |
| "leftValue": "={{ $json.sent }}", | |
| "rightValue": "TRUE", | |
| "operator": { | |
| "type": "string", | |
| "operation": "notEquals" | |
| } | |
| } | |
| ], | |
| "combinator": "and" | |
| }, | |
| "options": {} | |
| }, | |
| "type": "n8n-nodes-base.filter", | |
| "typeVersion": 2.2, | |
| "position": [ | |
| 288, | |
| 320 | |
| ], | |
| "id": "981ab90a-8329-4152-ac2d-2a6f77d0eae2", | |
| "name": "Filter Unsent" | |
| }, | |
| { | |
| "parameters": { | |
| "aggregate": "aggregateAllItemData", | |
| "options": {} | |
| }, | |
| "type": "n8n-nodes-base.aggregate", | |
| "typeVersion": 1, | |
| "position": [ | |
| 464, | |
| 560 | |
| ], | |
| "id": "9aecc555-50e8-47e9-923b-0d728c9326a7", | |
| "name": "Aggregate Items" | |
| }, | |
| { | |
| "parameters": { | |
| "conditions": { | |
| "options": { | |
| "caseSensitive": true, | |
| "leftValue": "", | |
| "typeValidation": "strict", | |
| "version": 2 | |
| }, | |
| "conditions": [ | |
| { | |
| "id": "check-has-items", | |
| "leftValue": "={{ $json.data.length }}", | |
| "rightValue": 0, | |
| "operator": { | |
| "type": "number", | |
| "operation": "gt" | |
| } | |
| } | |
| ], | |
| "combinator": "and" | |
| }, | |
| "options": {} | |
| }, | |
| "type": "n8n-nodes-base.if", | |
| "typeVersion": 2.2, | |
| "position": [ | |
| 560, | |
| 112 | |
| ], | |
| "id": "if-has-articles", | |
| "name": "有文章?" | |
| }, | |
| { | |
| "parameters": { | |
| "jsCode": "const items = $input.first().json.data || [];\nconst today = new Date().toLocaleDateString('zh-TW', {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit'\n});\n\n// 來源對應 emoji(可自行擴充)\nconst sourceEmoji = {\n 'DK': '📝',\n 'HN': '🔥',\n 'Steam': '🎮',\n 'LY Blog': '🇯🇵'\n};\n\n// 來源對應顏色(可自行擴充)\nconst sourceColor = {\n 'DK': '#4A90A4',\n 'HN': '#FF6600',\n 'Steam': '#1B2838',\n 'LY Blog': '#00C300'\n};\n\n// ===== 建立摘要統計 Bubble =====\nconst sourceCounts = {};\nitems.forEach(item => {\n const src = item.source || 'Unknown';\n sourceCounts[src] = (sourceCounts[src] || 0) + 1;\n});\n\n// 建立來源統計列表\nconst sourceStats = Object.entries(sourceCounts).map(([source, count]) => {\n const emoji = sourceEmoji[source] || '📰';\n return {\n \"type\": \"box\",\n \"layout\": \"horizontal\",\n \"contents\": [\n {\n \"type\": \"text\",\n \"text\": `${emoji} ${source}`,\n \"size\": \"sm\",\n \"color\": \"#555555\",\n \"flex\": 4\n },\n {\n \"type\": \"text\",\n \"text\": `${count} 篇`,\n \"size\": \"sm\",\n \"color\": \"#111111\",\n \"align\": \"end\",\n \"flex\": 1\n }\n ]\n };\n});\n\n// 摘要 Bubble\nconst summaryBubble = {\n \"type\": \"bubble\",\n \"size\": \"kilo\",\n \"header\": {\n \"type\": \"box\",\n \"layout\": \"vertical\",\n \"contents\": [\n {\n \"type\": \"text\",\n \"text\": \"📊 今日摘要\",\n \"weight\": \"bold\",\n \"size\": \"lg\",\n \"color\": \"#1DB446\"\n },\n {\n \"type\": \"text\",\n \"text\": today,\n \"size\": \"xs\",\n \"color\": \"#999999\",\n \"margin\": \"sm\"\n }\n ],\n \"paddingAll\": \"15px\",\n \"backgroundColor\": \"#F5F5F5\"\n },\n \"body\": {\n \"type\": \"box\",\n \"layout\": \"vertical\",\n \"contents\": [\n {\n \"type\": \"box\",\n \"layout\": \"horizontal\",\n \"contents\": [\n {\n \"type\": \"text\",\n \"text\": \"總計\",\n \"size\": \"md\",\n \"color\": \"#555555\",\n \"weight\": \"bold\",\n \"flex\": 4\n },\n {\n \"type\": \"text\",\n \"text\": `${items.length} 篇`,\n \"size\": \"md\",\n \"color\": \"#1DB446\",\n \"weight\": \"bold\",\n \"align\": \"end\",\n \"flex\": 1\n }\n ]\n },\n {\n \"type\": \"separator\",\n \"margin\": \"lg\"\n },\n {\n \"type\": \"box\",\n \"layout\": \"vertical\",\n \"contents\": sourceStats,\n \"margin\": \"lg\",\n \"spacing\": \"sm\"\n }\n ],\n \"paddingAll\": \"15px\"\n }\n};\n\n// ===== 建立每篇文章的 bubble =====\nconst articleBubbles = items.map((item, index) => {\n const emoji = sourceEmoji[item.source] || '📰';\n const color = sourceColor[item.source] || '#666666';\n \n const title = item.title || item.col_1 || item.link || '無標題';\n const summary = item.summary || '無摘要內容';\n const link = item.link || 'https://example.com';\n \n return {\n \"type\": \"bubble\",\n \"size\": \"kilo\",\n \"header\": {\n \"type\": \"box\",\n \"layout\": \"horizontal\",\n \"contents\": [\n {\n \"type\": \"text\",\n \"text\": emoji,\n \"size\": \"sm\",\n \"flex\": 0\n },\n {\n \"type\": \"text\",\n \"text\": item.source || 'Unknown',\n \"size\": \"sm\",\n \"color\": color,\n \"weight\": \"bold\",\n \"margin\": \"sm\"\n }\n ],\n \"paddingAll\": \"12px\",\n \"backgroundColor\": \"#F5F5F5\"\n },\n \"body\": {\n \"type\": \"box\",\n \"layout\": \"vertical\",\n \"contents\": [\n {\n \"type\": \"text\",\n \"text\": title,\n \"weight\": \"bold\",\n \"size\": \"md\",\n \"wrap\": true,\n \"maxLines\": 2\n },\n {\n \"type\": \"text\",\n \"text\": summary,\n \"size\": \"sm\",\n \"color\": \"#666666\",\n \"wrap\": true,\n \"margin\": \"md\",\n \"maxLines\": 5\n }\n ],\n \"paddingAll\": \"12px\"\n },\n \"footer\": {\n \"type\": \"box\",\n \"layout\": \"vertical\",\n \"contents\": [\n {\n \"type\": \"button\",\n \"action\": {\n \"type\": \"uri\",\n \"label\": \"閱讀原文\",\n \"uri\": link\n },\n \"style\": \"primary\",\n \"color\": color,\n \"height\": \"sm\"\n }\n ],\n \"paddingAll\": \"12px\"\n }\n };\n});\n\n// 組合:摘要 + 文章們\nconst allBubbles = [summaryBubble, ...articleBubbles];\n\n// 組合成 carousel\nconst flexMessage = {\n \"type\": \"flex\",\n \"altText\": `📰 每日資訊摘要 - ${today} (${items.length}篇)`,\n \"contents\": {\n \"type\": \"carousel\",\n \"contents\": allBubbles\n }\n};\n\n// 回傳 Flex Message 和原始 items (供後續更新用)\nreturn {\n json: {\n flexMessage,\n items,\n rowNumbers: items.map((item, idx) => item.row_number)\n }\n};" | |
| }, | |
| "type": "n8n-nodes-base.code", | |
| "typeVersion": 2, | |
| "position": [ | |
| 752, | |
| 112 | |
| ], | |
| "id": "c326027c-5dac-453b-b8eb-b834856f5685", | |
| "name": "Build Flex Message" | |
| }, | |
| { | |
| "parameters": { | |
| "method": "POST", | |
| "url": "https://api.line.me/v2/bot/message/push", | |
| "authentication": "genericCredentialType", | |
| "genericAuthType": "httpHeaderAuth", | |
| "sendBody": true, | |
| "specifyBody": "json", | |
| "jsonBody": "={\n \"to\": \"YOUR_LINE_USER_ID\",\n \"messages\": [\n {{ JSON.stringify($json.flexMessage) }}\n ]\n}", | |
| "options": {} | |
| }, | |
| "type": "n8n-nodes-base.httpRequest", | |
| "typeVersion": 4.2, | |
| "position": [ | |
| 944, | |
| 112 | |
| ], | |
| "id": "fddc401e-32e0-4e9d-9521-aa437009f78f", | |
| "name": "LINE Push Message" | |
| }, | |
| { | |
| "parameters": { | |
| "jsCode": "// 取得要更新的 items\nconst items = $('Build Flex Message').first().json.items;\n\n// 為每個 item 建立更新資料\nreturn items.map(item => ({\n json: {\n title: item.title,\n link: item.link,\n summary: item.summary,\n source: item.source,\n created_at: item.created_at,\n sent: 'TRUE'\n }\n}));\n" | |
| }, | |
| "type": "n8n-nodes-base.code", | |
| "typeVersion": 2, | |
| "position": [ | |
| 1168, | |
| 112 | |
| ], | |
| "id": "70cdc265-82b5-4067-9519-4b7e653953b8", | |
| "name": "Prepare Update Data" | |
| }, | |
| { | |
| "parameters": { | |
| "operation": "update", | |
| "documentId": { | |
| "__rl": true, | |
| "value": "YOUR_GOOGLE_SHEET_ID", | |
| "mode": "id" | |
| }, | |
| "sheetName": { | |
| "__rl": true, | |
| "value": "RSS_Feeds", | |
| "mode": "name" | |
| }, | |
| "columns": { | |
| "mappingMode": "defineBelow", | |
| "value": { | |
| "sent": "={{ $json.sent }}", | |
| "row_number": 0, | |
| "link": "={{ $json.link }}" | |
| }, | |
| "matchingColumns": [ | |
| "link" | |
| ], | |
| "schema": [ | |
| { | |
| "id": "link", | |
| "displayName": "link", | |
| "required": false, | |
| "defaultMatch": false, | |
| "display": true, | |
| "type": "string", | |
| "canBeUsedToMatch": true, | |
| "removed": false | |
| }, | |
| { | |
| "id": "summary", | |
| "displayName": "summary", | |
| "required": false, | |
| "defaultMatch": false, | |
| "display": true, | |
| "type": "string", | |
| "canBeUsedToMatch": true, | |
| "removed": false | |
| }, | |
| { | |
| "id": "source", | |
| "displayName": "source", | |
| "required": false, | |
| "defaultMatch": false, | |
| "display": true, | |
| "type": "string", | |
| "canBeUsedToMatch": true, | |
| "removed": false | |
| }, | |
| { | |
| "id": "created_at", | |
| "displayName": "created_at", | |
| "required": false, | |
| "defaultMatch": false, | |
| "display": true, | |
| "type": "string", | |
| "canBeUsedToMatch": true, | |
| "removed": false | |
| }, | |
| { | |
| "id": "sent", | |
| "displayName": "sent", | |
| "required": false, | |
| "defaultMatch": false, | |
| "display": true, | |
| "type": "string", | |
| "canBeUsedToMatch": true | |
| }, | |
| { | |
| "id": "row_number", | |
| "displayName": "row_number", | |
| "required": false, | |
| "defaultMatch": false, | |
| "display": true, | |
| "type": "number", | |
| "canBeUsedToMatch": true, | |
| "readOnly": true, | |
| "removed": false | |
| } | |
| ], | |
| "attemptToConvertTypes": false, | |
| "convertFieldsToString": false | |
| }, | |
| "options": { | |
| "cellFormat": "USER_ENTERED" | |
| } | |
| }, | |
| "type": "n8n-nodes-base.googleSheets", | |
| "typeVersion": 4.5, | |
| "position": [ | |
| 1168, | |
| 352 | |
| ], | |
| "id": "65af66ad-73e0-49d6-b397-88751d0a6da9", | |
| "name": "Update sent=TRUE" | |
| }, | |
| { | |
| "parameters": { | |
| "maxItems": 10 | |
| }, | |
| "type": "n8n-nodes-base.limit", | |
| "typeVersion": 1, | |
| "position": [ | |
| 304, | |
| 560 | |
| ], | |
| "id": "1f7c99de-ab8e-4459-b48b-ded2bd1944eb", | |
| "name": "Limit 10" | |
| }, | |
| { | |
| "parameters": {}, | |
| "type": "n8n-nodes-base.noOp", | |
| "typeVersion": 1, | |
| "position": [ | |
| 752, | |
| 320 | |
| ], | |
| "id": "no-op-skip", | |
| "name": "無文章 - 跳過" | |
| } | |
| ], | |
| "connections": { | |
| "每日 6:00 觸發": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Read Google Sheets", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Read Google Sheets": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Filter Unsent", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Filter Unsent": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Limit 10", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Limit 10": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Aggregate Items", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Aggregate Items": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "有文章?", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "有文章?": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Build Flex Message", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ], | |
| [ | |
| { | |
| "node": "無文章 - 跳過", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Build Flex Message": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "LINE Push Message", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "LINE Push Message": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Prepare Update Data", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| }, | |
| "Prepare Update Data": { | |
| "main": [ | |
| [ | |
| { | |
| "node": "Update sent=TRUE", | |
| "type": "main", | |
| "index": 0 | |
| } | |
| ] | |
| ] | |
| } | |
| }, | |
| "pinData": {}, | |
| "meta": { | |
| "templateCredsSetupCompleted": true | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment