Bikin Lark Bot untuk Mengirim Notifikasi Ketika Terjadi Error di Production

M. Husni Nur Fadillah
Sainseni
Published in
5 min readSep 3, 2023
Photo by Brett Jordan on Unsplash

Latar Belakang

Error di production mesti ditangulangi dengan cepat, untuk melakukan itu mesti ada Bot yang bisa ngasih notifikasi ke developer jika ada error. Bot ini digunakan untuk mengotomatisasi pengiriman message ke grup tertentu di dalam tim.

Itsuki is pointing at an error

Karena aku saat ini kerja di company yang menggunakan Lark sebagai messaging app-nya. Jadi, aku akan bikin Bot-nya di Lark.

Implementasi

alur kerja bot

Jika ada error yang muncul saat user berinteraksi dengan aplikasi, akan diperiksa terlebih dahulu apakah itu error yang sama dengan error yang terjadi di x detik yang lalu. Jika ngak sama, maka akan di-set key dengan value-nya beserta waktu kadaluarsa dari key tersebut. Kemudian, kirim notifikasi ke Lark. Sedangkan, jika itu adalah error yang sama, maka Bot ngak ngirim notifikasi ke Lark.

Memberikan waktu kadaluarsa pada key Redis digunakan untuk mengimplementasikan rate limiting. Tujuannya adalah agar Bot tidak mengirim pesan berulang-ulang dengan informasi yang sama.

1. Bikin Custom Bot di Grup Lark

Buka pengaturan grup yang ingin dipasangi Bot, kemudian pilih BOTs. Untuk catatan, kita bisa bikin lebih dari 1 bot di satu grup.

Group setting

Isi form yang tersedia, lalu salin URL Webhook yang diberikan. Dengan Webhook ini memungkikan kita untuk mengintegrasikan aplikasi yang kita buat dengan Lark, sehingga kita dapat mengotomatisasikan kegiatan atau proses di Lark.

Form buat bikin Bot

2. Notifikasi Alert di project Golang

Aku akan menggunakan project di blog sebelumnya, yang sudah terpasang logger. Dependency tambahannya adalah go-lark.

Di artikel ini aku bikin notifikasi-nya muncul jika status error-nya adalah 4xx dan 5xx . Namun, sebelum itu, mari bikin template message-nya terlebih dahulu. Function CardMessageTemplate ini akan merender message ke dalam format yang bisa dibaca oleh Lark nantinya.

func CardMessageTemplate(cardMsgData CardMsgData) *card.Block {
b := lark.NewCardBuilder()

var errText string = fmt.Sprintf("message: %s", cardMsgData.errMsg)
var reqText string = fmt.Sprintf("payload: %s", cardMsgData.reqData)
var respText string = fmt.Sprintf("response data: %+v", cardMsgData.respData)

cardCst := b.Card(
b.Div().
Text(b.Text(errText)),
b.Div().
Text(b.Text(reqText)),
b.Div().
Text(b.Text(respText)),
b.Action(
b.Button(b.Text("Inspect")).Primary().URL(cardMsgData.hyperLinkBtn),
),
).
Red().
Title("Yahallo Project Error")

return cardCst
}

Kalian bisa kustomisasi message template sesuka hati, ada beberapa contoh yang udah disiapin sama go-lark di repository-nya.

Berikutnya bikin function untuk ngasih notifikasinya

func SendNotifLark(errMsg string, code int, reqData string, respData ResponseData) {
url := Config("LARK_WEBHOOK_URL")
bot := lark.NewNotificationBot(url)

cardData := CardMsgData{
errMsg: errMsg,
hyperLinkBtn: Config("SEQ_URL"),
reqData: reqData,
respData: respData,
}

cardCst := CardMessageTemplate(cardData)
msg := lark.NewMsgBuffer(lark.MsgInteractive)
msg.Card(cardCst.String())

bot.PostNotificationV2(msg.Build())
}

3. Hindari Spam Message

Seperti penjelasan di awal, aku akan implementasi rate-limiting, untuk menghindari spam message. Untuk melakukan itu, aku akan menggunakan caching-nya redis.

func SendNotifLark(rateLimit int, rateLimitKey string, errMsg string, code int, reqData string, respData ResponseData) {
url := Config("LARK_WEBHOOK_URL")
bot := lark.NewNotificationBot(url)

cardData := CardMsgData{
errMsg: errMsg,
hyperLinkBtn: Config("SEQ_URL"),
reqData: reqData,
respData: respData,
}

cardCst := CardMessageTemplate(cardData)

msg := lark.NewMsgBuffer(lark.MsgInteractive)
msg.Card(cardCst.String())

if rateLimit > 0 {
// Use a default rateLimitKey if not provided
if rateLimitKey == "" {
rateLimitKey = errMsg
}

cacheExist, err := RDB.SetNX(context.Background(), rateLimitKey, 1, time.Duration(rateLimit)*time.Second).Result()
if err != nil {
// Handle Redis errors here
}

if cacheExist {
bot.PostNotificationV2(msg.Build())
}
} else {
// If rateLimit is not greater than 0, post the notification immediately
bot.PostNotificationV2(msg.Build())
}
}

Di sini aku bikin pilihan untuk implement rate-limiting atau tidak. Function SetNX digunakan untuk nge-set sebuah key di dalam Redis dengan beberapa opsi berikut:

  1. NX(No Exist): Fungsi ini menggunakan opsi NX, yang berarti bahwa kunci tersebut hanya akan di-set jika kunci tersebut belum ada dalam database Redis. Dengan kata lain, jika kunci sudah ada sebelumnya, maka operasi tidak akan dilakukan.
  2. EX (Expire): Fungsi ini juga menggunakan opsi EX (expire) untuk memberikan waktu kadaluwarsa pada key yang baru di-set. Nilai yang diberikan untuk EX adalah berapa detik key akan bertahan sebelum secara otomatis menghapusnya dari database Redis.

Jika udah, maka hasilnya akan seperti ini:

Notif Alert dengan Seq

Cara ini dapat dilakukan kalo kalian tidak perlu melakukan kustomisasi, dengan memanfaatkan fitur Alert yang udah disediakan oleh Seq.

Kalian bisa explore sendiri, cuman yang mesti kalian notice di sini adalah untuk plugin atau Output app instance yang digunakan tergantung messaging app yang kalian gunakan, jika Slack pake Seq.App.Slack, jika Microsoft Teams pake Seq.App.Teams dan sebagainya.

Di sinikan aku menggunakan Lark ya, tapi Seq ngak menyediakan plugin untuk Lark, meskipun begitu kita masih bisa menggunakan Seq.App.HttpRequest. Setelah itu tambahkan instance dengan menggunakan plugin tersebut.

Isi URL dengan web hook dari Custom Bot Lark sebelumnya dan ubah Method menjadi POST tentunya. Kustomisasi message yang akan dikirimkan oleh alert ini di Body field.

Penutup

Sekian artikel “Lark Bot untuk Mengirim Notifikasi Ketika Terjadi Error di Production”, jika pengen diskusi atau ngasih feedback bisa tinggalkan di comment section.

Aku harap kalian enjoy selama membaca dan menemukan apa yang kalian cari di artikel ini.

Thank you. Written on 4th September 2023

--

--