355 lines
10 KiB
JSON
355 lines
10 KiB
JSON
{
|
|
"name": "Geofeed Export to BunnyCDN",
|
|
"nodes": [
|
|
{
|
|
"parameters": {
|
|
"httpMethod": "POST",
|
|
"path": "geofeed-update",
|
|
"responseMode": "onReceived",
|
|
"options": {}
|
|
},
|
|
"id": "webhook-trigger",
|
|
"name": "Webhook Trigger",
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2,
|
|
"position": [240, 200],
|
|
"webhookId": "geofeed-update"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"rule": {
|
|
"interval": [
|
|
{
|
|
"field": "hours",
|
|
"hoursInterval": 24
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"id": "schedule-trigger",
|
|
"name": "Daily Backup Trigger",
|
|
"type": "n8n-nodes-base.scheduleTrigger",
|
|
"typeVersion": 1.1,
|
|
"position": [240, 400]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "// Log the trigger source for debugging\nconst webhookData = $('Webhook Trigger').item?.json || null;\nconst scheduleData = $('Daily Backup Trigger').item?.json || null;\n\nlet triggerSource = 'unknown';\nlet triggerReason = '';\nlet entriesAffected = 0;\nlet isImmediate = false;\n\nif (webhookData) {\n triggerSource = 'webhook';\n triggerReason = webhookData.trigger_reason || 'webhook_trigger';\n entriesAffected = webhookData.entries_affected || 0;\n isImmediate = webhookData.immediate || false;\n} else if (scheduleData) {\n triggerSource = 'schedule';\n triggerReason = 'daily_backup';\n}\n\nreturn [{\n json: {\n triggerSource,\n triggerReason,\n entriesAffected,\n isImmediate,\n timestamp: new Date().toISOString()\n }\n}];"
|
|
},
|
|
"id": "code-merge-triggers",
|
|
"name": "Process Trigger",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [460, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"operation": "executeQuery",
|
|
"query": "SELECT ip_prefix, IFNULL(country_code, '') as country_code, IFNULL(region_code, '') as region_code, IFNULL(city, '') as city, IFNULL(postal_code, '') as postal_code FROM geofeed_entries ORDER BY CASE WHEN ip_prefix LIKE '%:%' THEN 1 ELSE 0 END, INET_ATON(SUBSTRING_INDEX(ip_prefix, '/', 1)), ip_prefix",
|
|
"options": {}
|
|
},
|
|
"id": "mysql-query",
|
|
"name": "Query Geofeed Entries",
|
|
"type": "n8n-nodes-base.mySql",
|
|
"typeVersion": 2.3,
|
|
"position": [680, 300],
|
|
"credentials": {
|
|
"mySql": {
|
|
"id": "YOUR_MYSQL_CREDENTIAL_ID",
|
|
"name": "MariaDB Geofeed"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "// Build RFC 8805 compliant CSV\nconst items = $input.all();\n\nif (items.length === 0) {\n throw new Error('No entries found in database');\n}\n\n// CSV Header comments\nlet csv = '# Geofeed - Generated by Geofeed Manager\\r\\n';\ncsv += '# Format: ip_prefix,country_code,region_code,city,postal_code\\r\\n';\ncsv += `# Generated: ${new Date().toISOString()}\\r\\n`;\ncsv += `# Total Entries: ${items.length}\\r\\n`;\n\n// Process each entry\nfor (const item of items) {\n const row = item.json;\n \n // Build CSV line - RFC 8805 format\n // Escape any commas in city names\n const city = (row.city || '').replace(/,/g, '');\n const postalCode = (row.postal_code || '').replace(/,/g, '');\n \n csv += `${row.ip_prefix},${row.country_code},${row.region_code},${city},${postalCode}\\r\\n`;\n}\n\n// Return single item with CSV content\nreturn [{\n json: {\n csv: csv,\n entryCount: items.length,\n generatedAt: new Date().toISOString()\n }\n}];"
|
|
},
|
|
"id": "code-build-csv",
|
|
"name": "Build CSV Content",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [900, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "PUT",
|
|
"url": "=https://storage.bunnycdn.com/{{ $env.BUNNY_STORAGE_ZONE }}/geofeed.csv",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "AccessKey",
|
|
"value": "={{ $env.BUNNY_API_KEY }}"
|
|
},
|
|
{
|
|
"name": "Content-Type",
|
|
"value": "text/csv; charset=utf-8"
|
|
}
|
|
]
|
|
},
|
|
"sendBody": true,
|
|
"contentType": "raw",
|
|
"body": "={{ $json.csv }}",
|
|
"options": {
|
|
"response": {
|
|
"response": {
|
|
"fullResponse": true,
|
|
"responseFormat": "text"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"id": "http-upload-bunny",
|
|
"name": "Upload to BunnyCDN",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [1120, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": true,
|
|
"leftValue": "",
|
|
"typeValidation": "loose"
|
|
},
|
|
"conditions": [
|
|
{
|
|
"id": "check-upload-success",
|
|
"leftValue": "={{ $json.statusCode }}",
|
|
"rightValue": 201,
|
|
"operator": {
|
|
"type": "number",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"options": {}
|
|
},
|
|
"id": "if-upload-success",
|
|
"name": "Check Upload Success",
|
|
"type": "n8n-nodes-base.if",
|
|
"typeVersion": 2,
|
|
"position": [1340, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"operation": "executeQuery",
|
|
"query": "INSERT INTO geofeed_audit_log (entry_id, action, new_values, changed_by) VALUES (NULL, 'INSERT', JSON_OBJECT('type', 'csv_export', 'status', 'success', 'trigger', '{{ $('Process Trigger').item.json.triggerSource }}', 'reason', '{{ $('Process Trigger').item.json.triggerReason }}', 'entries', {{ $('Build CSV Content').item.json.entryCount }}, 'timestamp', NOW()), 'n8n_workflow')",
|
|
"options": {}
|
|
},
|
|
"id": "mysql-log-success",
|
|
"name": "Log Export Success",
|
|
"type": "n8n-nodes-base.mySql",
|
|
"typeVersion": 2.3,
|
|
"position": [1560, 200],
|
|
"credentials": {
|
|
"mySql": {
|
|
"id": "YOUR_MYSQL_CREDENTIAL_ID",
|
|
"name": "MariaDB Geofeed"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"operation": "executeQuery",
|
|
"query": "UPDATE geofeed_settings SET setting_value = NOW() WHERE setting_key = 'last_export_at'",
|
|
"options": {}
|
|
},
|
|
"id": "mysql-update-timestamp",
|
|
"name": "Update Last Export Time",
|
|
"type": "n8n-nodes-base.mySql",
|
|
"typeVersion": 2.3,
|
|
"position": [1780, 200],
|
|
"credentials": {
|
|
"mySql": {
|
|
"id": "YOUR_MYSQL_CREDENTIAL_ID",
|
|
"name": "MariaDB Geofeed"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"operation": "executeQuery",
|
|
"query": "INSERT INTO geofeed_audit_log (entry_id, action, new_values, changed_by) VALUES (NULL, 'INSERT', JSON_OBJECT('type', 'csv_export', 'status', 'failed', 'trigger', '{{ $('Process Trigger').item.json.triggerSource }}', 'timestamp', NOW()), 'n8n_workflow')",
|
|
"options": {}
|
|
},
|
|
"id": "mysql-log-failure",
|
|
"name": "Log Export Failure",
|
|
"type": "n8n-nodes-base.mySql",
|
|
"typeVersion": 2.3,
|
|
"position": [1560, 400],
|
|
"credentials": {
|
|
"mySql": {
|
|
"id": "YOUR_MYSQL_CREDENTIAL_ID",
|
|
"name": "MariaDB Geofeed"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"errorMessage": "=Failed to upload geofeed to BunnyCDN"
|
|
},
|
|
"id": "stop-error",
|
|
"name": "Stop and Error",
|
|
"type": "n8n-nodes-base.stopAndError",
|
|
"typeVersion": 1,
|
|
"position": [1780, 400]
|
|
},
|
|
{
|
|
"parameters": {},
|
|
"id": "no-op-complete",
|
|
"name": "Export Complete",
|
|
"type": "n8n-nodes-base.noOp",
|
|
"typeVersion": 1,
|
|
"position": [2000, 200]
|
|
}
|
|
],
|
|
"connections": {
|
|
"Webhook Trigger": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Process Trigger",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Daily Backup Trigger": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Process Trigger",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Process Trigger": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Query Geofeed Entries",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Query Geofeed Entries": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build CSV Content",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Build CSV Content": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Upload to BunnyCDN",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Upload to BunnyCDN": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Check Upload Success",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Check Upload Success": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Log Export Success",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "Log Export Failure",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Log Export Success": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Update Last Export Time",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Update Last Export Time": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Export Complete",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Log Export Failure": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Stop and Error",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"pinData": {},
|
|
"settings": {
|
|
"executionOrder": "v1"
|
|
},
|
|
"staticData": null,
|
|
"tags": [
|
|
{
|
|
"name": "geofeed",
|
|
"createdAt": "2024-01-01T00:00:00.000Z",
|
|
"updatedAt": "2024-01-01T00:00:00.000Z"
|
|
},
|
|
{
|
|
"name": "bunnycdn",
|
|
"createdAt": "2024-01-01T00:00:00.000Z",
|
|
"updatedAt": "2024-01-01T00:00:00.000Z"
|
|
},
|
|
{
|
|
"name": "webhook",
|
|
"createdAt": "2024-01-01T00:00:00.000Z",
|
|
"updatedAt": "2024-01-01T00:00:00.000Z"
|
|
}
|
|
],
|
|
"triggerCount": 0,
|
|
"updatedAt": "2024-01-01T00:00:00.000Z",
|
|
"versionId": "2"
|
|
}
|