Created
October 4, 2020 15:49
-
-
Save zamber/60e12bed44b71fb690c853ec0f5781bf to your computer and use it in GitHub Desktop.
BitBucket PR creation webhook -> AWS Lambda -> Slack bot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Used for a bigger team where not everyone is on Slack. A random user from the list is chosen and notified about a PR. | |
If the user is already set as a reviewer it's discarded from the random pool. | |
The lambda is the most simple configuration for requests with 128MB of RAM provisioned. | |
https://support.atlassian.com/bitbucket-cloud/docs/event-payloads/ | |
https://api.slack.com/messaging/webhooks | |
*/ | |
const https = require('https'); | |
const hook = data => new Promise((resolve, reject) => { | |
const options = { | |
host: 'hooks.slack.com', | |
path: '/services/...', // change me | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
}; | |
const req = https.request(options, res => { resolve(JSON.stringify(res.statusCode)); }); | |
req.on('error', e => { reject(e.message); }); | |
req.write(JSON.stringify(data)); | |
req.end(); | |
}); | |
const users = [ // [slack_user_id, bitbucket_user_name] | |
['UDEADBEEF', 'John Smith'], | |
]; | |
const pickReviewer = excludeUsers => { | |
const bb_users = users.map(u => u[1]); | |
const slack_users = users.map(u => u[0]); | |
excludeUsers.forEach(user => { | |
const i = bb_users.indexOf(user); | |
if (i > -1) { | |
bb_users.splice(i, 1); | |
slack_users.splice(i, 1); | |
} | |
}); | |
return slack_users[Math.floor(Math.random() * slack_users.length)]; | |
}; | |
const bb_users = users.map(u => u[1]); | |
const slack_users = users.map(u => u[0]); | |
const getUser = user => (bb_users.indexOf(user) !== -1 ? `<@${slack_users[bb_users.indexOf(user)]}>` : user); | |
const reviewersList = reviewers => { | |
if (reviewers.length === 0) return ''; | |
return ` | |
:mag_right: ${reviewers.map(getUser).join(', ')} | |
`; | |
}; | |
const formatSlackMessage = body => { | |
const pr = body.pullrequest; | |
const reviewers = pr.reviewers.map(r => r.display_name); | |
const author = body.pullrequest.author.display_name; | |
const text = `:git-pr: <${pr.links.html.href}|*${pr.title}*> | |
:writing_hand: ${pr.author.display_name}${reviewersList(reviewers)} | |
:game_die: <@${pickReviewer([...reviewers, author])}>`; | |
return { text }; | |
}; | |
exports.handler = async event => { | |
let body; | |
let statusCode = '200'; | |
const headers = { | |
'Content-Type': 'application/json', | |
'Access-Control-Allow-Origin': '*', | |
}; | |
try { | |
if (event.httpMethod === 'POST') { | |
body = await JSON.parse(event.body); | |
await hook(formatSlackMessage(body)) | |
.then(result => console.log(`Status code: ${result}`)) | |
.catch(err => console.error(`Error doing the request for the event: ${JSON.stringify(event)} => ${err}`)); | |
} | |
} catch (err) { | |
statusCode = '400'; | |
body = err.message; | |
} | |
return { | |
statusCode, | |
body, | |
headers, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment