# Enviar e-mails com Nuxt

> Envie e-mails de uma rota de API do servidor do Nuxt com o SDK de Node.js do Emailit, mantenha a chave no runtimeConfig privado e verifique webhooks com o h3.

Este guia mostra como enviar e-mails de uma aplicação Nuxt 3. Você chama o Emailit a partir de uma rota de API do servidor, mantém a chave de API no `runtimeConfig` privado e verifica os webhooks com os helpers do h3.

## Pré-requisitos

- Nuxt 3 com um preset de servidor Node.js 18+.
- 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 restrita ao seu domínio é suficiente.
- 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.

## Instalar o SDK

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

## Configurar a chave de API

Declare chaves privadas no runtime config. As chaves fora de `public` só ficam disponíveis no servidor:

```typescript title="nuxt.config.ts"
  runtimeConfig: {
    emailitApiKey: '',
    emailitWebhookSecret: '',
  },
});
```

O Nuxt as preenche a partir de variáveis de ambiente com o prefixo `NUXT_`:

```bash title=".env"
NUXT_EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••
NUXT_EMAILIT_WEBHOOK_SECRET=whsec_••••••••
```

> **Mantenha a chave fora de runtimeConfig.public:** Os valores em `runtimeConfig.public` são enviados ao navegador. Nunca coloque a chave de API ali e nunca chame o Emailit a partir de um componente ou de uma página.

Adicione um pequeno helper. Os arquivos em `server/utils` são importados automaticamente nas rotas do servidor:

```typescript title="server/utils/emailit.ts"

  return new Emailit(useRuntimeConfig(event).emailitApiKey);
}
```

Se o TypeScript acusar a falta de uma declaração para `@emailit/node`, adicione `declare module '@emailit/node';` a um arquivo `.d.ts` do seu projeto.

## Enviar um e-mail

Crie uma rota de API do servidor. Esta rota de formulário de contato envia para um endereço interno fixo, então os visitantes não podem usá-la para enviar e-mails a qualquer pessoa:

```typescript title="server/api/contact.post.ts"
  const { email, message } = await readBody(event);

  if (typeof email !== 'string' || typeof message !== 'string' || !email.includes('@')) {
    throw createError({ statusCode: 400, statusMessage: 'Invalid input' });
  }

  const sent = await emailitClient(event).emails.send({
    from: 'Acme website <website@acme.com>',
    to: 'support@acme.com',
    reply_to: email,
    subject: 'New contact form message',
    text: message,
  });

  return { id: sent.id };
});
```

Chame-a a partir de uma página ou de um componente com `$fetch`:

```vue title="pages/contact.vue"
<script setup lang="ts">
const email = ref('');
const message = ref('');
const sent = ref(false);

async function submit() {
  await $fetch('/api/contact', {
    method: 'POST',
    body: { email: email.value, message: message.value },
  });
  sent.value = true;
}
</script>

<template>
  <form @submit.prevent="submit">
    <input v-model="email" type="email" required />
    <textarea v-model="message" required />
    <button type="submit">Send</button>
    <p v-if="sent">Thanks, we'll be in touch.</p>
  </form>
</template>
```

Para enviar um template salvo em vez de conteúdo inline, passe `template` (um alias ou um ID `tem_`) e `variables`. Consulte [Templates](/pt/docs/templates/) e [Enviar um e-mail](/pt/docs/api-reference/emails/send/).

## Enviar por SMTP como alternativa

Se você preferir SMTP, use o Nodemailer em uma rota do servidor. O SMTP exige um preset de servidor Node.js; os presets de edge e de workers não conseguem abrir conexões SMTP, então use a API nesses casos.

```typescript title="server/utils/mailer.ts"

  return nodemailer.createTransport({
    host: 'smtp.emailit.com',
    port: 587,
    secure: false,
    requireTLS: true,
    auth: { user: 'emailit', pass: useRuntimeConfig().emailitApiKey },
  });
}
```

Depois, chame `await mailer().sendMail({ from, to, subject, html })` a partir de uma rota. Consulte [Configurações de SMTP](/pt/docs/smtp/settings/) para as outras portas.

## Receber webhooks

[Crie um webhook](/pt/docs/webhooks/set-up/) que aponte para `https://your-app.com/api/webhooks/emailit`. Verifique a assinatura com base no corpo bruto e depois interprete o array de eventos:

```typescript title="server/api/webhooks/emailit.post.ts"

  const rawBody = (await readRawBody(event)) ?? '';
  const signature = getHeader(event, 'x-emailit-signature') ?? '';
  const timestamp = getHeader(event, 'x-emailit-timestamp') ?? '';
  const secret = useRuntimeConfig(event).emailitWebhookSecret;

  const age = Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp));
  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
  const valid =
    Number.isFinite(age) &&
    age <= 300 &&
    expected.length === signature.length &&
    timingSafeEqual(Buffer.from(expected), Buffer.from(signature));

  if (!valid) {
    throw createError({ statusCode: 401, statusMessage: 'Invalid signature' });
  }

  const events = JSON.parse(rawBody) as Array<{ event_id: string; type: string; data: { object: any } }>;
  for (const item of events) {
    if (item.type === 'email.complained') {
      // Stop emailing item.data.object.to
    }
  }

  return { received: events.length };
});
```

Retorne um `2xx` em até 30 segundos; as outras respostas recebem novas tentativas. Consulte [Assinatura das requisições](/pt/docs/webhooks/request-signature/).

## Dicas para produção

- **Defina os segredos na sua hospedagem.** Configure `NUXT_EMAILIT_API_KEY` nas configurações de ambiente do seu provedor de hospedagem em vez de publicar um arquivo `.env`.
- **Valide antes de enviar.** Só aceite um destinatário vindo do navegador quando for o próprio endereço do usuário conectado e limite a taxa de requisições das rotas públicas. Cada e-mail custa créditos e conta para os seus [limites de envio](/pt/docs/limits/).
- **Use chaves separadas por ambiente** para poder revogar uma chave de preview sem mexer na produção.

## Próximos passos

  - [Guia de Node.js](/pt/docs/frameworks/nodejs/): Detalhes sobre tratamento de erros e Nodemailer.
  - [Enviar e-mails com a API](/pt/docs/email-api/send-email/): Anexos, agendamento e rastreamento.
  - [Tipos de evento de webhook](/pt/docs/webhooks/event-types/): Todos os eventos e os payloads deles.
  - [Chaves de API](/pt/docs/developers/api-keys/): Escopos, restrições de domínio e rotação.

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