Zum Inhalt springen
Doku

Tutorial

E-Mails mit Node.js senden

Senden Sie E-Mails aus Node.js mit dem SDK @emailit/node oder per SMTP mit Nodemailer und verifizieren Sie Emailit-Webhooks in einer Express-Route.

Aktualisiert am 1. Okt. 2026

Diese Anleitung zeigt, wie Sie E-Mails aus einer Node.js-App mit dem offiziellen SDK @emailit/node senden, wie Sie stattdessen Nodemailer per SMTP verwenden und wie Sie signierte Webhooks in Express empfangen.

Voraussetzungen

  • Node.js 18 oder neuer.
  • Eine verifizierte Versanddomain, zum Beispiel acme.com.
  • Ein API-Schlüssel. Zum Senden genügt ein reiner Sende-Schlüssel.
  • Solange Ihr Workspace keinen Produktionszugang hat, können Sie nur an die Konto-E-Mail-Adressen von Workspace-Mitgliedern senden. Verwenden Sie zum Testen Ihre eigene Adresse.

SDK installieren

Terminal
npm install @emailit/node

Das Paket unterstützt nur ESM. Verwenden Sie die import-Syntax oder in CommonJS-Code await import('@emailit/node').

API-Schlüssel konfigurieren

Halten Sie den Schlüssel aus Ihrem Code heraus. Legen Sie ihn in einer Umgebungsvariablen ab:

.env
EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••

Laden Sie die Datei mit node --env-file=.env (ab Node.js 20.6), einem Paket wie dotenv oder über die Secret-Einstellungen Ihrer Plattform. Nehmen Sie .env in .gitignore auf.

E-Mail senden

Erstellen Sie einen Client und verwenden Sie ihn für alle Anfragen wieder:

send.mjs
import { Emailit } from '@emailit/node';

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

Führen Sie es mit node --env-file=.env send.mjs aus. Die E-Mail erscheint innerhalb von Sekunden unter Email APIEmails.

In einer Express-App senden Sie aus der Route, die die E-Mail auslöst:

server.mjs
import express from 'express';
import { Emailit } from '@emailit/node';

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 akzeptiert einen Vorlagen-Alias oder eine tem_-ID, und variables füllt die Vorlage. Siehe Vorlagen und die vollständige Liste der Felder unter E-Mail senden.

Fehler behandeln

Das SDK wirft typisierte Fehler, sodass Sie auf jeden Fehlerfall gezielt reagieren können:

JavaScript
import {
  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;
  }
}

Alternativ per SMTP senden

Wenn Ihre App bereits Nodemailer verwendet, richten Sie es auf das SMTP-Relay von Emailit aus. Installieren Sie es mit npm install nodemailer:

mailer.mjs
import nodemailer from 'nodemailer';

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

Für Port 465 setzen Sie port: 465 und secure: true. Wenn Ihr Netzwerk 587 blockiert, verwenden Sie 2525 oder 2587 mit denselben Einstellungen. Siehe SMTP-Einstellungen.

Webhooks empfangen

Erstellen Sie einen Webhook, der auf https://your-app.com/webhooks/emailit zeigt, und kopieren Sie sein Signatur-Secret (whsec_…) in EMAILIT_WEBHOOK_SECRET.

Emailit signiert jede Anfrage mit einem HMAC-SHA256 von timestamp.rawBody; die Route muss daher den unveränderten Body lesen. Verwenden Sie auf dieser Route express.raw(), nicht express.json():

webhooks.mjs
import express from 'express';
import { createHmac, timingSafeEqual } from 'node:crypto';

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

export const webhooks = express.Router();

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

Binden Sie den Router mit app.use(webhooks) vor jeder globalen express.json()-Middleware ein. Geben Sie innerhalb von 30 Sekunden einen 2xx-Status zurück; alles andere wird wiederholt. Details finden Sie unter Anfragesignatur und Wiederholungen und Fehlschläge.

Tipps für den Produktivbetrieb

  • Scope des Schlüssels einschränken. Verwenden Sie für den App-Server einen reinen Sende-Schlüssel, der auf Ihre Versanddomain beschränkt ist. Behalten Sie Schlüssel mit Vollzugriff für Admin-Skripte vor.
  • Unter dem Rate Limit bleiben. Neue Workspaces können standardmäßig 2 E-Mails pro Sekunde und 5.000 pro Tag senden, gemeinsam für API und SMTP. Senden Sie Massen-Jobs aus einer Warteschlange. Mit Nodemailer hält pool: true, rateLimit: 2 einen gepoolten Transport bei 2 Nachrichten pro Sekunde. Siehe Limits.
  • Wiederholungen sicher machen. Wenn Sie einen Versand nach einem Timeout wiederholen, senden Sie einen Header Idempotency-Key, damit Emailit nicht doppelt sendet. Das SDK setzt keine eigenen Header, verwenden Sie für diese Aufrufe daher fetch. Siehe Idempotenz.
  • Webhooks idempotent verarbeiten. Speichern Sie jede verarbeitete event_id und überspringen Sie Duplikate. Erledigen Sie langsame Arbeit in einem Hintergrundjob, nachdem Sie 200 zurückgegeben haben.
  • TypeScript im Einsatz? Das SDK hat noch keine Typdeklarationen. Fügen Sie declare module '@emailit/node'; in eine .d.ts-Datei in Ihrem Projekt ein.

Nächste Schritte

Anhänge, Planung, Tracking und Metadaten.
Alle Events und ihre Payloads.
Route Handlers und Server Actions.
Alle offiziellen Bibliotheken.

War diese Seite hilfreich?

Danke für Ihr Feedback.

Danke, wir lesen jede Nachricht.