AIRTABLE LIST - Listar Registros do Airtable
O que é este Node?
O AIRTABLE LIST é o node responsável por listar múltiplos registros de uma tabela do Airtable com paginação e filtros opcionais.
Por que este Node existe?
Listar registros é fundamental para exibir dados, criar menus dinâmicos e processar múltiplos itens. O AIRTABLE LIST existe para:
- Exibição de Dados: Mostrar lista de produtos, pedidos, clientes
- Menus Dinâmicos: Criar opções baseadas em dados do Airtable
- Processamento em Lote: Buscar registros para processar com LOOP
- Relatórios: Gerar listagens e resumos de dados
Como funciona internamente?
Quando o AIRTABLE LIST é executado, o sistema:
- Coleta Credenciais: Obtém API Key, Base ID e nome da tabela
- Define Parâmetros: Configura maxRecords e view opcional
- Monta URL da API: Constrói
https://api.airtable.com/v0/{baseId}/{tableName} - Faz Requisição GET: Busca registros com parâmetros
- Se falha: Lança erro (tabela não existe ou credenciais inválidas)
- Se sucesso: Armazena array de registros na variável de resposta
- Continua Execução: Passa para próximo node com lista disponível
Código interno (airtable.executor.ts:55-63):
case 'list': {
const maxRecords = node.data.maxRecords || 100;
const view = node.data.view ? this.replaceVariables(node.data.view, context.variables) : undefined;
const params: any = { maxRecords };
if (view) params.view = view;
const response = await axios.get(baseUrl, { headers, params });
result = response.data;
break;
}
Quando você DEVE usar este Node?
Use AIRTABLE LIST sempre que precisar de listar múltiplos registros:
Casos de uso
- Menu de Produtos: "Listar todos os produtos disponíveis para venda"
- Histórico de Pedidos: "Mostrar últimos 10 pedidos do cliente"
- Lista de Opções: "Carregar categorias para criar menu dinâmico"
- Processamento em Lote: "Buscar todos os leads para enviar mensagem"
- Dashboard: "Listar registros para exibir estatísticas"
Quando NÃO usar AIRTABLE LIST
- Buscar registro específico: Use
AIRTABLE GETao invés - Buscar com filtros complexos: Use
AIRTABLE SEARCHao invés - Apenas um registro: Use
AIRTABLE GETao 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)
maxRecords (number, opcional)
O que é: Número máximo de registros a retornar.
Padrão: 100
Flow completo para testar:
{
"name": "Teste Airtable List - Max Records",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "airtable_1",
"type": "airtable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Listar Top 5",
"operation": "list",
"config": {
"apiKey": "patABC123456789xyz",
"baseId": "appXYZ123456",
"tableName": "Produtos"
},
"maxRecords": 5,
"responseVariable": "produtos"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mostrar Total",
"parameters": {
"message": "Total de produtos: {{produtos.records.length}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "airtable_1" },
{ "source": "airtable_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Inicie o fluxo. O sistema listará até 5 produtos.
view (string, opcional)
O que é: Nome da view (visualização) do Airtable para aplicar filtros/ordenação pré-configurados.
Padrão: Não há (lista default view)
Flow completo para testar:
{
"name": "Teste Airtable List - View",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "airtable_1",
"type": "airtable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Listar Ativos",
"operation": "list",
"config": {
"apiKey": "patABC123456789xyz",
"baseId": "appXYZ123456",
"tableName": "Clientes"
},
"maxRecords": 10,
"view": "Clientes Ativos",
"responseVariable": "clientesAtivos"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mostrar",
"parameters": {
"message": "Clientes ativos: {{clientesAtivos.records.length}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "airtable_1" },
{ "source": "airtable_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Inicie o fluxo. O sistema listará registros da view específica.
responseVariable (string, opcional)
O que é: Nome da variável onde a lista será armazenada.
Padrão: "airtableResult"
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | Deve ser "list" |
| 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 |
| maxRecords | number | Não | Máximo de registros (padrão: 100) |
| view | string | Não | Nome da view para filtrar/ordenar |
| responseVariable | string | Não | Nome da variável de resposta (padrão: "airtableResult") |
Exemplo 1: Menu de Produtos Dinâmico
Objetivo: Criar menu com produtos disponíveis do Airtable
JSON para Importar
{
"name": "Menu de Produtos",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 250, "y": 100 },
"data": {
"label": "Boas-vindas",
"parameters": {
"message": "Bem-vindo à nossa loja! Carregando produtos..."
}
}
},
{
"id": "airtable_1",
"type": "airtable",
"position": { "x": 400, "y": 100 },
"data": {
"label": "Listar Produtos",
"operation": "list",
"config": {
"apiKey": "patABC123456789xyz",
"baseId": "appXYZ123456",
"tableName": "Produtos"
},
"maxRecords": 10,
"view": "Produtos Disponíveis",
"responseVariable": "produtos"
}
},
{
"id": "formatter_1",
"type": "formatter",
"position": { "x": 550, "y": 100 },
"data": {
"label": "Formatar Lista",
"parameters": {
"template": "{{#each produtos.records}}{{@index + 1}}. {{this.fields.Nome}} - R$ {{this.fields.Preco}}\n{{/each}}",
"resultVariable": "menuProdutos"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Exibir Menu",
"parameters": {
"message": "📦 Produtos Disponíveis:\n\n{{menuProdutos}}\n\nDigite o número do produto:"
}
}
},
{
"id": "input_1",
"type": "number",
"position": { "x": 850, "y": 100 },
"data": {
"label": "Escolha",
"parameters": {
"message": "",
"variable": "escolha"
}
}
},
{
"id": "message_3",
"type": "message",
"position": { "x": 1000, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Você escolheu: {{produtos.records[escolha - 1].fields.Nome}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1150, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "airtable_1" },
{ "source": "airtable_1", "target": "formatter_1" },
{ "source": "formatter_1", "target": "message_2" },
{ "source": "message_2", "target": "input_1" },
{ "source": "input_1", "target": "message_3" },
{ "source": "message_3", "target": "end_1" }
]
}
Saída esperada:
Sistema: Bem-vindo à nossa loja! Carregando produtos...
Sistema: 📦 Produtos Disponíveis:
1. Curso React - R$ 997
2. Curso Node.js - R$ 797
3. Curso TypeScript - R$ 597
Digite o número do produto:
Usuário: 1
Sistema: Você escolheu: Curso React
Exemplo 2: Processamento em Lote com LOOP
Objetivo: Listar leads e processar cada um
JSON para Importar
{
"name": "Processar Leads em Lote",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "airtable_1",
"type": "airtable",
"position": { "x": 250, "y": 100 },
"data": {
"label": "Listar Leads Novos",
"operation": "list",
"config": {
"apiKey": "patABC123456789xyz",
"baseId": "appXYZ123456",
"tableName": "Leads"
},
"maxRecords": 20,
"view": "Leads Novos",
"responseVariable": "leads"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 400, "y": 100 },
"data": {
"label": "Info",
"parameters": {
"message": "Encontrados {{leads.records.length}} leads. Processando..."
}
}
},
{
"id": "loop_1",
"type": "loop",
"position": { "x": 550, "y": 100 },
"data": {
"label": "Para Cada Lead",
"parameters": {
"items": "{{leads.records}}",
"itemVariable": "lead"
}
}
},
{
"id": "airtable_2",
"type": "airtable",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Marcar Processado",
"operation": "update",
"config": {
"apiKey": "patABC123456789xyz",
"baseId": "appXYZ123456",
"tableName": "Leads"
},
"recordId": "{{lead.id}}",
"fields": {
"Status": "Processado",
"DataProcessamento": "{{hoje}}"
},
"responseVariable": "leadAtualizado"
}
},
{
"id": "delay_1",
"type": "delay",
"position": { "x": 850, "y": 100 },
"data": {
"label": "Aguardar",
"parameters": {
"delay": 500
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1000, "y": 100 },
"data": {
"label": "Finalizar",
"parameters": {
"message": "✅ Processamento concluído!\n\nTotal processados: {{leads.records.length}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1150, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "airtable_1" },
{ "source": "airtable_1", "target": "message_1" },
{ "source": "message_1", "target": "loop_1" },
{ "source": "loop_1", "target": "airtable_2" },
{ "source": "airtable_2", "target": "delay_1" },
{ "source": "delay_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Encontrados 15 leads. Processando...
Sistema: ✅ Processamento concluído!
Total processados: 15
Resposta do Node
{
"records": [
{
"id": "recABC123",
"createdTime": "2025-01-15T10:00:00.000Z",
"fields": {
"Nome": "José Roberto",
"Email": "jose@exemplo.com",
"Status": "Novo"
}
},
{
"id": "recDEF456",
"createdTime": "2025-01-15T11:00:00.000Z",
"fields": {
"Nome": "Maria Silva",
"Email": "maria@exemplo.com",
"Status": "Novo"
}
}
],
"offset": "itrXXXXXXXXXXXXXX"
}
Boas Práticas
✅ SIM:
- Use
maxRecordspara limitar resultados e melhorar performance - Use
viewpara aplicar filtros/ordenação configurados no Airtable - Combine com LOOP para processar registros individualmente
- Cache resultados em variável se precisar usar múltiplas vezes
- Use FORMATTER para criar listas legíveis para usuários
❌ NÃO:
- Não busque todos os registros sem limit (pode ser muito lento)
- Não use LIST quando só precisa de um registro (use GET)
- Não processe listas enormes sem batching/paginação
- Não esqueça de tratar lista vazia (records.length == 0)
Dicas
💡 Dica 1: Acesse registros com {{variavel.records[0].fields.NomeCampo}}
💡 Dica 2: Use {{variavel.records.length}} para contar quantos registros foram retornados
💡 Dica 3: Views do Airtable são perfeitas para filtros complexos - configure lá e apenas referencie aqui
💡 Dica 4: Para paginação, use o campo offset retornado na próxima requisição LIST
💡 Dica 5: Combine LIST + LOOP + UPDATE para processamento em lote eficiente
Próximo Node
→ AIRTABLE SEARCH - Buscar com filtros complexos → AIRTABLE GET - Buscar registro específico → LOOP - Processar lista de registros