Blog/Construindo um assistente de e-mail com IA usando Sendkit
·8 min de leitura·
Vanessa LozzardoVanessa Lozzardo

Construindo um assistente de e-mail com IA usando Sendkit

Combine um LLM com a API do Sendkit pra construir um assistente que rascunha, envia e monitora e-mails em nome dos seus usuários.

IAAPI de E-mailTutorialAutomação
Construindo um assistente de e-mail com IA usando Sendkit

Seu usuário digita "manda um e-mail pro John avisando que o standup vai pras 15h". Trinta segundos depois, uma mensagem bem escrita cai na caixa do John — rascunhada por um LLM, aprovada pelo usuário, enviada pela sua infraestrutura e monitorada de ponta a ponta. Esse é o padrão de assistente de e-mail com IA, e é surpreendentemente direto de construir.

Este tutorial passa pela arquitetura, pelo código e pelas pontas afiadas que você precisa lixar antes de levar isso pra produção. A gente vai usar a OpenAI para a camada do LLM e a API de e-mail do Sendkit para envio e monitoramento de entrega.

O que um assistente de e-mail com IA faz de verdade

Tire o hype e você tem uma pipeline de quatro etapas:

  1. Interpretar a intenção — O usuário diz algo como "manda um e-mail pro John sobre a reunião". O LLM extrai o destinatário, o tópico e o tom.
  2. Rascunhar — O LLM gera um assunto e corpo com base na intenção extraída mais qualquer contexto disponível (threads anteriores, dados de calendário, preferências do usuário).
  3. Aprovar — O rascunho é mostrado ao usuário. Ele pode editar, regenerar ou enviar.
  4. Enviar e monitorar — O e-mail aprovado sai pela API do Sendkit. Webhooks reportam entrega, bounces e aberturas de volta pro seu app.

Cada etapa importa. Pule a aprovação e você eventualmente vai mandar algo embaraçoso. Pule o monitoramento de entrega e você está voando às cegas.

Uma workspace com telas mostrando código e interfaces de e-mail

Visão geral da arquitetura

Aqui está o fluxo desenhado:

User input → LLM (draft) → Preview UI → User approves → Sendkit API (send)
                                                              ↓
                                              Webhook events (delivered/bounced/opened)
                                                              ↓
                                              Feed status back to assistant context

O backend é um serviço Node.js. A chamada do LLM e o envio do e-mail são chamadas de API separadas — nunca combine num único passo. Você quer um portão humano entre "a IA escreveu algo" e "esse algo foi pra uma pessoa real".

Construindo a etapa de rascunho

A etapa de rascunho chama seu LLM com a intenção do usuário e retorna um output estruturado. Use function calling ou um schema JSON pra forçar o formato da resposta.

import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const draftEmail = async (userIntent, recipientContext) => {
  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      {
        role: 'system',
        content: `You are an email drafting assistant. Given user intent and context, produce a JSON object with "subject" (string) and "body" (string, plain text). Keep the tone professional but natural. Do not invent facts.`,
      },
      {
        role: 'user',
        content: `Intent: ${userIntent}\nRecipient context: ${JSON.stringify(recipientContext)}`,
      },
    ],
    response_format: { type: 'json_object' },
  });

  return JSON.parse(response.choices[0].message.content);
};

// Usage
const draft = await draftEmail('Tell John the standup is moving to 3 PM tomorrow', {
  name: 'John Park',
  email: '[email protected]',
  relationship: 'teammate',
});

console.log(draft.subject); // "Standup time change — moving to 3 PM"
console.log(draft.body); // "Hey John, quick heads up..."

Force output JSON. Se você deixar o LLM retornar texto livre, você vai gastar metade do tempo parseando e a outra metade debugando por que quebrou.

Humano no loop

Essa é a parte que as pessoas pulam quando estão empolgadas com IA. Não pule.

Apresente o rascunho ao usuário na sua UI. Dê a ele três opções: Editar, Regenerar ou Enviar. Guarde o rascunho no servidor com um ID único pra que a ação de envio referencie um payload aprovado, não o que o cliente postar.

import { randomUUID } from 'crypto';

const drafts = new Map();

const saveDraft = (draft, recipientEmail) => {
  const id = randomUUID();
  drafts.set(id, {
    to: recipientEmail,
    subject: draft.subject,
    body: draft.body,
    approved: false,
    createdAt: Date.now(),
  });
  return id;
};

const approveDraft = draftId => {
  const draft = drafts.get(draftId);
  if (!draft) throw new Error('Draft not found');
  draft.approved = true;
  return draft;
};

O princípio-chave: o LLM propõe, o usuário dispõe. Nunca envie a partir de um rascunho que não foi explicitamente aprovado.

Enviando via Sendkit

Depois que o usuário aprova, envie pela API do Sendkit. Instale o SDK:

npm install @sendkitdev/sdk

Depois envie o rascunho aprovado:

import { Sendkit } from '@sendkitdev/sdk';

const sendkit = new Sendkit(process.env.SENDKIT_API_KEY);

const sendApprovedDraft = async draftId => {
  const draft = approveDraft(draftId);

  const { data, error } = await sendkit.emails.send({
    from: '[email protected]',
    to: draft.to,
    subject: draft.subject,
    html: `<p>${draft.body.replace(/\n/g, '</p><p>')}</p>`,
    text: draft.body,
  });

  if (error) {
    console.error('Send failed:', error.message);
    return { success: false, error: error.message };
  }

  console.log('Sent:', data.id);
  return { success: true, messageId: data.id };
};

