Created
February 25, 2019 12:00
-
-
Save joseluisq/66505b544bf8fca4486be86eb908779b to your computer and use it in GitHub Desktop.
Rocket Chat and Bitbucket Server webhooks integration
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
// Mock Request Data (Pull Request Comment) | |
module.exports = { | |
url: { | |
hash: null, | |
search: null, | |
query: {}, | |
pathname: '/hooks/2f7YhFx2f7YhFx2f7YhFx/hUPO&&)6@HqG_wY^B(2$MK_ivkEU1ix7MK_ivkEU1ix7', | |
path: '/hooks/2f7YhFx2f7YhFx2f7YhFx/hUPO&&)6@HqG_wY^B(2$MK_ivkEU1ix7MK_ivkEU1ix7' | |
}, | |
url_raw: '/hooks/2f7YhFx2f7YhFx2f7YhFx/hUPO&&)6@HqG_wY^B(2$MK_ivkEU1ix7MK_ivkEU1ix7', | |
url_params: { | |
integrationId: '2f7YhFx2f7YhFx2f7YhFx', | |
token: 'hUPO&&)6@HqG_wY^B(2$MK_ivkEU1ix7MK_ivkEU1ix7' | |
}, | |
content: { | |
actor: { | |
username: 'jd', | |
displayName: 'John Doe' | |
}, | |
pullrequest: { | |
id: '1', | |
title: 'ABCD-123: Create the results page', | |
link: 'https://bitbucket.mydomain.com/projects/ABCD/repos/some-project/pull-requests/1', | |
authorLogin: 'John Doe', | |
fromRef: [Object], | |
toRef: [Object] | |
}, | |
repository: { | |
scmId: 'git', | |
project: { key: "ABCD", name: "My Awesome Project" }, | |
slug: 'some-project', | |
links: { self: [ { href: "https://bitbucket.mydomain.com/projects/ABCD/repos/some-project/browse" } ] }, | |
owner: { username: "ABCD", displayName: "ABCD" }, | |
fullName: 'ABCD/some-project', | |
public: false, | |
ownerName: 'ABCD' | |
}, | |
comment: 'This is a new PR comment!' | |
}, | |
content_raw: null, | |
headers: { | |
host: 'chat.mydomain.com', | |
'user-agent': 'Apache-HttpClient/4.5.5 (Java/1.8.0_151)', | |
'content-length': '1696', | |
'accept-encoding': 'gzip,deflate', | |
'content-type': 'application/json; charset=UTF-8', | |
'x-bitbucket-type': 'server', | |
'x-event-key': 'pullrequest:comment', | |
'x-forwarded-for': '10.255.0.2', | |
'x-forwarded-host': 'chat.mydomain.com', | |
'x-forwarded-port': '443', | |
'x-forwarded-proto': 'https', | |
'x-forwarded-server': '1a2ad03db35e', | |
'x-real-ip': '10.255.0.2' | |
}, | |
body: { | |
actor: { | |
username: 'jd', | |
displayName: 'John Doe' | |
}, | |
pullrequest: { | |
id: '1', | |
title: 'ABCD-126: Create the results page', | |
link: 'https://bitbucket.mydomain.com/projects/ABCD/repos/some-project/pull-requests/1', | |
authorLogin: 'John Doe', | |
fromRef: [Object], | |
toRef: [Object] | |
}, | |
repository: { | |
scmId: 'git', | |
project: [Object], | |
slug: 'some-project', | |
links: [Object], | |
owner: [Object], | |
fullName: 'ABCD/some-project', | |
public: false, | |
ownerName: 'ABCD' | |
}, | |
comment: 'This is a new PR comment!' | |
}, | |
user: { | |
_id: 'rocket.bot', | |
name: 'Rocket.Bot', | |
username: 'rocket.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
const config = { | |
bitBucketUrl: '', | |
color: '#225159', | |
update: true | |
}; | |
const bitBucketUpdate = (request, i) => { | |
const text = 'New ' + request.content.refChanges[i].type.toLowerCase() + ' on project ' + request.content.repository.project.name; | |
const username = request.content.changesets.values[i].toCommit.author.name; | |
const usermail = request.content.changesets.values[i].toCommit.author.emailAddress; | |
const attachment = { | |
author_name: username + ' (' + usermail + ')', | |
title: 'Repository "' + request.content.repository.name + '" in project "' + request.content.repository.project.name + '" updated', | |
title_link: config['bitBucketUrl'].replace(/\/$/, '') + '/projects/' + request.content.repository.project.key + '/repos/' + request.content.repository.slug + '/browse/', | |
text: username + ' updated ' + request.content.changesets.values[i].changes.size + ((request.content.changesets.values[i].changes.size > 1) ? ' files' : ' file') + ' on branch ' + request.content.refChanges[i].refId + '` with message:\n"' + request.content.changesets.values[i].toCommit.message + '"', | |
color: ((config['color'] != '') ? '#' + config['color'].replace('#', '') : '#225159') | |
}; | |
return { | |
content: { | |
text: text, | |
attachments: [attachment] | |
} | |
}; | |
}; | |
function get_basic_info(request) { | |
const content = request.content; | |
const author = { | |
username: content.actor.username, | |
displayName: content.actor.displayName | |
}; | |
const repository = { | |
name: content.repository.fullName, | |
link: content.repository.links.self[0].href, | |
project: content.repository.project, | |
owner: content.repository.owner, | |
slug: content.repository.slug, | |
fullName: content.repository.fullName, | |
ownerName: content.repository.ownerName | |
}; | |
const pullrequest = content.pullrequest || {}; | |
const comment = content.comment || ''; | |
return { | |
author, | |
repository, | |
pullrequest, | |
comment | |
}; | |
} | |
function create_attachement(author, text, timestamp){ | |
const attachment = { | |
author_name: author.displayname, | |
author_link: author.link, | |
author_icon: author.avatar, | |
text: text, | |
ts: timestamp | |
}; | |
return attachment; | |
} | |
const processors = { | |
refChanges(request) { | |
let result = {}; | |
if(config[change.type.toLowerCase()]) { | |
switch(change.type) { | |
case 'UPDATE': | |
result = bitBucketUpdate(request, i); | |
} | |
} | |
return result | |
}, | |
pullrequest_created(request) { | |
const author = { | |
username: request.content.pullrequest.author.username, | |
displayname: request.content.pullrequest.author.display_name | |
}; | |
const pullrequest = { | |
sourcerepo: request.content.pullrequest.source.repository.name, | |
sourcebranch: request.content.pullrequest.source.branch.name, | |
destinationrepo: request.content.pullrequest.destination.repository.name, | |
destinationbranch: request.content.pullrequest.destination.branch.name, | |
id: request.content.pullrequest.id, | |
title: request.content.pullrequest.title, | |
description: request.content.pullrequest.description | |
}; | |
const links = { | |
self: request.content.pullrequest.links.self.href, | |
decline: request.content.pullrequest.links.decline.href, | |
approve: request.content.pullrequest.links.approve.href, | |
merge: request.content.pullrequest.links.merge.href, | |
commits: request.content.pullrequest.links.commits.href, | |
comments: request.content.pullrequest.links.comments.href | |
}; | |
let text = ''; | |
text += author.displayname + ' _(@' + author.username + ')_ *opened* a new pull request:\n'; | |
text += '`' + pullrequest.sourcerepo + '/' + pullrequest.sourcebranch + '` => `' + pullrequest.destinationrepo + '/' + pullrequest.destinationbranch + '`\n\n'; | |
text += 'Description:\n'; | |
text += pullrequest.description + '\n'; | |
let actions = 'Actions:'; | |
if(showLinks.decline) { | |
actions += ' | [decline](' + links.decline + ')'; | |
} | |
if(showLinks.approve) { | |
actions += ' | [approve](' + links.approve + ')'; | |
} | |
if(showLinks.merge) { | |
actions += ' | [merge](' + links.merge + ')'; | |
} | |
if(showLinks.commits) { | |
actions += ' | [view commits](' + links.commits + ')'; | |
} | |
if(showLinks.comments) { | |
actions += ' | [view comments](' + links.comments + ')'; | |
} | |
if(actions != 'Actions:') { | |
text += actions; | |
} | |
const attachment = { | |
author_name: '#' + pullrequest.id + ' - ' + pullrequest.title, | |
author_link: links.self | |
}; | |
return { | |
content: { | |
text: text, | |
attachments: [attachment], | |
parseUrls: false, | |
color: ((config.color !== '') ? '#' + config.color.replace('#', '') : '#225159') | |
} | |
}; | |
}, | |
pullrequest_comment(request) { | |
const info = get_basic_info(request); | |
const author = info.author | |
const text = info.comment; | |
const pr = info.pullrequest; | |
const repo = info.repository; | |
const attachment = { | |
author_name: author.displayName + ' (' + author.username + ')', | |
title: 'New PR comment on "' + pr.title + '" (' + repo.fullName + ')', | |
title_link: pr.link, | |
text, | |
color: ((config['color'] != '') ? '#' + config['color'].replace('#', '') : '#225159') | |
}; | |
return { | |
content: { | |
text, | |
attachments: [attachment] | |
} | |
}; | |
} | |
} | |
class Script { | |
process_incoming_request({ request }) { | |
let result = {}; | |
// debug only: output incoming request | |
console.log("REQUEST: ", request); | |
if (request.headers['x-event-key']) { | |
const key = request.headers['x-event-key'].replace(':', '_'); | |
const fn = processors[key]; | |
if (fn) { | |
result = processors[key](request); | |
} | |
} | |
if (result.content !== undefined) { | |
return result; | |
} | |
} | |
} |
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
// Note: | |
// This is not a test suite (unit test o similar) but just a conventional usage test | |
// as a previous step to perform an integration webhook into RocketChat. | |
// 1. Add module.exports to rocket_chat_bitbucket_server.webhook.js (testing purpose only) | |
const { Script } = require('./rocket_chat_bitbucket_server.webhook'); | |
// 2. Test a mocking request | |
const notice = new Script() | |
// Testing a Pull Request Comment (mocking) | |
const request = require('./request_comment.mock.js') | |
const res = notice.process_incoming_request({request}) | |
// 3. Check out if the data is returning ok | |
console.log(res.content.attachments) | |
// 4. When data is ok, then copy rocket_chat_bitbucket_server.webhook.js content into RocketChat "Incoming WebHook Integration" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment