Pular para conteúdo

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:

  1. Exibição de Dados: Mostrar lista de produtos, pedidos, clientes
  2. Menus Dinâmicos: Criar opções baseadas em dados do Airtable
  3. Processamento em Lote: Buscar registros para processar com LOOP
  4. Relatórios: Gerar listagens e resumos de dados

Como funciona internamente?

Quando o AIRTABLE LIST é executado, o sistema:

  1. Coleta Credenciais: Obtém API Key, Base ID e nome da tabela
  2. Define Parâmetros: Configura maxRecords e view opcional
  3. Monta URL da API: Constrói https://api.airtable.com/v0/{baseId}/{tableName}
  4. Faz Requisição GET: Busca registros com parâmetros
  5. Se falha: Lança erro (tabela não existe ou credenciais inválidas)
  6. Se sucesso: Armazena array de registros na variável de resposta
  7. 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

  1. Menu de Produtos: "Listar todos os produtos disponíveis para venda"
  2. Histórico de Pedidos: "Mostrar últimos 10 pedidos do cliente"
  3. Lista de Opções: "Carregar categorias para criar menu dinâmico"
  4. Processamento em Lote: "Buscar todos os leads para enviar mensagem"
  5. Dashboard: "Listar registros para exibir estatísticas"

Quando NÃO usar AIRTABLE LIST

  • Buscar registro específico: Use AIRTABLE GET ao invés
  • Buscar com filtros complexos: Use AIRTABLE SEARCH ao invés
  • Apenas um registro: Use AIRTABLE GET 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)

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 maxRecords para limitar resultados e melhorar performance
  • Use view para 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