Zum Inhalt springen

Node.js (@frontmail/node)

@frontmail/node ist für Server, Serverless-Funktionen und Skripte gedacht. Es authentifiziert sich mit dem privaten Schlüssel, daher entfallen Origin- und Turnstile-Prüfungen, und es schaltet Batch-Versand, Verlauf und Vorlagenschemas frei.

Terminal-Fenster
npm install @frontmail/node

Benötigt Node.js 20+ (nutzt das eingebaute fetch). Funktioniert auch in Bun, Deno und Edge-Runtimes, die fetch bereitstellen.

import { Frontmail } from '@frontmail/node';
const frontmail = new Frontmail({
privateKey: process.env.FRONTMAIL_PRIVATE_KEY!, // sk_…
// retry: { retries: 3 }, timeoutMs: 15_000, apiUrl: 'https://api.frontmail.dev'
});

Ohne privateKey liest der Client FRONTMAIL_PRIVATE_KEY (und FRONTMAIL_API_URL) aus der Umgebung. Geben Sie den privaten Schlüssel nie in ein Browser-Bundle – bewahren Sie ihn in Umgebungsvariablen oder einem Secret Manager auf. Siehe Öffentliche und private Schlüssel.

Das Paket verweigert die Ausführung im Webbrowser: Beim Import dort wird eine Warnung protokolliert, und new Frontmail() wirft private_key_in_browser (abschaltbar mit dangerouslyAllowPrivateKeyInBrowser: true – nur für interne Tools auf vertrauenswürdigen Rechnern). Im Browser verwenden Sie @frontmail/browser mit dem öffentlichen Schlüssel.

const result = await frontmail.send({
serviceId: 'svc_01J9…', // optional – ohne Angabe wird der Standarddienst verwendet
templateId: 'tpl_order',
params: {
order_id: 'A-1042',
items: [{ title: 'Zimmer', qty: 2, price: 89 }],
total: 178,
currency: 'EUR',
},
});
console.log(result.messageId, result.status); // 'queued' | 'held'

Weitere Eingabefelder: idempotencyKey (empfohlen, wenn der Versand von etwas ausgelöst wird, das sich wiederholen kann, z. B. einem Webhook – verwenden Sie dessen Event-ID), attachments, locale, signal.

locale (z. B. 'de') versendet die E-Mail in dieser Sprache der Vorlage – exakte Übereinstimmung, dann dieselbe Basissprache (de-AT → de), sonst die Standardsprache. result.locale ist die verwendete Sprache:

const { locale } = await frontmail.send({ templateId: 'tpl_order', params: { order_id: 'A-1042' }, locale: user.language });

Senden Sie bis zu 100 Nachrichten in einer Anfrage. Jede Nachricht wird einzeln validiert und abgerechnet – eine ungültige Nachricht lässt die anderen nicht scheitern. sendBatch wirft bei Fehlern einzelner Nachrichten keine Ausnahme; prüfen Sie ok bei jedem Ergebnis.

const results = await frontmail.sendBatch([
{ serviceId: 'svc_01J9…', templateId: 'tpl_reminder', params: { name: 'Jana' }, idempotencyKey: 'reminder-42-jana' },
{ serviceId: 'svc_01J9…', templateId: 'tpl_reminder', params: { name: 'Petr' }, idempotencyKey: 'reminder-42-petr' },
]);
for (const r of results) {
if (!r.ok) console.error(r.index, r.error.code);
else console.log(r.index, r.messageId, r.status);
}

Ein Batch zählt für die Rate Limits als eine Anfrage. Mehr als 100 Nachrichten teilen Sie in Blöcke auf. Jede Nachricht kann ein eigenes locale haben; erfolgreiche Ergebnisse enthalten das verwendete locale.

const page = await frontmail.history({
status: 'failed',
templateId: 'tpl_order',
from: '2026-09-01T00:00:00Z',
limit: 50,
});
for (const m of page.items) console.log(m.messageId, m.status, m.to, m.subject);
// Nächste Seite
if (page.nextCursor) await frontmail.history({ cursor: page.nextCursor });
// Oder über alles iterieren
for await (const m of frontmail.history({ status: 'bounced' })) console.log(m.to);

Filter: status, templateId, serviceId, from, to, q (Suche nach Empfänger), limit (≤ 100), cursor. Mit await history() erhalten Sie eine Seite; for await durchläuft alle Seiten nach Bedarf. Der Verlauf reicht so weit zurück wie der Aufbewahrungszeitraum Ihres Tarifs.

const msg = await frontmail.getMessage('msg_01J9Z3K7Q2');
// { messageId, status, createdAt, sentAt, templateId, serviceId, events: [{ type, at }, …] }
const templates = await frontmail.templates.list(); // Parameterschemas, genutzt von `frontmail types`
const contact = await frontmail.templates.get('tpl_contact');
contact.locales; // ['en', 'de', 'pt-BR'] – zuerst die Standardsprache, dann die Übersetzungen

frontmail types ergänzt den Doc-Kommentar jeder Vorlage um ihre Sprachen und erzeugt einen Union-Typ für die Option locale:

/** Contact form (tpl_contact) – languages: en (default), de, pt-BR */
export interface ContactFormParams { /* … */ }
/** Languages of tpl_contact (default first) – for the `locale` send option. */
export type ContactFormLocale = "en" | "de" | "pt-BR";

Das Paket enthält die CLI frontmail – siehe Typisierte Parameter.

Beispielprojekt: examples/node.