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] 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.'); + } + }); + } +}