Kirim Laporan Harian Otomatis dengan Cron + MailAnvil (Tanpa Server)
Banyak tim kecil di Indonesia masih membuka dashboard setiap pagi hanya untuk mengecek angka. Padahal angka yang sama bisa datang sendiri ke inbox: satu email ringkasan harian, dikirim otomatis jam 7 pagi. Cara paling ringan: cron + curl ke satu endpoint API. Tanpa server tambahan, tanpa library, tanpa antrian email.
Tutorial ini membangun laporan harian yang:
- Mengambil angka dari sistem Anda (penjualan, error, sign-up)
- Merakit email HTML sederhana yang enak dibaca
- Mengirim via
POST /v1/sendMailAnvil dari cron
Prasyarat
- VPS atau mesin yang selalu nyala dengan
crontersedia (Ubuntu:systemctl status cron) - API key MailAnvil (diawali
re_) dan domain pengirim yang sudah terverifikasi - Endpoint angka Anda: file JSON, response API internal, atau output skrip
Langkah 1 — Skrip pengambil angka
Buat ~/laporan/metrics.sh. Contoh: hitung transaksi hari ini dari API internal Anda.
#!/bin/bash
# metrics.sh — kembalikan 3 angka: transaksi, pendapatan, error
TX=$(curl -s "https://internal-api.acme.id/metrics?day=today" | grep -oP '"tx":\K[0-9]+')
REV=$(curl -s "https://internal-api.acme.id/metrics?day=today" | grep -oP '"revenue":\K[0-9]+')
ERR=$(grep -c 'ERROR' /var/log/acme/app.log 2>/dev/null || echo 0)
echo "$TX $REV $ERR"
ponytail: parsing dengan grep cukup untuk angka tunggal. Kalau JSON-mu bertingkat, ganti python3 -c 'import json,sys; ...'.
Langkah 2 — Template email
Email laporan yang dibaca manusia itu sederhana: tiga angka besar, satu tabel kecil, satu tombol. Simpan sebagai template.html:
<h2>Laporan Harian — {{DATE}}</h2>
<table>
<tr><td>Transaksi</td><td><b>{{TX}}</b></td></tr>
<tr><td>Pendapatan</td><td><b>Rp {{REV}}</b></td></tr>
<tr><td>Error</td><td><b>{{ERR}}</b></td></tr>
</table>
<p><a href="https://app.acme.id/dashboard">Buka dashboard</a></p>
Langkah 3 — Kirim via MailAnvil
Buat ~/laporan/send.sh:
#!/bin/bash
set -euo pipefail
read TX REV ERR <<< "$(/home/operator/laporan/metrics.sh)"
DATE=$(date '+%d %B %Y' --iso-8601)
HTML=$(sed -e "s/{{DATE}}/$DATE/g" -e "s/{{TX}}/$TX/g" \
-e "s/{{REV}}/$REV/g" -e "s/{{ERR}}/$ERR/g" template.html)
export TX REV ERR DATE HTML
BODY=$(python3 <<'EOF'
import json, os
print(json.dumps({
"from": "[email protected]",
"to": ["[email protected]", "[email protected]"],
"subject": f"Laporan harian {os.environ['DATE']} — {os.environ['TX']} tx, Rp {os.environ['REV']}",
"text": f"Transaksi {os.environ['TX']}, pendapatan Rp {os.environ['REV']}, error {os.environ['ERR']}.",
"html": os.environ['HTML']
}))
EOF
)
curl -s -X POST https://api.mailanvil.com/v1/send \
-H "authorization: Bearer $MAILANVIL_API_KEY" \
-H "idempotency-key: daily-report-$(date +%Y-%m-%d)" \
-H "content-type: application/json" \
-d "$BODY"
Poin penting:
Idempotency-Keymemakai tanggal hari ini. Kalau cron jalan dua kali (server restart, cron overlap), MailAnvil mendedupe — penerima tidak dapat dua email.- Header
authorization: Bearer re_.... Simpan key di file cron env, bukan di dalam skrip:bash # ~/.cron_env MAILANVIL_API_KEY=re_key_kamu_di_sini - Respons sukses adalah
202 Accepted. Kalau4xx, body-nya berisi alasan (domain belum verifikasi, format email salah).
Langkah 4 — Pasang cron
crontab -e
MAILANVIL_API_KEY=re_key_kamu_di_sini
0 7 * * * /home/operator/laporan/send.sh >> /home/operator/laporan/cron.log 2>&1
Jam 7 pagi WIB setiap hari. Cek cron.log besok pagi — harus terlihat {"id":"..."} dari API.
Langkah 5 — Verifikasi pertama
Jalankan manual sebelum pasang cron:
set -a; source ~/.cron_env; set +a
~/laporan/send.sh
Respons 202 berarti email sudah di antre. Cek inbox penerima, cek folder spam. Kalau masuk spam, periksa DKIM/SPF domain pengirim — MailAnvil otomatis setting DNS DKIM untuk domain di Cloudflare.
Kenapa bukan SMTP dari VPS sendiri?
- IP VPS tanpa reputasi pengirim = spam folder. SES di belakang MailAnvil mengurus reputasi, DKIM, dan rate limit.
sendmaillokal tidak punya idempotency dan tidak punya API status — email hilang tidak ada kabar.- Tagihan IDR dengan QRIS/GoPay, tanpa kartu kredit internasional.
Langkah lanjut
- Tambahkan perbandingan vs kemarin (
date -d 'yesterday') di tabel - Kirim versi WhatsApp ke group tim untuk error kritis — email untuk laporan, WhatsApp untuk alert
- Satu email gabungan mingguan: cron mingguan yang membaca log harian
Skrip penuh di tutorial ini jalan tanpa dependensi selain curl, python3, dan date — semua bawaan Ubuntu server standar.