# Odesílání e-mailů z Nuxtu

> Odesílejte e-maily ze serverové API routy v Nuxtu přes Node.js SDK Emailitu, držte klíč v privátním runtimeConfig a ověřujte webhooky pomocí h3.

Tento návod ukazuje, jak odesílat e-maily z aplikace v Nuxtu 3. Emailit voláte ze serverové API routy, API klíč držíte v privátním `runtimeConfig` a webhooky ověřujete pomocnými funkcemi h3.

## Předpoklady

- Nuxt 3 se serverovým presetem pro Node.js 18 nebo novější.
- [Ověřená odesílací doména](/cs/docs/domains/add-a-domain/), například `acme.com`.
- [API klíč](/cs/docs/developers/api-keys/). Stačí klíč jen pro odesílání omezený na vaši doménu.
- Dokud váš workspace nemá [produkční přístup](/cs/docs/workspaces/production-access/), můžete odesílat jen na e-mailové adresy účtů členů workspace.

## Nainstalujte SDK

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

## Nastavte API klíč

Deklarujte privátní klíče konfigurace runtime. Klíče mimo `public` jsou dostupné jen na serveru:

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

Nuxt je vyplní z proměnných prostředí s předponou `NUXT_`:

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

> **Nedávejte klíč do runtimeConfig.public:** Hodnoty v `runtimeConfig.public` se posílají do prohlížeče. Nikdy tam nedávejte API klíč a nikdy nevolejte Emailit z komponenty nebo stránky.

Přidejte malou pomocnou funkci. Soubory v `server/utils` se v serverových routách importují automaticky:

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

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

Pokud TypeScript hlásí chybějící deklaraci pro `@emailit/node`, přidejte do svého projektu soubor `.d.ts` s `declare module '@emailit/node';`.

## Odešlete e-mail

Vytvořte serverovou API routu. Tato routa kontaktního formuláře odesílá na pevnou interní adresu, takže ji návštěvníci nemohou zneužít k posílání e-mailů komukoli:

```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 };
});
```

Ze stránky nebo komponenty ji volejte pomocí `$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>
```

Pokud chcete místo obsahu přímo v požadavku odeslat uloženou šablonu, předejte `template` (alias nebo ID `tem_`) a `variables`. Viz [Šablony](/cs/docs/templates/) a [Odeslání e-mailu](/cs/docs/api-reference/emails/send/).

## Odesílání přes SMTP

Pokud dáváte přednost SMTP, použijte Nodemailer v serverové routě. SMTP potřebuje serverový preset pro Node.js; presety pro edge a workery nemohou otevírat SMTP spojení, takže tam použijte API.

```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 },
  });
}
```

Pak z routy zavolejte `await mailer().sendMail({ from, to, subject, html })`. Další porty najdete na stránce [Nastavení SMTP](/cs/docs/smtp/settings/).

## Přijímejte webhooky

[Vytvořte webhook](/cs/docs/webhooks/set-up/), který míří na `https://your-app.com/api/webhooks/emailit`. Ověřte podpis vůči surovému tělu požadavku a pak zpracujte pole událostí:

```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 };
});
```

Do 30 sekund vraťte `2xx`; při jiných odpovědích se požadavek opakuje. Viz [Ověření podpisu webhooků](/cs/docs/webhooks/request-signature/).

## Tipy pro produkční provoz

- **Tajné údaje nastavte u hostingu.** `NUXT_EMAILIT_API_KEY` nastavte v proměnných prostředí u svého poskytovatele hostingu, místo abyste nasazovali soubor `.env`.
- **Před odesláním validujte.** Příjemce z prohlížeče přijímejte, jen když jde o vlastní adresu přihlášeného uživatele, a u veřejných rout omezte rychlost. Každý e-mail stojí kredity a počítá se do vašich [limitů odesílání](/cs/docs/limits/).
- **Pro každé prostředí používejte samostatný klíč**, abyste mohli odvolat klíč pro náhledy, aniž byste sahali na produkci.

## Další kroky

  - [Návod pro Node.js](/cs/docs/frameworks/nodejs/): Podrobnosti k ošetření chyb a Nodemaileru.
  - [Odesílání e-mailů přes API](/cs/docs/email-api/send-email/): Přílohy, plánování a měření.
  - [Typy událostí webhooků](/cs/docs/webhooks/event-types/): Všechny události a jejich obsah.
  - [API klíče](/cs/docs/developers/api-keys/): Rozsahy oprávnění, omezení na doménu a výměna.

---
Zdroj: https://emailit.com/cs/docs/frameworks/nuxt/
