GUIA PRÁTICO · MOVANTI AUTOMAÇÃO

Monitoramento de mídia automatizado no N8N

Como montar um robô que lê imprensa, portais oficiais e YouTube todos os dias, joga fora o ruído, classifica o que sobra e te entrega um e-mail pronto para encaminhar.

ANTES DE COMEÇARO que você vai ter no final

Um fluxo que roda sozinho e te manda, por e-mail, um relatório com tudo que foi publicado sobre a sua marca (ou a do seu cliente) — já limpo, já classificado por tom e já agrupado por assunto.

É o que ferramentas prontas de mercado cobram entre R$ 1.100 e R$ 2.100 por mês para fazer.

Vou ser honesto com você: dá trabalho. Na primeira vez, reserve de 2 a 4 horas. A parte chata não é montar os nós — é acertar os filtros para o relatório não vir cheio de lixo. É exatamente aí que este guia economiza o seu tempo, porque eu já errei por você.

O que você precisa: uma instância do N8N (a versão gratuita serve), uma conta de e-mail com SMTP, e uma chave de API do YouTube (gratuita). Nada mais.

PARTE 1As 8 fontes que eu testei — e as 3 que não funcionam

Quase todo tutorial de monitoramento manda você sair plugando feeds. Metade não responde. Testei uma por uma, com requisição real, e este é o resultado:

FonteStatusObservação
RSS de busca do Google NotíciasFuncionaA base de tudo. Gratuito, sem chave, cobre imprensa nacional e regional.
Feed regional do G1FuncionaTraz o endereço real da matéria, coisa que o Google Notícias não dá.
Busca restrita a domínios .gov.brFuncionaPega prefeitura, câmara municipal e órgãos federais.
Diário Oficial da UniãoFuncionaA busca do in.gov.br responde a requisição direta.
YouTube Data API v3FuncionaGratuita. Mas a sintaxe da busca decide tudo — ver Parte 5.
Feed /feed de jornal regionalNão funcionaTestei dois portais locais. Ambos devolveram zero itens nesse caminho.
RSS do portal gov.br/saudeNão funcionaA rota /RSS devolve HTML sem nenhum item.
Link do item no Google NotíciasArmadilhaExiste, mas não abre. Explico logo abaixo.

A armadilha que vai te custar uma tarde

O RSS do Google Notícias entrega, em cada item, um link assim:

https://news.google.com/rss/articles/CBMimAFBVV95cUxNSlpTcll5...

Parece o endereço da matéria. Não é. É um redirecionamento fechado que só resolve dentro do próprio Google, por script. Eu tentei três caminhos para chegar no endereço real: decodificar o trecho em base64, seguir o redirecionamento e ler o HTML da página de destino. Nenhum funciona — o endereço verdadeiro não está em lugar nenhum do item do feed.

A solução: não use esse link no relatório. Monte um link de busca no domínio do veículo, assim:
https://www.google.com/search?q=site%3A<dominio>+<palavras+da+manchete>

Sem acentos nas palavras da manchete. Abre em qualquer navegador e leva o leitor direto na matéria. Quando a fonte tiver feed próprio (como o G1 regional), prefira sempre o feed — ali o link é real.

PARTE 2A estrutura do fluxo

São oito nós, nesta ordem:

Schedule Trigger
   ↓
Config            (nó Code — a única coisa que você edita no dia a dia)
   ↓
Feed URLs         (nó Code — transforma a lista de buscas em itens)
   ↓
RSS Read          (nó RSS — marque "continue on fail")
   ↓
Processar         (nó Code — filtra, deduplica, normaliza)
   ↓
Classificar       (nó de IA — define o tom de cada menção)
   ↓
Montar Digest     (nó Code — gera o HTML do e-mail)
   ↓
