Send Amplify previews build notifications to a discord channel.
Inspired by https://dev.to/aws-builders/enable-slack-notifications-for-aws-amplify-deployments-5a0l
You should probably read the article above and follow it. I added a few enhancments on the code - get more details on the PR and related JIRA ticket.
const https = require('https')
// Update this to be sent as Authorization header for bitbucket
const Authorization = "Basic 123"
const options = {
host: 'discord.com',
port: 443,
path: '/api/webhooks/{webhookId}/{webhookToken}',
headers: { 'Content-Type': 'application/json' },
method: 'POST'
};
exports.handler = async (event) => {
const message = event.Records[0].Sns.Message
const msgType = getMsgType(message)
if (!["success", "failed"].includes(msgType)) {
return;
}
const buildUrl = getBuildLink(message)
const prNumber = getPRNumber(message)
if (!prNumber) {
return;
}
const prDetails = await getPRDetails(prNumber)
const prTitle = prDetails.title ?? ""
const author = prDetails.author?.display_name ?? ""
const prLink = prDetails.links?.html?.href ?? ""
const ticketLink = getTicketLink(prDetails.rendered?.title?.html ?? "")
return await
requestAsync(options, {
username: "AWS Build Bot",
avatar_url: "Bot avatar url",
content : `Build ${msgType} for pull request: ${prTitle}`,
embeds: [{
title: "Build info",
url: buildUrl,
description: `Deployed at: ${buildUrl}`,
fields: [
{
name: "Ticket",
value: ticketLink,
inline: true
},
{
name: "Author",
value: author,
},
{
name: "PR Link",
value: prLink
}
]
}]
})
.then((data) => console.log(data))
.catch((e) => console.error(e.response.data))
}
function getMsgType(msg) {
if (typeof msg !== "string") {
return "invalid"
}
if (msg.includes("Your build status is STARTED")) {
return "start"
}
if (msg.includes("Your build status is SUCCEED")) {
return "success"
}
if (msg.includes("Your build status is FAILED")) {
return "failed"
}
return "unkown"
}
function getPRNumber(msg) {
return /pr-(\d+)/.exec(msg)[1]
}
function getTicketLink(html) {
return /https:\/\/.*\.atlassian\.net\/browse\/\c+-\d+/.exec(html)[0]
}
function getBuildLink(msg) {
return /https:\/\/pr-\d+\..*amplifyapp\.com/.exec(msg)[0]
}
async function getPRDetails(prNumber) {
const options = {
host: 'api.bitbucket.org',
port: 443,
path: `/2.0/repositories/.*/portal/pullrequests/${prNumber}`,
'method': 'GET',
'headers': {
'Authorization': Authorization,
'Accept': 'application/json'
}
};
const res = await requestAsync(options)
return JSON.parse(res)
}
async function requestAsync(options, payload) {
const data = new TextEncoder().encode(JSON.stringify(payload))
return new Promise((resolve, reject) => {
const post_req = https.request(options, (res) => {
res.setEncoding('utf8');
let str = ""
res.on('data', (chunk) => {
str+=chunk;
});
res.on('end', () => {
resolve(str)
})
res.on("error", (err) => {
reject(err);
});
});
if (payload) {
post_req.write(data);
}
post_req.end();
});
}