O SDK retorna { data, error } em vez de dar throw. Cheque error primeiro. O valor de data.id é sua referência pra monitorar a entrega depois. Sempre inclua html e text — alguns clientes de e-mail ainda preferem texto puro. Veja nosso guia completo de e-mail transacional com Node.js pra mais padrões.

Código em uma tela mostrando um ambiente de desenvolvimento

Monitorando entrega com webhooks

Enviar é metade do trabalho. Você precisa saber se o e-mail realmente chegou. Configure um endpoint de webhook no seu dashboard do Sendkit pra receber eventos de entrega.

import express from 'express';

const app = express();
app.use(express.json());

app.post('/webhooks/sendkit', (req, res) => {
  const { type, data } = req.body;

  switch (type) {
    case 'email.delivered':
      console.log(`Delivered: ${data.messageId} to ${data.to}`);
      // Update assistant context: "Your email to John was delivered"
      break;
    case 'email.bounced':
      console.log(`Bounced: ${data.messageId}${data.bounceReason}`);
      // Alert user: "Email to John bounced — check the address"
      break;
    case 'email.opened':
      console.log(`Opened: ${data.messageId}`);
      // Optional: "John opened your email"
      break;
  }

  res.sendStatus(200);
});

Alimente esses eventos de volta no contexto do assistente. Quando o usuário perguntar "o John recebeu meu e-mail?", o assistente pode responder com dados reais de entrega em vez de adivinhar. Para um mergulho mais profundo em tratamento de bounce, veja como lidar com bounces de e-mail.

Features inteligentes que valem a pena adicionar

Quando o loop principal funciona, sobreponha essas:

Validação de destinatário — Antes do LLM sequer rascunhar, valide o endereço do destinatário usando a API de validação de e-mail do Sendkit. Pegue erros de digitação e endereços descartáveis cedo. Sem sentido rascunhar um e-mail pra [email protected].

const { data: validation } = await sendkit.emailValidations.validate({
  email: recipientEmail,
});

if (validation.result !== 'deliverable') {
  // Ask user to double-check the address
}

Detecção de tom — Adicione um system prompt que classifica o tom do rascunho (formal, casual, urgente) e mostra isso ao usuário. "Isso soou formal — quer que eu deixe mais casual?" Detalhe pequeno, grande ganho de usabilidade.

Sugestões de horário de envio — Se você tem dados de fuso horário do destinatário, sugira horários ideais pra envio. Terça às 10h no fuso do destinatário bate sábado à meia-noite.

Consciência de thread — Passe threads anteriores de e-mail pro contexto do LLM pra que as respostas fiquem coerentes. O assistente deve saber o que o John disse antes, não só o que o usuário quer dizer agora.

Considerações de segurança

Um assistente de e-mail com IA e acesso a uma API de envio é um tiro no pé se você for descuidado. Tranque direito.

Allowlisting de destinatário — Nunca deixe o LLM escolher o destinatário. O usuário fornece o destinatário, seu código resolve o endereço de e-mail a partir do seu banco de contatos, e o LLM só rascunha o conteúdo. Se o usuário disser "manda pra empresa inteira", isso é decisão de lógica de negócio, não do LLM.

Sanitização de conteúdo — O LLM pode gerar conteúdo tipo HTML ou tentativas de injection (prompt injection via corpo de e-mail é uma superfície de ataque real). Sanitize o corpo antes de enviar. Retire scripts, limite tags HTML e escape qualquer coisa suspeita.

Rate limiting — Limite envios por usuário por hora. Um usuário entusiasmado (ou um cliente com bug) não deveria conseguir disparar 10.000 e-mails pelo seu assistente. O pricing do Sendkit é baseado em uso, então um loop descontrolado atinge sua carteira rapidinho.

Isolamento de chave de API — Use uma chave de API dedicada do Sendkit para seu assistente com permissões de envio restritas a domínio. Não reuse a chave principal da sua aplicação. Se a chave do assistente vazar, o raio da explosão fica contido.

Logging de auditoria — Logue cada envio com ID do usuário, ID do rascunho, destinatário e timestamp. Quando algo der errado (e vai dar), você precisa de um rastro.

Juntando tudo

O padrão de assistente de e-mail com IA é quatro preocupações costuradas: interpretação de intenção, geração de conteúdo, aprovação humana e entrega confiável. O LLM cuida das duas primeiras. Seu código cuida do portão de aprovação. O Sendkit cuida da última milha.

Comece pelo loop básico de envio — rascunhar, aprovar, enviar. Adicione monitoramento de webhooks quando isso estiver funcionando. Sobreponha validação e features inteligentes depois de ter embarcado a primeira versão e ter usuários reais te dizendo o que eles realmente precisam.

A documentação completa do Sendkit cobre chaves de API, verificação de domínio, assinaturas de webhook e rate limits. Se você está construindo agentes de IA que enviam e-mail autonomamente (sem humano no loop), leia nosso guia sobre agentes de IA que enviam e-mail pra ver os guardrails adicionais que isso exige.

Construa a versão simples primeiro. Embarque. Depois deixe inteligente.

Compartilhar este artigo