248 lines
7.6 KiB
Ruby
248 lines
7.6 KiB
Ruby
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
#
|
|
# Generates importable n8n workflow JSON from component pieces.
|
|
# Run: ruby scripts/build-n8n-workflows.rb
|
|
# Output: scripts/n8n-workflow-receiver.json
|
|
# scripts/n8n-workflow-reporter.json
|
|
#
|
|
# Before running:
|
|
# 1. Complete Task 7 and verify DATATABLE_TYPE / DATATABLE_TYPE_VERSION below.
|
|
# 2. After Task 10 (credentials set up), replace REPLACE_WITH_*_CREDENTIAL_ID
|
|
# in the generated JSON and re-run to regenerate clean files before import.
|
|
|
|
require 'json'
|
|
require 'securerandom'
|
|
|
|
SCRIPTS_DIR = File.dirname(__FILE__)
|
|
|
|
# Verify against the exported scratch-workflow JSON from Task 7.
|
|
DATATABLE_TYPE = 'n8n-nodes-base.dataTable'
|
|
DATATABLE_TYPE_VERSION = 1
|
|
|
|
evaluate_sources_js = File.read(File.join(SCRIPTS_DIR, 'n8n-evaluate-sources.js'))
|
|
build_email_js = File.read(File.join(SCRIPTS_DIR, 'n8n-build-email.js'))
|
|
|
|
# ── Workflow 1: Receiver ──────────────────────────────────────────────────────
|
|
|
|
receiver = {
|
|
name: 'Backup Monitor — Receiver',
|
|
nodes: [
|
|
{
|
|
parameters: {
|
|
httpMethod: 'POST',
|
|
path: 'backup-notify',
|
|
authentication: 'headerAuth',
|
|
responseMode: 'responseNode',
|
|
options: {}
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Webhook',
|
|
type: 'n8n-nodes-base.webhook',
|
|
typeVersion: 2,
|
|
position: [240, 300],
|
|
webhookId: SecureRandom.uuid,
|
|
credentials: {
|
|
httpHeaderAuth: {
|
|
id: 'REPLACE_WITH_BACKUP_CREDENTIAL_ID',
|
|
name: 'backup-monitor-token'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
parameters: {
|
|
resource: 'row',
|
|
operation: 'insert',
|
|
dataTableId: {
|
|
'__rl' => true,
|
|
mode: 'list',
|
|
value: 'REPLACE_WITH_DATATABLE_ID',
|
|
cachedResultName: 'backup_runs'
|
|
},
|
|
columns: {
|
|
mappingMode: 'defineBelow',
|
|
value: {
|
|
timestamp: '={{ $json.body.timestamp }}',
|
|
machine: '={{ $json.body.machine }}',
|
|
destination: '={{ $json.body.destination }}',
|
|
status: '={{ $json.body.status }}',
|
|
bytes_transferred: '={{ $json.body.bytes_transferred }}',
|
|
snapshot_id: '={{ $json.body.snapshot_id }}',
|
|
log_path: '={{ $json.body.log_path }}',
|
|
notes: '={{ $json.body.notes }}'
|
|
}
|
|
}
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Insert to backup_runs',
|
|
type: DATATABLE_TYPE,
|
|
typeVersion: DATATABLE_TYPE_VERSION,
|
|
position: [520, 300]
|
|
},
|
|
{
|
|
parameters: {
|
|
respondWith: 'json',
|
|
responseBody: '={{ JSON.stringify({ ok: true }) }}',
|
|
options: { responseCode: 200 }
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Respond 200',
|
|
type: 'n8n-nodes-base.respondToWebhook',
|
|
typeVersion: 1.1,
|
|
position: [800, 300]
|
|
}
|
|
],
|
|
connections: {
|
|
'Webhook' => { main: [[{ node: 'Insert to backup_runs', type: 'main', index: 0 }]] },
|
|
'Insert to backup_runs' => { main: [[{ node: 'Respond 200', type: 'main', index: 0 }]] }
|
|
},
|
|
active: false,
|
|
settings: { executionOrder: 'v1' },
|
|
pinData: {},
|
|
meta: { templateCredsSetupCompleted: true },
|
|
tags: []
|
|
}
|
|
|
|
# ── Workflow 2: Reporter ──────────────────────────────────────────────────────
|
|
|
|
reporter = {
|
|
name: 'Backup Monitor — Reporter',
|
|
nodes: [
|
|
{
|
|
parameters: {
|
|
rule: {
|
|
interval: [
|
|
{
|
|
field: 'weeks',
|
|
weeksInterval: 1,
|
|
triggerAtDay: [5],
|
|
triggerAtHour: 8,
|
|
triggerAtMinute: 0
|
|
}
|
|
]
|
|
}
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Every Friday 8 AM',
|
|
type: 'n8n-nodes-base.scheduleTrigger',
|
|
typeVersion: 1.2,
|
|
position: [240, 300]
|
|
},
|
|
{
|
|
parameters: {
|
|
mode: 'manual',
|
|
includeOtherFields: false,
|
|
assignments: {
|
|
assignments: [
|
|
{
|
|
id: SecureRandom.uuid,
|
|
name: 'sources',
|
|
value: '={{ [{"machine":"desktop","destination":"synology"},{"machine":"desktop","destination":"backblaze-b2"},{"machine":"vps-ovh-prod-01","destination":"local"}] }}',
|
|
type: 'arrayValue'
|
|
}
|
|
]
|
|
},
|
|
options: {}
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Set sources',
|
|
type: 'n8n-nodes-base.set',
|
|
typeVersion: 3.4,
|
|
position: [460, 300]
|
|
},
|
|
{
|
|
parameters: {
|
|
resource: 'row',
|
|
operation: 'getMany',
|
|
dataTableId: {
|
|
'__rl' => true,
|
|
mode: 'list',
|
|
value: 'REPLACE_WITH_DATATABLE_ID',
|
|
cachedResultName: 'backup_runs'
|
|
},
|
|
filters: {
|
|
conditions: [
|
|
{
|
|
keyName: 'timestamp',
|
|
condition: 'gt',
|
|
keyValue: '={{ $now.minus({days: 7}).toISO() }}'
|
|
}
|
|
]
|
|
},
|
|
options: {}
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Get backup_runs (last 7d)',
|
|
type: DATATABLE_TYPE,
|
|
typeVersion: DATATABLE_TYPE_VERSION,
|
|
position: [680, 300]
|
|
},
|
|
{
|
|
parameters: {
|
|
mode: 'runOnceForAllItems',
|
|
language: 'javaScript',
|
|
jsCode: evaluate_sources_js
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Evaluate Sources',
|
|
type: 'n8n-nodes-base.code',
|
|
typeVersion: 2,
|
|
position: [900, 300]
|
|
},
|
|
{
|
|
parameters: {
|
|
mode: 'runOnceForAllItems',
|
|
language: 'javaScript',
|
|
jsCode: build_email_js
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Build Email',
|
|
type: 'n8n-nodes-base.code',
|
|
typeVersion: 2,
|
|
position: [1120, 300]
|
|
},
|
|
{
|
|
parameters: {
|
|
method: 'POST',
|
|
url: 'https://app.mailpace.com/api/v1/send',
|
|
authentication: 'genericCredentialType',
|
|
genericAuthType: 'httpHeaderAuth',
|
|
sendBody: true,
|
|
specifyBody: 'json',
|
|
jsonBody: '={{ { from: "REPLACE_WITH_MAILPACE_FROM_ADDRESS", to: "jaredmswanson@gmail.com", subject: $json.subject, text_body: $json.body } }}',
|
|
options: {}
|
|
},
|
|
id: SecureRandom.uuid,
|
|
name: 'Send via MailPace',
|
|
type: 'n8n-nodes-base.httpRequest',
|
|
typeVersion: 4.2,
|
|
position: [1340, 300],
|
|
credentials: {
|
|
httpHeaderAuth: {
|
|
id: 'REPLACE_WITH_MAILPACE_CREDENTIAL_ID',
|
|
name: 'mailpace-token'
|
|
}
|
|
}
|
|
}
|
|
],
|
|
connections: {
|
|
'Every Friday 8 AM' => { main: [[{ node: 'Set sources', type: 'main', index: 0 }]] },
|
|
'Set sources' => { main: [[{ node: 'Get backup_runs (last 7d)', type: 'main', index: 0 }]] },
|
|
'Get backup_runs (last 7d)' => { main: [[{ node: 'Evaluate Sources', type: 'main', index: 0 }]] },
|
|
'Evaluate Sources' => { main: [[{ node: 'Build Email', type: 'main', index: 0 }]] },
|
|
'Build Email' => { main: [[{ node: 'Send via MailPace', type: 'main', index: 0 }]] }
|
|
},
|
|
active: false,
|
|
settings: { executionOrder: 'v1' },
|
|
pinData: {},
|
|
meta: { templateCredsSetupCompleted: true },
|
|
tags: []
|
|
}
|
|
|
|
File.write(File.join(SCRIPTS_DIR, 'n8n-workflow-receiver.json'), JSON.pretty_generate(receiver))
|
|
File.write(File.join(SCRIPTS_DIR, 'n8n-workflow-reporter.json'), JSON.pretty_generate(reporter))
|
|
|
|
puts 'Generated:'
|
|
puts " #{SCRIPTS_DIR}/n8n-workflow-receiver.json"
|
|
puts " #{SCRIPTS_DIR}/n8n-workflow-reporter.json"
|