Guia
Migrar do Resend
Migre do Resend para o Emailit. As APIs são parecidas, então as mudanças são pequenas. Faça a correspondência de campos, configurações SMTP e eventos de webhook, verifique as assinaturas e migre os contatos.
Este guia mostra a correspondência entre os conceitos, as chamadas à API, os webhooks e os templates do Resend e os equivalentes no Emailit. As duas APIs têm um formato parecido, então a maioria das mudanças no código é pequena. Leia antes Migrar para o Emailit para conhecer a ordem geral e saber como usar os dois provedores em paralelo.
Conceitos
| Resend | Emailit |
|---|---|
| Team | Workspace. Cada workspace tem os seus próprios domínios, chaves, membros e créditos. |
| Chave de API com acesso total ou de envio | Chave de API: Full Access, ou Sending Only, que pode ser restrita a um domínio |
| Domains | Domínios de envio |
| Audiences e contacts | Contatos e listas de contatos |
| Broadcasts | Campanhas |
| Webhooks | Webhooks |
| Emails e logs | Email APIEmails e Email APILogs |
tags |
meta |
| Componentes do React Email | HTML que você renderiza no seu código, ou templates criados no painel |
Atualizar as chamadas à API
O POST /emails do Resend passa a ser o POST /v2/emails do Emailit, com quase os mesmos campos. Em Node.js:
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
from: 'Acme <hello@acme.com>',
to: ['ada@example.com'],
subject: 'Your receipt',
html: '<p>Thanks for your order.</p>',
});import { Emailit } from '@emailit/node';
const emailit = new Emailit(process.env.EMAILIT_API_KEY);
await emailit.emails.send({
from: 'Acme <hello@acme.com>',
to: ['ada@example.com'],
subject: 'Your receipt',
html: '<p>Thanks for your order.</p>',
});| Resend | Emailit |
|---|---|
Authorization: Bearer re_… |
Authorization: Bearer secret_… |
from, subject, html, text, headers |
Iguais |
to, cc, bcc |
Iguais, até 50 cada |
reply_to (replyTo no SDK de Node.js) |
reply_to |
react (SDK de Node.js) |
Não disponível. Renderize o componente em HTML e passe html. |
attachments[] com filename e content ou path |
attachments[] com filename e content em base64 ou uma url. content_type é obrigatório com content. |
tags: [{ "name": "…", "value": "…" }] |
meta: { "name": "value" }, devolvido nos eventos de webhook |
scheduled_at |
scheduled_at (ISO 8601, horário Unix ou inglês simples) |
Cabeçalho Idempotency-Key |
Cabeçalho Idempotency-Key, mantido por 24 horas |
POST /emails/batch |
Não disponível. Envie uma requisição por mensagem. |
Resposta { "id": "…" } |
200 com id (em_…), status: "accepted" e ids, com um ID por destinatário |
Cada destinatário de uma requisição do Emailit vira um e-mail próprio, com o seu próprio ID. Quando você envia para vários destinatários, o ids da resposta associa cada endereço ao ID dele. O Emailit também rastreia aberturas e cliques por e-mail com tracking: { "loads": true, "clicks": true }, desde que o domínio tenha um subdomínio de rastreamento verificado. Consulte Enviar um e-mail.
React Email
Se você cria e-mails com o React Email, mantenha os seus componentes e renderize-os você mesmo antes de enviar:
import { render } from '@react-email/render';
import Receipt from './emails/receipt';
const html = await render(<Receipt order={order} />);
const text = await render(<Receipt order={order} />, { plainText: true });
await emailit.emails.send({ from, to, subject, html, text });Mudar as configurações SMTP
| Configuração | Resend | Emailit |
|---|---|---|
| Host | smtp.resend.com |
smtp.emailit.com |
| Porta | 587, 2587 ou 25 (STARTTLS), 465 ou 2465 (TLS) |
587, 2587, 2525 ou 25 (STARTTLS), 465 (TLS) |
| Usuário | resend |
emailit |
| Senha | A sua chave de API do Resend | A sua chave de API do Emailit |
Consulte Configurações SMTP.
Correspondência dos eventos de webhook
| Evento do Resend | Evento do Emailit |
|---|---|
email.sent |
email.accepted (somente API) |
email.delivered |
email.delivered |
email.delivery_delayed |
email.attempted |
email.bounced |
email.bounced |
email.complained |
email.complained |
email.opened |
email.loaded |
email.clicked |
email.clicked |
contact.created, contact.updated, contact.deleted |
Os mesmos nomes |
domain.created, domain.updated, domain.deleted |
Os mesmos nomes |
O formato da requisição muda:
- O Resend envia um evento por requisição. O Emailit envia um array JSON de até 100 eventos, então percorra o corpo em um loop.
- O e-mail fica em
data.object. Usedata.object.id, o IDem_da resposta do envio, em vez dedata.email_id. Os seus valores demetaficam emdata.object.meta. - As assinaturas funcionam de outro jeito. O Resend assina os webhooks pelo Svix, com cabeçalhos
svix-*. O Emailit enviaX-Emailit-Signature, o HMAC-SHA256 em hexadecimal de<timestamp>.<raw body>, com o segredo inteiro como chave, incluindo o prefixowhsec_. Uma biblioteca de verificação do Svix não vai funcionar, embora os dois segredos comecem comwhsec_. Consulte Assinatura das requisições.
for (const event of req.body) {
const email = event.data.object;
if (event.type === 'email.bounced') markBounced(email.to, email.id);
if (event.type === 'email.complained') unsubscribe(email.to);
}Migrar as supressões e os contatos
-
Reúna todos os endereços que deram bounce ou reclamaram enquanto você usava o Resend, pelo painel do Resend ou pelos eventos que os seus webhooks armazenaram.
-
Monte um único CSV com as colunas
email,type,reason:email,type,reason old-address@example.com,recipient,resend bounce angry@example.com,recipient,resend complaintUse o tipo
recipientpara endereços que nunca devem receber e-mails. Ele bloqueia envios pela API, por SMTP e de campanhas. -
Em Email APISuppressions, selecione Import e envie o arquivo. Cada arquivo pode ter até 10.000 linhas e no máximo 8 MB. Os duplicados são ignorados.
Se você envia broadcasts, exporte cada audience do Resend como CSV e importe-a em Email MarketingContacts com Import, escolhendo a lista de contatos correspondente no Emailit. Mapeie a coluna de descadastro para que as pessoas que saíram continuem descadastradas. Consulte Importar e exportar contatos.
Migrar os templates
Se você renderiza os e-mails no código, com o React Email ou qualquer outra coisa, nada muda: envie o HTML. Se você guarda templates no Resend, recrie-os em Email MarketingTemplates ou com a API de templates, dê um alias a cada um e envie-os com template e variables.
Os templates do Emailit usam o Temple: {{name}}, valores aninhados como {{user.name}}, valores padrão como {{name|"there"}} e {{#if plan}}…{{else}}…{{/if}}. Não há loops, então renderize as listas no seu código. O Temple nunca escapa HTML, então escape o que vier dos usuários antes de passar.
Alterar o DNS
Adicione o seu domínio em Email APIDomains e publique os registros do Emailit. Eles usam nomes próprios (emailit._domainkey, emailit.<domain> e, opcionalmente, go e inbound), então não entram em conflito com os registros do Resend, que normalmente ficam em resend._domainkey e em um subdomínio send. Mantenha o seu registro DMARC. Depois da virada, remova os registros do Resend. Consulte Registros DNS.
Próximos passos
- Checklist para entrar em produção
- Configurar webhooks
- Migração prioritária: deixe os engenheiros do Emailit fazerem a migração com você