E-maile transakcyjne to wiadomości, które Twój produkt wysyła, bo użytkownik coś zrobił: zarejestrował się, zresetował hasło, opłacił fakturę, dostał zaproszenie do przestrzeni roboczej. Muszą wychodzić szybko, z Twojej własnej domeny i bez spowalniania żądania, które je wywołało.
Ten artykuł pokazuje, jak wysyłać je przez REST API Inbixio z języków, których zespoły używają najczęściej, a potem zamienia jednorazowe wywołanie w niewielką funkcję pomocniczą, którą wstawisz do dowolnego projektu.
Żądanie w jednym miejscu
Każdy z poniższych przykładów wysyła to samo żądanie HTTP:
- Metoda i URL:
POST https://backend.inbixio.com/api/send-email/, razem z końcowym ukośnikiem - Uwierzytelnianie: nagłówek
X-API-Keyz kluczem mającym uprawnienie Send (wysyłanie) - Treść: JSON z polami
to_email,subjectimessage(HTML)
Udane wywołanie zwraca 200 z {"message": "Email queued successfully."}. Jeśli nie masz jeszcze klucza ani podłączonego serwera SMTP, zacznij od pięciominutowego szybkiego startu.
We wszystkich przykładach klucz jest odczytywany ze zmiennej środowiskowej INBIXIO_API_KEY. Trzymaj go na serwerze; nigdy nie wysyłaj go do przeglądarki ani aplikacji mobilnej.
cURL
Przydaje się do testowania klucza, debugowania z serwera albo wywołań ze skryptu powłoki czy zadania cron:
curl -sS -X POST https://backend.inbixio.com/api/send-email/ \
-H "X-API-Key: $INBIXIO_API_KEY" \
-H "Content-Type: application/json" \
--max-time 15 \
-d '{
"to_email": "ada@example.com",
"subject": "Your invoice is ready",
"message": "<p>Hi Ada, your invoice for October is ready.</p>"
}'
-sS ukrywa pasek postępu, ale nadal wypisuje błędy, a --max-time nie pozwala skryptowi zawisnąć, gdy zawiedzie sieć.
Node.js
Node.js 18 i nowsze mają wbudowany fetch, więc nie potrzebujesz biblioteki HTTP:
// send-email.js
const INBIXIO_URL = 'https://backend.inbixio.com/api/send-email/';
export async function sendEmail({ to, subject, html }) {
const res = await fetch(INBIXIO_URL, {
method: 'POST',
headers: {
'X-API-Key': process.env.INBIXIO_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ to_email: to, subject, message: html }),
signal: AbortSignal.timeout(15_000),
});
const body = await res.json().catch(() => ({}));
if (!res.ok) {
const reason = body.error || body.detail || res.statusText;
throw new Error(`Inbixio ${res.status}: ${reason}`);
}
return body; // { message: 'Email queued successfully.' }
}
A tak wygląda użycie w trasie Express:
app.post('/signup', async (req, res) => {
const user = await createUser(req.body);
await sendEmail({
to: user.email,
subject: 'Welcome aboard',
html: `<h1>Welcome, ${escapeHtml(user.name)}!</h1><p>Your account is ready.</p>`,
});
res.status(201).json({ id: user.id });
});
Zwróć uwagę na escapeHtml. Pole message jest renderowane jako HTML, więc wszystko, co wpisał użytkownik, np. jego imię, musi zostać zabezpieczone (escaped), zanim trafi do treści.
Python
Z biblioteką requests:
# send_email.py
import os
import requests
INBIXIO_URL = "https://backend.inbixio.com/api/send-email/"
class EmailError(Exception):
pass
def send_email(to: str, subject: str, html: str) -> dict:
res = requests.post(
INBIXIO_URL,
headers={"X-API-Key": os.environ["INBIXIO_API_KEY"]},
json={"to_email": to, "subject": subject, "message": html},
timeout=15,
)
if not res.ok:
try:
body = res.json()
except ValueError:
body = {}
reason = body.get("error") or body.get("detail") or res.reason
raise EmailError(f"Inbixio {res.status_code}: {reason}")
return res.json()
Przekazanie json= ustawia nagłówek Content-Type za Ciebie. Zawsze ustawiaj timeout: domyślnie requests czeka w nieskończoność.
W Django wywołuj wysyłkę dopiero po zatwierdzeniu transakcji w bazie, aby nigdy nie wysłać e-maila o rekordzie, który został wycofany:
from django.db import transaction
transaction.on_commit(lambda: send_email(user.email, "Welcome!", render_welcome(user)))
PHP
<?php
function send_email(string $to, string $subject, string $html): array {
$ch = curl_init('https://backend.inbixio.com/api/send-email/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . getenv('INBIXIO_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'to_email' => $to,
'subject' => $subject,
'message' => $html,
]),
]);
$body = json_decode(curl_exec($ch), true) ?? [];
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException("Inbixio $status: " . ($body['error'] ?? $body['detail'] ?? 'request failed'));
}
return $body;
}
Wysyłka do kilku osób
Każde żądanie dostarcza wiadomość do jednego to_email. Aby powiadomić listę użytkowników, wyślij jedno żądanie na odbiorcę. W przypadku e-maili transakcyjnych i tak tego właśnie chcesz: każdy użytkownik dostaje własną wiadomość, nikt nie widzi cudzego adresu, a jeden błędny adres nie blokuje pozostałych.
Utrzymuj umiarkowaną współbieżność, aby nie przeciążyć własnego serwera SMTP. Pula 5–10 równoległych żądań w zupełności wystarcza większości aplikacji.
Nie wysyłaj w trakcie obsługi żądania
Wywołanie API jest szybkie, ale to wciąż przejście przez sieć tam i z powrotem. Wszystko, co nie jest krytyczne czasowo, przenieś do zadania w tle (BullMQ, Celery, Sidekiq, kolejka w chmurze), dzięki czemu:
- strona użytkownika ładuje się bez czekania na e-mail,
- chwilowy błąd można ponowić bez wiedzy użytkownika,
- nagły skok, np. duży import wywołujący tysiące e-maili powitalnych, jest obsługiwany w równym tempie.
Przy kodach OTP i resetowaniu hasła użytkownicy aktywnie czekają, więc wysyłaj od razu i pokaż przyjazny komunikat, jeśli się nie uda. Artykuł obsługa błędów i limitów API e-mail wyjaśnia, które błędy ponawiać, a które pokazywać użytkownikowi.
Checklista przed wdrożeniem
- Klucz API pochodzi ze zmiennej środowiskowej lub menedżera sekretów i ma wyłącznie uprawnienie Send (wysyłanie).
- Każda wartość podana przez użytkownika w HTML jest zabezpieczona (escaped).
- Żądania mają timeout 10–15 sekund.
- Odpowiedzi inne niż 200 są logowane razem z treścią odpowiedzi, więc komunikaty
erroridetailnie giną. - Twoja domena nadawcza ma skonfigurowane SPF, DKIM i DMARC, więc e-maile trafiają do skrzynki odbiorczej.
Wyślij to przez Inbixio
Podłącz własny serwer SMTP, utwórz klucz API z ograniczonymi uprawnieniami i wysyłaj z dowolnego języka jednym żądaniem HTTPS.