Alejandro Rioja.
AI Agents Growth

Como Automatizar sua Newsletter com um Agente de IA

Alejandro Rioja
Alejandro Rioja
5 min de leitura
TL;DR

Um agente Claude lê minha fila de conteúdo, escolhe o ângulo mais forte da semana, rascunha uma newsletter na minha voz, segmenta a lista por nível de engajamento e agenda o envio via API do Kit — tudo sem que eu abra um editor. Reviso uma prévia renderizada e clico em aprovar. O trabalho criativo difícil é meu; a execução mecânica é do agente.

Newsletter gratuita

Toda quarta-feira. 28.400+ operadores. Zero enrolação.

Índice

Atualizado junho de 2026.

TL;DR: Um agente Claude lê minha fila de conteúdo, escolhe o ângulo mais forte da semana, rascunha uma newsletter na minha voz, segmenta a lista por nível de engajamento e agenda o envio via API do Kit — tudo sem que eu abra um editor. Reviso uma prévia renderizada e clico em aprovar. O trabalho criativo difícil é meu; a execução mecânica é do agente.

[Leitura do operador] Uma newsletter que envia consistentemente supera uma que é “melhor” mas que vai quando a inspiração aparece. A restrição era a sobrecarga de execução, não as ideias. Eu tinha ideias; não tinha largura de banda para formatá-las, agendá-las e segmentá-las toda semana. O agente eliminou essa lacuna.

O verdadeiro gargalo na maioria dos workflows de newsletter

A maioria dos conselhos de automação de newsletter foca na coisa errada: sequências de boas-vindas, automações, lógica de tags. Isso é bom, mas não resolve o problema de criação semana a semana.

O verdadeiro obstáculo é este: você sabe o que quer dizer, mas sentar para formatá-lo, escrever as variantes da linha de assunto, escolher o segmento certo e agendá-lo no momento certo custa 2-3 horas de troca de contexto por semana. Multiplique por 52 semanas e você terá passado uma semana inteira de trabalho apenas enviando newsletters.

O agente lida com cada etapa após “eu sei qual é o ângulo desta semana.”

O stack que estou usando

Se você não está no Kit, o mesmo padrão funciona com qualquer plataforma que tenha uma API REST para criar e agendar transmissões.

Passo 1: A fila de conteúdo

O agente precisa de uma fonte de verdade sobre “sobre o que estamos escrevendo.” A minha é uma tabela Airtable com colunas:

Cada semana, passo 10 minutos adicionando 2-3 tópicos à fila. Essa é minha contribuição criativa. O resto é trabalho do agente.

Passo 2: O agente de rascunho

typescript
// workers/newsletter-agent/index.ts
import Anthropic from "@anthropic-ai/sdk";
import Airtable from "airtable";

const client = new Anthropic();

const VOICE_SYSTEM = `You are writing a weekly newsletter for Alejandro Rioja's subscribers.
His audience: founders and operators interested in AI agents, SEO, and growing a one-person business.
Voice: direct, first-person, practitioner. No hype, no "exciting times," no excessive bullet lists.
Structure every newsletter as:
1. One-sentence hook (the problem or observation)
2. The core insight (3–5 paragraphs, no headers, conversational)
3. One concrete action the reader can take this week
4. A short sign-off (2 sentences max)
Subject line: specific, outcome-oriented, under 50 chars. No clickbait.
Return JSON: { "subject": "...", "preheader": "...", "body": "..." }`;

async function getNextTopic(): Promise<{ id: string; topic: string; notes: string; tier: string }> {
  const base = new Airtable({ apiKey: process.env.AIRTABLE_API_KEY }).base(process.env.AIRTABLE_BASE_ID!);
  const records = await base("Newsletter Queue")
    .select({ filterByFormula: "{Status} = 'Queue'", sort: [{ field: "Created", direction: "asc" }], maxRecords: 1 })
    .firstPage();
  if (!records.length) throw new Error("Queue is empty. Add topics.");
  const r = records[0];
  return { id: r.id, topic: r.get("Topic") as string, notes: (r.get("Notes") as string) ?? "", tier: (r.get("Tier") as string) ?? "all" };
}