Tem resultado?    (nó IF) → Send Email
Tela do passo descrito abaixo
O fluxo completo no n8n. Da esquerda para a direita: o gatilho diário, o Config, a montagem das buscas, a leitura das notícias, o filtro, a classificação por inteligência artificial, a montagem do relatório e a decisão de enviar ou não.
Tela do passo descrito abaixo
O gatilho. Trigger Interval em Days, Days Between Triggers em 1, Trigger at Hour em 7am e Trigger at Minute em 0 — ou seja, todo dia às sete em ponto.
Marque "continue on fail" no nó de RSS. Sem isso, uma única fonte fora do ar derruba a execução inteira e você não recebe nada naquele dia.
Tela do passo descrito abaixo
O nó Ler Notícias. O campo URL recebe {{ $json.url }}, que vem do nó anterior. A opção de continuar em caso de erro fica na aba Settings.
Tela do passo descrito abaixo
A aba Settings do mesmo nó. O campo On Error precisa estar em Continue — é isso que impede que uma fonte fora do ar derrube a execução inteira do dia.

PARTE 3O nó Config — com as buscas que funcionam

Este é o único nó que você mexe depois de montado. Cole isto num nó Code, em modo "Run Once for All Items":

Tela do passo descrito abaixo
O nó Config aberto. Mode em "Run Once for All Items", Language em JavaScript, e o código com as buscas, a janela de dias e as listas de incluir e excluir.

O código exato do nó Config

// O unico no que voce edita no dia a dia.
return [{ json: {
  buscas: [
    '"Nome da Marca" Cidade',
    '"Nome Completo da Organizacao"',
    '"Nome da Marca" Cidade site:gov.br'
  ],
  janelaDias: 7,
  incluir: [ ['nome da marca', 'cidade'] ],
  excluir: [ 'homonimo conhecido' ],
  limiteVistos: 5000
}}];

Como a URL da busca é montada

https://news.google.com/rss/search?q=<BUSCA>+when%3A<N>d
&hl=pt-BR&gl=BR&ceid=BR:pt-150

A busca vai codificada para URL. Os parâmetros hl, gl e ceid são o que força resultado em português do Brasil — sem eles, vem conteúdo de Portugal e dos Estados Unidos misturado.

Tela do passo descrito abaixo
O nó Montar Buscas. Ele lê a lista do Config e transforma cada busca numa URL de RSS do Google Notícias, já com a janela de dias e os parâmetros de idioma.

O código exato do nó Montar Buscas

// Uma URL de RSS do Google Noticias por busca.
const c = $('Config').first().json;
return (c.buscas || []).map(b => ({ json: {
  url: 'https://news.google.com/rss/search?q=' +
    encodeURIComponent(b + ' when:' + c.janelaDias + 'd') +
    '&hl=pt-BR&gl=BR&ceid=BR:pt-150'
}}));

PARTE 4O filtro — e o erro que quase ninguém percebe

A regra é simples: um item entra se casar com todos

Tela do passo descrito abaixo
O nó Filtrar e Deduplicar. Repare na primeira linha: a função limpar usa normalize('NFD') para tirar o acento antes de comparar — é o que evita o problema explicado abaixo.

O código exato do nó Filtrar e Deduplicar

const limpar = s => String(s || '').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').trim();
const casa = (t, x) => limpar(t).includes(limpar(x));
const c = $('Config').first().json;
const st = $getWorkflowStaticData('global');
if (!Array.isArray(st.vistos)) st.vistos = [];
const visto = new Set(st.vistos);
const saida = [];
for (const it of items) {
  const j = it.json || {};
  const txt = (j.title || '') + ' ' + (j.contentSnippet || '');
  if (!(c.incluir || []).some(b => b.every(t => casa(txt, t)))) continue;
  if ((c.excluir || []).some(t => casa(txt, t))) continue;
  if (visto.has(j.link)) continue;
  visto.add(j.link);
  saida.push({ json: { titulo: j.title, link: j.link, data: j.isoDate } });
}
st.vistos = [...visto].slice(-(c.limiteVistos || 5000));
return saida;
Um detalhe sobre a linha 1. Na imagem acima, o trecho [̀-ͯ] aparece como uns caracteres estranhos, quase invisíveis — são os sinais de acento em si. Ao copiar daqui, você leva a versão escrita como ̀-ͯ, que é a mesma coisa e sobrevive a copiar e colar. Use a daqui, não tente copiar da imagem.
os termos de pelo menos um bloco de incluir, e não casar com nenhum termo de excluir.

