Bora construir um Agente de Notícias Hiper-Personalizado? 🤖📰 (Codar Juntos)
Source: Dev.to
A ideia: Chega de newsletter genérica!
Você já percebeu que a maioria das newsletters de tech são genéricas demais ou só cobrem o que acontece no Vale do Silício? Decidi mudar isso criando um Software Agêntico que faz curadoria sob medida, e quero convidar você a codar comigo.
Não é só um chatbot. É um agente autônomo que:
- Varre a web em tempo real usando Tavily.
- Filtra por país e idioma: quer notícias sobre IA que saíram no Japão, mas resumidas em português? O agente resolve.
- Sintetiza com Gemini 1.5 Pro – o “cérebro” que traduz, resume e formata.
- Entrega via Resend – automação direto para a sua inbox (ou de uma audiência inteira).
Funcionalidades principais
- Busca em tempo real na web (Tavily).
- Filtragem por país e idioma.
- Síntese e tradução com Gemini 1.5 Pro.
- Envio de e‑mail automatizado (Resend + MJML).
Stack tecnológica
| Camada | Tecnologia |
|---|---|
| Framework | Next.js (Vercel) |
| Inteligência | Gemini SDK + Tavily API |
| Banco de dados & ORM | MongoDB + Prisma |
| E‑mail | Resend (Audiences para escalabilidade) |
| Design de e‑mail | MJML (responsivo) |
Roadmap (tarefas)
- Definir a arquitetura (Prisma + Mongo).
- Criar o formulário de captura de preferências (temas, países, idiomas).
- Orquestrar o loop do agente: pesquisa → resumo → tradução.
- Configurar o Cron Job na Vercel para envio semanal automático.
Como você pode colar junto
- Comente: qual feature você adicionaria a um agente de notícias?
- Escolha a stack que mais te interessa (Prompt Engineering, Integração de APIs ou Frontend no Next.js).
- GitHub: o repositório será liberado com a aplicação completa.
Objetivo inicial: ter o projeto rodando localmente e o banco pronto para receber inscritos.
Setup rápido
# Crie a aplicação Next.js
npx create-next-app@latest ai-newsletter
Instale as dependências:
npm install @prisma/client @google/generative-ai @tavily/core resend zod mjml
Configure o schema.prisma com o modelo Subscriber (ver exemplo abaixo).
Implementação
Interface do usuário
- Formulário com:
- Input de e‑mail.
- Selects para País e Idioma.
- Checkboxes para Temas de interesse.
API
- Rota
/api/subscribesalva o cadastro no MongoDB via Prisma.
// pages/api/subscribe.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { prisma } from '../../lib/prisma';
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
country: z.string(),
language: z.string(),
topics: z.array(z.string()),
});
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') return res.status(405).end();
const result = schema.safeParse(req.body);
if (!result.success) return res.status(400).json(result.error.format());
await prisma.subscriber.create({ data: result.data });
return res.status(200).json({ message: 'Inscrição salva com sucesso!' });
}
Busca & Síntese (A “mágica” agêntica)
// lib/agent.ts
import { Tavily } from '@tavily/core';
import { Gemini } from '@google/generative-ai';
export async function generateNewsletter(preferences) {
const searchResults = await Tavily.search({
query: preferences.topics.join(', '),
region: preferences.country,
language: preferences.language,
});
const prompt = `
Você é um assistente que deve:
1. Resumir as notícias encontradas.
2. Traduzir o resumo para ${preferences.language}.
3. Formatar o conteúdo como e‑mail (HTML).
`;
const gemini = new Gemini({ model: 'gemini-1.5-pro' });
const response = await gemini.generate({
prompt,
documents: searchResults,
});
return response.text; // HTML pronto para MJML
}
Prompt Engineering
- O prompt acima instrui o Gemini a formatar especificamente para o idioma do usuário e a gerar HTML pronto para MJML.
Integração MJML
// lib/mjml.ts
import mjml2html from 'mjml';
export function renderEmail(htmlContent) {
const mjmlTemplate = `
<mjml>
<mj-body>
<mj-section>
<mj-column>
${htmlContent}
</mj-column>
</mj-section>
</mj-body>
</mjml>
`;
const { html } = mjml2html(mjmlTemplate);
return html;
}
Lógica de batch (envio)
// pages/api/send-newsletter.ts
import { prisma } from '../../lib/prisma';
import { generateNewsletter } from '../../lib/agent';
import { renderEmail } from '../../lib/mjml';
import { resend } from '../../lib/resend';
export default async function handler(req, res) {
const subscribers = await prisma.subscriber.findMany();
for (const sub of subscribers) {
const content = await generateNewsletter(sub);
const html = renderEmail(content);
await resend.sendEmail({
from: 'news@yourdomain.com',
to: sub.email,
subject: 'Sua newsletter personalizada',
html,
});
}
res.status(200).json({ message: 'Newsletters enviadas' });
}
Cron Job na Vercel
Crie o arquivo vercel.json:
{
"crons": [
{
"path": "/api/send-newsletter",
"schedule": "0 9 * * MON"
}
]
}
Isso agenda a execução toda segunda‑feira às 9h.
Teste final
- Cadastre um e‑mail via formulário.
- Verifique a recepção da newsletter na caixa de entrada.
Próximos passos
- Refatorar a orquestração usando queues (ex.: BullMQ).
- Adicionar suporte a multiplas audiências no Resend.
- Implementar cache de resultados de busca para reduzir custos.
Bora parar de só dar “oi” pro ChatGPT e começar a construir ferramentas que realmente entregam valor de forma autônoma. 🚀