# Odesílání e-mailů z Node.js

> Odesílejte e-maily z Node.js přes SDK @emailit/node, nebo přes SMTP s Nodemailerem, a ověřujte webhooky Emailitu v routě Expressu.

Tento návod ukazuje, jak odesílat e-maily z aplikace v Node.js přes oficiální SDK `@emailit/node`, jak místo toho použít Nodemailer přes SMTP a jak přijímat podepsané webhooky v Expressu.

## Předpoklady

- 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/). K odesílání stačí klíč jen pro odesílání.
- 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. Při testování používejte svou vlastní adresu.

## Nainstalujte SDK

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

Balíček je jen ve formátu ESM. Používejte syntaxi `import`, nebo v kódu CommonJS `await import('@emailit/node')`.

## Nastavte API klíč

Klíč nedávejte do kódu. Uložte ho do proměnné prostředí:

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

Soubor načtěte pomocí `node --env-file=.env` (Node.js 20.6 a novější), balíčku jako `dotenv`, nebo nastavení tajných údajů vaší platformy. Soubor `.env` přidejte do `.gitignore`.

## Odešlete e-mail

Vytvořte jednoho klienta a používejte ho pro všechny požadavky:

```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_…
```

Spusťte ho příkazem `node --env-file=.env send.mjs`. E-mail se během několika sekund objeví v **Email API → Emails**.

V aplikaci v Expressu odesílejte z routy, která e-mail spouští:

```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` přijímá alias šablony nebo ID `tem_` a `variables` šablonu vyplní. Viz [Šablony](/cs/docs/templates/) a úplný seznam polí na stránce [Odeslání e-mailu](/cs/docs/api-reference/emails/send/).

## Ošetřete chyby

SDK vyhazuje typované chyby, takže můžete na každé selhání reagovat zvlášť:

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

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

Pokud vaše aplikace už používá [Nodemailer](https://nodemailer.com), nasměrujte ho na SMTP relay Emailitu. Nainstalujte ho příkazem `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_…
```

Pro port 465 nastavte `port: 465` a `secure: true`. Pokud vaše síť blokuje port 587, použijte se stejným nastavením port 2525 nebo 2587. Viz [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/webhooks/emailit`, a jeho tajný klíč (`whsec_…`) zkopírujte do `EMAILIT_WEBHOOK_SECRET`.

Emailit podepisuje každý požadavek pomocí HMAC-SHA256 z `timestamp.rawBody`, takže routa musí číst surové tělo požadavku. Na této routě použijte `express.raw()`, ne `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);
});
```

Router připojte pomocí `app.use(webhooks)` dřív než jakýkoli globální middleware `express.json()`. Do 30 sekund vraťte `2xx`; cokoli jiného se opakuje. Podrobnosti najdete na stránkách [Ověření podpisu webhooků](/cs/docs/webhooks/request-signature/) a [Opakování a selhání](/cs/docs/webhooks/retries-and-failures/).

## Tipy pro produkční provoz

- **Omezte oprávnění klíče.** Pro aplikační server použijte klíč jen pro odesílání omezený na vaši odesílací doménu. Klíče s plným přístupem si nechte pro administrativní skripty.
- **Držte se pod limitem rychlosti.** Nové workspace mohou ve výchozím stavu odeslat 2 e-maily za sekundu a 5 000 za den, společně přes API i SMTP. Hromadné úlohy odesílejte z fronty. U Nodemaileru udrží `pool: true, rateLimit: 2` transport s poolem spojení na 2 zprávách za sekundu. Viz [Limity a kvóty](/cs/docs/limits/).
- **Zajistěte bezpečné opakování.** Pokud po vypršení časového limitu odeslání opakujete, pošlete hlavičku `Idempotency-Key`, aby Emailit neodeslal e-mail dvakrát. SDK vlastní hlavičky nenastavuje, proto pro tato volání použijte `fetch`; viz [Idempotentní požadavky](/cs/docs/email-api/idempotency/).
- **Zpracovávejte webhooky idempotentně.** Ukládejte si každé zpracované `event_id`, duplicity přeskakujte a pomalou práci dělejte v úloze na pozadí až poté, co vrátíte `200`.
- **Používáte TypeScript?** SDK zatím nemá deklarace typů. Přidejte do svého projektu soubor `.d.ts` s `declare module '@emailit/node';`.

## Další kroky

  - [Odesílání e-mailů přes API](/cs/docs/email-api/send-email/): Přílohy, plánování, měření a metadata.
  - [Typy událostí webhooků](/cs/docs/webhooks/event-types/): Všechny události a jejich obsah.
  - [Next.js](/cs/docs/frameworks/nextjs/): Route handlery a server actions.
  - [SDK a knihovny](/cs/docs/sdks/): Všechny oficiální knihovny.

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