
Este guia apresenta um método de referência para você construir e testar localmente. Ele estabelece um fluxo de ingestão repetível, e não uma importação pronta nem uma implantação completa verificada. Um checkpoint é um registro salvo do progresso da execução, e um upsert é uma operação de banco de dados que insere uma nova linha ou atualiza um registro existente quando há correspondência de uma chave única duplicada.
Escopo técnico e limites operacionais
Antes de configurar o fluxo no n8n, você precisa entender o que este pipeline de extração trata e onde estão os limites. Este sistema se concentra apenas na extração automática de dados e no armazenamento persistente. Ele não faz filtragem de spam, análise de sentimento, pontuação de intenção do cliente, respostas automáticas nem moderação de conteúdo. Se você precisa agrupar comentários em categorias personalizadas, leia nosso guia sobre Análise de feedback de clientes em comentários do Facebook. Se você precisa encaminhar perguntas de suporte para uma mesa de atendimento ativa, consulte nosso tutorial sobre a Fila de perguntas sem resposta em comentários do Facebook.
Este tutorial cobre a implementação técnica com nós padrão do n8n e a API HTTP do Facebook Comments Scraper. Uma API (Interface de Programação de Aplicações) é um conjunto de regras e endpoints que permite que programas de software diferentes se comuniquem pela web. O scraper aceita como entrada URLs específicas e conhecidas de publicações públicas. Ele não aceita links gerais de perfil, URLs de grupos nem páginas de canal de marca. Quando executado, o scraper retorna registros de dados planos no formato JSON (JavaScript Object Notation), que é um formato de texto padrão para compartilhar dados estruturados.
Cada linha de saída representa um comentário de nível superior ou uma resposta aninhada direta. O payload retornado inclui identificadores de string como commentId e contentId. Observe que authorId e publishedAt podem ser null, publishedAt e scrapedAt são carimbos de data e hora, e isReply é um valor booleano, e não um identificador de string exato. O objeto JSON bruto preserva parentCommentId, rootCommentId, isReply, text e valores null. Entre as execuções, o banco de dados trata a deduplicação com uma restrição única composta em contentId e commentId, implementada por consultas parametrizadas.
Mantenha os seguintes parâmetros operacionais em mente ao configurar o pipeline:
- Links de destino: você deve passar de 1 a 100 URLs explícitas de publicações públicas como itens de string dentro de um array.
- Limites de resultado: o parâmetro maxResultsPerPost define o número máximo de linhas de comentários e respostas coletadas por publicação. Definir esse valor como 25 limita a execução a no máximo 25 linhas por publicação.
- Extração de respostas: definir includeReplies como true faz o scraper coletar respostas aninhadas junto com os comentários principais.
- Extração completa: definir collectAllAvailable como true ignora o limite numérico de resultados, embora a extração continue sujeita aos limites de visibilidade da plataforma e às cobranças de computação.
- Parâmetros de ordenação: opções de ordenação como all, newest ou most_relevant determinam como o Facebook ordena os comentários antes da extração, de forma independente dos limites de resultado.
Referência dos endpoints principais da API
A tabela a seguir resume os endpoints usados neste fluxo, junto com as estruturas brutas de URL e os campos de resposta esperados:
| URL do endpoint | Descrição | Campos de resposta esperados |
|---|---|---|
| https://api.apify.com/v2/acts/chronometrica~facebook-comments-scraper/runs | Inicia a execução do scraper | data.id, data.defaultDatasetId, data.defaultKeyValueStoreId, data.status |
| https://api.apify.com/v2/actor-runs/RUN_ID | Verifica o status da execução | data.status |
| https://api.apify.com/v2/datasets/DATASET_ID/items?format=json&clean=false&offset=0&limit=100 | Busca páginas de itens do conjunto de dados | Array JSON de registros de comentários |
| https://api.apify.com/v2/key-value-stores/STORE_ID/records/OUTPUT | Inspeciona o armazenamento de resumo da execução | Registro de resumo específico da execução |
Nota: substitua marcadores como RUN_ID, DATASET_ID e STORE_ID pelos valores reais da execução salva. Nunca inclua tokens de acesso diretamente nas strings de URL.
Arquitetura passo a passo e sequência de nós
Para montar este pipeline no n8n, você configura uma sequência estruturada de nós integrados. Você precisa do n8n instalado, de um token de API da Apify armazenado em uma credencial Header Auth do n8n (chamada Authorization, com o valor Bearer your_token) e de uma credencial de banco de dados relacional (como o Postgres).
1. Configuração de gatilhos e credenciais
Comece criando um novo fluxo no n8n. Abra as configurações do fluxo, selecione o fuso horário local e deixe o fluxo não publicado enquanto constrói e testa os componentes.
Você cria dois pontos de entrada:
- Schedule Trigger: dispara automaticamente a execução recorrente diária ou horária da coleta, conforme as configurações de fuso horário.
- Gatilho manual e entrada de recuperação: um ponto de entrada manual separado para operadores. Como um gatilho manual não pode receber um ID de execução diretamente, coloque um nó Edit Fields depois dele, onde um operador pode informar um ID de execução já salvo. Isso permite recuperar execuções paradas sem iniciar um novo trabalho de scraping.
2. Início do scraper
Conecte o gatilho de agendamento a um nó HTTP Request chamado Launch Scraper. Defina o método como POST e aponte para o endpoint de execução do Actor da Apify. Anexe a credencial Header Auth. Configure um corpo de requisição JSON pequeno e simples, usando strings de URL brutas:
{
"startUrls": [
"https://www.facebook.com/story.php?story_fbid=123456789&id=987654321"
],
"maxResultsPerPost": 25,
"includeReplies": true,
"collectAllAvailable": false,
"commentSortMode": "all"
}Quando essa requisição é bem-sucedida, a API da Apify retorna um envelope com metadados da execução. O fluxo deve capturar e salvar quatro valores imediatamente: data.id, data.defaultDatasetId, data.defaultKeyValueStoreId e data.status.
Salve esses valores em um checkpoint durável no banco de dados, com chave pelo ID da execução, iniciando a contagem de tentativas em zero e o próximo offset em zero. Durável significa armazenado de forma permanente em um banco de dados relacional, fora da memória temporária do fluxo.
Regra crítica de segurança: nunca repita automaticamente uma requisição POST de início ambígua se ocorrer um tempo limite de rede. Se a primeira requisição chegou ao servidor, uma nova tentativa cega inicia uma segunda execução de scraping cobrável. Se o início for ambíguo, inspecione manualmente a lista de execuções da sua conta Apify antes de disparar uma nova.
3. O caminho de recuperação
Se uma execução falhar ou parar, o ramo de recuperação manual seleciona o registro de checkpoint existente com o ID de execução informado pelo operador e ignora por completo o nó de início.
O fluxo impõe a regra de uma execução ativa por ID de execução. Se uma execução recuperada já mostrar no banco um status terminal salvo SUCCEEDED, o fluxo ignora por completo a consulta de status e vai direto para o carregamento de páginas. Se o status salvo for failed, o fluxo encaminha para revisão manual. Os outros estados entram em consulta limitada. As contagens de tentativas nunca são zeradas automaticamente pelas execuções de recuperação.
4. Consulta de status e controle do contador
Antes de cada verificação de status, o fluxo consulta o banco de dados para verificar a contagem atual de tentativas. Se a contagem chegou a 30, o sistema encaminha a execução para um ramo de revisão manual, para evitar laços infinitos.
Se a contagem for menor que 30, o fluxo incrementa a contagem de tentativas no banco, pausa a execução por 10 segundos com um nó Wait e, em seguida, usa uma requisição HTTP GET para verificar o status da execução na API da Apify (https://api.apify.com/v2/actor-runs/RUN_ID).
Erros de requisição de rede durante a consulta devem usar novas tentativas de leitura limitadas (no máximo 3 tentativas, com espera de 10 segundos), em vez de repetir requisições POST.
O fluxo avalia o status retornado:
- SUCCEEDED: o fluxo salva o status simples no banco de dados e segue para a busca do conjunto de dados.
- READY / RUNNING / ABORTING / TIMING-OUT: o fluxo devolve a execução ao controle do contador para esperar e verificar de novo.
- FAILED / ABORTED / TIMED-OUT: o fluxo registra o status de falha e para ou encaminha para revisão manual.
- Status desconhecido: encaminha para revisão manual.
Nota: interromper o laço de consulta não cancela o Actor remoto da Apify; isso apenas faz o fluxo do n8n parar de esperar. Um tempo limite da consulta não significa que a publicação tinha zero comentários.
5. Paginação e carregamento de páginas
Quando a execução é bem-sucedida, o fluxo entra no laço de paginação. Antes de buscar cada página, ele recarrega o estado atual do checkpoint no banco de dados para obter o offset mais recente e o ID do conjunto de dados.
Ele faz uma requisição HTTP GET para buscar os itens do conjunto de dados (https://api.apify.com/v2/datasets/DATASET_ID/items?format=json&clean=false&offset=0&limit=100, substituindo o offset atual e o ID do conjunto de dados salvo). Você deve usar o ID do conjunto de dados da execução específica, e não um alias genérico latest. Defina o formato da requisição como JSON, use clean=false e defina limit=100.
Configure o nó HTTP para retornar o corpo completo da resposta. Registre o comprimento do array recebido antes de passar os dados a qualquer nó de divisão. Se o array da página inicial estiver completamente vazio, ignore a divisão e inspecione o registro de saída do armazenamento de chave-valor pelo endpoint dedicado (https://api.apify.com/v2/key-value-stores/STORE_ID/records/OUTPUT), usando o ID do armazenamento salvo, para determinar se ocorreu um erro. Nas páginas seguintes, um array vazio apenas indica o fim da coleta.
6. Divisão e upsert no banco de dados
Passe o array do conjunto de dados para um nó Split Out configurado com um campo de destino explícito chamado comment.
O nó de armazenamento no banco, mais adiante no fluxo, recebe cada item dividido e mapeia os campos diretamente a partir de comment. Ele valida a existência de identificadores de string não vazios e de carimbos de data e hora válidos. Ele executa um upsert com consultas parametrizadas contra uma restrição de chave única composta (contentId e commentId). Um upsert insere uma nova linha ou atualiza um registro existente se houver uma correspondência duplicada.
Para impedir que dados antigos substituam atualizações recentes, configure a condição de atualização do banco para que o texto e os metadados recebidos sejam atualizados somente se o carimbo scrapedAt recebido for maior ou igual ao carimbo armazenado. Isso representa o estado observado mais recente da publicação pública, e não um registro histórico de auditoria imutável nem uma prova de exclusão.
7. Avanço do checkpoint
Depois que todos os itens da página atual forem gravados com sucesso no banco, o fluxo atualiza o offset do checkpoint no banco somando 100.
Regra crucial: nunca avance o offset do checkpoint uma vez por comentário. Você deve atualizar o offset do checkpoint exatamente uma vez por página, depois que o lote inteiro for bem-sucedido. Se uma gravação no banco falhar no meio de uma página, o offset do checkpoint permanece inalterado, e o fluxo pode reproduzir a página com segurança sem duplicar registros.
Preserve separadamente os metadados do comprimento da página atual ao longo das etapas de divisão e de banco. A verificação final usa o comprimento da página atual, não o comprimento do primeiro laço. Se o comprimento da página atual for menor que 100 itens, a coleta está completa e o fluxo termina. Se o comprimento da página for igual a 100, o fluxo volta para recarregar o checkpoint e buscar o próximo lote.
Protocolo de teste e validação para o leitor
Antes de publicar o fluxo para execução automática em produção, você deve construir e testar o fluxo localmente com verificações estruturadas. Não dependa de modelos não testados.
- Teste isolado de ingestão: injete diretamente em um nó Split Out, encaminhado ao nó de banco e configurado para STOP imediatamente, uma entrada de teste fixa {body: [25 comments]}, ignorando todos os nós ativos de checkpoint e de resumo de página. Verifique se o banco armazena exatamente 25 linhas. Executar exatamente a mesma entrada de teste fixa uma segunda vez resulta em 0 novas linhas inseridas, e os registros existentes são avaliados sem regressão. Adicionar um 26º registro distinto insere exatamente 1 nova linha. Além disso, verifique se uma entrada de teste fixa mais antiga não pode substituir um texto mais recente.
- Teste do caso de paginação: teste o laço de offset com um checkpoint simulado e 201 registros em 3 páginas de 100, 100 e 1, sem gerar chamadas pagas de Actor.
- Teste de tolerância a falhas e de consulta: teste se as contagens máximas de consulta disparam corretamente a revisão manual no caminho de consulta. Simule uma falha de gravação no banco em uma página intermediária. Verifique se o offset do checkpoint permanece inalterado, se a recuperação não inicia o scraper de novo e se os status que não são de sucesso bloqueiam corretamente a busca do conjunto de dados.
- Verificação manual ao vivo: execute um único teste manual com um link real de publicação pública. Revise os limites da plataforma, os custos de computação e os registros de execução.
Só depois que todos os testes locais passarem e o fuso horário do agendamento estiver configurado corretamente você deve salvar e publicar o fluxo no n8n.
Fontes e leituras adicionais
- Actor Facebook Comments Scraper
- Documentação do Schedule Trigger do n8n
- Documentação do nó HTTP Request do n8n
- Documentação do nó Wait do n8n
- Documentação do nó Postgres do n8n
- Documentação do nó Split Out do n8n
- Referência da API da Apify - Get Actor Run
- Referência da API da Apify - Get Dataset Items
- Guia de análise de feedback da Chronometrica
- Guia de perguntas sem resposta da Chronometrica
Por Chronometrica · Atualizado
Voltar ao topo ↑

