Kirim Email Konfirmasi Booking dengan MailAnvil + Express.js — Tutorial Lengkap
Bayangkan: pelanggan Anda baru saja memesan tiket pesawat ke Bali lewat aplikasi Anda. Dalam hitungan detik, email konfirmasi beserta e-ticket harus sampai di inbox mereka. Kalau email terlambat atau masuk spam? Kepercayaan pelanggan langsung turun.
Ini masalah nyata yang dihadapi startup travel seperti Tiket.com, layanan food delivery seperti GoSend, atau platform OTP verifikasi di fintech seperti DANA. Mereka semua butuh email API yang cepat, andal, dan — yang paling penting — harganya masuk akal dalam Rupiah.
Di tutorial ini, kita akan bangun endpoint kirim email konfirmasi booking pakai MailAnvil dan Express.js. Siap?
Kenapa MailAnvil?
Sebelum ngoding, satu pertanyaan: kenapa nggak pakai SendGrid atau Resend?
| Faktor | SendGrid/Resend | MailAnvil |
|---|---|---|
| Harga 100K email | ~Rp 900rb (USD) | Rp 599rb |
| Pembayaran | Kartu kredit | QRIS, GoPay, kartu kredit |
| Support | Bahasa Inggris | Bahasa Indonesia |
| Infrastruktur | AWS US/EU | AWS ap-southeast-1 (Jakarta latency rendah) |
| AI/Agent ready | Tidak native | MCP-native — AI agent langsung bisa pakai |
Harga 2.4x lebih murah di volume 100K email. Untuk startup Indonesia yang kirim ribuan email per hari, selisih ini signifikan.
Prasyarat
- Node.js 18+
- Akun MailAnvil (daftar gratis di mailanvil.com)
- Domain terverifikasi DKIM (panduan lengkap ada di docs.mailanvil.com)
Step 1: Setup Project
mkdir booking-email && cd booking-email
npm init -y
npm install express dotenv
Step 2: Dapatkan API Key
Login ke app.mailanvil.com, buka tab API Keys, dan generate key baru. Simpan di .env:
MAILANVIL_API_KEY=ma_key_xxxxxxxxxxxx
Step 3: Buat Email Service
Buat file email.js:
const MAILANVIL_API = 'https://api.mailanvil.com/v1';
async function sendBookingEmail({ to, bookingId, customerName, details }) {
const res = await fetch(`${MAILANVIL_API}/send`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.MAILANVIL_API_KEY}`,
'Idempotency-Key': bookingId // cegah kirim 2x
},
body: JSON.stringify({
from: 'booking@travelokaclone.id',
to: [to],
subject: `Konfirmasi Booking #${bookingId} — ${details.route}`,
html: `
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
<h1 style="color: #ff801f;">Booking Dikonfirmasi! ✅</h1>
<p>Halo ${customerName},</p>
<p>Booking Anda <strong>#${bookingId}</strong> sudah terkonfirmasi.</p>
<table style="width: 100%; border-collapse: collapse; margin: 16px 0;">
<tr><td style="padding: 8px; border-bottom: 1px solid #eee;">Rute</td><td style="padding: 8px; border-bottom: 1px solid #eee;"><strong>${details.route}</strong></td></tr>
<tr><td style="padding: 8px; border-bottom: 1px solid #eee;">Tanggal</td><td style="padding: 8px; border-bottom: 1px solid #eee;">${details.date}</td></tr>
<tr><td style="padding: 8px; border-bottom: 1px solid #eee;">Penumpang</td><td style="padding: 8px; border-bottom: 1px solid #eee;">${details.passengers}</td></tr>
<tr><td style="padding: 8px;">Total</td><td style="padding: 8px;"><strong>Rp ${details.total.toLocaleString('id-ID')}</strong></td></tr>
</table>
<p>E-ticket terlampir dalam lampiran email ini.</p>
<p style="color: #666; font-size: 12px;">Butuh bantuan? Balas email ini atau hubungi support@travelokaclone.id</p>
</div>
`,
text: `Booking #${bookingId} dikonfirmasi. Rute: ${details.route}. Tanggal: ${details.date}. Total: Rp ${details.total.toLocaleString('id-ID')}`,
})
});
if (!res.ok) {
const err = await res.json();
throw new Error(`MailAnvil error: ${err.error?.message || res.status}`);
}
return res.json();
}
module.exports = { sendBookingEmail };
Step 4: Buat Route Express
server.js:
require('dotenv').config();
const express = require('express');
const { sendBookingEmail } = require('./email');
const app = express();
app.use(express.json());
app.post('/api/booking', async (req, res) => {
try {
const { customerEmail, customerName, route, date, passengers, total } = req.body;
// Generate booking ID
const bookingId = `BK-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
// Simpan ke database... (mongodb, postgres, etc.)
// Kirim email konfirmasi — fire-and-forget
sendBookingEmail({
to: customerEmail,
bookingId,
customerName,
details: { route, date, passengers, total }
}).catch(err => console.error('Email failed:', err));
res.json({ bookingId, status: 'confirmed' });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Step 5: Uji Coba
curl -X POST http://localhost:3000/api/booking \
-H "Content-Type: application/json" \
-d '{
"customerEmail": "pelanggan@example.com",
"customerName": "Budi Santoso",
"route": "Jakarta (CGK) → Bali (DPS)",
"date": "15 Agustus 2026",
"passengers": 2,
"total": 2450000
}'
Response:
{ "bookingId": "BK-1753459200000-x7k2m", "status": "confirmed" }
Email langsung terkirim. Cek dashboard MailAnvil untuk lihat status delivery (delivered/bounced/complaint).
Use Case Lain: Bukan Cuma Travel
Pola yang sama bisa dipakai untuk:
- Food delivery — kirim struk digital + estimasi waktu antar (contoh: GoSend, GrabFood merchant)
- Fintech OTP — kirim kode verifikasi lewat email (fallback selain SMS)
- E-commerce — notifikasi pesanan dikemas, dikirim, sampai
- SaaS onboarding — welcome email + link aktivasi akun
- Healthtech — pengingat jadwal konsultasi (contoh: Halodoc, Alodokter)
Semua pakai API yang sama: POST /v1/send.
Tips Produksi
- Selalu pakai
Idempotency-Key— cegah email terkirim 2x kalau retry. Pakai booking ID sebagai key. - Verifikasi domain dulu — DKIM wajib. Tanpa itu, email masuk spam.
- Pantau dashboard bounce rate — MailAnvil punya kill switch otomatis kalau bounce >5%.
- Gunakan template — API MailAnvil support template CRUD. Simpan HTML di server MailAnvil, panggil via
template_id. - Webhook untuk status delivery — daftarkan webhook untuk tracking real-time: delivered, bounced, complaint.
Mulai Gratis
MailAnvil punya Free Plan: 500 email/bulan. Cukup untuk development dan testing. Daftar di mailanvil.com — nggak perlu kartu kredit. Pembayaran pakai QRIS atau GoPay.
Untuk startup yang sudah production, Starter Plan 10.000 email cuma Rp 149rb/bulan. Harga lokal, support lokal, infrastruktur lokal.
Dokumentasi lengkap: docs.mailanvil.com MCP Server: mcp.mailanvil.com Dashboard: app.mailanvil.com