Blog Post
Menghubungkan Webhook Discord dan Telegram untuk Notifikasi Deployment Otomatis
Panduan untuk membangun notifikasi deployment otomatis ke Discord dan Telegram dengan payload yang berguna, noise yang terkontrol, dan jejak audit yang tetap jelas.
TL;DR
- Notifikasi deployment sebaiknya dikirim lewat notifier kecil yang mengurus format, deduplikasi, dan routing channel.
- Discord dan Telegram efektif sebagai surface koordinasi, bukan sebagai source of truth audit release.
- Payload yang berguna harus menyertakan service, environment, version, status, dan link ke pipeline atau dashboard.
Pendahuluan
Mengirim notifikasi deployment ke chat tool terdengar mudah, tetapi implementasi yang terlalu langsung biasanya cepat menjadi sumber noise. Semua build masuk ke satu channel, retry CI menciptakan spam, dan tidak ada link ke log atau release. Dalam kondisi itu, pesan deployment berhenti menjadi sinyal operasional.
Tutorial ini membuat jalur notifikasi deployment yang sederhana tetapi cukup production-ready. Targetnya adalah satu notifier berbasis Node.js yang menerima event deploy dari CI/CD, lalu menerjemahkannya ke Discord dan Telegram dengan format yang konsisten.
Prerequisites
- Linux server atau runner CI yang bisa menjalankan Node.js 18+.
- Akses ke Discord server dan Telegram bot.
- Discord webhook URL yang sudah dibuat.
- Telegram bot token dan
chat_id. - Pipeline CI/CD yang bisa menjalankan script setelah deploy.
- Secret management untuk menyimpan webhook dan token, misalnya GitHub Actions secrets atau environment file yang aman.
Problem di Production
Masalah terbesar biasanya bukan kegagalan mengirim HTTP request, tetapi kualitas event yang buruk. Semua pesan terlihat sama, environment tidak jelas, dan retry deployment mengirim tiga atau empat notifikasi untuk event yang sama. Tim akhirnya berhenti membaca channel.
Mental Model
Anggap notifikasi deployment sebagai contract operasional. Setiap pesan harus menjawab:
- apa yang berubah
- di environment mana
- status deploy apa
- ke mana operator bergerak berikutnya
Jika pesan tidak menjawab keempat hal itu, ia lebih dekat ke noise daripada notifikasi.
Konsep Utama
Notifier terpusat lebih sehat daripada webhook langsung dari banyak job
Jika tiap pipeline memanggil Discord dan Telegram langsung dengan format berbeda, kualitas sinyal akan cepat rusak. Satu notifier kecil memberi kontrol lebih baik.
Deduplikasi itu wajib
Retry network, rerun job, atau parallel deploy bisa menciptakan event ganda. Notifier harus bisa mengenali event yang sama.
Chat channel bukan audit system
Pesan chat mudah hilang di timeline. Notifikasi seharusnya selalu mengandung pointer ke pipeline, release, atau dashboard.
Arsitektur / Context
Arsitektur yang dipakai:
- pipeline deploy mengirim payload JSON ke notifier
- notifier memvalidasi secret dan event shape
- notifier membuat
dedupeKey - notifier mengirim pesan ke Discord dan Telegram
- notifier mencatat hasil kirim ke log lokal
Pola ini memudahkan pemisahan channel berdasarkan environment, misalnya staging ke channel yang lebih tenang dan production ke channel yang lebih ketat.
Practical Implementation
Step 1: Buat project notifier
mkdir -p ~/deploy-notifier
cd ~/deploy-notifier
npm init -y
npm install express
Step 2: Siapkan environment variable
cat > .env <<'EOF'
PORT=4010
NOTIFIER_SHARED_SECRET=change-me
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/xxx/yyy
TELEGRAM_BOT_TOKEN=123456:ABCDEF
TELEGRAM_CHAT_ID=-1001234567890
EOF
Jangan commit file ini ke repo.
Step 3: Buat service notifier
// server.js
import express from "express";
const app = express();
app.use(express.json());
const sentEvents = new Map();
function buildMessage(payload) {
return [
`deploy ${payload.status}`,
`service: ${payload.service}`,
`env: ${payload.environment}`,
`version: ${payload.version}`,
`url: ${payload.url}`
].join("\n");
}
async function sendDiscord(message) {
const res = await fetch(process.env.DISCORD_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content: "```txt\n" + message + "\n```" })
});
if (!res.ok) {
throw new Error(`Discord failed with status ${res.status}`);
}
}
async function sendTelegram(message) {
const res = await fetch(
`https://api.telegram.org/bot${process.env.TELEGRAM_BOT_TOKEN}/sendMessage`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
chat_id: process.env.TELEGRAM_CHAT_ID,
text: message
})
}
);
if (!res.ok) {
throw new Error(`Telegram failed with status ${res.status}`);
}
}
app.post("/notify/deploy", async (req, res) => {
if (req.headers["x-notifier-secret"] !== process.env.NOTIFIER_SHARED_SECRET) {
return res.status(401).json({ ok: false, error: "unauthorized" });
}
const payload = req.body;
const dedupeKey = `${payload.environment}:${payload.service}:${payload.version}:${payload.status}`;
if (sentEvents.has(dedupeKey)) {
return res.json({ ok: true, deduped: true });
}
const message = buildMessage(payload);
await Promise.all([sendDiscord(message), sendTelegram(message)]);
sentEvents.set(dedupeKey, Date.now());
console.log(JSON.stringify({ event: "deploy_notification_sent", dedupeKey, payload }));
res.json({ ok: true });
});
app.listen(process.env.PORT || 4010, () => {
console.log(`notifier listening on ${process.env.PORT || 4010}`);
});
Untuk runtime yang lebih stabil, simpan dedupe key di Redis atau database, bukan Map in-memory.
Step 4: Jalankan notifier
node --env-file=.env server.js
Jika memakai CommonJS, sesuaikan import menjadi require.
Step 5: Uji manual dengan curl
curl -X POST http://localhost:4010/notify/deploy \
-H "Content-Type: application/json" \
-H "x-notifier-secret: change-me" \
-d '{
"service": "billing-api",
"environment": "production",
"version": "sha-9f1ab23",
"status": "succeeded",
"url": "https://github.com/org/repo/actions/runs/123456"
}'
Pastikan pesan muncul di Discord dan Telegram sebelum integrasi ke CI.
Step 6: Pasang sebagai systemd service
sudo tee /etc/systemd/system/deploy-notifier.service > /dev/null <<'EOF'
[Unit]
Description=Deployment Notifier
After=network.target
[Service]
WorkingDirectory=/home/ubuntu/deploy-notifier
EnvironmentFile=/home/ubuntu/deploy-notifier/.env
ExecStart=/usr/bin/node server.js
Restart=always
User=ubuntu
[Install]
WantedBy=multi-user.target
EOF
Aktifkan:
sudo systemctl daemon-reload
sudo systemctl enable --now deploy-notifier
sudo systemctl status deploy-notifier
Step 7: Integrasikan ke GitHub Actions
- name: Send deployment notification
if: always()
run: |
STATUS="${{ job.status }}"
curl -X POST https://notifier.example.com/notify/deploy \
-H "Content-Type: application/json" \
-H "x-notifier-secret: ${{ secrets.NOTIFIER_SHARED_SECRET }}" \
-d "{
\"service\": \"billing-api\",
\"environment\": \"production\",
\"version\": \"${{ github.sha }}\",
\"status\": \"${STATUS}\",
\"url\": \"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\"
}"
Pisahkan endpoint atau payload jika staging dan production memakai channel berbeda.
Verification
Periksa health process:
sudo systemctl status deploy-notifier
journalctl -u deploy-notifier -n 50
Uji endpoint secara manual:
curl -s http://localhost:4010/notify/deploy \
-H "Content-Type: application/json" \
-H "x-notifier-secret: change-me" \
-d '{"service":"demo","environment":"staging","version":"v1","status":"failed","url":"https://example.com"}'
Sukses berarti:
- endpoint merespons
ok: true - pesan terkirim ke Discord dan Telegram
- log lokal mencatat
dedupeKey - event ganda dengan payload sama tidak mengirim pesan kedua
Studi Kasus / Masalah Nyata
Semua build masuk ke channel production
Penyebabnya biasanya tidak ada routing berdasarkan environment. Hasilnya channel kehilangan kredibilitas.
Pesan sukses muncul dua kali
Sering terjadi saat pipeline di-retry. Jika tidak ada deduplication key, noise akan menumpuk.
Troubleshooting
Discord webhook gagal
Periksa response status dari Discord. 404 biasanya berarti webhook URL salah atau sudah dihapus.
journalctl -u deploy-notifier -n 100 | grep Discord
Telegram tidak menerima pesan
Validasi bot token dan chat id:
curl "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe"
curl "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates"
Unauthorized ke notifier
Pastikan header x-notifier-secret sama dengan nilai di environment notifier dan secret CI.
Production Notes
- Simpan webhook URL dan bot token di secret manager, bukan di repo.
- Pisahkan channel notifikasi staging dan production.
- Tambahkan timeout, retry terbatas, dan logging terstruktur jika notifier makin penting.
- Untuk dedupe yang persisten, pindahkan state dari memory ke Redis.
- Pastikan notifier sendiri dimonitor; sistem notifikasi yang mati diam-diam tidak memberi nilai.
Trade-offs
- Notifier terpusat memberi konsistensi, tetapi menambah satu service operasional baru.
- Mengirim hanya event penting menurunkan noise, tetapi sebagian tim mungkin merasa visibilitas berkurang.
- Deduplikasi menjaga channel tetap bersih, tetapi perlu state management yang lebih matang.
Failure Modes
- Retry pipeline mengirim notifikasi ganda karena deduplication tidak persisten.
- Secret webhook bocor dan endpoint dibanjiri event palsu.
- Pesan terkirim, tetapi tidak punya link ke pipeline sehingga operator tetap harus mencari konteks manual.
Best Practices
- Kirim hanya event deploy yang bernilai koordinasi.
- Gunakan format pesan yang konsisten lintas channel.
- Sertakan environment, service, version, status, dan URL.
- Pisahkan audit release dari timeline chat.
Kesalahan Umum
- mengirim semua event CI ke satu channel
- tidak punya deduplication key
- menyimpan secret di repository
- menganggap pesan chat sebagai audit trail utama
Kesimpulan
Notifikasi deployment ke Discord dan Telegram akan berguna jika diperlakukan sebagai contract operasional yang disiplin. Dengan notifier kecil yang mengatur format, deduplikasi, dan routing, tim bisa mendapatkan sinyal release yang ringkas, konsisten, dan tetap relevan saat produksi sedang bergerak cepat.
Kalau artikel ini membantu, kamu bisa support eksperimen berikutnya.
Apresiasi di TrakteerKeep Reading
Related posts
AI Attack Surface di DevOps Pipeline yang Lebih Berbahaya dari Dugaan
Analisis production-grade tentang attack surface baru saat AI masuk ke DevOps pipeline, termasuk prompt injection, tool abuse, dan governance untuk automation yang menyentuh production.
Desain Pipeline CI/CD Modern untuk Pengiriman Perangkat Lunak yang Andal
Panduan praktis merancang pipeline CI/CD yang fokus pada reliabilitas, jejak audit, keamanan rantai pasok, dan proses rilis yang bisa dipulihkan dengan cepat.