AutomationFlowsData & Sheets › Tool: Salvar Cliente - Bellory

Tool: Salvar Cliente - Bellory

Tool: Salvar Cliente - Bellory. Uses executeWorkflowTrigger, postgres. Event-driven trigger; 10 nodes.

Event trigger★★★★☆ complexity10 nodesExecute Workflow TriggerPostgres
Data & Sheets Trigger: Event Nodes: 10 Complexity: ★★★★☆ Added:

This workflow follows the Execute Workflow Trigger → Postgres recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Tool: Salvar Cliente - Bellory",
  "nodes": [
    {
      "parameters": {
        "inputSource": "passthrough"
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000001",
      "name": "Execute Workflow Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        -600,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// TOOL: SALVAR CLIENTE (Cadastro R\u00e1pido)\n// Cadastra novo cliente via WhatsApp\n// Padr\u00e3o: clienteRapido = true\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst input = $input.item.json;\nconst query = input.query || '';\nconst organizacaoId = input.organizacao_id || input.organizacaoId;\nconst telefoneLimpo = input.telefone_limpo || input.telefone || '';\nconst remoteJid = input.remote_jid || input.remetente_numero || '';\n\n// Extrair nome do query\nlet nome = input.nome || '';\nif (!nome && query) {\n  // O agente deve passar o nome no query\n  nome = query.trim();\n}\n\n// Extrair telefone\nlet telefone = telefoneLimpo;\nif (!telefone && remoteJid) {\n  telefone = remoteJid.replace('@s.whatsapp.net', '').replace('@c.us', '');\n}\n\nif (!nome) {\n  return [{ json: { error: true, message: 'Nome do cliente n\u00e3o informado.' } }];\n}\nif (!telefone) {\n  return [{ json: { error: true, message: 'Telefone do cliente n\u00e3o informado.' } }];\n}\nif (!organizacaoId) {\n  return [{ json: { error: true, message: 'organizacao_id n\u00e3o informado.' } }];\n}\n\n// Gerar username e password no padr\u00e3o clienteRapido\nconst codigo6Digitos = String(Math.floor(100000 + Math.random() * 900000));\nconst username = 'cliente_rapido_' + codigo6Digitos;\nconst passwordPlain = 'cliente_rapido';\n\nreturn [{\n  json: {\n    nome: nome,\n    telefone: telefone,\n    organizacao_id: organizacaoId,\n    username: username,\n    password_plain: passwordPlain\n  }\n}];"
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000002",
      "name": "Extrair Par\u00e2metros",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "position": [
        -400,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.error }}",
              "value2": true
            }
          ]
        }
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000003",
      "name": "Tem Erro?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        -200,
        0
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT c.id FROM app.cliente c WHERE REGEXP_REPLACE(c.telefone, '[^0-9]', '', 'g') = REGEXP_REPLACE($1, '[^0-9]', '', 'g') AND c.organizacao_id = $2 LIMIT 1;",
        "options": {
          "queryReplacement": "={{ $json.telefone }},={{ $json.organizacao_id }}"
        }
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000004",
      "name": "Verificar Duplicidade",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        0,
        -64
      ],
      "alwaysOutputData": true,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Verificar se cliente j\u00e1 existe\nconst resultado = $input.item.json;\nconst dadosCliente = $('Extrair Par\u00e2metros').item.json;\n\nif (resultado && resultado.id) {\n  return [{\n    json: {\n      duplicado: true,\n      cliente_id: resultado.id,\n      ...dadosCliente\n    }\n  }];\n}\n\nreturn [{\n  json: {\n    duplicado: false,\n    ...dadosCliente\n  }\n}];"
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000005",
      "name": "Verificar Resultado",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "position": [
        200,
        -64
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.duplicado }}",
              "value2": true
            }
          ]
        }
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000006",
      "name": "J\u00e1 Existe?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        400,
        -64
      ]
    },
    {
      "parameters": {
        "jsCode": "// Cliente j\u00e1 existe - retornar dados existentes\nconst dados = $input.item.json;\nreturn [{\n  json: {\n    response: JSON.stringify({\n      sucesso: false,\n      mensagem: 'Este telefone j\u00e1 est\u00e1 cadastrado.',\n      cliente_id: dados.cliente_id\n    }),\n    success: false\n  }\n}];"
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000007",
      "name": "Retornar Duplicado",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "position": [
        600,
        -128
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO app.cliente (organizacao_id, nome_completo, telefone, username, password, email, ativo, is_cadastro_incompleto, role, dt_criacao) VALUES ($1, $2, $3, $4, crypt($5, gen_salt('bf', 10)), NULL, true, true, 'ROLE_CLIENTE', NOW()) RETURNING id AS cliente_id, nome_completo AS nome;",
        "options": {
          "queryReplacement": "={{ $json.organizacao_id }},={{ $json.nome }},={{ $json.telefone }},={{ $json.username }},={{ $json.password_plain }}"
        }
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000008",
      "name": "Inserir Cliente",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        600,
        0
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Formatar resposta de sucesso\nconst resultado = $input.item.json;\n\nif (resultado && resultado.cliente_id) {\n  return [{\n    json: {\n      response: JSON.stringify({\n        sucesso: true,\n        cliente_id: resultado.cliente_id,\n        nome: resultado.nome,\n        mensagem: 'Cliente cadastrado com sucesso!'\n      }),\n      success: true\n    }\n  }];\n} else {\n  return [{\n    json: {\n      response: JSON.stringify({\n        sucesso: false,\n        mensagem: 'Erro ao cadastrar cliente. Tente novamente.'\n      }),\n      success: false\n    }\n  }];\n}"
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000009",
      "name": "Formatar Sucesso",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "position": [
        800,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "return [{ json: { response: $input.item.json.message, success: false } }];"
      },
      "id": "b1b2c3d4-1002-4002-a002-000000000010",
      "name": "Retornar Erro",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "position": [
        0,
        96
      ]
    }
  ],
  "connections": {
    "Execute Workflow Trigger": {
      "main": [
        [
          {
            "node": "Extrair Par\u00e2metros",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extrair Par\u00e2metros": {
      "main": [
        [
          {
            "node": "Tem Erro?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tem Erro?": {
      "main": [
        [
          {
            "node": "Retornar Erro",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Verificar Duplicidade",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verificar Duplicidade": {
      "main": [
        [
          {
            "node": "Verificar Resultado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verificar Resultado": {
      "main": [
        [
          {
            "node": "J\u00e1 Existe?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "J\u00e1 Existe?": {
      "main": [
        [
          {
            "node": "Retornar Duplicado",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Inserir Cliente",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Inserir Cliente": {
      "main": [
        [
          {
            "node": "Formatar Sucesso",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    {
      "name": "Bellory"
    },
    {
      "name": "Tool"
    }
  ]
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Tool: Salvar Cliente - Bellory. Uses executeWorkflowTrigger, postgres. Event-driven trigger; 10 nodes.

Source: https://github.com/GuikBit/Bellory-back/blob/efcae38bb4114c036e0c8477aebe1850faae67e7/n8n-workflows/tool-salvar-cliente.json — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Agendamiento_v2. Uses n8n-nodes-evolution-api, redis, httpRequest, executeWorkflowTrigger. Event-driven trigger; 59 nodes.

N8N Nodes Evolution Api, Redis, HTTP Request +3
Data & Sheets

Cancelacion_v2. Uses executeWorkflowTrigger, redis, httpRequest, n8n-nodes-evolution-api. Event-driven trigger; 46 nodes.

Execute Workflow Trigger, Redis, HTTP Request +3
Data & Sheets

Youtube Searcher. Uses splitInBatches, httpRequest, manualTrigger, executeWorkflowTrigger. Event-driven trigger; 21 nodes.

HTTP Request, Execute Workflow Trigger, Postgres +1
Data & Sheets

QuepasaAutomatic. Uses postgres, executeWorkflowTrigger. Event-driven trigger; 20 nodes.

Postgres, Execute Workflow Trigger
Data & Sheets

Log errors and avoid sending too many emails. Uses errorTrigger, postgres, stickyNote, emailSend. Event-driven trigger; 16 nodes.

Error Trigger, Postgres, Email Send +2