'use strict'; var jp = require('jsonpath'); var moment = require('moment'); var numeral = require('numeral'); var request = require('request'); exports.commands = [ "price" ] exports.price = { usage: " ", description: 'displays price of lbc', process: function(bot,msg,suffix){ var ChannelID = '369896313082478594' 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: 'USD ' }, GBP: { steps: ['LBCBTC', 'BTCGBP'], format: '£0,0.00', sign: '£' }, AUD: { steps: ['LBCBTC', 'BTCAUD'], format: '$0,0.00', sign: 'AUD ' }, BRL: { steps: ['LBCBTC', 'BTCBRL'], format: 'R$0,0.00', sign: 'R$' }, CAD: { steps: ['LBCBTC', 'BTCCAD'], format: '$0,0.00', sign: 'CAD ' }, CHF: { steps: ['LBCBTC', 'BTCCHF'], format: 'CHF 0,0.00', sign: 'CHF' }, CLP: { steps: ['LBCBTC', 'BTCCLP'], format: '$0,0.00', sign: 'CLP ' }, CNY: { steps: ['LBCBTC', 'BTCCNY'], format: '¥0,0.00', sign: '¥' }, DKK: { steps: ['LBCBTC', 'BTCDKK'], format: 'kr 0,0.00', sign: 'kr' }, EUR: { steps: ['LBCBTC', 'BTCEUR'], format: '€0,0.00', sign: '€' }, HKD: { steps: ['LBCBTC', 'BTCHKD'], format: '$0,0.00', sign: 'HKD ' }, INR: { steps: ['LBCBTC', 'BTCINR'], format: '₹0,0.00', sign: '₹' }, ISK: { steps: ['LBCBTC', 'BTCISK'], format: 'kr 0,0.00', sign: 'kr' }, JPY: { steps: ['LBCBTC', 'BTCJPY'], format: '¥0,0.00', sign: '¥' }, KRW: { steps: ['LBCBTC', 'BTCKRW'], format: '₩0,0.00', sign: '₩' }, NZD: { steps: ['LBCBTC', 'BTCNZD'], format: '$0,0.00', sign: 'NZD ' }, PLN: { steps: ['LBCBTC', 'BTCPLN'], format: 'zł 0,0.00', sign: 'zł' }, RUB: { steps: ['LBCBTC', 'BTCRUB'], format: 'RUB 0,0.00', sign: 'RUB' }, SEK: { steps: ['LBCBTC', 'BTCSEK'], format: 'kr 0,0.00', sign: 'kr' }, SGD: { steps: ['LBCBTC', 'BTCSGD'], format: '$0,0.00', sign: 'SGD ' }, THB: { steps: ['LBCBTC', 'BTCTHB'], format: '฿0,0.00', sign: '฿' }, TWD: { steps: ['LBCBTC', 'BTCTWD'], format: 'NT$0,0.00', sign: 'NT$' }, IDR: { steps: ['LBCBTC', 'BTCIDR'], format: 'Rp0,0.00', sign: 'Rp' }, BTC: { steps: ['LBCBTC'], format: '0,0[.][00000000] BTC', sign: 'BTC' } }, // 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' }, BTCAUD: { url: 'https://blockchain.info/ticker', path: '$.AUD.buy' }, BTCBRL: { url: 'https://blockchain.info/ticker', path: '$.BRL.buy' }, BTCCAD: { url: 'https://blockchain.info/ticker', path: '$.CAD.buy' }, BTCCHF: { url: 'https://blockchain.info/ticker', path: '$.CHF.buy' }, BTCCLP: { url: 'https://blockchain.info/ticker', path: '$.CLP.buy' }, BTCCNY: { url: 'https://blockchain.info/ticker', path: '$.CNY.buy' }, BTCDKK: { url: 'https://blockchain.info/ticker', path: '$.DKK.buy' }, BTCEUR: { url: 'https://blockchain.info/ticker', path: '$.EUR.buy' }, BTCHKD: { url: 'https://blockchain.info/ticker', path: '$.HKD.buy' }, BTCINR: { url: 'https://blockchain.info/ticker', path: '$.INR.buy' }, BTCISK: { url: 'https://blockchain.info/ticker', path: '$.ISK.buy' }, BTCJPY: { url: 'https://blockchain.info/ticker', path: '$.JPY.buy' }, BTCKRW: { url: 'https://blockchain.info/ticker', path: '$.KRW.buy' }, BTCNZD: { url: 'https://blockchain.info/ticker', path: '$.NZD.buy' }, BTCPLN: { url: 'https://blockchain.info/ticker', path: '$.PLN.buy' }, BTCRUB: { url: 'https://blockchain.info/ticker', path: '$.RUB.buy' }, BTCSEK: { url: 'https://blockchain.info/ticker', path: '$.SEK.buy' }, BTCSGD: { url: 'https://blockchain.info/ticker', path: '$.SGD.buy' }, BTCTHB: { url: 'https://blockchain.info/ticker', path: '$.THB.buy' }, BTCTWD: { url: 'https://blockchain.info/ticker', path: '$.TWD.buy' }, BTCIDR: { url: 'https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=IDR', path: '$.IDR'} }, // 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: 100000 }; var words = suffix.trim().split(' ').filter( function(n){return n !== "";} ); var currency = (words.length > 0) ? words[0].toUpperCase() : options.defaultCurrency; var amount = (words.length > 1) ? parseFloat(words[1], 10) : 1; var showHelp = (isNaN(amount)) || (Object.keys(options.currencies).indexOf(currency) === -1); // store the last retrieved rate var cachedRates = {}; var command = "!price" var currencies = Object.keys(options.currencies); for (var i = 0; i < currencies.length; i++) { cachedRates[currencies[i]] = { rate: 0, time: null }; } if (showHelp) { doHelp(bot,msg,suffix); } else { if(!inPrivateOrBotSandbox(msg)){ msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to price bot.'); return; } doSteps(bot, currency, amount); } function doHelp(bot,msg,suffix) { if(!inPrivateOrBotSandbox(msg)){ msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to price bot.'); return; } 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 Listed Below\n' + '**' + command + ' CURRENCY AMOUNT**: show the price of AMOUNT LBC in CURRENCY\n' + '**Supported Currencies:** *usd*, *gbp*, *eur*, *aud*, *brl*, *cad*, *chf*, *clp*, *cny*, *dkk*, *hkd*, *inr*, *isk*, *jpy*, *krw*, *nzd*, *pln* ,*rub*, *sek*, *sgd*, *thb*, *twd*, *idr* and *btc* (case-insensitive)'; msg.channel.send(message); } function formatMessage(amount, rate, option) { var cur = option.sign; var value = numeral(rate.rate * amount).format(option.format); return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' ' + value + '*\n_last updated ' + rate.time.utc().format(options.dtFormat) + '_'; } function doSteps(bot, 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); msg.channel.send(message); } } if (shouldReload) { // copy the steps array var steps = []; for (var i = 0; i < option.steps.length; i++) { steps.push(option.steps[i]); } processSteps(bot, currency, 0, amount, steps, option); } } function processSteps(bot, currency, rate, amount, steps, option) { if (steps.length > 0) { var pairName = steps[0]; if (!options.api[pairName]) { msg.channel.send('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) { msg.channel.send( 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, currency, rate, amount, steps, option); return; } // final step, cache and then response var result = { rate: rate, time: moment() }; cachedRates[currency] = result; msg.channel.send(formatMessage(amount, result, option)); } else { msg.channel.send('The rate returned for the ' + pairName + ' pair was invalid.'); } }); } } function inPrivateOrBotSandbox(msg){ if((msg.channel.type == 'dm') || (msg.channel.id === ChannelID)){ return true; }else{ return false; } } } }