Node.js (@frontmail/node)
@frontmail/node jest przeznaczony dla serwerów, funkcji serverless i skryptów. Uwierzytelnia się
kluczem prywatnym, więc nie obowiązują go sprawdzenia originu ani Turnstile, a do tego
udostępnia wysyłki zbiorcze, historię i schematy szablonów.
npm install @frontmail/nodeWymaga Node.js 20+ (korzysta z wbudowanego fetch). Działa też w Bunie, Deno i środowiskach edge,
które udostępniają fetch.
Tworzenie klienta
Dział zatytułowany „Tworzenie klienta”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'});Bez privateKey klient odczytuje FRONTMAIL_PRIVATE_KEY (oraz FRONTMAIL_API_URL) ze zmiennych
środowiskowych. Nigdy nie umieszczaj klucza prywatnego w bundlu dla przeglądarki – trzymaj go
w zmiennych środowiskowych albo w menedżerze sekretów. Zobacz
Klucze publiczne i prywatne.
Pakiet odmawia działania w przeglądarce: przy imporcie wypisuje ostrzeżenie, a new Frontmail()
rzuca private_key_in_browser (można to wyłączyć opcją dangerouslyAllowPrivateKeyInBrowser: true,
ale tylko dla wewnętrznych narzędzi na zaufanych komputerach). W przeglądarce używaj
@frontmail/browser z kluczem publicznym.
Wysyłka
Dział zatytułowany „Wysyłka”const result = await frontmail.send({ serviceId: 'svc_01J9…', // opcjonalne – bez niego zostanie użyta domyślna usługa templateId: 'tpl_order', params: { order_id: 'A-1042', items: [{ title: 'Pokój', qty: 2, price: 89 }], total: 178, currency: 'EUR', },});console.log(result.messageId, result.status); // 'queued' | 'held'Inne pola wejściowe: idempotencyKey (zalecany, gdy wysyłkę wyzwala coś, co może się powtórzyć,
np. webhook – użyj ID jego zdarzenia), attachments, locale, signal.
locale (np. 'de') wysyła e-mail w tym języku szablonu – najpierw
dokładne dopasowanie, potem ten sam język bazowy (de-AT → de), w przeciwnym razie język
domyślny. result.locale to użyty język:
const { locale } = await frontmail.send({ templateId: 'tpl_order', params: { order_id: 'A-1042' }, locale: user.language });Wysyłka zbiorcza
Dział zatytułowany „Wysyłka zbiorcza”Wyślij do 100 wiadomości w jednym żądaniu. Każda wiadomość jest walidowana i rozliczana osobno –
jedna nieprawidłowa wiadomość nie psuje pozostałych. sendBatch nie rzuca wyjątku z powodu błędów
poszczególnych wiadomości; sprawdzaj ok w każdym wyniku.
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);}Do rate limitów paczka liczy się jako jedno żądanie. Więcej niż 100
wiadomości podziel na kilka paczek. Każda wiadomość może mieć własne locale; udane wyniki
zawierają użyte locale.
Historia
Dział zatytułowany „Historia”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);
// Następna stronaif (page.nextCursor) await frontmail.history({ cursor: page.nextCursor });
// Albo przejdź przez wszystkofor await (const m of frontmail.history({ status: 'bounced' })) console.log(m.to);Filtry: status, templateId, serviceId, from, to, q (wyszukiwanie po odbiorcy), limit
(≤ 100), cursor. await history() zwraca jedną stronę; for await leniwie przechodzi przez
wszystkie strony. Historia obejmuje okres przechowywania danych w twoim planie.
Status wiadomości
Dział zatytułowany „Status wiadomości”const msg = await frontmail.getMessage('msg_01J9Z3K7Q2');// { messageId, status, createdAt, sentAt, templateId, serviceId, events: [{ type, at }, …] }Szablony
Dział zatytułowany „Szablony”const templates = await frontmail.templates.list(); // schematy parametrów, używa ich `frontmail types`const contact = await frontmail.templates.get('tpl_contact');contact.locales; // ['en', 'de', 'pt-BR'] – najpierw język domyślny, potem tłumaczeniafrontmail types dopisuje języki każdego szablonu do jego komentarza dokumentacyjnego i generuje
typ unii dla opcji 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";Pakiet zawiera CLI frontmail – zobacz Typowane parametry.
Przykładowy projekt: examples/node.