Using Libraries in Integrations
As someone who works in tech, you're likely familiar with the benefits of automation and integrations. However, have you ever considered the role that libraries could play in making your life easier when writing integrations? This article will explore the importance of using libraries in integration development with a practical example.
In our example, we'll discuss a small library that makes API calls to PagerDuty for a Slack bot. This library comprises one file that allows you to save the API key in a more secure place while also letting you use the PagerDuty integration library in different Slack bots.
Using this library means you don't have to worry about repeatedly writing the same integration code. You can focus on the actual logic of the integration instead of updating API calls or keys in five different files. This idea isn't new and is commonly called Abstraction in Object Oriented Programming. Furthermore, libraries save you time and resources, as you don't have to start from scratch every time you develop an integration.
In addition to saving time and resources, using libraries can help you ensure that your integrations are consistent and reliable. Using a library already developed and tested, you can be confident that your integration will work as expected. This can be particularly important if you are developing integrations for a business or enterprise, as consistency and reliability are crucial.
Here's a practical look at the PagerDuty library I built for Google Script:
function Duty() {
this.token = 'sjdflkas94lkjd'
this.get = function(url, params) {
var options = {
'contentType': 'application/json',
'headers': {"Authorization": "Token token=" + this.token,
"Accept": "application/vnd.pagerduty+json;version=2",
"Content-Type" : "application/json"
},
'muteHttpExceptions': true
};
var res = UrlFetchApp.fetch('https://api.pagerduty.com' + url + this.params(params), options);
if(res.getContentText().length === 0){
return null
}
var data = JSON.parse(res.getContentText())
return data
}
//Helper function
this.params = function(data) {
const params = [];
for (var d in data)
params.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
return '?' + params.join('&');
}
this.getOnCall = function(schedule){
var now = new Date()
var almostNow = new Date(now.setMinutes(now.getMinutes()+5))
var params = {
'time_zone': 'CET',
'since': now.toISOString(),
'until':almostNow.toISOString(),
'earliest':true,
'include[]':'users',
'schedule_ids[]': schedule
}
return this.get('/oncalls', params)
}
this.listSchedules = function(){
var params = {
}
var res = this.get('/schedules', params)
Logger.log(res)
}
}
//Use this to get the scheudle ID's from PagerDuty
function test(){
var p = new Duty()
var res = p.listSchedules()
}
Now the integration gets whoever is on duty and posts it to a channel. This also uses my SlackBot library. Combining these two libraries makes the integration code easier to follow and update.
const SP_USER_ON_CALL = "USER_ON_CALL"
function checkWhoIsOnDuty() {
//Get existing user
var scriptProps = PropertiesService.getScriptProperties()
var sp_user = scriptProps.getProperty(SP_USER_ON_CALL)
//Check for new user
var pager = new Pager.Duty()
var res = pager.getOnCall('ScheduleID')
if(res.oncalls.length < 1){
return
}
var onCall = res.oncalls[0]
var pg_user = onCall.user
Logger.log(pg_user)
//Duty has not changed, exit script
if(pg_user.email == sp_user){
Logger.log(sp_user + " still on duty")
return
}
//Send message if change
var slack = new Slack.Bot()
var slack_id = slack.getSlack(pg_user.email)
var endTime = Utilities.formatDate(new Date(onCall.end), "CET", "MM/dd/yyyy HH:mm a")
slack.send("<@" + slack_id + "> is on pager duty till " + endTime + ":pager:", "channelID")
//Update property
scriptProps.setProperty(SP_USER_ON_CALL, pg_user.email)
}