# Enviar e-mails com Node.js

> Envie e-mails do Node.js com o SDK @emailit/node ou com o Nodemailer por SMTP, e verifique os webhooks do Emailit em uma rota do Express.

Este guia mostra como enviar e-mails de uma aplicação Node.js com o SDK oficial `@emailit/node`, como usar o Nodemailer por SMTP como alternativa e como receber webhooks assinados no Express.

## Pré-requisitos

- Node.js 18 ou mais recente.
- Um [domínio de envio verificado](/pt/docs/domains/add-a-domain/), por exemplo, `acme.com`.
- Uma [chave de API](/pt/docs/developers/api-keys/). Uma chave Sending Only é suficiente para enviar.
- Até o seu workspace ter [acesso de produção](/pt/docs/workspaces/production-access/), você só pode enviar para os e-mails das contas dos membros do workspace. Use o seu próprio endereço durante os testes.

## Instalar o SDK

```bash
npm install @emailit/node
```

O pacote é apenas ESM. Use a sintaxe `import` ou `await import('@emailit/node')` em código CommonJS.

## Configurar a chave de API

Mantenha a chave fora do seu código. Coloque-a em uma variável de ambiente:

```bash title=".env"
EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••
```

Carregue o arquivo com `node --env-file=.env` (Node.js 20.6 e mais recentes), com um pacote como o `dotenv` ou com as configurações de segredos da sua plataforma. Adicione o `.env` ao `.gitignore`.

## Enviar um e-mail

Crie um único cliente e reutilize-o entre as requisições:

```javascript title="send.mjs"

const emailit = new Emailit(process.env.EMAILIT_API_KEY);

const email = await emailit.emails.send({
  from: 'Acme <hello@acme.com>',
  to: 'ada@example.com',
  subject: 'Welcome to Acme',
  html: '<p>Thanks for signing up.</p>',
  text: 'Thanks for signing up.',
});

console.log(email.id); // em_…
```

Execute-o com `node --env-file=.env send.mjs`. O e-mail aparece em **Email API → Emails** em poucos segundos.

Em uma aplicação Express, envie a partir da rota que dispara o e-mail:

```javascript title="server.mjs"

const app = express();
const emailit = new Emailit(process.env.EMAILIT_API_KEY);

app.post('/signup', express.json(), async (req, res) => {
  const { email } = req.body;
  // Create the user here, then send the welcome email.
  const sent = await emailit.emails.send({
    from: 'Acme <hello@acme.com>',
    to: email,
    template: 'welcome',
    variables: { email },
  });
  res.status(201).json({ emailId: sent.id });
});

app.listen(3000);
```

`template` recebe o alias ou o ID `tem_` de um template, e `variables` o preenche. Consulte [Templates](/pt/docs/templates/) e a lista completa de campos em [Enviar um e-mail](/pt/docs/api-reference/emails/send/).

## Tratar erros

O SDK lança erros tipados, então você pode reagir a cada falha:

```javascript
  AuthenticationException,
  RateLimitException,
  UnprocessableEntityException,
  ApiErrorException,
} from '@emailit/node';

try {
  await emailit.emails.send(message);
} catch (err) {
  if (err instanceof RateLimitException) {
    // 429: wait err.jsonBody.retry_after seconds, then retry
  } else if (err instanceof AuthenticationException) {
    // 401: the API key is missing or invalid
  } else if (err instanceof UnprocessableEntityException) {
    // 422: for example, the from domain isn't verified
  } else if (err instanceof ApiErrorException) {
    console.error(err.httpStatus, err.jsonBody);
  } else {
    throw err;
  }
}
```

## Enviar por SMTP como alternativa

