Pular para conteúdo

AIRTABLE SEARCH - Buscar Registros com Filtros no Airtable

O que é este Node?

O AIRTABLE SEARCH é o node responsável por buscar registros usando fórmulas de filtro complexas do Airtable.

Por que este Node existe?

Buscar registros com filtros específicos é essencial para encontrar dados baseados em critérios dinâmicos. O AIRTABLE SEARCH existe para:

  1. Busca Avançada: Encontrar registros usando condições complexas
  2. Filtros Dinâmicos: Buscar baseado em dados do usuário (email, telefone, etc)
  3. Consultas Inteligentes: Aplicar lógica condicional nas buscas
  4. Evitar Duplicatas: Verificar se registro já existe antes de criar

Como funciona internamente?

Quando o AIRTABLE SEARCH é executado, o sistema:

  1. Coleta Credenciais: Obtém API Key, Base ID e nome da tabela
  2. Monta Filtro: Processa a fórmula de filtro substituindo variáveis
  3. Define Limite: Configura maxRecords (padrão: 100)
  4. Faz Requisição GET: Busca com parâmetro filterByFormula
  5. Se falha: Lança erro (fórmula inválida ou erro de sintaxe)
  6. Se sucesso: Armazena array de registros filtrados
  7. Continua Execução: Passa para próximo node com resultados

Código interno (airtable.executor.ts:65-70):

case 'search': {
  const filterFormula = this.replaceVariables(node.data.filterFormula, context.variables);
  const response = await axios.get(baseUrl, { headers, params: { filterByFormula: filterFormula, maxRecords: node.data.maxRecords || 100 } });
  result = response.data;
  break;
}

Quando você DEVE usar este Node?

Use AIRTABLE SEARCH sempre que precisar de buscar com filtros:

Casos de uso

  1. Buscar por Email: "Encontrar cliente pelo email informado"
  2. Evitar Duplicatas: "Verificar se lead já existe antes de criar"
  3. Filtros Complexos: "Buscar pedidos pagos nos últimos 30 dias"
  4. Consultas Condicionais: "Encontrar tickets abertos de prioridade alta"
  5. Validação: "Checar se CPF já está cadastrado"
  • Sabe o ID do registro: Use AIRTABLE GET ao invés
  • Listar todos sem filtro: Use AIRTABLE LIST ao invés
  • Filtro simples pré-configurado: Use AIRTABLE LIST com view ao invés

Parâmetros Detalhados

config.apiKey (string, obrigatório)

O que é: Token de autenticação da API do Airtable.

Padrão: Não há padrão (obrigatório)

config.baseId (string, obrigatório)

O que é: Identificador da base do Airtable.

Padrão: Não há padrão (obrigatório)

config.tableName (string, obrigatório)

O que é: Nome exato da tabela no Airtable.

Padrão: Não há padrão (obrigatório)

filterFormula (string, obrigatório)

O que é: Fórmula de filtro do Airtable (sintaxe Airtable Formula). Aceita variáveis.

Padrão: Não há padrão (obrigatório)

Flow completo para testar:

