{
  "name": "FaktCheckr \u2013 Automated Fact-Check Pipeline",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "faktcheck-webhook",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "node-webhook-trigger",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        240,
        300
      ],
      "notes": "Entry point. POST JSON: { \"text\": \"claim to verify\" }\nURL: http://your-n8n-host:5678/webhook/faktcheck-webhook"
    },
    {
      "parameters": {
        "functionCode": "// Validate and sanitise incoming payload\nconst body = $input.first().json;\nconst text = (body.text || body.message || body.claim || '').trim();\n\nif (!text) {\n  throw new Error('Missing required field: text');\n}\n\nif (text.length > 2000) {\n  throw new Error('Input too long (max 2000 chars)');\n}\n\nreturn [{ json: { text, notify: body.notify !== false, source_channel: body.source || 'n8n-webhook' } }];"
      },
      "id": "node-validate-input",
      "name": "Validate Input",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://api-gateway:8000/verify",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "text",
              "value": "={{ $json.text }}"
            },
            {
              "name": "notify",
              "value": "={{ $json.notify }}"
            }
          ]
        },
        "options": {
          "timeout": 90000,
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "node-call-faktcheckr",
      "name": "Call FaktCheckr API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        680,
        300
      ],
      "notes": "Calls the FaktCheckr API Gateway.\nAdjust URL if running outside Docker: http://localhost:8000/verify"
    },
    {
      "parameters": {
        "functionCode": "// Route based on overall verdict\nconst result = $input.first().json;\nconst verdict = (result.overall_verdict || 'UNVERIFIED').toUpperCase();\nconst confidence = result.overall_confidence || 0;\n\n// Attach routing metadata\nreturn [{\n  json: {\n    ...result,\n    _routing: {\n      verdict,\n      confidence,\n      is_false:      verdict === 'FALSE',\n      is_true:       verdict === 'TRUE',\n      is_misleading: verdict === 'MISLEADING',\n      is_unverified: verdict === 'UNVERIFIED',\n      high_confidence:   confidence >= 0.75,\n      medium_confidence: confidence >= 0.4 && confidence < 0.75,\n      low_confidence:    confidence < 0.4,\n    }\n  }\n}];"
      },
      "id": "node-route-verdict",
      "name": "Route by Verdict",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json._routing.is_false }}",
              "value2": true
            }
          ]
        }
      },
      "id": "node-if-false",
      "name": "Is FALSE?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1120,
        200
      ],
      "notes": "Branch: FALSE verdicts get priority alerting"
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json._routing.is_misleading }}",
              "value2": true
            }
          ]
        }
      },
      "id": "node-if-misleading",
      "name": "Is MISLEADING?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1120,
        400
      ],
      "notes": "Branch: MISLEADING gets warning-level alert"
    },
    {
      "parameters": {
        "functionCode": "// Format a summary for logging / downstream use\nconst d = $input.first().json;\nconst verdicts = d.verdicts || [];\n\nconst summary = verdicts.map((v, i) => {\n  const aiTag = v.enhanced_sources && v.enhanced_sources.length\n    ? ` [via ${v.enhanced_sources.join(', ')}]`\n    : ' [via FAISS retrieval]';\n  return `Claim ${i+1}: ${v.raw_claim.substring(0, 80)}\\n` +\n         `  \u2192 ${v.verdict} (${Math.round(v.confidence * 100)}%)${aiTag}\\n` +\n         `  Explanation: ${v.explanation.substring(0, 150)}`;\n}).join('\\n\\n');\n\nreturn [{\n  json: {\n    request_id:         d.request_id,\n    input_text:         d.input_text,\n    overall_verdict:    d.overall_verdict,\n    overall_confidence: d.overall_confidence,\n    claim_count:        verdicts.length,\n    processing_ms:      d.processing_time_ms,\n    summary_text:       summary,\n    timestamp:          new Date().toISOString(),\n    raw_response:       d,\n  }\n}];"
      },
      "id": "node-format-summary",
      "name": "Format Summary",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1340,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "// Build a webhook response for the original caller\nconst d = $input.first().json;\nreturn [{\n  json: {\n    status: 'ok',\n    request_id:      d.request_id,\n    overall_verdict: d.overall_verdict,\n    confidence:      d.overall_confidence,\n    claims_checked:  d.claim_count,\n    processing_ms:   d.processing_ms,\n    message: `Verified ${d.claim_count} claim(s). Overall: ${d.overall_verdict} (${Math.round(d.overall_confidence*100)}% confidence)`,\n  }\n}];"
      },
      "id": "node-build-response",
      "name": "Build Response",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1560,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "node-respond-webhook",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        1780,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "// Log FALSE verdict to console / n8n execution log\nconst d = $input.first().json;\nconsole.log(`[FaktCheckr] FALSE CLAIM DETECTED`);\nconsole.log(`  Request: ${d.request_id}`);\nconsole.log(`  Text: ${d.input_text.substring(0, 100)}`);\nconsole.log(`  Confidence: ${Math.round(d._routing.confidence * 100)}%`);\nreturn $input.all();"
      },
      "id": "node-log-false",
      "name": "Log FALSE Alert",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1120,
        80
      ],
      "notes": "Extend this node to write to a Google Sheet, database, or Slack"
    },
    {
      "parameters": {
        "functionCode": "// Log MISLEADING verdict\nconst d = $input.first().json;\nconsole.log(`[FaktCheckr] MISLEADING CLAIM`);\nconsole.log(`  Request: ${d.request_id}`);\nconsole.log(`  Text: ${d.input_text.substring(0, 100)}`);\nreturn $input.all();"
      },
      "id": "node-log-misleading",
      "name": "Log MISLEADING Alert",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1120,
        520
      ],
      "notes": "Extend to write to a moderation queue"
    },
    {
      "parameters": {
        "functionCode": "// Handle errors from FaktCheckr API call\nconst error = $input.first().error || {};\nconsole.error('[FaktCheckr] Pipeline error:', error.message || 'Unknown error');\nreturn [{\n  json: {\n    status: 'error',\n    error: error.message || 'FaktCheckr pipeline failed',\n    timestamp: new Date().toISOString(),\n  }\n}];"
      },
      "id": "node-handle-error",
      "name": "Handle Error",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        680,
        500
      ],
      "notes": "Catches errors from the HTTP request node"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {
          "responseCode": 500
        }
      },
      "id": "node-respond-error",
      "name": "Respond Error",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        900,
        500
      ]
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Validate Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Input": {
      "main": [
        [
          {
            "node": "Call FaktCheckr API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call FaktCheckr API": {
      "main": [
        [
          {
            "node": "Route by Verdict",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Handle Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Verdict": {
      "main": [
        [
          {
            "node": "Is FALSE?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Is MISLEADING?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is FALSE?": {
      "main": [
        [
          {
            "node": "Log FALSE Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is MISLEADING?": {
      "main": [
        [
          {
            "node": "Log MISLEADING Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log FALSE Alert": {
      "main": [
        [
          {
            "node": "Format Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log MISLEADING Alert": {
      "main": [
        [
          {
            "node": "Format Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Summary": {
      "main": [
        [
          {
            "node": "Build Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Response": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Handle Error": {
      "main": [
        [
          {
            "node": "Respond Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": ""
  },
  "staticData": null,
  "tags": [
    "faktcheckr",
    "fact-checking",
    "automation"
  ],
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "versionId": "1.0.0",
  "id": "faktcheckr-main-workflow",
  "_readme": {
    "description": "FaktCheckr n8n Workflow",
    "how_to_import": [
      "1. Open n8n (http://localhost:5678)",
      "2. Click 'Workflows' \u2192 'Import from file'",
      "3. Select this JSON file",
      "4. Activate the workflow",
      "5. POST to: http://your-n8n:5678/webhook/faktcheck-webhook"
    ],
    "example_request": {
      "method": "POST",
      "url": "http://localhost:5678/webhook/faktcheck-webhook",
      "body": {
        "text": "COVID vaccine causes autism",
        "notify": true
      }
    },
    "extending": [
      "Log FALSE claims to Google Sheets: add a Google Sheets node after 'Log FALSE Alert'",
      "Slack alerts: add Slack node after 'Log FALSE Alert' with webhook URL",
      "Schedule periodic checks: replace Webhook Trigger with Cron Trigger node",
      "WhatsApp input: add Twilio node as trigger, connect to Validate Input"
    ]
  }
}