O erro: quase todo exemplo pronto na internet usa \b na expressão regular para casar palavra inteira. \b foi desenhado para o alfabeto inglês e se comporta de forma errada com acento e cedilha. "Misericórdia", "atenção" e "São" quebram de formas silenciosas — o filtro simplesmente deixa passar ou barra sem você entender por quê.
A correção: normalize antes de comparar. Tire o acento dos dois lados e compare em minúsculas.
function limpar(s) {
  return String(s || '')
    .toLowerCase()
    .normalize('NFD')
    .replace(/[̀-ͯ]/g, '')  // remove acentos
    .replace(/\s+/g, ' ')
    .trim();
}

function casa(texto, termo) {
  return limpar(texto).includes(limpar(termo));
}

Os três tipos de lixo que você vai encontrar

  1. Homônimos institucionais. Organizações com o mesmo nome em outras cidades. A imprensa regional cobre todas, e depois do primeiro parágrafo o texto passa a dizer só o nome curto. Resolve com excluir.
  2. Pessoas com apelido igual ao da marca. Em período eleitoral isso é comum: candidatos adotam o nome de instituições conhecidas como apelido de urna. Toda matéria sobre a pessoa casa com o seu termo. Resolve com excluir.
  3. Matérias que só citam a cidade. Acidente de trânsito, agenda cultural, previsão do tempo. Resolve exigindo o nome da marca junto, no mesmo bloco de incluir.

Numa rodada real, foi assim: 120 notícias coletadas, 9 no relatório final. O resto era exatamente esses três tipos.

PARTE 5Deduplicação — para não mandar a mesma notícia duas vezes

O mesmo link chega com parâmetros de campanha diferentes e vira duas menções. Limpe o endereço antes de comparar:

Isto é uma melhoria, não está no nó da imagem. O nó que você acabou de montar compara o link como ele vem. Funciona na maioria dos casos. Se as suas fontes mandarem o mesmo link com parâmetros de campanha diferentes, troque a comparação pela função abaixo.
function chaveDoLink(url) {
  try {
    const u = new URL(String(url).trim().toLowerCase());
    u.hash = '';
    ['utm_source','utm_medium','utm_campaign','utm_term',
     'utm_content','gclid','fbclid'].forEach(p => u.searchParams.delete(p));
    return u.hostname.replace(/^www\./,'') +
           u.pathname.replace(/\/$/,'') + u.search;
  } catch { return String(url); }
}

Guarde essas chaves no workflow static data do N8N, cortando as mais antigas quando passar do limite que você definiu no Config.

Detalhe que muda tudo: não busque "as notícias de hoje". Busque tudo desde a última execução bem-sucedida. Se a máquina ficou fora do ar três dias, a execução seguinte traz os três dias juntos. Assim, queda vira atraso — nunca vira perda.

PARTE 6YouTube — onde mora o que a imprensa não mostra

Essa foi a parte que mais me surpreendeu, e é a que quase ninguém monitora.

Num teste real, a imprensa passou 30 dias sem publicar nada sobre a organização monitorada. No mesmo período, havia 7 vídeos no YouTube citando ela — todos do mesmo canal, todos recentes. Quem monitorava só jornal não veria nada.

A sintaxe decide tudo

Busca solta: q=Nome da Marca Cidade
Devolveu 322 mil resultados. Casa à venda, jogo de futebol amador, qualquer coisa que tenha uma das palavras. Imprestável.
Frase exata, ordenada por data, com janela:
https://www.googleapis.com/youtube/v3/search
  ?part=snippet
  &type=video
  &order=date
  &publishedAfter=2026-09-01T00:00:00Z
  &q=%22Nome%20Exato%20da%20Marca%22
  &key=SUA_CHAVE