{
  "name": "Teste Airtable Search - Filter Formula",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "email",
      "position": { "x": 250, "y": 100 },
      "data": {
        "label": "Email",
        "parameters": {
          "message": "Digite seu email:",
          "variable": "emailBusca"
        }
      }
    },
    {
      "id": "airtable_1",
      "type": "airtable",
      "position": { "x": 400, "y": 100 },
      "data": {
        "label": "Buscar por Email",
        "operation": "search",
        "config": {
          "apiKey": "patABC123456789xyz",
          "baseId": "appXYZ123456",
          "tableName": "Clientes"
        },
        "filterFormula": "{Email} = '{{emailBusca}}'",
        "maxRecords": 1,
        "responseVariable": "cliente"
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 550, "y": 100 },
      "data": {
        "label": "Encontrado?",
        "parameters": {
          "condition": "{{cliente.records.length}} > 0"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 50 },
      "data": {
        "label": "Encontrado",
        "parameters": {
          "message": "Cliente encontrado: {{cliente.records[0].fields.Nome}}"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 700, "y": 150 },
      "data": {
        "label": "Não Encontrado",
        "parameters": {
          "message": "Email não encontrado em nossa base."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 850, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "airtable_1" },
    { "source": "airtable_1", "target": "condition_1" },
    { "source": "condition_1", "target": "message_1", "label": "true" },
    { "source": "condition_1", "target": "message_2", "label": "false" },
    { "source": "message_1", "target": "end_1" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Teste: Digite um email. O sistema buscará cliente com esse email.

maxRecords (number, opcional)

O que é: Número máximo de registros a retornar.

Padrão: 100

responseVariable (string, opcional)

O que é: Nome da variável onde os resultados serão armazenados.

Padrão: "airtableResult"

Parâmetros

Campo Tipo Obrigatório Descrição
operation string Sim Deve ser "search"
config.apiKey string Sim Token de autenticação do Airtable
config.baseId string Sim ID da base do Airtable
config.tableName string Sim Nome da tabela
filterFormula string Sim Fórmula de filtro (sintaxe Airtable)
maxRecords number Não Máximo de registros (padrão: 100)
responseVariable string Não Nome da variável de resposta (padrão: "airtableResult")

Exemplo 1: Evitar Duplicatas ao Criar Lead

Objetivo: Verificar se email já existe antes de criar novo lead

JSON para Importar

{
  "name": "Cadastro sem Duplicatas",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 250, "y": 100 },
      "data": {
        "label": "Nome",
        "parameters": {
          "message": "Qual seu nome?",
          "variable": "nome"
        }
      }
    },
    {
      "id": "input_2",
      "type": "email",
      "position": { "x": 400, "y": 100 },
      "data": {
        "label": "Email",
        "parameters": {
          "message": "Qual seu email?",
          "variable": "email"
        }
      }
    },
    {
      "id": "airtable_1",
      "type": "airtable",
      "position": { "x": 550, "y": 100 },
      "data": {
        "label": "Verificar Duplicata",
        "operation": "search",
        "config": {
          "apiKey": "patABC123456789xyz",
          "baseId": "appXYZ123456",
          "tableName": "Leads"
        },
        "filterFormula": "{Email} = '{{email}}'",
        "maxRecords": 1,
        "responseVariable": "leadExistente"
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Já Existe?",
        "parameters": {
          "condition": "{{leadExistente.records.length}} > 0"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 850, "y": 50 },
      "data": {
        "label": "Duplicata",
        "parameters": {
          "message": "Este email já está cadastrado em nosso sistema!"
        }
      }
    },
    {
      "id": "airtable_2",
      "type": "airtable",
      "position": { "x": 850, "y": 150 },
      "data": {
        "label": "Criar Novo Lead",
        "operation": "create",
        "config": {
          "apiKey": "patABC123456789xyz",
          "baseId": "appXYZ123456",
          "tableName": "Leads"
        },
        "fields": {
          "Nome": "{{nome}}",
          "Email": "{{email}}",
          "Data": "{{hoje}}",
          "Status": "Novo"
        },
        "responseVariable": "novoLead"
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1000, "y": 150 },
      "data": {
        "label": "Sucesso",
        "parameters": {
          "message": "Cadastro realizado com sucesso, {{nome}}!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1150, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "input_2" },
    { "source": "input_2", "target": "airtable_1" },
    { "source": "airtable_1", "target": "condition_1" },
    { "source": "condition_1", "target": "message_1", "label": "true" },
    { "source": "condition_1", "target": "airtable_2", "label": "false" },
    { "source": "airtable_2", "target": "message_2" },
    { "source": "message_1", "target": "end_1" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Qual seu nome?
Usuário: José Roberto
Sistema: Qual seu email?
Usuário: jose@exemplo.com
Sistema: Cadastro realizado com sucesso, José Roberto!

Exemplo 2: Buscar Pedidos Recentes

Objetivo: Encontrar pedidos do cliente nos últimos 30 dias

JSON para Importar

{
  "name": "Consultar Pedidos Recentes",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "email",
      "position": { "x": 250, "y": 100 },
      "data": {
        "label": "Email",
        "parameters": {
          "message": "Digite seu email para consultar pedidos:",
          "variable": "emailCliente"
        }
      }
    },
    {
      "id": "airtable_1",
      "type": "airtable",
      "position": { "x": 400, "y": 100 },
      "data": {
        "label": "Buscar Pedidos",
        "operation": "search",
        "config": {
          "apiKey": "patABC123456789xyz",
          "baseId": "appXYZ123456",
          "tableName": "Pedidos"
        },
        "filterFormula": "AND({Email} = '{{emailCliente}}', {Status} = 'Pago')",
        "maxRecords": 10,
        "responseVariable": "pedidos"
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 550, "y": 100 },
      "data": {
        "label": "Tem Pedidos?",
        "parameters": {
          "condition": "{{pedidos.records.length}} > 0"
        }
      }
    },
    {
      "id": "formatter_1",
      "type": "formatter",
      "position": { "x": 700, "y": 50 },
      "data": {
        "label": "Formatar Lista",
        "parameters": {
          "template": "{{#each pedidos.records}}📦 {{this.fields.Produto}} - R$ {{this.fields.Valor}}\n{{/each}}",
          "resultVariable": "listaPedidos"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 850, "y": 50 },
      "data": {
        "label": "Exibir Pedidos",
        "parameters": {
          "message": "Seus pedidos recentes:\n\n{{listaPedidos}}"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 700, "y": 150 },
      "data": {
        "label": "Sem Pedidos",
        "parameters": {
          "message": "Você ainda não possui pedidos em nosso sistema."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1000, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "airtable_1" },
    { "source": "airtable_1", "target": "condition_1" },
    { "source": "condition_1", "target": "formatter_1", "label": "true" },
    { "source": "condition_1", "target": "message_2", "label": "false" },
    { "source": "formatter_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Digite seu email para consultar pedidos:
Usuário: jose@exemplo.com
Sistema: Seus pedidos recentes:

📦 Curso React - R$ 997
📦 Curso Node.js - R$ 797

Resposta do Node

{
  "records": [
    {
      "id": "recABC123",
      "createdTime": "2025-01-15T10:00:00.000Z",
      "fields": {
        "Nome": "José Roberto",
        "Email": "jose@exemplo.com",
        "Status": "Ativo"
      }
    }
  ]
}

Boas Práticas

SIM:

  • Use fórmulas Airtable corretas: {Campo} = 'valor'
  • Para múltiplas condições: AND({Campo1} = 'A', {Campo2} = 'B')
  • Para OR: OR({Status} = 'Novo', {Status} = 'Pendente')
  • Sempre verifique se records.length > 0 antes de acessar resultados
  • Use variáveis dinâmicas nas fórmulas: {Email} = '{{emailUsuario}}'

NÃO:

  • Não use sintaxe SQL (WHERE, SELECT) - use fórmulas Airtable
  • Não esqueça aspas simples em strings: {Email} = '{{valor}}'
  • Não assuma que sempre haverá resultados - trate lista vazia
  • Não faça buscas muito amplas sem maxRecords

Dicas

💡 Dica 1: Fórmulas Airtable: {Campo} para campo, 'valor' para string, números sem aspas

💡 Dica 2: Combos úteis: AND(), OR(), NOT(), FIND(), IS_BEFORE(), IS_AFTER()

💡 Dica 3: Para buscar parte de texto: FIND('{{busca}}', {Campo})

💡 Dica 4: Sempre verifique {{variavel.records.length}} antes de acessar records[0]

💡 Dica 5: Use SEARCH antes de CREATE para evitar duplicatas

Próximo Node

AIRTABLE CREATE - Criar registro se busca não encontrar → AIRTABLE UPDATE - Atualizar registro encontrado → AIRTABLE LIST - Listar sem filtros complexos → CONDITION - Verificar se encontrou resultados