From ab2cd1891dc7a25ec55a738951426057717db494 Mon Sep 17 00:00:00 2001 From: Shaikh Farhan <98farhan94@gmail.com> Date: Mon, 7 Aug 2017 15:30:01 +0530 Subject: [PATCH 1/4] Added statbot with EUR --- .DS_Store | Bin 0 -> 6148 bytes bots/statbot.js | 250 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 .DS_Store create mode 100644 bots/statbot.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d9865a752a8e7869a45277786f9c022d1fd99682 GIT binary patch literal 6148 zcmeHK&2AGh5FWRo-SC@ANbPYiNF35CO)DaVkV2XqA^}1K!2wXa+eFF2b~nmyh#&;z z!aD$Oz@zX4JO~c}-;7PQ`QwNX@UWAAIxsVUVPy(s#ACp1ZKI>E!cH{)+Rm)r&{1)Jum+%^N(IR?zPF zMt>5=;koYlPlL|rxN!X_j#4j(I)jY)i)TU9jz_h47_}3L^T0})-o6{ZpM3Z%sglB`CUVW-Z}OWD~8hU=y#1>)!t=z^|HkV3|E!a3Sq3Zv{}lr&S8vs8 zNXeY73(4_W>!O^Xu&~`!qqv|l$FV4U6z`yj;F-$`uxfCs5j_z5M?h$>m1W?sGVlwF Cq|Utn literal 0 HcmV?d00001 diff --git a/bots/statbot.js b/bots/statbot.js new file mode 100644 index 0000000..a89b675 --- /dev/null +++ b/bots/statbot.js @@ -0,0 +1,250 @@ +var jp = require('jsonpath'); +var moment = require('moment'); +var numeral = require('numeral'); +var request = require('request'); + +var options = { + defaultCurrency: 'USD', + + // supported currencies and api steps to arrive at the final value + currencies: { + USD: { steps: ['LBCBTC', 'BTCUSD'], format: '$0,0.00', sign:'$' }, + BTC: { steps: ['LBCBTC',], format: 'BTC 0,0.00000000', sign:'BTC' }, + ETH: { steps: ['LBCETH',], format: 'ETH 0,0.00000000', sign: 'ETH' }, + GBP: { steps: ['LBCBTC', 'BTCGBP'], format: '£0,0.00', sign: '£' }, + EUR: { steps: ['LBCBTC', 'BTCGBP'], format: '€0,0.00', sign: '€' } + }, + + // api steps + api: { + LBCBTC: { url: 'https://bittrex.com/api/v1.1/public/getticker?market=BTC-LBC', path: '$.result.Bid' }, + BTCUSD: { url: 'https://blockchain.info/ticker', path: '$.USD.buy' }, + BTCGBP: { url: 'https://blockchain.info/ticker', path: '$.GBP.buy' }, + LBCETH: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eth', path: '$[0].price_eth' } + LBCEUR: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eur', path: '$[0].price_eur' } + }, + + // display date/time format + dtFormat: 'Do MMM YYYY h:mma [UTC]', + + // refresh rate in milliseconds to retrieve a new price (default to 10 minutes) + refreshTime: 600000 +}; + +// store the last retrieved rate +var cachedRates = {}; + +var mktChannel; + +// !price {currency} +// !price {currency} {amount} +var command = '!stats'; + +module.exports={ + command: command, + init: init, + respond: respond +}; + +function init(channel_) { + mktChannel = channel_; + if (!channel_) { + console.log('No market and trading channel. Statbot will only respond to DMs.'); + } + + var currencies = Object.keys(options.currencies); + for (var i = 0; i < currencies.length; i++) { + cachedRates[currencies[i]] = { rate: 0, time: null }; + } +} + +var globalSlackParams = {}; + +function respond(bot, data) { + var channel = data.channel, + words = data.text.trim().split(' ').filter( function(n){return n !== "";} ); + + if (words[0] !== command || (channel != mktChannel && !channel.startsWith('D'))) { + // if the received message isn't starting with the trigger, + // or the channel is not the market-and-trading channel, nor sandbox, nor a DM -> ignore + return; + } + + var currency = /*(words.length > 1) ? words[2].toUpperCase() :*/ options.defaultCurrency; + var amount = /*(words.length > 2) ? parseFloat(words[2], 10) :*/ 1; + var showHelp = (isNaN(amount)) || (Object.keys(options.currencies).indexOf(currency) === -1); + + var moveToBotSandbox = showHelp && channel !== mktChannel && !channel.startsWith("D"); + if (moveToBotSandbox) { + bot.postMessage(channel, 'Please use PM to talk to bot.', globalSlackParams); + return; + } + + if (showHelp) { + doHelp(bot, channel); + } else { + + doSteps(bot, channel, 'ETH', amount); + doSteps(bot, channel, 'USD', amount); + doSteps(bot, channel, 'BTC', amount); + setTimeout(function() { marketstats(bot,channel); }, 250); + //marketstats(bot,channel); + //volume24(bot,channel); can't get this part to work, someone help me fix - i think it's because 24h_volume_usd starts with number + } +} + +function doHelp(bot, channel) { + var message = + '`' + command + '`: show the price of 1 LBC in ' + options.defaultCurrency + '\n' + + '`' + command + ' help`: this message\n' + + '`' + command + ' CURRENCY`: show the price of 1 LBC in CURRENCY. Supported values for CURRENCY are *btc* and *usd* (case-insensitive)\n' + + '`' + command + ' CURRENCY AMOUNT`: show the price of AMOUNT LBC in CURRENCY\n'; + + if (!channel.startsWith("D")) { + message = + '*USE PM FOR HELP*\n' + + message + + '\n' + + '*Everyone will see what I say. Send me a Direct Message if you want to interact privately.*\n' + + 'If I\'m not responding in some channel, you can invite me by @mentioning me.\n'; + } + + bot.postMessage(channel, message, globalSlackParams); +} + +function formatMessage(amount, rate, option) { + var cur = option.sign; + var value = numeral(rate.rate * amount).format('0,0[.][00000000]'); + if (option.sign == '$' || option.sign == '£' || option.sign == '€'){ + return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' '+ value + '*'; + } + else { + return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + value + ' ' + cur + '*'; + } +} + +function formaty(n, decimals, currency) { + n = parseFloat(n); + return currency + " " + n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,"); +} + +function doSteps(bot, channel, currency, amount) { + + var option = options.currencies[currency]; + var shouldReload = true; + if (cachedRates[currency]) { + var cache = cachedRates[currency]; + shouldReload = cache.time === null || moment().diff(cache.time) >= options.refreshTime; + if (!shouldReload) { + var message = formatMessage(amount, cache, option); + bot.postMessage(channel, message, {icon_emoji: ':lbr:'}); + } + } + + if (shouldReload) { + // copy the steps array + var steps = []; + for (var i = 0; i < option.steps.length; i++) { + steps.push(option.steps[i]); + } + + processSteps(bot, channel, currency, 0, amount, steps, option); + } +} + +function marketstats(bot,channel) { + var statsurl='https://api.coinmarketcap.com/v1/ticker/library-credit/'; + + request.get(statsurl, function(error, response, body) { + if (error) { + bot.postMessage(channel, err.message ? err.message : 'The request could not be completed at this time. Please try again later.'); + return; + } + var marketcap = 0; + try { + marketcap = jp.query(JSON.parse(body), '$[0].market_cap_usd'); + if (Array.isArray(marketcap) && marketcap.length > 0) { + marketcap = marketcap[0]; + marketcap = formaty(marketcap,2,'$') + } + + } catch (ignored) { + // invalid response or pair rate + } + + var statmsg = '*'+'Marketcap: '+marketcap+'*\n'; + + bot.postMessage(channel, statmsg, {icon_emoji: ':lbr:'}); + + }); +} + +function volume24(bot,channel) { + var statsurl='https://api.coinmarketcap.com/v1/ticker/library-credit/'; + + request.get(statsurl, function(error, response, body) { + if (error) { + bot.postMessage(channel, err.message ? err.message : 'The request could not be completed at this time. Please try again later.'); + return; + } + var volume24 = 0; + try { + volume24 = jp.query(JSON.parse(body),'$[0].24h_volume_usd'); + if (Array.isArray(volume24) && volume24.length > 0) { + volume24 = volume24[0]; + } + + } catch (ignored) { + // invalid response or pair rate + } + + var statmsg = '*'+'Volume: $'+volume24+'*\n'; + + bot.postMessage(channel, statmsg, {icon_emoji: ':lbr:'}); + + }); +} + +function processSteps(bot, channel, currency, rate, amount, steps, option) { + if (steps.length > 0) { + var pairName = steps[0]; + if (!options.api[pairName]) { + bot.postMessage(channel, 'There was a configuration error. ' + pairName + ' pair was not found.'); + return; + } + + var pair = options.api[pairName]; + request.get(pair.url, function(error, response, body) { + if (error) { + bot.postMessage(channel, err.message ? err.message : 'The request could not be completed at this time. Please try again later.'); + return; + } + var pairRate = 0; + try { + pairRate = jp.query(JSON.parse(body), pair.path); + if (Array.isArray(pairRate) && pairRate.length > 0) { + pairRate = pairRate[0]; + } + } catch (ignored) { + // invalid response or pair rate + } + + if (pairRate > 0) { + rate = (rate === 0) ? pairRate : rate * pairRate; + steps.shift(); + if (steps.length > 0) { + processSteps(bot, channel, currency, rate, amount, steps, option); + return; + } + + // final step, cache and then response + var result = { rate: rate, time: moment() }; + cachedRates[currency] = result; + + bot.postMessage(channel, formatMessage(amount, result, option), {icon_emoji: ':bulb:'}); + } else { + bot.postMessage(channel, 'The rate returned for the ' + pairName + ' pair was invalid.'); + } + }); + } +} From 529b0181c6144debb6cc67e663e3ef14cd221d90 Mon Sep 17 00:00:00 2001 From: Shaikh Farhan <98farhan94@gmail.com> Date: Mon, 7 Aug 2017 15:53:04 +0530 Subject: [PATCH 2/4] typo fix --- app.js | 10 +++++++++- bots/statbot.js | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app.js b/app.js index 8eb1832..72991dd 100644 --- a/app.js +++ b/app.js @@ -26,11 +26,14 @@ function sendWelcomeMessage(user) { var hashbot = require('./bots/hashbot'); hashbot.init(slackbot, process.env.MINING_CHANNEL); +var statbot = require('./bots/statbot'); +statbot.init(process.env.MARKET_TRADING_CHANNEL); + var claimbot = require('./bots/claimbot'); claimbot.init(slackbot, process.env.CLAIMS_CHANNEL, process.env.RPCUSER, process.env.RPCPASSWORD, process.env.MONGODB_URL); var pricebot = require('./bots/pricebot'); -pricebot.init(process.env.MARKET_TRADING_CHANNEL); +pricebot.init(); //price bot only in PM var modbot = require('./bots/modbot'); modbot.init(process.env.MONGODB_URL, process.env.SLACK_TOKEN, slackbot); @@ -50,6 +53,8 @@ slackbot.on('start', function() { var helpMsg = "I'm Wunderbot, LBRY's slackbot. Here's what I can do:\n" + '`!help` shows this message\n' + '`!tip` sends LBC tips to others, and withdraws and deposits credits into the your tipping wallet *(now handled by <@tipbot>)*\n' + + '`!stats` shows market stats in trading channel\n' + + '`!price` works only in PM now\n' + '`!hash` reports on the LBRY blockchain\n' + '_type any of the above commands for more info_\n' + '\n' + @@ -72,6 +77,9 @@ slackbot.on('start', function() { if (command === pricebot.command) { pricebot.respond(slackbot, data); } + if (command === statbot.command) { + statbot.respond(slackbot, data); + } } }); }); diff --git a/bots/statbot.js b/bots/statbot.js index a89b675..ce410ed 100644 --- a/bots/statbot.js +++ b/bots/statbot.js @@ -20,7 +20,7 @@ var options = { LBCBTC: { url: 'https://bittrex.com/api/v1.1/public/getticker?market=BTC-LBC', path: '$.result.Bid' }, BTCUSD: { url: 'https://blockchain.info/ticker', path: '$.USD.buy' }, BTCGBP: { url: 'https://blockchain.info/ticker', path: '$.GBP.buy' }, - LBCETH: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eth', path: '$[0].price_eth' } + LBCETH: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eth', path: '$[0].price_eth' }, LBCEUR: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eur', path: '$[0].price_eur' } }, From b587037da6fe673745bbd608552cf7380c69c39c Mon Sep 17 00:00:00 2001 From: Shaikh Farhan <98farhan94@gmail.com> Date: Mon, 7 Aug 2017 16:18:20 +0530 Subject: [PATCH 3/4] Statbot fixes --- bots/statbot.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/bots/statbot.js b/bots/statbot.js index ce410ed..a493d50 100644 --- a/bots/statbot.js +++ b/bots/statbot.js @@ -9,10 +9,10 @@ var options = { // supported currencies and api steps to arrive at the final value currencies: { USD: { steps: ['LBCBTC', 'BTCUSD'], format: '$0,0.00', sign:'$' }, - BTC: { steps: ['LBCBTC',], format: 'BTC 0,0.00000000', sign:'BTC' }, - ETH: { steps: ['LBCETH',], format: 'ETH 0,0.00000000', sign: 'ETH' }, + BTC: { steps: ['LBCBTC'], format: 'BTC 0,0.00000000', sign:'BTC' }, + ETH: { steps: ['LBCETH'], format: 'ETH 0,0.00000000', sign: 'ETH' }, GBP: { steps: ['LBCBTC', 'BTCGBP'], format: '£0,0.00', sign: '£' }, - EUR: { steps: ['LBCBTC', 'BTCGBP'], format: '€0,0.00', sign: '€' } + EUR: { steps: ['LBCEUR'], format: '€0,0.00', sign: '€' } }, // api steps @@ -84,8 +84,10 @@ function respond(bot, data) { doHelp(bot, channel); } else { - doSteps(bot, channel, 'ETH', amount); doSteps(bot, channel, 'USD', amount); + doSteps(bot, channel, 'EUR', amount); + doSteps(bot, channel, 'GBP', amount); + doSteps(bot, channel, 'ETH', amount); doSteps(bot, channel, 'BTC', amount); setTimeout(function() { marketstats(bot,channel); }, 250); //marketstats(bot,channel); @@ -114,12 +116,12 @@ function doHelp(bot, channel) { function formatMessage(amount, rate, option) { var cur = option.sign; - var value = numeral(rate.rate * amount).format('0,0[.][00000000]'); + var value = rate.rate * amount; if (option.sign == '$' || option.sign == '£' || option.sign == '€'){ - return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' '+ value + '*'; + return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' '+ value.toFixed(2) + '*'; } else { - return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + value + ' ' + cur + '*'; + return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + numeral(value).format('0,0[.][00000000]') + ' ' + cur + '*'; } } From f86cc10db87132b8350838ad998fceabe706022a Mon Sep 17 00:00:00 2001 From: Shaikh Farhan <98farhan94@gmail.com> Date: Mon, 7 Aug 2017 16:25:10 +0530 Subject: [PATCH 4/4] Update in 5 minutes --- bots/statbot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bots/statbot.js b/bots/statbot.js index a493d50..262a47e 100644 --- a/bots/statbot.js +++ b/bots/statbot.js @@ -28,7 +28,7 @@ var options = { dtFormat: 'Do MMM YYYY h:mma [UTC]', // refresh rate in milliseconds to retrieve a new price (default to 10 minutes) - refreshTime: 600000 + refreshTime: 300000 }; // store the last retrieved rate