Fork of Lightning_Report adding: - n8n_report_branch.json: workflow branch for storm-triggered report delivery - report_service/: FastAPI microservice wrapping create_docx_report() so n8n can produce byte-identical reports without fighting the Python Code sandbox Made-with: Cursor
198 lines
12 KiB
JSON
198 lines
12 KiB
JSON
{
|
|
"name": "Lightning Report Branch (paste into Lightning_Report_Automatic)",
|
|
"nodes": [
|
|
{
|
|
"parameters": {
|
|
"assignments": {
|
|
"assignments": [
|
|
{ "id": "rpt-cid", "name": "customer_id", "value": "={{ $('Loop Over Items').item.json.id }}", "type": "string" },
|
|
{ "id": "rpt-cname", "name": "customer_name", "value": "={{ $('Loop Over Items').item.json.customer_name }}", "type": "string" },
|
|
{ "id": "rpt-tz", "name": "timezone", "value": "={{ $('Loop Over Items').item.json.timezone || 'Europe/Istanbul' }}", "type": "string" },
|
|
{ "id": "rpt-clat", "name": "centroid_lat", "value": "={{ $('Centroid & Distance Ring calculation').item.json.centroid_latitude }}", "type": "number" },
|
|
{ "id": "rpt-clon", "name": "centroid_lon", "value": "={{ $('Centroid & Distance Ring calculation').item.json.centroid_longitude }}", "type": "number" },
|
|
{ "id": "rpt-bnd", "name": "boundary_m", "value": "={{ $('Centroid & Distance Ring calculation').item.json.monitoring_boundary_m }}","type": "number" },
|
|
{ "id": "rpt-rings", "name": "rings", "value": "={{ $('Centroid & Distance Ring calculation').item.json.rings }}", "type": "object" },
|
|
{ "id": "rpt-rcolors", "name": "ring_colors", "value": "={{ [\"#B71C1C\", \"#F94144\", \"#F8961E\", \"#90BE6D\"] }}", "type": "array" },
|
|
{ "id": "rpt-ts", "name": "t_start", "value": "={{ $('Logic Gate').item.json.tStart }}", "type": "number" },
|
|
{ "id": "rpt-te", "name": "t_end", "value": "={{ $('Logic Gate').item.json.tLast }}", "type": "number" },
|
|
{ "id": "rpt-ns", "name": "n_strikes", "value": "={{ $('Logic Gate').item.json.allStrikes.length }}", "type": "number" },
|
|
{ "id": "rpt-strikes", "name": "strikes", "value": "={{ $('Logic Gate').item.json.allStrikes }}", "type": "array" },
|
|
{ "id": "rpt-turbines", "name": "turbines", "value": "={{ $('Get Customer Wind Turbines').all().map(t => t.json) }}", "type": "array" }
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.4,
|
|
"position": [3440, 480],
|
|
"id": "a1a1a1a1-0001-4a01-8a01-000000000001",
|
|
"name": "Report: Gather Inputs"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "const crypto = require('crypto');\nconst HMAC_SECRET = 'c88f845bd6d520ded507ef6b02efc223019ccf68f41d9070705712d480ba5166';\nconst URI = '/v1/thunderstorms/within';\n\nconst ctx = $('Report: Gather Inputs').item.json;\nconst auth = $('Restore Credentials').all().pop().json;\n\nif (!ctx.t_start || !ctx.t_end) {\n throw new Error('Missing storm timestamps from Logic Gate.');\n}\n\nconst durationSeconds = Math.max(600, Math.floor((ctx.t_end - ctx.t_start) / 1000));\nconst timestamp = Date.now().toString();\n\nconst bodyPayload = {\n latitude: Number(Number(ctx.centroid_lat).toFixed(6)),\n longitude: Number(Number(ctx.centroid_lon).toFixed(6)),\n radius: parseInt(ctx.boundary_m, 10),\n backwardInterval: durationSeconds,\n endTimeEpoch: Number(ctx.t_end),\n intersectsWith: 'THREAT_POLYGON',\n pageNumber: 0,\n pageSize: 100\n};\n\nconst bodyString = JSON.stringify(bodyPayload);\nconst dataToSign = `POST|${URI}|${timestamp}|${bodyString}`;\nconst signature = crypto.createHmac('sha256', HMAC_SECRET).update(dataToSign).digest('hex').toLowerCase();\n\nreturn [{\n json: {\n requestBody: bodyPayload,\n headers: {\n 'X-Signature': signature,\n 'X-Timestamp': timestamp,\n 'X-Nonce': crypto.randomUUID(),\n 'X-Idempotency-Key': crypto.randomUUID(),\n 'Authorization': 'Bearer ' + auth.accessToken,\n 'Content-Type': 'application/json'\n }\n }\n}];"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [3680, 480],
|
|
"id": "a2a2a2a2-0002-4a02-8a02-000000000002",
|
|
"name": "Report: Calc Thunderstorm Headers"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "https://api-test.iklim.co/v1/thunderstorms/within",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{ "name": "Authorization", "value": "={{ $json.headers.Authorization }}" },
|
|
{ "name": "X-Signature", "value": "={{ $json.headers['X-Signature'] }}" },
|
|
{ "name": "X-Timestamp", "value": "={{ $json.headers['X-Timestamp'] }}" },
|
|
{ "name": "X-Nonce", "value": "={{ $json.headers['X-Nonce'] }}" },
|
|
{ "name": "X-Idempotency-Key", "value": "={{ $json.headers['X-Idempotency-Key'] }}" },
|
|
{ "name": "Content-Type", "value": "={{ $json.headers['Content-Type'] }}" },
|
|
{ "name": "Accept", "value": "={{ $json.headers['Content-Type'] }}" }
|
|
]
|
|
},
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ $json.requestBody }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.3,
|
|
"position": [3920, 480],
|
|
"id": "a3a3a3a3-0003-4a03-8a03-000000000003",
|
|
"name": "Report: Fetch Thunderstorms",
|
|
"onError": "continueRegularOutput"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={{ $env.GEMINI_API_KEY }}",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { contents: [ { parts: [ { text: 'Sen bir yildirim risk analisti raportorusun. Asagidaki verileri kullanarak Turkce, 2-3 paragraf, profesyonel bir ozet yaz. Sayilari dogal dilde ver; asiri teknik olma; santral adini kullan; sure, toplam darbe ve yogunluk hakkinda yorum yap.\\n\\nSantral: ' + $('Report: Gather Inputs').item.json.customer_name + '\\nZaman dilimi: ' + $('Report: Gather Inputs').item.json.timezone + '\\nFirtina baslangici (epoch ms): ' + $('Report: Gather Inputs').item.json.t_start + '\\nFirtina bitisi (epoch ms): ' + $('Report: Gather Inputs').item.json.t_end + '\\nToplam yildirim darbesi: ' + $('Report: Gather Inputs').item.json.n_strikes + '\\nIzleme yaricapi (m): ' + $('Report: Gather Inputs').item.json.boundary_m } ] } ] } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.3,
|
|
"position": [4160, 480],
|
|
"id": "a4a4a4a4-0004-4a04-8a04-000000000004",
|
|
"name": "Report: Gemini Commentary",
|
|
"onError": "continueRegularOutput"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"assignments": {
|
|
"assignments": [
|
|
{ "id": "bp-cid", "name": "customer_id", "value": "={{ $('Report: Gather Inputs').item.json.customer_id }}", "type": "string" },
|
|
{ "id": "bp-cname", "name": "customer_name", "value": "={{ $('Report: Gather Inputs').item.json.customer_name }}", "type": "string" },
|
|
{ "id": "bp-tz", "name": "timezone", "value": "={{ $('Report: Gather Inputs').item.json.timezone }}", "type": "string" },
|
|
{ "id": "bp-clat", "name": "centroid_lat", "value": "={{ $('Report: Gather Inputs').item.json.centroid_lat }}", "type": "number" },
|
|
{ "id": "bp-clon", "name": "centroid_lon", "value": "={{ $('Report: Gather Inputs').item.json.centroid_lon }}", "type": "number" },
|
|
{ "id": "bp-bnd", "name": "boundary_m", "value": "={{ $('Report: Gather Inputs').item.json.boundary_m }}", "type": "number" },
|
|
{ "id": "bp-rings", "name": "rings", "value": "={{ $('Report: Gather Inputs').item.json.rings }}", "type": "object" },
|
|
{ "id": "bp-rcolors", "name": "ring_colors", "value": "={{ $('Report: Gather Inputs').item.json.ring_colors }}", "type": "array" },
|
|
{ "id": "bp-ts", "name": "t_start", "value": "={{ $('Report: Gather Inputs').item.json.t_start }}", "type": "number" },
|
|
{ "id": "bp-te", "name": "t_end", "value": "={{ $('Report: Gather Inputs').item.json.t_end }}", "type": "number" },
|
|
{ "id": "bp-ns", "name": "n_strikes", "value": "={{ $('Report: Gather Inputs').item.json.n_strikes }}", "type": "number" },
|
|
{ "id": "bp-strikes", "name": "strikes", "value": "={{ $('Report: Gather Inputs').item.json.strikes }}", "type": "array" },
|
|
{ "id": "bp-turbines", "name": "turbines", "value": "={{ $('Report: Gather Inputs').item.json.turbines }}", "type": "array" },
|
|
{ "id": "bp-gem", "name": "gemini_text", "value": "={{ $('Report: Gemini Commentary').item.json?.candidates?.[0]?.content?.parts?.[0]?.text || '' }}", "type": "string" },
|
|
{ "id": "bp-storms", "name": "storm_records", "value": "={{ $('Report: Fetch Thunderstorms').item.json?.thunderstorms || $('Report: Fetch Thunderstorms').item.json?.data || [] }}", "type": "array" }
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.4,
|
|
"position": [4320, 480],
|
|
"id": "a8a8a8a8-0008-4a08-8a08-000000000008",
|
|
"name": "Report: Build Payload"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "={{ $env.REPORT_SERVICE_URL || 'http://report-service:8000' }}/generate",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{ "name": "Content-Type", "value": "application/json" },
|
|
{ "name": "Accept", "value": "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }
|
|
]
|
|
},
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ $json }}",
|
|
"options": {
|
|
"timeout": 300000,
|
|
"response": {
|
|
"response": {
|
|
"responseFormat": "file",
|
|
"outputPropertyName": "report"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.3,
|
|
"position": [4560, 480],
|
|
"id": "a5a5a5a5-0005-4a05-8a05-000000000005",
|
|
"name": "Report: Generate DOCX"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"resource": "file",
|
|
"operation": "upload",
|
|
"binaryData": true,
|
|
"binaryPropertyName": "report",
|
|
"channelId": {
|
|
"__rl": true,
|
|
"value": "REPLACE_WITH_USER_ID",
|
|
"mode": "id",
|
|
"cachedResultName": "DM target user"
|
|
},
|
|
"options": {
|
|
"fileName": "={{ $binary.report.fileName || ($('Report: Build Payload').item.json.customer_name + '_report.docx') }}",
|
|
"initialComment": "={{ '⚡ ' + $('Report: Build Payload').item.json.customer_name + ' — yeni firtina raporu (' + $('Report: Build Payload').item.json.n_strikes + ' darbe) — rapor ekte' }}"
|
|
}
|
|
},
|
|
"type": "n8n-nodes-base.slack",
|
|
"typeVersion": 2.4,
|
|
"position": [4800, 480],
|
|
"id": "a6a6a6a6-0006-4a06-8a06-000000000006",
|
|
"name": "Report: Send to User",
|
|
"credentials": {
|
|
"slackApi": {
|
|
"id": "OKgM8VkM05pJl9kU",
|
|
"name": "Tarla Slack Account"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"pinData": {},
|
|
"connections": {
|
|
"Report: Gather Inputs": {
|
|
"main": [[{ "node": "Report: Calc Thunderstorm Headers", "type": "main", "index": 0 }]]
|
|
},
|
|
"Report: Calc Thunderstorm Headers": {
|
|
"main": [[{ "node": "Report: Fetch Thunderstorms", "type": "main", "index": 0 }]]
|
|
},
|
|
"Report: Fetch Thunderstorms": {
|
|
"main": [[{ "node": "Report: Gemini Commentary", "type": "main", "index": 0 }]]
|
|
},
|
|
"Report: Gemini Commentary": {
|
|
"main": [[{ "node": "Report: Build Payload", "type": "main", "index": 0 }]]
|
|
},
|
|
"Report: Build Payload": {
|
|
"main": [[{ "node": "Report: Generate DOCX", "type": "main", "index": 0 }]]
|
|
},
|
|
"Report: Generate DOCX": {
|
|
"main": [[{ "node": "Report: Send to User", "type": "main", "index": 0 }]]
|
|
}
|
|
},
|
|
"active": false,
|
|
"settings": { "executionOrder": "v1" }
|
|
}
|