Devolveu 29 resultados, quase todos relevantes.

As aspas em volta da frase (%22) e o publishedAfter são obrigatórios. Sem os dois, o YouTube entope o seu relatório e você desiste da fonte achando que ela não presta.

A chave é gratuita: console do Google Cloud, ative a YouTube Data API v3, crie uma chave e restrinja ela a essa API. A cota diária dá para umas 100 buscas, muito mais do que um monitoramento diário precisa.

Como pegar a chave, passo a passo

Entre em console.cloud.google.com com a sua conta Google. Não precisa de cartão de crédito — e se aparecer uma faixa oferecendo créditos de teste, ignore, você não vai precisar.

1. No seletor de projeto, lá em cima, crie um projeto novo. Dê o nome que quiser e confirme que ele ficou selecionado antes de seguir.

Tela do passo descrito abaixo
O nome do projeto aparece no topo, ao lado do logo do Google Cloud. Confira sempre — criar a chave no projeto errado é o tropeço mais comum daqui para a frente.

2. Abra o menu das três linhas e vá em APIs e serviços → Biblioteca.

Tela do passo descrito abaixo
O caminho no menu lateral: APIs e serviços, depois Biblioteca.

3. Busque por youtube data api v3. Vai voltar um resultado só.

Tela do passo descrito abaixo
A busca devolve um resultado único: YouTube Data API v3, do Google.

4. Abra o resultado e clique em Ativar.

Tela do passo descrito abaixo
A tela do produto. O botão Ativar é o que liga a API neste projeto. Se você já tiver ativado antes, no lugar dele vai aparecer Gerenciar.

5. Agora vá em APIs e serviços → Credenciais, clique em Criar credenciais e escolha Chave de API.

Tela do passo descrito abaixo
Das quatro opções, a que interessa é a primeira: Chave de API. As outras servem para casos em que o usuário final precisa autorizar o acesso, que não é o nosso.

6. Antes de salvar, restrinja a chave. Em "Selecionar restrições da API", marque apenas a YouTube Data API v3. Em "Restrições do aplicativo", deixe em Nenhum.

Tela do passo descrito abaixo
A chave restrita a uma API só. Se ela vazar, não serve para mais nada. Restrições do aplicativo fica em Nenhum porque o seu IP de internet residencial muda sozinho — se você travar por IP, a chave para de funcionar do nada.

7. A chave aparece numa janela, uma única vez. Copie e guarde num arquivo seu.

Tela do passo descrito abaixo
A janela que mostra a chave. Repare que aqui ela está rasurada de propósito: é exatamente o que você deve fazer se algum dia precisar mostrar essa tela para alguém.
E aqui vai o conselho mais importante deste guia: chave de API é senha. Não cole em conversa, não mande por mensagem, não coloque em print e não suba para repositório de código. Se algum dia você desconfiar que expôs uma, apague e crie outra — leva trinta segundos e não quebra nada além do que você mesmo configurou.

PARTE 7A classificação — onde a IA entra (e onde não deve entrar)

Quase todo modelo pronto de monitoramento classifica sentimento com lista de palavras: soma pontos de palavras boas e ruins e decide. Dois problemas graves:

Troque esse bloco inteiro por uma chamada de IA. O prompt que funciona:

Tela do passo descrito abaixo
O nó Classificar com IA, configurado como requisição HTTP. Método POST, o endereço da API e o envio de cabeçalhos ligado.
Você recebe uma lista de menções sobre [ORGANIZAÇÃO].

Para cada uma:
1. Decida se é REALMENTE sobre essa organização. Se a manchete
   citar só o nome curto e puder ser outra, marque A_CONFIRMAR
   e escreva o motivo da dúvida. Nunca chute.
2. Classifique o tom: POSITIVO, NEUTRO, NEGATIVO ou CRISE.
   CRISE é o que exige resposta no mesmo dia: denúncia,
   investigação, morte, processo, acusação pública.
