diff --git a/.gitignore b/.gitignore index e9049bb..3b8f584 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .DS_Store* .hubot_history +/tmp diff --git a/hubot-scripts.json b/hubot-scripts.json index 0637a08..6a181e8 100644 --- a/hubot-scripts.json +++ b/hubot-scripts.json @@ -1 +1,3 @@ -[] \ No newline at end of file +[ + "hubot-kredits" +] diff --git a/package.json b/package.json index 21aeedf..c4ac3dd 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,11 @@ "hubot-shipit": "^0.2.0", "hubot-tell": "^1.2.3", "hubot-yubikey-invalidation": "0.0.3", + "node-fetch": "^1.6.3", "request": "2.30.0" }, "engines": { - "node": "0.12.x", + "node": "6.x.x", "npm": "2.1.x" } } diff --git a/run.sh b/run.sh old mode 100644 new mode 100755 index bf7f03d..c14829e --- a/run.sh +++ b/run.sh @@ -14,4 +14,5 @@ LOG_HTTP_PORT=7000 \ LOG_STEALTH="true" \ WEBHOOK_TOKEN="kosmosplusplus" \ HUBOT_YUBIKEY_API_ID="change-me" \ -bin/hubot -a irc --name hal7000 +KREDITS_WEBHOOK_TOKEN="123" \ +bin/hubot --name hal7000 diff --git a/scripts/hubot-kredts.js b/scripts/hubot-kredts.js new file mode 100644 index 0000000..da6ff44 --- /dev/null +++ b/scripts/hubot-kredts.js @@ -0,0 +1,127 @@ +// Description: +// Kosmos Kredits chat integration +// +// Configuration: +// KREDITS_WEBHOOK_TOKEN: A string for building your secret webhook URL +// KREDITS_ROOM: Kredit proposals are posted to this chatroom +// +// Authors: +// Sebastian Kippe + +const fs = require('fs'); +const fetch = require('node-fetch'); + +(function() { + "use strict"; + + module.exports = function(robot) { + + function amountFromIssueLabels(issue) { + let kreditsLabel = issue.labels.map(l => l.name) + .filter(n => n.match(/^kredits/))[0]; + // No label, no kredits + if (typeof kreditsLabel === 'undefined') { return 0; } + + // TODO move to config maybe? + let amount; + switch(kreditsLabel) { + case 'kredits-1': + amount = 50; + break; + case 'kredits-2': + amount = 150; + break; + case 'kredits-3': + amount = 500; + break; + } + + return amount; + } + + function createProposal(recipient, amount, url/*, metaData*/) { + return new Promise((resolve/*, reject*/) => { + // TODO write metaData to IPFS + console.log(`Creating proposal to issue ${amount}₭S to ${recipient} for ${url}...`); + + // robot.messageRoom(process.env.KREDITS_ROOM, message); + resolve(); + }); + } + + function handleGitHubIssueClosed(data) { + return new Promise((resolve/*, reject*/) => { + fs.writeFileSync('tmp/github-issue.json', JSON.stringify(data, null, 4)); + let recipients; + let issue = data.issue; + let assignees = issue.assignees.map(a => a.login); + let web_url = issue.html_url; + + let amount = amountFromIssueLabels(issue); + if (amount === 0) { resolve(); return; } + + if (assignees.length > 0) { + recipients = assignees; + } else { + recipients.push(issue.user.login); + } + + recipients.forEach(recipient => { + createProposal(recipient, amount, web_url, issue); + }); + + resolve(); + }); + } + + function handleGitHubPullRequestClosed(data) { + return new Promise((resolve, reject) => { + // fs.writeFileSync('tmp/github-pr.json', JSON.stringify(data, null, 4)); + let recipients; + let pull_request = data.pull_request; + let assignees = pull_request.assignees.map(a => a.login); + let web_url = pull_request._links.html.href; + let pr_issue_url = pull_request.issue_url; + + if (assignees.length > 0) { + recipients = assignees; + } else { + recipients.push(pull_request.user.login); + } + + fetch(pr_issue_url) + .then(response => { + if (response.status >= 400) { + reject('Bad response from fetching PR issue'); + } + return response.json(); + }) + .then(issue => { + // fs.writeFileSync('tmp/github-pr-issue.json', JSON.stringify(data, null, 4)); + let amount = amountFromIssueLabels(issue); + if (amount === 0) { resolve(); return(); } + + recipients.forEach(recipient => { + createProposal(recipient, amount, web_url, pull_request); + }); + + resolve(); + }); + }); + } + + robot.router.post('/incoming/kredits/github/'+process.env.KREDITS_WEBHOOK_TOKEN, (req, res) => { + let evt = req.header('X-GitHub-Event'); + let data = req.body; + console.log(`Received GitHub hook. Event: ${evt}, action: ${data.action}`); + + if (evt === 'pull_request' && data.action === 'closed') { + handleGitHubPullRequestClosed(data).then(() => res.send(200)); + } + else if (evt === 'issues' && data.action === 'closed') { + handleGitHubIssueClosed(data).then(() => res.send(200)); + } + }); + + }; +}());