async function draftNewsletter(topic: string, notes: string): Promise<{ subject: string; preheader: string; body: string }> {
  const msg = await client.messages.create({
    model: "claude-sonnet-4-6",
    max_tokens: 2048,
    system: VOICE_SYSTEM,
    messages: [{ role: "user", content: `Write this week's newsletter on: "${topic}". Additional notes: ${notes || "none"}` }],
  });
  const text = (msg.content[0] as any).text.replace(/```json\n?/, "").replace(/```/, "").trim();
  return JSON.parse(text);
}

async function scheduleWithKit(draft: { subject: string; preheader: string; body: string }, tier: string): Promise<string> {
  const segmentId = tier === "engaged" ? process.env.KIT_ENGAGED_SEGMENT_ID : null;
  const sendAt = new Date();
  sendAt.setDate(sendAt.getDate() + ((4 - sendAt.getDay() + 7) % 7)); // next Thursday
  sendAt.setHours(9, 0, 0, 0); // 9am CT

  const payload: any = {
    broadcast: {
      subject: draft.subject,
      content: draft.body,
      description: draft.preheader,
      send_at: sendAt.toISOString(),
      email_layout_template: "minimal",
    },
  };
  if (segmentId) payload.broadcast.segment_id = segmentId;

  const res = await fetch("https://api.kit.com/v4/broadcasts", {
    method: "POST",
    headers: { "Content-Type": "application/json", "X-Kit-Api-Key": process.env.KIT_API_KEY! },
    body: JSON.stringify(payload),
  });
  const data = await res.json();
  return data.broadcast?.id ?? "";
}

export default {
  async scheduled(_event: ScheduledEvent, env: Env) {
    // Inject env vars
    Object.assign(process.env, env);
    const { id, topic, notes, tier } = await getNextTopic();
    const draft = await draftNewsletter(topic, notes);
    const broadcastId = await scheduleWithKit(draft, tier);

    // Mark as Approved in Airtable (not Sent — human reviews the Kit preview before confirm)
    const base = new Airtable({ apiKey: env.AIRTABLE_API_KEY }).base(env.AIRTABLE_BASE_ID);
    await base("Newsletter Queue").update(id, { Status: "Approved", KitBroadcastId: broadcastId });

    console.log(`Scheduled broadcast ${broadcastId} for topic: ${topic}`);
  },
};

Passo 3: A etapa de aprovação

O agente cria a transmissão no estado de rascunho do Kit e marca o registro do Airtable como “Approved.” O Kit me envia uma notificação com um link de prévia. Clico nele, leio, e se parecer certo, confirmo o envio. Se quiser mudanças, edito diretamente no Kit.

Este é o portão que impede o agente de se tornar totalmente autônomo no email de saída. Confio nos rascunhos aproximadamente 90% das vezes. Os 10% que detecto na revisão — um tom ligeiramente errado, uma estatística que quero verificar, um link que quero adicionar — valem os 3 minutos de revisão.

O que o agente lida e que nunca mais quero fazer

O que ainda é meu

A ideia. O tópico na fila é meu. O ângulo é meu. O agente é um ótimo executor de um briefing claro; não é uma camada estratégica. Se eu colocar um tópico ruim na fila, obtenho uma newsletter bem escrita sobre um tópico ruim.

Também: o portão de primeira revisão. Cada envio passa pelos meus olhos antes de sair. Isso não vai mudar.

A conclusão do operador

Se você está gastando mais de uma hora por semana em mecânicas de newsletter — formatação, agendamento, segmentação — você deveria automatizar. A API do Kit é limpa, o gatilho cron do Worker é sólido como rocha, e a qualidade do rascunho do Claude é alta o suficiente para que eu aprove ~90% dos primeiros rascunhos sem alterações. Construa a fila no Airtable, conecte o Worker e volte a criar ideias em vez de executar envios.

Continue lendo

Receba o manual de IA na sua caixa de entrada

Toda quarta-feira. 28.400+ operadores. Zero enrolação.

↵ ver todos os resultados esc esc para fechar