3. Marque se envolve política (candidato, vereador, deputado,
   prefeito ou câmara).
4. Agrupe menções do mesmo acontecimento num item só,
   com todos os links juntos.

Não opine. Registre o que foi publicado, por quem e quando.
O agrupamento é o que separa relatório lido de relatório ignorado. Num teste, cinco veículos cobriram a mesma inauguração em dois dias. O relatório certo mostra um acontecimento com cinco links, não cinco itens seguidos dizendo a mesma coisa.

E a regra que não se negocia: o relatório registra, não opina. Nada de qualificar candidato, sugerir resposta ou insinuar irregularidade. A leitura é de quem recebe. Isso protege você e protege o cliente.

PARTE 8O e-mail

Duas decisões que parecem detalhe e não são:

Estilo embutido, linha a linha

Tela do passo descrito abaixo
O nó Montar Relatório. Repare que o estilo vai dentro de cada elemento, com style=, e não num bloco separado no topo.

O código exato do nó Montar Relatório

let html = '<div style="font-family:Arial,sans-serif;max-width:680px">';
html += '<h1 style="font-size:20px">Monitoramento de midia</h1>';
for (const i of items) {
  const j = i.json;
  html += '<div style="border:1px solid #e3e6ea;border-radius:8px;padding:14px;margin-bottom:12px">';
  html += '<a href="' + j.link + '" style="color:#0b5cad;font-weight:600">' + j.titulo + '</a></div>';
}
html += '</div>';
return [{ json: { html: html, total: items.length } }];

Nada de bloco <style> no topo. Gmail e Outlook tratam isso de forma diferente e o seu relatório chega desmontado. Coloque o estilo dentro de cada elemento, com style="...". É feio de escrever e é o que funciona em todo lugar.

Dia sem menção, sem e-mail

Tela do passo descrito abaixo
O nó Tem menção?. A condição compara {{ $json.total }} com zero: se não houver nenhuma menção, o fluxo desvia e nenhum e-mail é enviado.
Tela do passo descrito abaixo
O nó Enviar E-mail. Os campos de remetente, destinatário, assunto e o formato em HTML. A credencial de SMTP é conectada no botão do topo.

Use o nó IF para cortar execução vazia. E-mail dizendo "nenhuma novidade" toda semana treina o destinatário a ignorar você.

Mas cuidado com o oposto: se a marca passa semanas em silêncio, o relatório vira raro demais e some da memória de quem recebe. A saída é ter uma seção de contexto do setor — o que aconteceu com organizações parecidas — que sustenta a edição quando o cliente está quieto.

PARTE 9Os erros que custam tempo

  1. Usar o link do Google Notícias. Não abre. Monte link de busca no domínio do veículo.
  2. Usar \b na expressão regular. Quebra com acento. Normalize antes de comparar.
  3. Buscar no YouTube sem aspas. 322 mil resultados de lixo.
  4. Buscar "hoje" em vez de "desde a última execução". Um dia fora do ar vira notícia perdida para sempre.
  5. Confiar na manchete para identificar a organização. Abra a matéria. Supor por coincidência de data é o erro mais fácil e o mais caro: atribuir uma crise à instituição errada destrói a confiança de uma vez.
  6. Não marcar "continue on fail" no RSS. Uma fonte fora do ar derruba o dia inteiro.

PARA FECHARO que fazer agora

  1. Suba um N8N (a versão gratuita serve) e monte os oito nós da Parte 2.
  2. Comece só com a imprensa. Faça funcionar, veja o que vem de lixo, ajuste o excluir. Vai ajustar umas cinco vezes nas duas primeiras semanas — é normal e é assim que fica bom.
  3. Só depois ligue o YouTube e os canais oficiais.
  4. Rode manualmente por uma ou duas semanas antes de automatizar o envio. Você precisa ver o que o robô erra antes de deixar ele falar com alguém.

Se travar em alguma parte, me chama no LinkedIn e me diz onde travou. Eu respondo.