Como automatizei notícias no meu blog
Antes de mais nada, quero explicar por que criei este blog.
Em determinado acontecimento da minha vida profissional, cheguei à conclusão de que precisava evidenciar meu conhecimento. Talvez isso me ajudasse a evitar entrar em alguma fria. Foi aí que entendi que uma das melhores formas seria criar um blog: um espaço para compartilhar o que sei, o que aprendo e, ao mesmo tempo, dar a quem procura por meu trabalho uma visão mais real do que eu me proponho a fazer.
No momento em que escrevo este artigo, é bem provável que o blog ainda tenha pouco (ou nenhum) conteúdo, já que este é um dos primeiros textos.
Voltando um pouco no tempo, lembrei que recentemente eu tinha criado uma newsletter personalizada só pra mim. Ela era gerada por um pipeline rodando numa VPS minha, usando o n8n. Já explico que bicho é o n8n.
Esse fluxo buscava notícias a partir de uma lista de feeds, tratava erros, filtrava apenas notícias das últimas 24 horas, organizava o conteúdo em um layout baseado em tags de assunto e enviava tudo por e-mail. Era perfeita, pelo menos perfeita pra mim.
Bom, certamente eu não vou postar artigos todos os dias. Mas pensei, já que essa newsletter é totalmente personalizada, nada melhor do que ela também mostrar quais são meus interesses.
Então, pra suprir também um pouco essa necessidade de conteúdo, desde que isso não virasse o foco principal do blog, decidi publicar essa lista de notícias por aqui. Então coloquei a mão na massa.
O que é n8n
É uma ferramenta pra automatizar workflows. Basicamente, ele conecta tudo com tudo. Você monta um fluxograma numa interface e vai encaixando componentes em componente tipo “salvar conteúdo em um arquivo”, “fazer upload pro Drive”, “chamar uma API”, “enviar e-mail” e por aí vai.
A quantidade de componentes é gigante. E quando não tem o que você precisa, dá pra resolver com um que roda JavaScript, ou até acessando um servidor via SSH pra executar algum comando.
Por isso que tem gente tão maluca por ele. Eu como um bom programador não acho que ele seja tanto. Mas para pequenos processos como esse que fiz, que vão rodar uma vez por dia, que eu não me preocupo com disponibilidade, não tem porque não usar.
A ferramenta é fair-code (Sustainable Use License), significa que você pode usar de graça para uso pessoal ou interno da empresa. Mas não pode revender.
Github
O que eu precisava
Eu já tinha o pipeline que usava para a newsletter. Mas eu queria uma coisa mais organizada, pois aquele pipeline foi feito de qualquer jeito. Queria fazer algo sem 'copia e cola', para entender melhor como o n8n funcionava.
- Executar o fluxo de 24 em 24 horas
- Ler uma lista de feeds e criar uma lista com todas as notícias
- Filtrar as notícias das últimas 24 horas
- Filtrar por notícias que eram mais relevantes aos assuntos que eu queria
- Montar um layout
- Cadastrar um post no blog
Então para criar isso eis o fluxo no n8n:

Traduzindo isso:
1. É executado um cron todo o dia pela manhã. Componente Schedule Trigger
2. Fornece lista de feeds. Componente Edit Fields (Set)
3. Separa cada url de feed. Componente Split Out
4. Executa um loop para cada url. Componente Loop Over Items
5. Lê o feed. Componente RSS Read
6. Filtra por notícias da última 24 horas. Componente Filter
7. Cria uma CSV com todas as notícias. Componente Convert to File
8. Faz upload do csv para o gemini. Componente Gemini
9. A IA analisa o csv usando um prompt. Componente Gemini
10. Finalmente cadastra um post. Componente HTTP Request
Ainda temos o fluxo quando o feed da erro:
1. Organiza os dados de erro. Componente Edit Fields (Set)
2. Salva em uma tabela criada próprio n8n. Componente Data table
Como a IA analisa
No item 9, onde a IA analisa os dados do CSV é a executarão do seguinte prompt:
# Regra
Você é um Editor Sênior de Tecnologia e Blogueiro especializado em desenvolvimento de software. Sua tarefa é curar, resumir e formatar uma lista bruta de notícias para um blog técnico.
# Contexto de Entrada
Você receberá uma lista de notícias cruas na variável: {{news_list}}
Você deve considerar a data e hora atual como: {{current_time_utc}} (para cálculos de tempo)
# Etapa 1: Curadoria e Filtragem
Analise a lista `{{news_list}}` e aplique as seguintes regras estritas:
1. **Prioridade de Tópicos:** Ruby, Ruby on Rails, IA/LLM, Notícias do Brasil (Tech), React, Golang, Elixir, Produtividade, Ops/DevOps.
2. **Deduplicação:** Remova itens com a mesma URL ou títulos extremamente similares.
3. **Ordenação:** Se houver data, use "Mais recente primeiro". Se não, mantenha a ordem original.
4. **Quantidade:** Selecione no máximo os 40 itens mais relevantes baseados na prioridade acima.
# Etapa 2: Geração de Conteúdo (Mental)
Para cada item selecionado:
1. Escreva um resumo objetivo em Português (PT-BR) entre 200 e 300 caracteres. Sem opiniões, apenas fatos.
2. Agrupe os itens nas categorias: "Ruby/Rails", "IA/LLM", "React", "Golang", "Elixir", "Produtividade", "Ops", "Brasil" ou "Geral".
# Etapa 3: Formatação de Saída (JSON Crítico)
Você deve gerar **APENAS** um objeto JSON válido. Não use blocos de código markdown (\`\`\`).
## Estrutura do JSON
{
"post": {
"title": "Título de no máximo 60 caracteres (Ex: Resumo Tech: Rails, IA e DevOps)",
"summary": "Resumo geral do dia em português, 300-450 caracteres, destacando os temas principais.",
"content": "STRING_MARKDOWN_ESCAPADA",
"post_type": "news",
"tags": "Tag1, Tag2, Tag3, Tag4, Tag5",
"locale": "pt",
"show_sidebar": true,
"published_at": "CALCULATED_DATE"
}
}
## Regras para o campo "published_at"
1. Pegue a data/hora atual fornecida em `{{current_time_utc}}`.
2. Subtraia exatamente 4 horas.
3. Formate como ISO 8601 UTC: `YYYY-MM-DDTHH:MM:SSZ`.
## Regras para o campo "content" (Atenção Máxima)
Este campo é uma **string única**. Você deve formatar o conteúdo em Markdown e depois escapá-lo para JSON:
1. Use `\n` para quebras de linha.
2. Use `\"` para aspas duplas dentro do texto.
3. Estrutura do Markdown dentro da string:
- `## Categoria` (H2)
- `### Título da Notícia` (H3)
- `Resumo do texto...` (Texto)
- `[Fonte](URL_DA_NOTICIA)` (Link)
# SAÍDA
Gere apenas o JSON final.
Essa estrutura de JSON descrita no prompt é o que o último componente (HTTP Request) recebe enviando como payload para a API do blog via POST com um token no header previamente cadastrado na administração do Blog.
E para que as notícias não fiquem mais evidentes que os próprios posts, foi feito o seguinte layout:

Notícias em sequencia se agrupam para ocupar menos espaço.
Finalizando
Acredito que todos podem ter algum processo do dia a dia que faz manualmente. Talvez nem perceba que pode automatizar. Apesar de que esse post não tenha sido um passo a passo de como fazer isso, espero que ele possa ter incentivado alguém. E se alguém tiver interesse em saber mais, terei o prazer em responder qualquer dúvida.