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:
- Busca Avançada: Encontrar registros usando condições complexas
- Filtros Dinâmicos: Buscar baseado em dados do usuário (email, telefone, etc)
- Consultas Inteligentes: Aplicar lógica condicional nas buscas
- Evitar Duplicatas: Verificar se registro já existe antes de criar
Como funciona internamente?
Quando o AIRTABLE SEARCH é executado, o sistema:
- Coleta Credenciais: Obtém API Key, Base ID e nome da tabela
- Monta Filtro: Processa a fórmula de filtro substituindo variáveis
- Define Limite: Configura maxRecords (padrão: 100)
- Faz Requisição GET: Busca com parâmetro
filterByFormula - Se falha: Lança erro (fórmula inválida ou erro de sintaxe)
- Se sucesso: Armazena array de registros filtrados
- 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
- Buscar por Email: "Encontrar cliente pelo email informado"
- Evitar Duplicatas: "Verificar se lead já existe antes de criar"
- Filtros Complexos: "Buscar pedidos pagos nos últimos 30 dias"
- Consultas Condicionais: "Encontrar tickets abertos de prioridade alta"
- Validação: "Checar se CPF já está cadastrado"
Quando NÃO usar AIRTABLE SEARCH
- Sabe o ID do registro: Use
AIRTABLE GETao invés - Listar todos sem filtro: Use
AIRTABLE LISTao invés - Filtro simples pré-configurado: Use
AIRTABLE LISTcom 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 > 0antes 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