{"id":"bpwcitkNoQVWlaiX","meta":{"instanceId":"7aaad48c714db2d503d009516f7b1f7c2a87eb30bffff4a635c76d7ede586a84"},"name":"Route NASA DONKI space-weather alerts to Slack and Google Sheets","tags":[],"nodes":[{"id":"ad59916d-079b-4ca4-833d-d59051c977f9","name":"Cron","type":"n8n-nodes-base.scheduleTrigger","position":[-1088,704],"parameters":{"rule":{"interval":[{"field":"minutes","minutesInterval":30}]}},"typeVersion":1.2},{"id":"1652b5c1-281f-4d66-a5c8-989aa8e29fa9","name":"NASA DONKI Notifications","type":"n8n-nodes-base.nasa","position":[-864,704],"parameters":{"resource":"donkiNotifications","additionalFields":{"endDate":"={{ $now.toFormat('yyyy-MM-dd') }}","startDate":"={{ $now.minus(1, 'day').toFormat('yyyy-MM-dd') }}"}},"typeVersion":1},{"id":"cad0aeeb-a843-4978-bcd2-be399684117c","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[80,416],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4.1-mini"},"options":{}},"typeVersion":1.2},{"id":"1bfddfd0-2b11-4e05-aec1-bb674f6fcbb6","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1376,688],"parameters":{"content":"## Cron\nTriggers the workflow to run automatically every 30 minutes."},"typeVersion":1},{"id":"3030ed59-8f04-4731-a190-055f31b1bf56","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-928,496],"parameters":{"content":"## NASA DONKI Notifications\nFetches the latest space weather data from the NASA DONKI API for the past 24 hours."},"typeVersion":1},{"id":"5c7e795b-c06f-45b0-b36e-10b566d91c48","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1968,576],"parameters":{"color":5,"width":576,"height":432,"content":"## Workflow Overview\nThis workflow monitors NASA’s space-weather feed and notifies your team about important events while quietly logging routine items for later review. A Cron trigger runs the flow every 30 minutes, then the NASA DONKI node fetches all notifications from the past 24 hours (e.g., CMEs, solar flares, SEPs). A custom “Analyze & Prioritize Events” code step deduplicates entries, identifies the event type, and assigns a severity label (CRITICAL, HIGH, or OTHER). A Switch node then routes each item based on that severity.\nFor CRITICAL items, an LLM (“AI Agent — Critical”) turns the raw message into a short, urgent Japanese alert. That alert is posted to Slack in a clearly formatted message that includes the event time and the official reference link. HIGH items follow a similar path with a slightly less urgent tone via a separate LLM and Slack message.\nEverything else (informational or low-impact events) is summarized by a third LLM (“AI Agent — for Sheets”) in a concise, scannable style. A small merge step combines the summary with structured fields (type, ID, severity, time, link, details), and the result is appended as a new row in Google Sheets for tracking and later analysis.\nSticky Notes embedded in the canvas document the schedule, data source, and high-level flow so template users can understand and customize the setup quickly."},"typeVersion":1},{"id":"a82035ae-30bd-4b58-a655-3ad770546d29","name":"AI Agent (Critical)","type":"@n8n/n8n-nodes-langchain.agent","position":[0,192],"parameters":{"text":"=あなたは危機管理を担当する宇宙科学の専門家です。\n以下のJSON形式の宇宙天気イベントは「CRITICAL (緊急)」と判定されました。\n\n{{ $json.messageBody }}\n\nこのイベントが地球上の「通信システム、電力網、人工衛星」に及ぼす潜在的な影響と最悪のシナリオを、専門用語を一切使わずに、誰にでも危険性が伝わるように具体的に解説してください。\n箇条書きで、簡潔に、力強くまとめてください。\n**必ず、すべての出力を日本語にしてください。**","options":{},"promptType":"define"},"typeVersion":3},{"id":"9cfba52b-b5d3-4bb3-b9c3-baba0dda1a67","name":"Slack Notify (Critical)","type":"n8n-nodes-base.slack","position":[352,304],"webhookId":"abee6bec-a260-48ee-9941-0c0bdb02f245","parameters":{"text":"=<!channel> 🔴 緊急警報：宇宙天気イベント 🔴\n\n{{ $('AI Agent (Critical)').item.json.output }}\n\n---\nイベントタイプ: {{ $json.eventType }}\n発生時刻: {{ new Date($json.time).toLocaleString('ja-JP') }}\n詳細情報: {{ $json.link }}","select":"channel","channelId":{"__rl":true,"mode":"name","value":"#general"},"otherOptions":{},"authentication":"oAuth2"},"typeVersion":2.3},{"id":"85682255-9942-4ae1-9a44-619e231decfb","name":"Analyze & Prioritize Events","type":"n8n-nodes-base.code","position":[-576,704],"parameters":{"jsCode":"// Deduplication using Workflow Static Data\nconst staticData = $getWorkflowStaticData('global');\nif (!staticData.seenEventIds) {\n  staticData.seenEventIds = [];\n}\n\n// Filter and process events\nconst newEvents = [];\nfor (const item of $input.all()) {\n  const eventId = item.json.activityID || item.json.messageID;\n  \n  // Skip if already seen\n  if (staticData.seenEventIds.includes(eventId)) {\n    continue;\n  }\n  \n  // Add to seen events\n  staticData.seenEventIds.push(eventId);\n  \n  // Keep only last 1000 event IDs to prevent unlimited growth\n  if (staticData.seenEventIds.length > 1000) {\n    staticData.seenEventIds.shift();\n  }\n  \n  // Determine event type and severity\n  let eventType = item.json.messageType || 'Unknown';\n  let severity = 'INFO'; // Default severity\n  \n  if (eventType.includes('FLR')) { // Solar Flare\n    const flareClass = item.json.classType || '';\n    if (flareClass.startsWith('X')) {\n      severity = 'CRITICAL';\n    } else if (flareClass.startsWith('M')) {\n      severity = 'HIGH';\n    } else {\n      severity = 'MEDIUM';\n    }\n  } else if (eventType.includes('CME')) { // Coronal Mass Ejection\n    const speed = item.json.speed || 0;\n    if (speed > 1500) {\n      severity = 'CRITICAL';\n    } else if (speed > 1000) {\n      severity = 'HIGH';\n    } else {\n      severity = 'MEDIUM';\n    }\n  } else if (eventType.includes('GST')) { // Geomagnetic Storm\n    severity = 'HIGH'; // GST alerts are generally significant.\n  }\n  \n  newEvents.push({\n    json: { // Keep the original structure for subsequent nodes\n      eventId,\n      eventType,\n      severity, // Add our calculated severity\n      time: item.json.messageIssueTime || item.json.beginTime || new Date().toISOString(),\n      link: item.json.link || 'N/A',\n      messageBody: item.json.messageBody, // Pass the original message body\n      details: item.json\n    }\n  });\n}\n\n// Return only the new, processed events\nreturn newEvents;"},"typeVersion":2},{"id":"cd26ac0d-15d3-452c-a6fa-52d0f82e5e61","name":"Switch","type":"n8n-nodes-base.switch","position":[-304,688],"parameters":{"rules":{"values":[{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"5e8c89ac-b3ab-4716-84cc-ee7a500d1e2b","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.severity }}","rightValue":"CRITICAL"}]}},{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"c668b3af-35c1-4a07-abd4-88bcc213a71e","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.severity }}","rightValue":"HIGH"}]}},{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"3651b6f0-6846-4b0c-beea-da3d568c65af","operator":{"type":"string","operation":"notEmpty","singleValue":true},"leftValue":"={{ $json.severity }}","rightValue":""}]}}]},"options":{}},"typeVersion":3.3,"alwaysOutputData":false},{"id":"a3730809-60eb-4306-bd34-b7d8733ccc41","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[80,928],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4.1-mini"},"options":{}},"credentials":{"openAiApi":{"id":"jvk7Fyof6QJhxv99","name":"OpenAi account"}},"typeVersion":1.2},{"id":"eabd1129-daf4-4266-86fb-525413bfd900","name":"AI Agent (High)","type":"@n8n/n8n-nodes-langchain.agent","position":[0,704],"parameters":{"text":"=あなたは宇宙科学の専門家で、複雑なデータを一般の人にも分かりやすく説明するのが得意です。\n以下のJSON形式の宇宙天気イベントについて、平易な言葉で解説してください。\n\n{{ $json.messageBody }}\n\n太陽フレア（FLR）の場合はその規模、コロナ質量放出（CME）の場合はその速度に触れてください。\n**必ず、すべての出力を日本語にしてください。**","options":{},"promptType":"define"},"typeVersion":3},{"id":"9a66ab25-d573-46cd-bea6-1699a4e75f25","name":"Slack Notify (High)","type":"n8n-nodes-base.slack","position":[352,704],"webhookId":"abee6bec-a260-48ee-9941-0c0bdb02f245","parameters":{"text":"=🟡 高レベル宇宙天気情報 🟡\n\n{{ $('AI Agent (High)').item.json.output }}\n\n---\nイベントタイプ: {{ $json.eventType }}\n発生時刻: {{ new Date($json.time).toLocaleString('ja-JP') }}\n詳細情報: {{ $json.link }}","select":"channel","channelId":{"__rl":true,"mode":"name","value":"#general"},"otherOptions":{},"authentication":"oAuth2"},"credentials":{"slackOAuth2Api":{"id":"JuiRbsWlx6f6Pk4q","name":"Slack account"}},"typeVersion":2.3},{"id":"d84b4274-067b-4709-a8d1-7601ddeb78b3","name":"Append row in sheet","type":"n8n-nodes-base.googleSheets","position":[640,1200],"parameters":{"columns":{"value":{"time":"={{ $json.time }}"," link":"={{ $json.link }}","details":"={{ $json.details }}","eventId":"={{ $json.eventId }}","severity":"={{ $json.severity }}","eventType":"={{ $json.eventType }}"},"schema":[{"id":"eventId","type":"string","display":true,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventType","type":"string","display":true,"required":false,"displayName":"eventType","defaultMatch":false,"canBeUsedToMatch":true},{"id":"severity","type":"string","display":true,"required":false,"displayName":"severity","defaultMatch":false,"canBeUsedToMatch":true},{"id":"time","type":"string","display":true,"required":false,"displayName":"time","defaultMatch":false,"canBeUsedToMatch":true},{"id":" link","type":"string","display":true,"required":false,"displayName":" link","defaultMatch":false,"canBeUsedToMatch":true},{"id":"details","type":"string","display":true,"required":false,"displayName":"details","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":1384917801,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1fZf14pfCSRZV4wQKt0DAvixcDdqLHSonK2BjE8SCNCA/edit#gid=1384917801","cachedResultName":"nasa_news"},"documentId":{"__rl":true,"mode":"list","value":"1fZf14pfCSRZV4wQKt0DAvixcDdqLHSonK2BjE8SCNCA","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1fZf14pfCSRZV4wQKt0DAvixcDdqLHSonK2BjE8SCNCA/edit?usp=drivesdk","cachedResultName":"n8n_連携シート"}},"typeVersion":4.7},{"id":"0afa027b-35d1-454e-9874-1d2c0c6bfb20","name":"OpenAI Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[112,1408],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4.1-mini"},"options":{}},"credentials":{"openAiApi":{"id":"jvk7Fyof6QJhxv99","name":"OpenAi account"}},"typeVersion":1.2},{"id":"38c796ac-3004-4a45-82c6-7212c8ab0cf7","name":"AI Agent (for Sheets)","type":"@n8n/n8n-nodes-langchain.agent","position":[96,1200],"parameters":{"text":"=あなたは宇宙科学の専門家です。\n以下のJSON形式の宇宙天気イベントのデータを、後から人間がスプレッドシートで見返すことを想定して、何が起こったのかが1〜2行で簡潔にわかる日本語の概要を作成してください。\n\n{{ $json.messageBody }}\n\n専門用語は避け、最も重要な事実だけを記述してください。","options":{},"promptType":"define"},"typeVersion":3},{"id":"ba5d841b-d14b-43e7-b6ff-7eb46e8b1ec0","name":"Merge Summary & Data (Code)","type":"n8n-nodes-base.code","position":[432,1200],"parameters":{"jsCode":"const finalData = {};\n\n// 4. 必要なデータを一つずつ finalData に追加していきます。\nfinalData.summary_jp = $input.first().json.output\nfinalData.eventId = $('Switch').first().json.eventId;\nfinalData.eventType = $('Switch').first().json.eventType;\nfinalData.severity = $('Switch').first().json.severity;\nfinalData.time = $('Switch').first().json.time;\nfinalData.link = $('Switch').first().json.link;\nfinalData.details = $('Switch').first().json.details;\n\n// 5. 完成したデータを次のノード（Google Sheets）に渡します\nreturn finalData;"},"typeVersion":2},{"id":"93c7842d-d4e0-402b-8f1a-23146d01b090","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"content":"## AI Agent (Critical)\nTakes CRITICAL-severity events and drafts a short, forceful Japanese alert that highlights the phenomenon, likely impact, and what to watch next."},"typeVersion":1},{"id":"88f4d702-895f-4fba-8080-489fa08cb810","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[368,80],"parameters":{"width":336,"content":"## Slack Notify (Critical)\nPosts an @channel emergency message to Slack with the agent’s summary, the event time (localized), and the official reference link."},"typeVersion":1},{"id":"8969d0db-e826-405b-9168-297f0b8e00c9","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[304,528],"parameters":{"content":"## Slack Notify (High)\nSends a Slack post for HIGH-priority events with the agent’s summary, localized time, and source link to keep teams informed."},"typeVersion":1},{"id":"ef18ba69-3b7f-4ebe-a4a9-1719d380ad5b","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-416,480],"parameters":{"content":"## Switch\nRoutes each processed event to the appropriate branch based on the computed severity: CRITICAL, HIGH, or “everything else.”"},"typeVersion":1},{"id":"a85b7c43-bc70-46c7-91c1-1466f22f4fe0","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[0,544],"parameters":{"content":"## AI Agent (High)\nConverts HIGH-severity items into clear Japanese updates that are informative but less urgent in tone than the critical alerts."},"typeVersion":1},{"id":"82040817-eeb6-4a8e-8e74-40da934f18a5","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[528,1024],"parameters":{"width":368,"content":"## Append row in sheet\nAppends non-urgent events to a specified Google Sheet (e.g., nasa_news) with columns such as eventType, eventId, severity, time, link, details, and a summary for later review."},"typeVersion":1},{"id":"a1897c58-844a-4a68-8c03-b0d82cad9a58","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[416,1408],"parameters":{"width":400,"content":"## Merge Summary & Data (Code)\nCombines the Sheets-oriented summary with the event’s structured fields (ID, type, severity, time, link, details) into a single payload for the Google Sheets node."},"typeVersion":1},{"id":"866e778d-8fcd-4b92-a9cf-20a9ed5bc641","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[-208,1296],"parameters":{"height":192,"content":"## AI Agent (for Sheets)\nProduces a concise Japanese summary focusing on key facts only, suitable for spreadsheet rows and quick, future reference."},"typeVersion":1},{"id":"eebc7155-b872-4637-82db-5682278a64b4","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[-704,896],"parameters":{"width":352,"content":"## Analyze & Prioritize Events\nRuns custom JavaScript to deduplicate by event/message ID, classify the event type, and assign a severity label (e.g., CRITICAL, HIGH, or other) before routing."},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"f4128553-f03d-446d-a761-c5508074deeb","connections":{"Cron":{"main":[[{"node":"NASA DONKI Notifications","type":"main","index":0}]]},"Switch":{"main":[[{"node":"AI Agent (Critical)","type":"main","index":0}],[{"node":"AI Agent (High)","type":"main","index":0}],[{"node":"AI Agent (for Sheets)","type":"main","index":0}]]},"AI Agent (High)":{"main":[[{"node":"Slack Notify (High)","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent (Critical)","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"AI Agent (High)","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model2":{"ai_languageModel":[[{"node":"AI Agent (for Sheets)","type":"ai_languageModel","index":0}]]},"AI Agent (Critical)":{"main":[[{"node":"Slack Notify (Critical)","type":"main","index":0}]]},"AI Agent (for Sheets)":{"main":[[{"node":"Merge Summary & Data (Code)","type":"main","index":0}]]},"NASA DONKI Notifications":{"main":[[{"node":"Analyze & Prioritize Events","type":"main","index":0}]]},"Analyze & Prioritize Events":{"main":[[{"node":"Switch","type":"main","index":0}]]},"Merge Summary & Data (Code)":{"main":[[{"node":"Append row in sheet","type":"main","index":0}]]}}}