Transform Webhook Data to Pass Third Parties (Firebase Alert and Dingtalk Use Case)

Hi, so today I will explain how to create middle-ware for transform Webhook data payload into another Webhook data. But I know it will become abstract if i just explain without the real case, then I will elaborate more about that. Last time I got a question from one of my team members, how we can get alert request in Dingtalk based Firebase Crashlytics. Dingtalk had easy integration for several third parties library, such as Github, Jira, Gitlab, Travis, Trello, and etc. But Firebase is not provided, so I use custom message via Dingtalk Webhook.

After we create custom message in Dingtalk we will get URL, Token, and Payload. Those three components should be tested first, you can use curl or API testing tools(Postman, PostWoman, Insomnia, etc). if you face some issue related to integration or payload better you go to Dingtalk documentation, but I should give you warn, Dingtalk documentation using Mandarin language in default, then if you got problem with those, please use language translation chrome extension to translate.

After you integrate then message already received, congrats you complete one step, but how Firebase will trigger this API Webhook? Hmm, I tried to explore and read the documentation on how to trigger webhook from Firebase. I got several methods to do this, but some methods will turn into fail after I implement and notice after reading the documentation, let me explain a little bit.

First Method, Cloud Function

Cloud function is great, those services bring a lot of benefit, but google still develop it so maybe there are many features that deprecate soon. At first glance I was impressed about this service, I am not familiar with that actually but after i read the blog, an article that how to use that i tried one step to implement it, but i should warn you, this cloud function service only can develop it if you already had blazing categories account service, mean you cannot use for free account. You can read detailed blog from official Firebase blog

So i tried it first, like always i should download Firebase SDK, then setting up and get authentication in terminal. after that i choose my project relate project that you already mention before. Answer all following question, for guide Firebase cloud function you can refer to here, after that you should edit index.js with this Gist. Cloud function can trigger background processing from Crashlytic API with 3 type function, issue().onNew({}) issue().onRegressed({}) and issue().onVelocityAlert({}) . Those three types already reserved in Cloud function API. But the main issue will come out, when you try to deploy fail event will occur, always fail. Then after i look into Cloud documentation relate Crashlytics. Crashlytic in cloud function already deprecated. Done, First Method cannot be used anymore. So we try to use another method.

Second Method, Official Third Parties

Firebase already deprecated for Crashlytic cloud function, then we should handle another way to create Alert. When you look deeper, Firebase provides an extension to integrate third parties service, such as Pager duty, Gitlab, and Atlassian. Only Pager Duty that relates for Crashlytic reporting, so Firebase recommend for integrate Pager Duty for management issue, Pager Duty more than that actually a SaaS incident response platform for IT departments. We decide to use Pager Duty, then in Pager Duty will forwarding data into other Webhook, its kind of chaining Webhook from one service into another service. because Firebase cannot provide proper Webhook so we need another service that customizes Webhook.

But you should have blazing account type Firebase to integrate Firebase into third parties service. After that you should create services in Pager Duty, its fine if you go for free tier first, it doesn't matter for free or not, you still can push alert and notify to the target.

After you already setup all those services, you will create Heroku account, we using Heroku to consume data from Pager Duty and passing into Webhook URL. why we need Heroku because we need transform data into suitable JSON that match with target Webhook, example use case is i create alert to Dingtalk message, Dingtalk message only satisfied with json format, if the format is not match, Dingtalk will return HTTP error. So basically Pager duty will send rich data that cant handle by Dingtalk directly so we need transform Pager Duty data into Dingtalk JSON format.

Heroku is Sass platform to execute function in the cloud based on url, this the simple way to understand what Heroku provide is. But Heroku is just tools, its just server, storage, domain, it still empty data on there so we should fill it up. First, i gonna use Express.Js. Express.js is easy way to create middle-ware API, consume and transform into another data. So its suitable for us to solve our case. Express.js is Javascript language, you can gather Express documentation in here. Below is an example index.js for third parties transformation.

// Require express and body-parserconst express = require("express")const bodyParser = require("body-parser")var request = require('request');// Initialize express and define a portconst app = express()const PORT = process.env.PORT || 3000// Tell express to use body-parser's JSON parsingapp.use(bodyParser.urlencoded({extended: true}));app.use(bodyParser.json())"/hook", function (req, res) {//console.log(req) // Call your action on the request hereconsole.log(req.body.messages) // Call your action on the request herevar title = req.body.messages[0].incident.title.replace("New Fatal Issue","Issue").replace("my.maukerja.applicant", "Android").replace("com.maukerja.iosapplicant", "IOS")var data = {msgtype: 'markdown',markdown: {title: req.body.messages[0].event,text: `Hi Guys I need your help to check ->,\n> **Type:** ` + req.body.messages[0].incident.type + `\n>` + title + `\n` + `**Summary:** ${req.body.messages[0].incident.summary} \n` + `[Learn More](${req.body.messages[0].incident.html_url})`}}{headers: {'Content-Type' : 'application/json;charset=utf-8'},url:'{access_token}',json: data},function(error, response, body){console.log(response);console.log(error);console.log(body);res.send(body);});//res.status(200).end() // Responding is important})// Start express on the defined portapp.listen(PORT, () => console.log(`🚀 Server running on port ${PORT}`))

After you update index.js, then push it into Heroku cloud service. please check your configuration before push, frequent issue is like PORT configuration because our port using local port, if you still using static port you should change it into dynamic and let Heroku handle those PORT. Your log will appear in Heroku terminal or in Heroku Dashboard, so if you had error you can stake trace on there.

Because all component already there, we can test it, go to Firebase dashboard and go to extension setting, choose Pager Duty then add API key from pager duty into Firebase, please wait at moment. You can test alert from that configuration, just tap send test alert. Finish, if not receive in your Dingtalk account maybe there is some error occur in our code, please check in log from Heroku dashboard, it will give you insight which error trigger is.


Android Developer and Learner.