Skip to content

Instantly share code, notes, and snippets.

@rehan-vanzyl
Last active September 13, 2016 15:40
Show Gist options
  • Save rehan-vanzyl/aa06e6cb7508742bd0be20b55366b5ae to your computer and use it in GitHub Desktop.
Save rehan-vanzyl/aa06e6cb7508742bd0be20b55366b5ae to your computer and use it in GitHub Desktop.
// Adapted from:
// AWS cloudwatch-alarm-to-slack blueprint
// https://gist.github.com/lukehutton/74c47f7fd0dfdf08cc26d6e3403fd61a
// https://github.com/chizou/codedeploy-slack/blob/master/lambda_function_slack.py
var url = require('url');
var https = require('https');
var util = require('util');
var webhookUrl, slackChannel;
webhookUrl = '<WEBHOOK_URL>';
slackChannel = '<SLACK_CHANNEL>';
var postMessage = function(message, callback) {
var body = JSON.stringify(message);
var options = url.parse(webhookUrl);
options.method = 'POST';
options.headers = {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body),
};
var postReq = https.request(options, function(res) {
var chunks = [];
res.setEncoding('utf8');
res.on('data', function(chunk) {
return chunks.push(chunk);
});
res.on('end', function() {
var body = chunks.join('');
if (callback) {
callback({
body: body,
statusCode: res.statusCode,
statusMessage: res.statusMessage
});
}
});
return res;
});
postReq.write(body);
postReq.end();
};
// Adapted from: http://stackoverflow.com/a/34270811
var humanizeDuration = function (seconds) {
var levels = [
[Math.floor(seconds / 31536000), 'years'],
[Math.floor((seconds % 31536000) / 86400), 'days'],
[Math.floor(((seconds % 31536000) % 86400) / 3600), 'hours'],
[Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), 'minutes'],
[(((seconds % 31536000) % 86400) % 3600) % 60, 'seconds'],
];
var returntext = '';
for (var i = 0, max = levels.length; i < max; i++) {
if ( levels[i][0] === 0 ) continue;
returntext += ' ' + levels[i][0] + ' ' + (levels[i][0] === 1 ? levels[i][1].substr(0, levels[i][1].length-1): levels[i][1]);
}
return returntext.trim();
};
var getDeploymentLink = function(region, deploymentId) {
return util.format("<https://%s.console.aws.amazon.com/codedeploy/home?region=%s#/deployments/%s|%s>",
region, region, deploymentId, deploymentId);
};
var getDeployMessage = function(message) {
var slackMessage = {
channel: slackChannel,
text: util.format('_%s_ *%s* deployment *%s* for `%s`',
getDeploymentLink(message["region"], message["deploymentId"]),
message["deploymentGroupName"],
message["status"],
message["applicationName"])
};
var deploymentOverview = message["deploymentOverview"];
if (deploymentOverview) {
deploymentOverview = JSON.parse(deploymentOverview);
var duration = humanizeDuration((Date.parse(message["completeTime"]) - Date.parse(message["createTime"]))/1000);
var fields = [ {
title: 'Duration',
value: duration,
short: false
}];
for (var key in deploymentOverview) {
fields.push({
title: key,
value: deploymentOverview[key],
short: true
});
}
slackMessage["attachments"] = [
{
title: "Deployment Overview",
fields: fields
}
];
}
return slackMessage;
};
var getDeployInstanceMessage = function(message) {
return {
channel: slackChannel,
text: util.format('_%s_ deployment to instance (%s) *%s*',
getDeploymentLink(message["region"], message["deploymentId"]),
message["instanceId"],
message["instanceStatus"])
};
};
var processEvent = function(event, context) {
try {
console.log("Message received: " + event.Records[0].Sns.Message);
var message = JSON.parse(event.Records[0].Sns.Message);
} catch (error) {
// Ignore non-JSON messages.
return;
}
var slackMessage;
if (message["status"]) {
slackMessage = getDeployMessage(message);
} else {
slackMessage = getDeployInstanceMessage(message);
}
console.log(slackMessage);
postMessage(slackMessage, function(response) {
if (response.statusCode < 400) {
console.info('Message posted successfully');
context.succeed();
} else if (response.statusCode < 500) {
console.error("Error posting message to Slack API: " + response.statusCode + " - " + response.statusMessage);
context.succeed(); // Don't retry because the error is due to a problem with the request
} else {
// Let Lambda retry
context.fail("Server error when processing message: " + response.statusCode + " - " + response.statusMessage);
}
});
};
exports.handler = function(event, context) {
processEvent(event, context);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment