API Integrations Using Postman: Building a Slack Channel Bot
APIs break down information silos and make data more actionable. By bridging together different systems, an organization can increase its productivity radically. Unfortunately, these benefits are not realized as most APIs are undocumented or undiscoverable. Integrating APIs from different entities is a huge pain point. Coding and debugging an API integration can take days if not hours. Our users have cited API integrations from 3rd parties as the biggest cause of project delays!
Postman has several tools to help you build API integrations quickly
- Postman can import curl commands into the request builder. This lets Postman import calls from existing API documentation or any tool that can export curl commands.
- If the API is not documented, you can use the Postman Interceptor for web apps or the Postman Proxy for desktop apps to capture HTTP requests and start documenting them into Collections.
- Postman supports several response formats like JSON, XML and JSONP to make sense of vast bodies of text responses easily.
- Postman’s scripting environment can help you chain requests. You can maintain request state and transfer data from the response of one request to another request.
- While you are building an API integration, you can also write tests that can tell you if an API call worked as expected.
- You can run a Collection inside Postman for debugging and then use Newman to run the same Collection in the command line.
To illustrate this process, we’ll build a Slack bot in this article that we actually use at Postman. We are quite fanatical about reviews and whether users are facing any issue with the app. We have multiple channels through which we talk to users. We send data from Github, Twitter and Zendesk to a Slack channel (#users) where our team can quickly respond to people. Our Chrome Web Store listing is something that we have to go to manually every time to check user reviews. I wanted to build a bot that would periodically post reviews from the Chrome Web Store on to #users.
Building the bot
The first step in building the bot was finding out how the Chrome Web Store renders reviews. My hunch was that the reviews would be rendered as part of the web page itself. To check this hypothesis, I looked at the Chrome Network inspector window as part of Chrome Dev Tools:
[youtube http://www.youtube.com/watch?v=Jda0ZbCBbpY&w=660&h=375]
Luckily, I found out that the reviews are loaded through a JSONP API. The request name in the Chrome Network Inspector was “components”. You will have to select the right request as there might be multiple calls made to this endpoint. I looked at the responses and selected the request that had the comment data.
The Chrome Network Inspector does not format the response but Postman does. I copied the curl command from Dev Tools and then imported it into Postman. The imported request body needed some changes for it to work in Postman. I removed the apostrophes from the beginning and the end of the request raw body. I also changed the js
parameter to false
.
[youtube http://www.youtube.com/watch?v=mg23N3v-9NM&w=660&h=375]
Firing the request inside Postman but after changing request body slightly, I was able to retreive the JSON in a prettified way.
I wrote a test script to parse this JSONP response into an array called reviews. I had to modify the JSONP response a little bit, but overall it was pretty simple. I could now iterate through this array and then build a string that I could post to a Slack channel.
// Parse JSONP manually here var reviews = {}; var newBody = responseBody.remove("window.google.annotations2.component."); var f = new Function("load", newBody); f(function(json) { reviews = json["1"].results.annotations; }); var review; var i; var comments = "*Latest reviews from the Chrome Web Store*\n\n"; var comment; var reviewTimestamp; var now = Date.now()/1000; function addReview(review) { var comment; comment = "*" + "<" + review.entity.profileUrl + "|" + review.entity.displayName + ">* \n"; comment += "Rating: " + review.starRating + "/5 \n"; comment += review.comment + "\n"; comment += "`" + review.formattedTimeString + "` \n"; return comment; } var count = 0; for(i = 0; i < reviews.length; i++) { reviewTimestamp = reviews[i].creationTimestamp; if (now - reviewTimestamp < 24 * 60 * 60) { count++; comment = addReview(reviews[i]); comments = comments + comment + "\n\n"; } } postman.setEnvironmentVariable("comments", comments);
To transfer data from the test script to the Slack request, I created an environment called “Chrome Web Store” through the environment and set it as my active environment. I sent this request once to make sure everything is working.
Slack’s API lets you create an incoming webhook. You can POST data to the webhook URL and it will show up in a Slack channel.
Sending the webhook request inside Postman is pretty simple. We just set the request URL as the webhook URL and set the method as POST. The request body is set as per Slack’s webhook API definition. The request body contains the variable {{comments}}
. The comments
environment variable will store the string that’s built in the test script of the previous request.
On sending this request, Slack’s API tells me that everything is ok. Though it would be great to get a JSON response but for now this is fine. As soon as I post this request, the string shows up in my Slack channel!
To run both requests together, I can use the Postman Collection Runner.
Now, we want to run this Collection periodically. The Collection Runner is designed for you to run Collections manually but you can export this Collection as a JSON file and run it through Newman.
newman -c CWS-Slack.postman_collection
Everything remains the same but now we can run this collection with any frequency we want using cron (well as low as every minute). You do not need anything else to make a fully functional bot now!
Having the collection saved in Postman can act as a great starting for other integrations. Using this as a base, I was able to build an integration with Stack Overflow in just a few minutes. Thankfully, Stack Exchange has a documented API so it was easier.
Conclusion
API integrations can be hard. Postman’s toolchain can save effort in debugging, coding and running an integration. You don’t have to jump between multiple tools to get your work done. Once you have built one integration, subsequent integrations take lesser time. Newman gives you the flexibility of where you want to run these integrations. This means that additional concerns of security and deployment are completely under your control. Newman can run behind firewalls or on the cloud with equal ease.
So I went ahead and created a script that posts a Newman summary to a Slack webhook: https://github.com/cameronoxley/Newman-to-Slack