Se a sua aplicação já usa o [Nodemailer](https://nodemailer.com), aponte-o para o SMTP relay do Emailit. Instale-o com `npm install nodemailer`:

```javascript title="mailer.mjs"

const transporter = nodemailer.createTransport({
  host: 'smtp.emailit.com',
  port: 587,
  secure: false, // upgraded with STARTTLS after connecting
  requireTLS: true,
  auth: {
    user: 'emailit',
    pass: process.env.EMAILIT_API_KEY,
  },
});

const info = await transporter.sendMail({
  from: 'Acme <hello@acme.com>',
  to: 'ada@example.com',
  subject: 'Welcome to Acme',
  text: 'Thanks for signing up.',
  html: '<p>Thanks for signing up.</p>',
});

console.log(info.response); // 250 2.0.0 OK: queued as em_…
```

Para a porta 465, defina `port: 465` e `secure: true`. Se a sua rede bloquear a 587, use 2525 ou 2587 com as mesmas configurações. Consulte [Configurações de SMTP](/pt/docs/smtp/settings/).

## Receber webhooks

[Crie um webhook](/pt/docs/webhooks/set-up/) que aponte para `https://your-app.com/webhooks/emailit` e copie o segredo de assinatura dele (`whsec_…`) para `EMAILIT_WEBHOOK_SECRET`.

O Emailit assina cada requisição com um HMAC-SHA256 de `timestamp.rawBody`, então a rota precisa ler o corpo bruto. Use `express.raw()` nesta rota, não `express.json()`:

```javascript title="webhooks.mjs"

function verifyEmailitSignature(rawBody, signature, timestamp, secret) {
  if (!signature || !timestamp) return false;
  const age = Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp));
  if (!Number.isFinite(age) || age > 300) return false; // reject replays older than 5 minutes
  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(signature);
  return a.length === b.length && timingSafeEqual(a, b);
}

webhooks.post('/webhooks/emailit', express.raw({ type: 'application/json' }), (req, res) => {
  const rawBody = req.body.toString('utf8');
  const valid = verifyEmailitSignature(
    rawBody,
    req.get('x-emailit-signature'),
    req.get('x-emailit-timestamp'),
    process.env.EMAILIT_WEBHOOK_SECRET,
  );
  if (!valid) return res.status(401).send('Invalid signature');

  // The body is an array of up to 100 events.
  const events = JSON.parse(rawBody);
  for (const event of events) {
    switch (event.type) {
      case 'email.delivered':
        // event.data.object.id is the em_ ID
        break;
      case 'email.bounced':
      case 'email.complained':
        // stop emailing event.data.object.to
        break;
    }
  }

  res.sendStatus(200);
});
```

Monte o router com `app.use(webhooks)` antes de qualquer middleware global `express.json()`. Retorne um `2xx` em até 30 segundos; qualquer outra resposta recebe novas tentativas. Leia [Assinatura das requisições](/pt/docs/webhooks/request-signature/) e [Novas tentativas e falhas](/pt/docs/webhooks/retries-and-failures/) para mais detalhes.

## Dicas para produção

- **Restrinja o escopo da chave.** Use no servidor da aplicação uma chave Sending Only restrita ao seu domínio de envio. Reserve as chaves Full Access para scripts administrativos.
- **Fique dentro do seu limite de envio.** Por padrão, os workspaces novos podem enviar 2 e-mails por segundo e 5.000 por dia, compartilhados entre a API e o SMTP. Envie os jobs em massa a partir de uma fila. Com o Nodemailer, `pool: true, rateLimit: 2` mantém um transporte com pool em 2 mensagens por segundo. Consulte [Limites](/pt/docs/limits/).
- **Torne as novas tentativas seguras.** Se você tentar um envio de novo depois de um timeout, envie um cabeçalho `Idempotency-Key` para que o Emailit não envie duas vezes. O SDK não define cabeçalhos personalizados, então use `fetch` nessas chamadas; consulte [Idempotência](/pt/docs/email-api/idempotency/).
- **Processe os webhooks de forma idempotente.** Guarde cada `event_id` que você já tratou e ignore os duplicados, e faça o trabalho demorado em um job em segundo plano depois de retornar `200`.
- **Usa TypeScript?** O SDK ainda não tem declarações de tipos. Adicione `declare module '@emailit/node';` a um arquivo `.d.ts` do seu projeto.

## Próximos passos

  - [Enviar e-mails com a API](/pt/docs/email-api/send-email/): Anexos, agendamento, rastreamento e metadados.
  - [Tipos de evento de webhook](/pt/docs/webhooks/event-types/): Todos os eventos e os payloads deles.
  - [Next.js](/pt/docs/frameworks/nextjs/): Route handlers e server actions.
  - [SDKs e bibliotecas](/pt/docs/sdks/): Todas as bibliotecas oficiais.

---
Fonte: https://emailit.com/pt/docs/frameworks/nodejs/
