{
  "name": "REMAX \u2014 2. SignZen Proxy",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "remax/enviar",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "4f0b541b-7268-4cb5-a77e-30b4602323e5",
      "name": "POST /remax/enviar",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        368,
        240
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// Normaliza el body seg\u00fan la versi\u00f3n de n8n.\n// En algunas versiones el webhook expone el body en $json.body;\n// en otras, $json ES el body directamente.\nconst incoming = $input.first().json;\nconst body = (incoming.body && typeof incoming.body === 'object')\n  ? incoming.body\n  : incoming;\nreturn [{ json: body }];"
      },
      "id": "c0a57a5f-28c8-4000-9636-7512f171d8a4",
      "name": "Normalizar body",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        592,
        240
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://signzen-process-api.signzen-demo.com.ar/api/Processes",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "Basic Y2NyZW9AZ3J1cG9scGEuY29tOjEyMzQ1Njc4"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json-patch+json",
        "body": "={{ JSON.stringify($json) }}",
        "options": {
          "allowUnauthorizedCerts": true
        }
      },
      "id": "4241bdbb-53e9-4c15-849f-0e6f1063d949",
      "name": "Llamar SignZen API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        2832,
        240
      ],
      "continueOnFail": true
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const item = $input.first();\n\nif (item.error) {\n  const errMsg = item.error.message ?? JSON.stringify(item.json);\n  const match = errMsg.match(/^(\\d{3})\\s+-/);\n  const statusCode = match ? parseInt(match[1]) : 502;\n  return [{ json: { statusCode, responseBody: JSON.stringify({ error: errMsg }) } }];\n}\n\n// \u00c9xito: item.json es la respuesta de SignZen directamente\nreturn [{ json: { statusCode: 200, responseBody: JSON.stringify(item.json) } }];"
      },
      "id": "dc76cbac-9b0e-44e8-9624-303d4336c003",
      "name": "Preparar respuesta",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3056,
        240
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.responseBody }}",
        "options": {
          "responseCode": "={{ $json.statusCode }}",
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/json"
              },
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "id": "6765cabf-ce7e-40e4-9669-e30d249c2242",
      "name": "Responder al Frontend",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        3280,
        240
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://signzenv2-api.signzen-demo.com.ar/api/Templates/Search?GroupId={{ $json.groupId }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "Basic Y2NyZW9AZ3J1cG9scGEuY29tOjEyMzQ1Njc4"
            }
          ]
        },
        "options": {
          "allowUnauthorizedCerts": true
        }
      },
      "id": "a1000001-0000-0000-0000-000000000001",
      "name": "Buscar Plantilla",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        1936,
        240
      ],
      "continueOnFail": false
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const templateData = $input.first().json;\nconst body = $('Merge').first().json;\n\nconst templateKey = body.templateKey;\nconst templates = (templateData.data || []);\nconst found = templates.find(t => t.key === templateKey);\n\nif (!found) {\n  throw new Error('No se encontr\u00f3 plantilla con key=\"' + templateKey + '\" para groupId=' + body.groupId);\n}\n\nreturn [{ json: { templateId: found.id, body } }];"
      },
      "id": "a1000002-0000-0000-0000-000000000002",
      "name": "Resolver templateId",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2160,
        240
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://signzenv2-api.signzen-demo.com.ar/api/Documents/Search?TemplateId={{ $json.templateId }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "Basic Y2NyZW9AZ3J1cG9scGEuY29tOjEyMzQ1Njc4"
            }
          ]
        },
        "options": {
          "allowUnauthorizedCerts": true
        }
      },
      "id": "a1000003-0000-0000-0000-000000000003",
      "name": "Buscar Documento",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        2384,
        240
      ],
      "continueOnFail": false
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const docData = $input.first().json;\nconst { body } = $('Resolver templateId').first().json;\n\nconst docs = (docData.data || []);\nconst found = docs.find(d => d.key === 'documento');\n\nif (!found) {\n  throw new Error('No se encontr\u00f3 documento con key=\"documento\" en la plantilla');\n}\n\nconst enrichedBody = JSON.parse(JSON.stringify(body));\nif (!enrichedBody.documents || enrichedBody.documents.length === 0) {\n  throw new Error('El body no contiene documentos');\n}\n\n// Inyectar documentTemplateId y limpiar campos internos que SignZen no acepta\nconst { fileName: _fn, ...cleanDoc } = enrichedBody.documents[0];\nenrichedBody.documents[0] = { ...cleanDoc, documentTemplateId: found.id };\n\nreturn [{ json: enrichedBody }];"
      },
      "id": "a1000004-0000-0000-0000-000000000004",
      "name": "Resolver documentTemplateId",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2608,
        240
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond-word-check",
              "leftValue": "={{ (/\\.(doc|docx)$/i).test($json.documents?.[0]?.fileName || '') }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "c1000001-0000-0000-0000-000000000001",
      "name": "IF \u00bfEs Word?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        816,
        240
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const body = $input.first().json;\nconst doc = body.documents[0];\nconst ext = (doc.fileName || '').split('.').pop().toLowerCase();\nconst mimeType = ext === 'docx'\n  ? 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n  : 'application/msword';\n\nreturn [{\n  json: body,\n  binary: {\n    docFile: {\n      data: doc.base64,\n      mimeType,\n      fileName: doc.fileName || 'documento.' + ext,\n      fileExtension: ext,\n      fileSize: Math.ceil(doc.base64.length * 0.75),\n    }\n  }\n}];"
      },
      "id": "c1000002-0000-0000-0000-000000000002",
      "name": "Preparar binario",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1040,
        80
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://circular-steady-hawk.ngrok-free.app/forms/libreoffice/convert",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Basic YWRtaW46THBhMjMyOTE="
            }
          ]
        },
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formBinaryData",
              "name": "files",
              "inputDataFieldName": "docFile"
            }
          ]
        },
        "options": {
          "allowUnauthorizedCerts": true,
          "response": {
            "response": {
              "responseFormat": "file",
              "outputPropertyName": "pdfData"
            }
          }
        }
      },
      "id": "c1000003-0000-0000-0000-000000000003",
      "name": "Llamar Gotenberg",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        1264,
        80
      ]
    },
    {
      "parameters": {
        "mode": "binaryToJson",
        "setAllData": false,
        "destinationKey": "pdfBase64",
        "sourceKey": "pdfData",
        "options": {
          "keepAsBase64": true
        }
      },
      "id": "c1000008-0000-0000-0000-000000000008",
      "name": "PDF a Base64",
      "type": "n8n-nodes-base.moveBinaryData",
      "typeVersion": 1,
      "position": [
        1488,
        80
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const pdfBase64 = $input.first().json.pdfBase64;\n\nif (!pdfBase64) {\n  throw new Error('Gotenberg no devolvi\u00f3 datos PDF');\n}\n\nconst body = $('Preparar binario').first().json;\nconst oldFileName = body.documents?.[0]?.fileName || 'documento.docx';\nconst pdfFileName = oldFileName.replace(/\\.docx?$/i, '.pdf');\n\nreturn [{\n  json: {\n    ...body,\n    documents: [{\n      ...body.documents[0],\n      fileName: pdfFileName,\n      base64: pdfBase64,\n    }]\n  }\n}];"
      },
      "id": "c1000004-0000-0000-0000-000000000004",
      "name": "Post Gotenberg",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1712,
        80
      ]
    },
    {
      "parameters": {
        "mode": "append"
      },
      "id": "c1000005-0000-0000-0000-000000000005",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 2.1,
      "position": [
        1712,
        240
      ]
    }
  ],
  "connections": {
    "POST /remax/enviar": {
      "main": [
        [
          {
            "node": "Normalizar body",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalizar body": {
      "main": [
        [
          {
            "node": "IF \u00bfEs Word?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF \u00bfEs Word?": {
      "main": [
        [
          {
            "node": "Preparar binario",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Preparar binario": {
      "main": [
        [
          {
            "node": "Llamar Gotenberg",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Llamar Gotenberg": {
      "main": [
        [
          {
            "node": "PDF a Base64",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PDF a Base64": {
      "main": [
        [
          {
            "node": "Post Gotenberg",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Gotenberg": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Buscar Plantilla",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Buscar Plantilla": {
      "main": [
        [
          {
            "node": "Resolver templateId",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resolver templateId": {
      "main": [
        [
          {
            "node": "Buscar Documento",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Buscar Documento": {
      "main": [
        [
          {
            "node": "Resolver documentTemplateId",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resolver documentTemplateId": {
      "main": [
        [
          {
            "node": "Llamar SignZen API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Llamar SignZen API": {
      "main": [
        [
          {
            "node": "Preparar respuesta",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preparar respuesta": {
      "main": [
        [
          {
            "node": "Responder al Frontend",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "ffffffff-ffff-ffff-ffff-ffffffffffff",
  "id": "remax-proxy-flow",
  "tags": []
}