Hubungkan skrip BASH dengan dunia luar: curl untuk GET/POST dan timing request, jq untuk memproses JSON, notifikasi ke Slack & Telegram, hingga query database non-interaktif. Disertai studi kasus mengambil data API dan jebakan umum seputar integrasi.

Setelah di episode 22 sebelumnya kita membahas integrasi dengan sed, awk, dan text processing — bagaimana skrip mengolah teks, file, dan log di dalam server — pada episode kali ini kita membuka jendela ke luar. Kita akan menghubungkan skrip BASH dengan dunia luar: HTTP API, layanan notifikasi, dan database.
Bayangkan skrip kalian selama ini seperti petugas yang rajin bekerja di dalam satu ruangan tertutup: menata file, merapikan log, memproses data. Episode ini mengubahnya menjadi kurir yang berkomunikasi dengan dunia: ia bisa bertanya ke layanan cuaca, melaporkan status ke kanal Slack tim, mengirim pesan Telegram, dan mengeksekusi query ke database. Ini adalah lompatan besar, karena sebagian besar otomasi DevOps yang bernilai tinggi — monitoring, alerting, deployment pipeline, backup reporting — dibangun di atas kemampuan "skrip berbicara dengan sistem lain".
Bayangkan juga situasi nyata: pukul tiga pagi, skrip backup gagal. Tanpa integrasi API, kalian baru tahu esok pagi saat membaca log. Dengan integrasi, Telegram kalian berbunyi pukul 03.00: "BACKUP GAGAL di server produksi". Perbedaan antara "menunggu masalah ditemukan" dan "masalah menemukan kalian" inilah yang membuat integrasi menjadi keterampilan wajib DevOps.
Pada episode ini kita akan membedah curl sebagai klien HTTP, jq sebagai parser JSON, notifikasi ke Slack dan Telegram, eksekusi query database non-interaktif, lalu menggabungkannya dalam satu studi kasus end-to-end. Siapkan diri kalian — episode ini menghasilkan skrip yang benar-benar berguna di dunia kerja.
curl adalah klien HTTP/HTTPS yang hampir selalu tersedia di sistem Linux (cek dengan curl --version). Ia adalah "tangan panjang" skrip kalian: melakukan request, menerima respons, dan menyimpannya.
Request paling sederhana adalah GET:
curl -s https://api.example.com/usersTanpa -s, curl menampilkan progress meter ke stderr — berguna di terminal interaktif, tapi mengganggu di dalam skrip. Gunakan -s (silent) untuk menyembunyikannya. Namun -s juga menyembunyikan error, jadi di skrip produksi ia hampir selalu dipasangkan dengan -f (fail on error): curl akan keluar dengan status non-zero jika server membalas 4xx/5xx, sehingga kegagalan bisa dideteksi di dalam skrip.
if curl -sf https://api.example.com/health > /dev/null; then
echo "API sehat"
else
echo "API bermasalah"
fiUntuk mengirim data, kita memakai -X POST bersama -d (data). Contoh mengirim form:
curl -s -X POST -d "title=Belajar%20BASH" https://api.example.com/postsPerhatikan bahwa -X POST dan -d mengubah metode dari GET (default) menjadi POST. Header khusus bisa ditambahkan dengan -H, misalnya token autentikasi atau tipe konten JSON:
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Arman","role":"devops"}' https://api.example.com/usersSering kali output API berupa JSON yang panjang. Daripada mencemari layar, simpan ke file dengan -o, atau biarkan nama file diikuti -O untuk mengambil konten:
curl -s -o response.json https://api.example.com/report
curl -s -w "HTTP %{http_code} dalam %{time_total}s\n" -o /dev/null https://api.example.com/healthOpsi -w (write-out) adalah sekutu terbaik untuk mengukur performa: %{http_code} memberi kode status, %{time_total} memberi total waktu request. Ini sangat berguna untuk health check yang sekaligus mencatat latensi.
| Opsi curl | Fungsi |
|---|---|
-s | Silent: sembunyikan progress meter & pesan error |
-f | Gagal (exit non-zero) pada kode status 4xx/5xx |
-o file | Tulis respons ke file |
-O | Simpan konten dengan nama file dari URL |
-d "data" | Kirim body request (POST) |
-H "Key: Value" | Tambah header |
-w "fmt" | Cetak data spesifik setelah request selesai |
-X METODE | Paksa metode HTTP |
BASH tidak punya cara bawaan untuk memparsing JSON — mencoba ekstrak nilai dengan sed/regex dari JSON adalah resep bencana, karena struktur JSON bisa berubah kapan saja. Di sinilah jq hadir: parser JSON khusus yang membaca input dan mengekstrak apa yang kalian minta. Jika belum terpasang, instal dengan package manager kalian (apt install jq, brew install jq, dll).
Penggunaan paling dasar: ambil satu field:
curl -s api.example.com/weather | jq '.temperature'Jika responsnya berlapis (objek di dalam objek), gunakan titik untuk turun level:
{
"location": {
"city": "Jakarta",
"country": "ID"
},
"temperature": 29.5
}curl -s api.example.com/weather | jq '.location.city'
curl -s api.example.com/forecast | jq '.days[0].temp_max'Untuk array, .[0] mengambil elemen pertama, sedangkan .[] mengiterasi semua elemen. Kombinasi .days[] | select(.rain > 0) memfilter elemen berdasarkan kondisi — setara dengan grep, tapi paham struktur JSON:
curl -s api.example.com/forecast | jq '.days[] | select(.rain > 0) | .date'Satu opsi lagi yang krusial: -r (raw). Tanpa -r, output jq selalu dibungkus tanda kutip string; dengan -r, outputnya murni teks — sehingga bisa langsung ditangkap sebagai variabel BASH:
kota=$(curl -s api.example.com/weather | jq -r '.location.city')
echo "Cuaca di $kota"Ingat pola dari episode 22: echo "$json" | jq '.name' bekerja karena jq membaca dari stdin — dan pipeline curl | jq adalah pasangan paling umum dalam skrip DevOps. Dengan jq, kalian bisa memproses respons API menjadi struktur data yang siap dipakai, bukan sekadar teks mentah.
Skrip otomasi sering berjalan di malam hari, jauh dari mata manusia. Agar hasilnya sampai ke kalian, skrip perlu mengirim notifikasi. Dua target paling umum di Indonesia: Slack (kanal tim) dan Telegram (perangkat pribadi).
Slack memakai Incoming Webhook: kalian membuat URL unik di Slack, lalu cukup POST JSON berisi teks ke URL tersebut:
curl -s -X POST -H 'Content-type: application/json' \
-d '{"text":"Deploy selesai: versi 2.4.1 live di produksi 🚀"}' \
"$SLACK_WEBHOOK_URL"Telegram memakai Bot API. Buat bot via BotFather untuk mendapatkan token, lalu kirim pesan ke sendMessage:
curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
--data-urlencode "chat_id=$TELEGRAM_CHAT_ID" \
--data-urlencode "text=Backup server berhasil diselesaikan"--data-urlencode sangat penting di sini: ia memastikan spasi, karakter khusus, dan simbol URL di dalam pesan di-encode dengan benar — menulis -d "text=..." mentah-mentah akan rusak jika pesan mengandung spasi atau tanda &.
Tip
Simpan kredensial sebagai environment variable, bukan hardcode. Token Slack, token bot Telegram, dan password database tidak boleh tertulis di dalam skrip. Pola yang benar: SLACK_WEBHOOK_URL dibaca dari environment, diisi dari .env lokal saat development dan dari secret manager saat produksi. Ini juga menyelamatkan kalian dari kecelakaan git push yang membawa rahasia.
Otomasi sering kali butuh membaca atau menulis data ke database. Untungnya, klien CLI mysql dan psql bisa berjalan non-interaktif — tanpa sesi terminal interaktif — sehingga cocok di dalam skrip.
Untuk MySQL/MariaDB, query langsung dengan -e, atau gunakan heredoc untuk query yang panjang:
mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" myapp <<SQL
SELECT COUNT(*) AS total_users FROM users WHERE status = 'active';
SQLUntuk PostgreSQL, psql -c melakukan hal yang sama, dan pg_dump mengekstrak backup:
psql -h "$DB_HOST" -U "$DB_USER" -d myapp -c \
"SELECT COUNT(*) FROM orders WHERE created_at >= NOW() - interval '1 day';"
pg_dump -h "$DB_HOST" -U "$DB_USER" -d myapp -Fc -f /backup/myapp.dumpWarning
Perhatikan dua jebakan heredoc: (1) Gunakan delimiter berkutip (<<SQL, <<'SQL') agar variabel di dalam query tetap dievaluasi, tapi jangan lupa bahwa isi heredoc masih bisa diekspansi oleh shell — untuk query yang mengandung $, gunakan <<'SQL' agar tidak ikut diekspansi. (2) Menulis password di command line (-p"$DB_PASS") terlihat di process list sesaat; untuk produksi gunakan file .my.cnf dengan permission 600 atau mekanisme server-side seperti PGPASSWORD/.pgpass.
Saatnya menggabungkan semuanya. Kita akan membuat skrip yang mengambil prakiraan cuaca, memeriksa apakah besok hujan deras, dan memberi tahu tim di Slack jika ya. Ini adalah template nyata dari skrip monitoring berbasis cuaca — misalnya untuk tim yang mengelola event outdoor atau distribusi logistik.
#!/usr/bin/env bash
set -euo pipefail
SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:?SLACK_WEBHOOK_URL wajib diisi}"
CITY="${1:-Jakarta}"
json=$(curl -sf "https://api.open-meteo.com/v1/forecast?latitude=-6.2&longitude=106.8&daily=precipitation_sum&timezone=Asia%2FJakarta")
rain=$(echo "$json" | jq -r '.daily.precipitation_sum[0]')
if [ "$rain" -gt 10 ]; then
curl -s -X POST -H 'Content-type: application/json' \
-d "{\"text\":\"⚠️ Hujan deras ($rain mm) besok di $CITY. Antisipasi keterlambatan logistik!\"}" \
"$SLACK_WEBHOOK_URL" > /dev/null
else
echo "Aman: curah hujan besok $rain mm"
fiBahas skrip ini baris per baris:
set -euo pipefail — strict mode (ingat episode 13): skrip berhenti jika ada langkah gagal.:? pada SLACK_WEBHOOK_URL — jika variabel tidak terisi, skrip langsung error dengan pesan jelas. Pola ini menutup pintu bagi "skrip jalan tapi diam-diam tanpa kredensial".curl -sf — silent + fail on error: kegagalan jaringan tidak diteruskan ke jq.jq -r '.daily.precipitation_sum[0]' — ambil nilai hujan hari pertama sebagai teks murni.[ "$rain" -gt 10 ] — pembanding aritmatika (ingat episode 5). Hati-hati: > di dalam [...] adalah redirection, makanya pakai -gt.Skrip semacam ini adalah arsitektur dasar dari semua otomasi berbasis API: ambil → proses → bandingkan → aksi. Setelah kalian paham pola ini, hampir semua integrasi — status deploy, harga saham, uptime monitor, orderan baru — hanyalah variasi dari template yang sama.
1. -s menyembunyikan error sampai semuanya terlambat. Tanpa -f atau pengecekan $?/%{http_code}, respons error (misal 500) dianggap sukses dan diproses lebih lanjut. Selalu pasangkan -sf dan verifikasi status sebelum memproses output.
2. jq belum terpasang di server. Skrip yang bergantung pada jq akan gagal diam-diam. Deteksi sejak awal dengan pesan yang jelas:
if ! command -v jq > /dev/null; then
echo "ERROR: jq tidak terpasang. Instal dengan 'apt install jq'" >&2
exit 1
fi3. Tanda kutip hilang di sekitar payload JSON. Payload Slack {"text":"..."} berisi banyak tanda kutip ganda — jika tidak diapit tanda kutip tunggal dengan benar, shell akan memecahnya. Untuk nilai dinamis, susun JSON dengan jq -n atau printf dan escape tanda kutip ganda secara eksplisit, seperti pada skrip praktik di atas.
4. Melewati rate limit API. API publik membatasi jumlah request per menit. Skrip yang memanggil API dalam loop tanpa jeda akan ditolak (429). Tambahkan sleep di antara panggilan, dan untuk retry gunakan jeda eksponensial (sleep $((2 ** retry))).
5. Logging kredensial. Jangan pernah mencetak token atau password ke log. Cukup log hasilnya ("notifikasi terkirim"), bukan payload yang berisi rahasia.
Pada episode 23 ini, kalian telah membuka skrip BASH ke dunia luar. Kita mempelajari curl sebagai klien HTTP: -s untuk silent, -f untuk gagal pada error, -o untuk menyimpan output, -w untuk mengukur latensi, dan -X POST bersama -d/-H untuk mengirim data dan header. Lalu jq untuk memproses JSON: mengambil field dengan .key, mengakses array dengan .[] dan indeks, memfilter dengan select, dan menangkap output bersih dengan -r. Kita juga membangun notifikasi ke Slack via webhook dan Telegram via Bot API, mengeksekusi query MySQL/PostgreSQL non-interaktif dengan heredoc, dan merakit semuanya menjadi skrip monitoring cuaca yang mengirim alert hanya ketika kondisi terpenuhi.
Poin kunci yang perlu kalian bawa:
curl -sf + verifikasi status adalah standar minimum untuk request di dalam skrip.jq adalah satu-satunya cara yang andal memproses JSON di BASH; gabungkan dengan -r untuk nilai murni.--data-urlencode untuk pesan notifikasi yang mengandung spasi dan simbol.Dengan kemampuan berbicara ke dunia luar, skrip kalian kini hidup dan berdiri sendiri. Namun skrip yang hidup perlu menceritakan kisahnya — di episode 24 selanjutnya kita akan membahas logging, colorizing output, dan terminal UX: mencatat jejak dengan timestamp dan level log, mewarnai output untuk panduan mata, serta menambahkan spinner dan progress untuk pengalaman terminal yang profesional. Sampai jumpa di episode berikutnya!