diff --git a/bot/github.js b/bot/github.js index 59b5a6a..0d5ccc7 100644 --- a/bot/github.js +++ b/bot/github.js @@ -5,45 +5,49 @@ const config = require('../config'); // Returns the url for getting the labels of a request (Github API v3) // req has req.issue.labels_url -const getLabelsURL = function(req) { +const getLabelsURL = function (req) { let url = req.body.issue.labels_url; // Make the URL generic removing the name of the label return url.replace('{/name}', ''); } -// Returns all labelNames of a given issue (Github API v3) -const getLabels = function(req) { - let url = getLabelsURL(req); - const options = { - hostname: 'api.github.com', - path: '/repos/jomsdev/my-github-bot/issues/6/labels', - headers: { 'User-Agent': 'kafkasl' } - }; - console.log('Url in getLabels(): [' + url + ']'); - return new Promise((resolve, reject) => { - const request = https.get(options, (response) => { - // handle http errors - if (response.statusCode < 200 || response.statusCode > 299) { - bot.error(response, 'Failed to load page, status code: ' + response.statusCode); - reject(new Error('Failed to load page, status code: ' + response.statusCode)); - } - console.log('Processing Promise'); - // temporary data holder - const body = []; - // on every content chunk, push it to the data array - response.on('data', (chunk) => body.push(chunk)); - // we are done, resolve promise with those joined chunks - response.on('end', () => { +// Returns the bounty labelNames of the request, only for testing motives +const getLabelsMock = function (req) { + return new Promise((resolve, reject) => { resolve(req.body.issue.labels) }); +} - let labels = JSON.parse(body.join('')).map(labelObj => labelObj.name); - let bountyLabel = labels.filter(name => config.bountyLabels.hasOwnProperty(name)); - console.log('Label: ' + bountyLabel); - resolve(bountyLabel); +// Returns all the bounty labelNames of a given issue (Github API v3) +const getLabels = function (req) { + if (config.debug) { + return getLabelsMock(req); + } else { + let path = getLabelsURL(req).remplace('api.github.com', ''); + const options = { + hostname: 'api.github.com', + path: path, + headers: { 'User-Agent': 'kafkasl' } + }; + return new Promise((resolve, reject) => { + const request = https.get(options, (response) => { + // handle http errors + if (response.statusCode < 200 || response.statusCode > 299) { + bot.error(response, 'Failed to load page, status code: ' + response.statusCode); + reject(new Error('Failed to load page, status code: ' + response.statusCode)); + } + // temporary data holder + const body = []; + // on every content chunk, push it to the data array + response.on('data', (chunk) => body.push(chunk)); + // we are done, resolve promise with those joined chunks + response.on('end', () => { + let labels = JSON.parse(body.join('')).map(labelObj => labelObj.name); + resolve(labels); + }); }); + // handle connection errors of the request + request.on('error', (err) => reject(err)) }); - // handle connection errors of the request - request.on('error', (err) => reject(err)) - }); + } } module.exports = { diff --git a/bot/index.js b/bot/index.js index 516907f..aba7b44 100644 --- a/bot/index.js +++ b/bot/index.js @@ -5,82 +5,109 @@ const github = require('./github'); const logger = winston.createLogger({ - level: 'info', - format: winston.format.json(), - transports: [ - new winston.transports.File({ filename: config.logPath + 'error.log', level: 'error' }), - new winston.transports.File({ filename: config.logPath + 'info.log', level: 'info'}), - new winston.transports.File({ filename: config.logPath + 'combined.log' }) - ] + level: 'info', + format: winston.format.json(), + transports: [ + new winston.transports.File({ filename: config.logPath + 'error.log', level: 'error' }), + new winston.transports.File({ filename: config.logPath + 'info.log', level: 'info' }), + ] }); -const needsFunding = function(req) { +const needsFunding = function (req) { if (req.body.action !== 'created' || !req.body.hasOwnProperty('comment')) { return false - } else if (req.body.comment.user.login !== 'status-open-bounty') { + } else if (req.body.comment.user.login !== config.githubUsername) { return false } return true } -const getAddress = function(req) { +const getAddress = function (req) { let commentBody = req.body.comment.body; - return commentBody.substring(commentBody.search("Contract address:") + 18, commentBody.search("Contract address:") + 60) + return commentBody.substring(commentBody.search("Contract address:") + 18, commentBody.search("Contract address:") + 60) } -const getLabel = function(req) { - return github.getLabels(req).then(labels => { - if (labels.length === 1) { - return labels[0]; - } else { - error(req.body, 'More than 1 label found: ['+ labels.length + ']'); - // reject(new Error('More than 1 label found: ['+ labels.length + ']')); - } - }).catch(err => { - error(req.body, 'Could not get label' + err); - // reject(new Error('Could not get label' + err)); +const getLabelMock = function (req) { + return new Promise((resolve, reject) => { + github.getLabels(req) + .then(labels => { + let bountyLabels = labels.filter(name => config.bountyLabels.hasOwnProperty(name)); + if (bountyLabels.length === 1) { + resolve(bountyLabels[0]); + } else { + reject('Error getting bounty labels: ' + bountyLabels); + } + }) + .catch((err) => { + reject(err) + }); }); } -const getAmount = function(req) { +const getLabel = function (req) { + if (config.debug) { + return getLabelMock(req); + } return new Promise((resolve, reject) => { - let labelPromise = getLabels(req); + github.getLabels(req) + .then(labels => { + let bountyLabels = labels.filter(name => config.bountyLabels.hasOwnProperty(name)); + if (bountyLabels.length === 1) { + resolve(bountyLabels[0]); + } else { + error(req.body, 'More than 1 label found: [' + labels.length + ']'); + reject(new Error('More than 1 label found: ['+ labels.length + ']')); + } + }).catch(err => { + reject(err); + }); + }); +} + +const getAmountMock = function(req) { + return new Promise((resolve, reject) => { + resolve(10); + }); + +} + +const getAmount = function (req) { + return new Promise((resolve, reject) => { + let labelPromise = getLabel(req); let tokenPricePromise = prices.getTokenPrice(config.token); Promise.all([labelPromise, tokenPricePromise]) - .then(function(values) { - let label = values[0]; - let tokenPrice = values[1]; - let amountToPayDollar = config.priceHour * config.bountyLabels[label]; - resolve(config.amountToPayDollar/tokenPrice); - }) - .catch(err => { - error(req.body, 'Failed to resolve label or token price: ' + err); - reject(new Error('Failed to resolve label or token price: ' + err)); - }); + .then(function (values) { + let label = values[0]; + let tokenPrice = values[1]; + let amountToPayDollar = config.priceHour * config.bountyLabels[label]; + resolve(amountToPayDollar / tokenPrice); + }) + .catch((err) => { + reject(err); + }); }); } // Logging functions -const logTransaction = function(txId, from, to, amount, gasPrice){ +const logTransaction = function (txId, from, to, amount, gasPrice) { logger.info("[OK] Succesfully funded bounty with transaction " + txId); logger.info(" * From: " + from); logger.info(" * To: " + to); logger.info(" * Amount: " + amount); - logger.info(" * Gas Price: " + gasPrice); + logger.info(" * Gas Price: " + gasPrice); logger.info("===================================================="); } -const log = function(msg) { +const log = function (msg) { logger.info(msg); } -const error = function(requestInfo, errorMessage) { +const error = function (errorMessage) { logger.error("[ERROR] Request processing failed: " + errorMessage); - logger.error("[ERROR] Request: " + requestInfo); } diff --git a/bot/prices.js b/bot/prices.js index 8deb5c3..66d2ce4 100644 --- a/bot/prices.js +++ b/bot/prices.js @@ -1,6 +1,8 @@ "use strict" const https = require("https"); +const config = require("../config"); + const getGasPrice = function() { const url = 'https://ethgasstation.info/json/ethgasAPI.json'; @@ -11,7 +13,7 @@ const getGasPrice = function() { const request = lib.get(url, (response) => { // handle http errors if (response.statusCode < 200 || response.statusCode > 299) { - reject(new Error('Failed to load page, status code: ' + response.statusCode)); + reject('Failed to load page, status code: ' + response.statusCode); } // temporary data holder const body = []; @@ -26,11 +28,18 @@ const getGasPrice = function() { }); }); // handle connection errors of the request - request.on('error', (err) => reject(err)) + request.on('error', (err) => reject(err)); }) }; +const getTokenPriceMock = function() { + return new Promise((resolve, reject) => resolve(0.35)); +} + const getTokenPrice = function(token) { + if (config.debug) { + return getTokenPriceMock(); + } const currency = 'USD' const url = 'https://min-api.cryptocompare.com/data/price?fsym=' + token + '&tsyms=' + currency; // return new pending promise @@ -40,7 +49,7 @@ const getTokenPrice = function(token) { const request = lib.get(url, (response) => { // handle http errors if (response.statusCode < 200 || response.statusCode > 299) { - reject(new Error('Failed to load page, status code: ' + response.statusCode)); + reject('Failed to load page, status code: ' + response.statusCode); } // temporary data holder const body = [];