{
  "name": "ezGPT - HTTP Request Send File",
  "active": false,
  "nodes": [
    {
      "id": "manual-trigger",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        200,
        300
      ],
      "parameters": {}
    },
    {
      "id": "sample-note",
      "name": "Sample Note",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        420,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "return [{ json: {\n  request_id: 'demo-001',\n  text: 'Заявка: demo-001\\nНужен учебный расчёт.\\n',\n} }];"
      }
    },
    {
      "id": "make-txt",
      "name": "Make TXT",
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "position": [
        640,
        300
      ],
      "parameters": {
        "operation": "toText",
        "sourceProperty": "text",
        "binaryPropertyName": "upload",
        "options": {
          "encoding": "utf8",
          "addBOM": false,
          "fileName": "note-demo.txt"
        }
      }
    },
    {
      "id": "check-file",
      "name": "Check File",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        860,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const items = $input.all();\nif (items.length !== 1) throw new Error('Expected one file');\nconst source = $('Sample Note').first().json;\nif (typeof source.request_id !== 'string' || !/^demo-[0-9]{3}$/.test(source.request_id) ||\n    typeof source.text !== 'string' || !source.text.trim() || source.text.includes('\\u0000')) {\n  throw new Error('Invalid sample fields');\n}\nconst item = items[0];\nif (Object.keys(item.binary ?? {}).join('|') !== 'upload') {\n  throw new Error('Expected binary.upload');\n}\nconst file = item.binary.upload;\nif (file.fileName !== 'note-demo.txt' || file.mimeType !== 'text/plain') {\n  throw new Error('Expected note-demo.txt with text/plain');\n}\nconst bytes = await this.helpers.getBinaryDataBuffer(0, 'upload');\nconst expected = Buffer.from(source.text, 'utf8');\nif (bytes.length < 1 || bytes.length > 4096 || !bytes.equals(expected)) {\n  throw new Error('File bytes differ from the sample');\n}\nreturn [{\n  json: { request_id: source.request_id, expected_text: source.text, expected_bytes: bytes.length },\n  binary: { upload: file },\n}];"
      }
    },
    {
      "id": "send-file",
      "name": "Send File",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1080,
        300
      ],
      "parameters": {
        "method": "POST",
        "url": "http://127.0.0.1:5678/webhook-test/ezgpt-http-upload-receiver",
        "authentication": "none",
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formData",
              "name": "request_id",
              "value": "={{ $json.request_id }}"
            },
            {
              "parameterType": "formBinaryData",
              "name": "document",
              "inputDataFieldName": "upload"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": false,
              "responseFormat": "json"
            }
          },
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "timeout": 15000,
          "allowUnauthorizedCerts": false
        }
      }
    },
    {
      "id": "check-receipt",
      "name": "Check Receipt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1300,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const response = $input.first().json;\nconst expected = $('Check File').first().json;\nconst body = response.body;\nif (response.statusCode !== 200 || !body || typeof body !== 'object' || Array.isArray(body)) {\n  throw new Error('Expected HTTP 200 with a JSON object');\n}\nconst keys = Object.keys(body).sort().join('|');\nif (keys !== 'action|bytes|file_name|request_id|status|text' ||\n    body.status !== 'preview' || body.request_id !== expected.request_id ||\n    body.file_name !== 'note-demo.txt' || body.bytes !== expected.expected_bytes ||\n    body.text !== expected.expected_text || body.action !== false) {\n  throw new Error('Receiver did not confirm the exact file');\n}\nreturn [{ json: {\n  status: 'verified', request_id: body.request_id, file_name: body.file_name,\n  bytes: body.bytes, uploaded: true, action: false,\n} }];"
      }
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Sample Note",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sample Note": {
      "main": [
        [
          {
            "node": "Make TXT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Make TXT": {
      "main": [
        [
          {
            "node": "Check File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check File": {
      "main": [
        [
          {
            "node": "Send File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send File": {
      "main": [
        [
          {
            "node": "Check Receipt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {}
}
