Removed Slackbot, moved to old_slack, master will contain discord ver.

This commit is contained in:
Fillerino 2017-10-25 19:51:26 +02:00
parent 36f5e18324
commit 94f305cfd2
17 changed files with 0 additions and 1933 deletions

BIN
.DS_Store vendored

Binary file not shown.

2
.gitignore vendored
View file

@ -1,2 +0,0 @@
node_modules
.idea/

15
LICENSE
View file

@ -1,15 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015-2016 LBRY Inc
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -1,24 +0,0 @@
# Bot for [LBRY's Slack](https://slack.lbry.io)
Features:
- Tipbot for LBC. Responds to `!tip`.
- Posts mining info to #mining every few hours and anytime someone says `!hash`.
## Requirements
- node
- npm > 0.12.x
## Installation
Create a bot and get the bot's API Token: https://YOURSLACK.slack.com/apps/manage/custom-integrations
Then run:
```
npm install
SLACK_TOKEN=<your-slack-token> CHANNEL=<channel-for-bot> node bot.js
```

85
app.js
View file

@ -1,85 +0,0 @@
var SlackBot = require('slackbots');
var request = require('request');
var fs = require('fs');
var path = require('path');
['SLACK_TOKEN', 'RPCUSER', 'RPCPASSWORD', 'MONGODB_URL'].forEach(function (envVar) {
if (!process.env[envVar]) {
throw new Error(envVar + ' env var required');
}
});
var slackbot = new SlackBot({
token: process.env.SLACK_TOKEN,
name: 'wunderbot'
});
function sendWelcomeMessage(user) {
fs.readFile(path.join(path.dirname(require.main.filename), 'slack-greeting.md'), {encoding: 'utf-8'}, function (error, data) {
if (!error) {
slackbot.postMessage(user, data);
}
});
};
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(); //price bot only in PM
var modbot = require('./bots/modbot');
modbot.init(process.env.MONGODB_URL, process.env.SLACK_TOKEN, slackbot);
slackbot.on('start', function() {
slackbot.on('message', function(data) {
modbot.check(slackbot,data);
if (data.type == 'team_join') {
setTimeout(function() { sendWelcomeMessage(data.user.id); }, 2000); //Delay because of slow slack api updates which sometimes does not send msg.
}
if (data.text) {
// gifbot.handle_msg(data.text, data.channel);
var command = data.text.trim().split(' ')[0];
if (command === '!help') {
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' +
'I also update <#C266N3RMM|content> anytime new content is published on LBRY\n' +
'\n' +
'My code is at https://github.com/lbryio/lbry-wunderbot. I love learning new tricks.\n';
slackbot.postMessage(data.channel, helpMsg, {icon_emoji: ':bulb:'});
}
if (command === hashbot.command) {
hashbot.respond(slackbot, data);
}
if (command === '!tip' && data.channel.startsWith("D")) {
var tipMsg = 'Sorry, tipping is now handled by <@tipbot>\n';
slackbot.postMessage(data.channel, tipMsg, {icon_emoji: ':bulb:'});
}
if (command === pricebot.command) {
pricebot.respond(slackbot, data);
}
if (command === statbot.command) {
statbot.respond(slackbot, data);
}
}
});
});

View file

@ -1,318 +0,0 @@
'use strict';
var lbry;
var mongo;
var slackbot;
var channel;
var moment = require('moment');
var request = require('request');
var sleep = require('sleep');
module.exports = {
init: init,
};
function init(slackbot_, channel_, rpcuser, rpcpassword, mongodburl) {
if (lbry) {
throw new Error('init was already called once');
}
slackbot = slackbot_;
channel = channel_;
if (!channel_) {
console.log('No claims channel, disabling claimbot');
return;
}
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect(mongodburl, function (err, db) {
if (err) {
throw err;
}
mongo = db;
const bitcoin = require('bitcoin');
lbry = new bitcoin.Client({
host: 'localhost',
'port': 9245,
'user': rpcuser,
'pass': rpcpassword
});
console.log('Activating claimbot');
setInterval(function () {
announceNewClaims();
}, 60 * 1000);
announceNewClaims();
});
}
function announceNewClaims() {
if (!mongo) {
slackPost('Failed to connect to mongo', { icon_emoji: ':exclamation:' });
return;
}
if (!lbry) {
slackPost('Failed to connect to lbrycrd', { icon_emoji: ':exclamation:' });
return;
}
Promise.all([getLastBlock(), lbryCall('getinfo')])
.then(function ([lastProcessedBlock, currentBlockInfo]) {
const currentHeight = currentBlockInfo['blocks'];
// console.log('Checking for new blocks');
if (lastProcessedBlock === null) {
console.log('First run. Setting last processed block to ' + currentHeight + ' and exiting.');
return setLastBlock(currentHeight);
}
const testBlock = false;
if (testBlock || lastProcessedBlock < currentHeight) {
const firstBlockToProcess = testBlock || lastProcessedBlock + 1,
lastBlockToProcess = testBlock || currentHeight;
// console.log('Doing blocks ' + firstBlockToProcess + ' to ' + lastBlockToProcess);
return announceClaimsLoop(firstBlockToProcess, lastBlockToProcess, currentHeight);
}
})
.catch(function (err) {
slackPost(err.stack, { icon_emoji: ':exclamation:' });
});
}
function announceClaimsLoop(block, lastBlock, currentHeight) {
// console.log('Doing block ' + block)
let claimsFound = 0;
return lbryCall('getblockhash', block)
.then(function (blockHash) {
return lbryCall('getblock', blockHash);
})
.then(function (blockData) {
return Promise.all(blockData['tx'].map(getClaimsForTxid))
})
.then(function (arrayOfClaimArrays) {
const claims = Array.prototype.concat(...arrayOfClaimArrays).filter(function (c) {
return !!c;
});
console.log('Found ' + claims.length + ' claims in ' + block);
claimsFound = claims.length;
return Promise.all(claims.map(function (claim) {
//slack has a rate limit. to avoid hitting it we must have a small delay between each message
//if claims were found in this block, then we wait, otherwise we don't
if (claimsFound > 0)
sleep.msleep(300);
return announceClaim(claim, block, currentHeight);
}));
})
.then(function () {
return setLastBlock(block);
})
.then(function () {
const nextBlock = block + 1;
if (nextBlock <= lastBlock) {
return announceClaimsLoop(nextBlock, lastBlock, currentHeight);
}
});
}
function announceClaim(claim, claimBlockHeight, currentHeight) {
//console.log(claim);
console.log('' + claimBlockHeight + ': New claim for ' + claim['name']);
var options = {
method: 'GET',
url: 'https://explorer.lbry.io/api/getclaimbyid/' + claim['claimId']
//url: 'http://127.0.0.1:5000/claim_decode/' + claim['name']
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
try {
console.log(body);
let claimData = null;
let channelName = null;
try {
body = JSON.parse(body);
if (body.hasOwnProperty('value') && body.value.hasOwnProperty('stream') && body.value.stream.hasOwnProperty('metadata')) {
claimData = body.value.stream.metadata;
channelName = (body.hasOwnProperty('channel_name') ? body['channel_name'] : null);
}
}
catch (e) {
console.error(e);
}
return Promise.all([
lbryCall('getvalueforname', claim['name']),
lbryCall('getclaimsforname', claim['name']),
])
.then(function ([currentWinningClaim, claimsForName]) {
//console.log(JSON.stringify(claimData));
let value = null;
if (claimData !== null)
value = claimData;
else {
try {
value = JSON.parse(claim['value']);
} catch (e) { }
}
const text = [];
if (value) {
/*if (channelName) {
text.push("Channel: lbry://" + channelName);
}
else*/
if (value['author']) {
text.push("author: " + value['author']);
}
if (value['description']) {
text.push(value['description']);
}
// if (value['content_type'])
// {
// text.push("*Content Type:* " + value['content_type']);
// }
if (value['nsfw']) {
text.push("*Warning: Adult Content*");
}
//"fee":{"currency":"LBC","amount":186,"version":"_0_0_1","address":"bTGoFCakvQXvBrJg1b7FJzombFUu6iRJsk"}
if (value['fee']) {
const fees = [];
text.push("Price: " + value['fee'].amount + " *" + value['fee'].currency + '*');
/*for (var key in value['fee']) {
fees.push(value['fee'][key]['amount'] + ' ' + key);
}
text.push(fees.join(', '));*/
}
}
if (!claim['is controlling']) {
// the following is based on https://lbry.io/faq/claimtrie-implementation
const lastTakeoverHeight = claimsForName['nLastTakeoverHeight'],
maxDelay = 4032, // 7 days of blocks at 2.5min per block
activationDelay = Math.min(maxDelay, Math.floor((claimBlockHeight - lastTakeoverHeight) / 32)),
takeoverHeight = claimBlockHeight + activationDelay,
secondsPerBlock = 161, // in theory this should be 150, but in practice its closer to 161
takeoverTime = Date.now() + ((takeoverHeight - currentHeight) * secondsPerBlock * 1000);
text.push('Takes effect on approx. *' + moment(takeoverTime, 'x').format('MMMM Do [at] HH:mm [UTC]') + '* (block ' + takeoverHeight + ')');
}
const attachment = {
"fallback": "New claim for lbry://" + claim['name'],
"color": "#155b4a",
// "pretext": "New claim in block " + claimBlockHeight,
// "author_name": 'lbry://' + claim['name'],
// "author_link": 'lbry://' + claim['name'],
// "author_icon": "http://flickr.com/icons/bobby.jpg",
"title": "lbry://" + (channelName ? channelName + '/' : '') + claim['name'], //escapeSlackHtml(value['title']),
"title_link": "lbry://" + (channelName ? channelName + '/' : '') + claim['name'],
"text": escapeSlackHtml(text.join("\n")),
// "fields": [],
// "image_url": value['nsfw'] ? null : value['thumbnail'],
// "thumb_url": (!value || value['nsfw']) ? null : value['thumbnail'],
"unfurl_links": false,
"unfurl_media": false,
"link_names": false,
"parse": "none",
"footer": "Block " + claimBlockHeight + " • Claim ID " + claim['claimId'],
"mrkdwn_in": ['text'],
};
if (value) {
attachment['fallback'] += (': "' + value['title'] + '" by ' + value['author']);
attachment['author_name'] = 'lbry://' + (channelName ? channelName + '/' : '') + claim['name'];
attachment['author_link'] = 'lbry://' + (channelName ? channelName + '/' : '') + claim['name'];
attachment['title'] = escapeSlackHtml(value['title']);
if (!value['nsfw']) {
attachment['thumb_url'] = value['thumbnail'];
}
}
slackPost('', { icon_emoji: ':bellhop_bell:', attachments: [attachment] });
});
}
catch (e) {
console.error(e);
}
});
}
function escapeSlackHtml(txt) {
return txt.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;');
}
function getClaimsForTxid(txid) {
return lbryCall('getclaimsfortx', txid)
.catch(function (err) {
// an error here most likely means the transaction is spent,
// which also means there are no claims worth looking at
return [];
});
}
function getLastBlock() {
return new Promise(function (resolve, reject) {
mongo.collection('claimbot').findOne({}, function (err, obj) {
if (err) {
reject(err);
}
else if (!obj) {
mongo.collection('claimbot').createIndex({ 'last_block': 1 }, { unique: true });
resolve(null);
}
else {
resolve(obj.last_block);
}
});
});
}
function setLastBlock(block) {
return new Promise(function (resolve, reject) {
mongo.collection('claimbot').findOneAndUpdate(
{ 'last_block': { '$exists': true } },
{ 'last_block': block },
{ 'upsert': true, 'returnOriginal': false },
function (err, obj) {
if (!err && obj && obj.value.last_block != block) {
reject('Last value should be ' + block + ', but it is ' + obj.value.last_block);
}
else {
resolve();
}
}
);
});
}
function slackPost(text, params) {
slackbot.postMessage(channel, text, params).fail(function (value) {
console.log('FAILED TO SLACK to ' + channel + '. Text: "' + text + '". Params: ' + JSON.stringify(params) + "\nResponse: " + JSON.stringify(value));
});
}
function lbryCall(...args) {
return new Promise(function (resolve, reject) {
lbry.cmd(...args, function (err, ...response) {
if (err) {
reject(new Error('JSONRPC call failed. Args: [' + args.join(', ') + ']'));
}
else {
resolve(...response);
}
});
});
}

View file

@ -1,186 +0,0 @@
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
var path = require('path');
var fs = require('fs');
var slackbot;
var imgur;
var cache = {};
var cache_timeout = 3600; // 1h
var output_dir = path.resolve(path.dirname(require.main.filename), 'files');
//function will check if a directory exists, and create it if it doesn't
function checkDirectory(directory, callback) {
fs.stat(directory, function(err, stats) {
//Check if error defined and the error code is "not exists"
if (err && err.errno === 34) {
//Create the directory, call the callback.
fs.mkdir(directory, callback);
} else {
//just in case there was a different error:
callback(err)
}
});
}
module.exports = {
init: init,
handle_msg: handle_msg
};
function init(_slackbot, imgur_client_id)
{
if (!imgur_client_id)
{
console.log('No imgur client id, disabling gifbot');
return;
}
slackbot = _slackbot;
imgur = require('imgur');
imgur.setClientId(imgur_client_id);
}
function jsonrpc_call(method, params, callback) {
var xhr = new XMLHttpRequest;
xhr.addEventListener('load', function() {
var response = JSON.parse(xhr.responseText);
callback(response);
});
xhr.addEventListener('error', function (e) {
callback({error: e})
});
xhr.open('POST', 'http://localhost:5279/lbryapi', true);
payload = {
'jsonrpc': '2.0',
'method': method,
'params': [params],
'id': 0
};
console.log('JSONRPC', payload);
xhr.send(JSON.stringify(payload));
}
function handle_msg(msg, channel)
{
if (!imgur)
{
return;
}
var words = msg.trim().split(' ');
words.forEach(function(word)
{
if (word.lastIndexOf('<lbry://', 0) === 0)
{
word = word.slice(8, -1); // strip <lbry:// and >
handle_url(word, channel);
}
});
}
function check_url(url, callback)
{
jsonrpc_call('resolve_name', {'name': url}, function(response)
{
if (response.error)
{
callback(response.error);
return;
}
var resolved = response.result;
if (!resolved)
{
callback(false);
return;
}
if (resolved.fee)
{
callback(false);
return;
}
var meta_version = resolved.ver ? resolved.ver : '0.0.1';
var field_name = (meta_version == '0.0.1' || meta_version == '0.0.2') ? 'content-type' : 'content_type';
var content_type = resolved[field_name];
callback(content_type == 'image/gif');
});
}
function handle_url(url, channel)
{
console.log('Detected URL', url, 'on channel', channel);
if (!cache[channel])
{
cache[channel] = {};
}
var now = new Date().getTime() / 1000;
if (cache[channel][url])
{
var elapsed = now - cache[channel][url];
if (elapsed < cache_timeout)
{
console.log(url, 'is cached for this channel, ignoring...')
return;
}
}
check_url(url, function(valid)
{
if (valid)
{
console.log('Fetching', url);
fetch_url(url, channel);
}
else
{
console.log('Ignoring', url);
}
});
}
function fetch_url(url, channel)
{
checkDirectory(output_dir, function(error)
{
if(error) {
console.error("Could not create output directory", error);
slackbot.postMessage(channel, 'Unable to fetch URL [' + url + ']. Output directory missing.');
} else {
jsonrpc_call('get', {'name': url, 'download_directory': output_dir}, function(response)
{
var result = response.result;
if (!result)
{
console.warn('Failed to fetch', url);
console.warn(response);
slackbot.postMessage(channel, 'Unable to fetch URL [' + url + ']. Insufficient funds?');
return;
}
var filename = result.path;
console.log('Uploading', filename);
imgur.uploadFile(filename).then(function(uploaded)
{
var link = uploaded.data.link;
console.log(link);
var attachments = [{image_url: link, title: url}];
slackbot.postMessage(channel, null, {attachments: attachments})
cache[channel][url] = new Date().getTime() / 1000;
}).catch(function(err)
{
console.error(err.message);
});
});
}
});
}

View file

@ -1,65 +0,0 @@
var needle = require('needle');
var command = '!hash';
module.exports={
command: command,
init: init,
respond: respond
};
function init(slackbot, channel) {
if (channel) {
setInterval(function() {
sendMiningInfo(slackbot, channel);
}, 6 * 60 * 60 * 1000);
// sendMiningInfo(slackbot, channel);
}
}
function respond(slackbot, data) {
var words = data.text.trim().split(' ');
if (words[0] !== command) {
// wtf?
return;
}
if (words.length > 1) {
// e.g. "!hash and some other words"
return;
}
sendMiningInfo(slackbot, data.channel);
}
function sendMiningInfo(slackbot, channel) {
needle.get('https://explorer.lbry.io/api/v1/status', function(error, response) {
if (error || response.statusCode !== 200) {
slackbot.postMessage(channel, 'Explorer API is not available');
}
else {
var data, hashrate = "", difficulty = "", height = "";
data = response.body;
height += data.status.height;
hashrate += data.status.hashrate;
difficulty += data.status.difficulty;
slackbot.postMessage(channel,
// 'Blockchain stats:\n' +
'Hashrate: ' + hashrate + '\n' +
'Difficulty: ' + difficulty + '\n' +
'Current block: ' + height + '\n' +
'_Source: https://explorer.lbry.io_'
, {icon_emoji: ':miner:'});
}
});
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

View file

@ -1,104 +0,0 @@
var needle = require('needle');
var slackbot;
var mongo;
var command = '!m';
var apitoken;
module.exports={
command: command,
init: init,
check: check
};
var globalSlackParams = {
icon_emoji: ':lbr:'
};
function init(mongodburl,apitoken_, slackbot) {
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect(mongodburl, function (err, db) {
if (err) {
throw err;
}
mongo = db;
});
apitoken = apitoken_
slackbot.getChannels()
.then( data => {
data.channels.forEach(function(ch) {
mongo.collection('m_topic').findOneAndUpdate(
{ 'channel': ch.id },
{ 'channel': ch.id, 'topic': ch.topic.value },
{ 'upsert': true, 'returnOriginal': false },
function (err, obj) {
if(err){
console.log(err);
}
});
}, this);
}, err => {
console.log(err);
})
console.log('Loaded moderationbot!');
}
function check(slackbot, data) {
if(data.text){
if (data.text.trim().split(' ')[0] === command) {
//Add commands here later aswell!
}
}
if(data.topic){ // Gets called on topic change in a channel
slackbot.getUser(data.user_profile.name)
.then( usr => {
if(usr.is_admin){
mongo.collection('m_topic').findOneAndUpdate(
{ 'channel': data.channel },
{ 'channel': data.channel, 'topic': data.topic },
{ 'upsert': true, 'returnOriginal': false },
function (err, obj) {
if(err){
console.log(err);
}
});
}else if(!usr.is_bot){
mongo.collection('m_topic').findOne({'channel': data.channel}, function(err, document) {
slackbot.postMessage(data.user,`Hey <@${data.user_profile.name}>, you are not allowed to change the topic in <#${data.channel}>!`, globalSlackParams);
if(process.env.CHANNEL_LOG){
slackbot.postMessage(process.env.CHANNEL_LOG,`User <@${data.user_profile.name}> tried to change the topic in <#${data.channel}> to: \`\`\`${data.topic}!\`\`\``, globalSlackParams);
}
needle.get(`https://slack.com/api/channels.setTopic?token=${apitoken}&channel=${data.channel}&topic=${document.topic}`);
});
}
}, err => {
console.log(err);
})
}
if(data.type == 'pin_added'){ // Gets called on a user pin
needle.get(`https://slack.com/api/users.info?token=${apitoken}&user=${data.user}`, function(err, resp) {
if(!resp.body.user.is_admin){
needle.get(`https://slack.com/api/pins.remove?token=${apitoken}&channel=${data.item.channel}&timestamp=${data.item.message.ts}`);
slackbot.postMessage(data.user,`Hey <@${resp.body.user.name}>, you are not allowed to add pins in <#${data.channel_id}>!`, globalSlackParams);
if(process.env.CHANNEL_LOG){
slackbot.postMessage(process.env.CHANNEL_LOG,`User <@${resp.body.user.name}> tried to pin a message in <#${data.channel_id}>!`, globalSlackParams);
}
}
});
}
if(data.channel == process.env.CHANNEL_OA && data.type == 'message'){ //If user is trying to post in a admin only channel..
needle.get(`https://slack.com/api/users.info?token=${apitoken}&user=${data.user}`, function(err, resp) {
if(!resp.body.user.is_admin){
console.log(`https://slack.com/api/chat.delete?token=${apitoken}&ts=${data.ts}&channel=${data.channel}`);
needle.get(`https://slack.com/api/chat.delete?token=${apitoken}&ts=${data.ts}&channel=${data.channel}`);
if(data.subtype !=='channel_join' && data.subtype !=='channel_leave') {
slackbot.postMessage(data.user,`Hey <@${resp.body.user.name}>, you are not allowed to post messages in <#${data.channel}>!`, globalSlackParams);
if(data.subtype !=='channel_join' && data.subtype !=='channel_leave' && process.env.CHANNEL_LOG){
slackbot.postMessage(process.env.CHANNEL_LOG,`User <@${resp.body.user.name}> tried to post a message in <#${data.channel}>!`, globalSlackParams);
}
}
}
});
}
}

View file

@ -1,216 +0,0 @@
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' },
GBP: { steps: ['LBCBTC', 'BTCGBP'], format: '£0,0.00' },
AUD: { steps: ['LBCBTC', 'BTCAUD'], format: '$0,0.00' },
BRL: { steps: ['LBCBTC', 'BTCBRL'], format: 'R$0,0.00' },
CAD: { steps: ['LBCBTC', 'BTCCAD'], format: '$0,0.00' },
CHF: { steps: ['LBCBTC', 'BTCCHF'], format: 'CHF 0,0.00' },
CLP: { steps: ['LBCBTC', 'BTCCLP'], format: '$0,0.00' },
CNY: { steps: ['LBCBTC', 'BTCCNY'], format: '¥0,0.00' },
DKK: { steps: ['LBCBTC', 'BTCDKK'], format: 'kr 0,0.00' },
EUR: { steps: ['LBCBTC', 'BTCEUR'], format: '€0,0.00' },
HKD: { steps: ['LBCBTC', 'BTCHKD'], format: '$0,0.00' },
INR: { steps: ['LBCBTC', 'BTCINR'], format: '₹0,0.00' },
ISK: { steps: ['LBCBTC', 'BTCISK'], format: 'kr 0,0.00' },
JPY: { steps: ['LBCBTC', 'BTCJPY'], format: '¥0,0.00' },
KRW: { steps: ['LBCBTC', 'BTCKRW'], format: '₩0,0.00' },
NZD: { steps: ['LBCBTC', 'BTCNZD'], format: '$0,0.00' },
PLN: { steps: ['LBCBTC', 'BTCPLN'], format: 'zł 0,0.00' },
RUB: { steps: ['LBCBTC', 'BTCRUB'], format: 'RUB 0,0.00' },
SEK: { steps: ['LBCBTC', 'BTCSEK'], format: 'kr 0,0.00' },
SGD: { steps: ['LBCBTC', 'BTCSGD'], format: '$0,0.00' },
THB: { steps: ['LBCBTC', 'BTCTHB'], format: '฿0,0.00' },
TWD: { steps: ['LBCBTC', 'BTCTWD'], format: 'NT$0,0.00' },
IDR: { steps: ['LBCBTC', 'BTCIDR'], format: 'Rp0,0.00' },
BTC: { steps: ['LBCBTC'], format: '0,0[.][00000000] 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=LBC&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: 600000
};
// store the last retrieved rate
var cachedRates = {};
var mktChannel;
// !price {currency}
// !price {currency} {amount}
var command = '!price';
module.exports={
command: command,
init: init,
respond: respond
};
function init(channel_) {
mktChannel = channel_;
if (!channel_) {
console.log('No market and trading channel. Pricebot will only respond to #bot-sandbox and 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 !== 'C1TEEBS2Z' && !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[1].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 !== 'C1TEEBS2Z' && !channel.startsWith("D");
if (moveToBotSandbox) {
bot.postMessage(channel, 'Please use <#C1TEEBS2Z|bot-sandbox> to talk to bots.', globalSlackParams);
return;
}
if (showHelp) {
doHelp(bot, channel);
} else {
doSteps(bot, channel, currency, amount);
}
}
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 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)';
if (!channel.startsWith("D")) {
message =
'*USE <#C1TEEBS2Z|bot-sandbox> 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 value = numeral(rate.rate * amount).format(option.format);
return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + value + '*\n_last updated ' + rate.time.utc().format(options.dtFormat) + '_';
}
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);
}
}
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 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));
} else {
bot.postMessage(channel, 'The rate returned for the ' + pairName + ' pair was invalid.');
}
});
}
}

View file

@ -1,252 +0,0 @@
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: ['LBCEUR'], 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: 300000
};
// 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, '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);
//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 = rate.rate * amount;
if (option.sign == '$' || option.sign == '£' || option.sign == '€'){
return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' '+ value.toFixed(2) + '*';
}
else {
return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + numeral(value).format('0,0[.][00000000]') + ' ' + 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.');
}
});
}
}

BIN
miner.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

622
package-lock.json generated
View file

@ -1,622 +0,0 @@
{
"name": "hashbot",
"version": "1.0.2",
"lockfileVersion": 1,
"dependencies": {
"ajv": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
"integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY="
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
},
"assert-plus": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
"integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8="
},
"aws4": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
"optional": true
},
"bitcoin": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/bitcoin/-/bitcoin-3.0.1.tgz",
"integrity": "sha1-/54LYqcbu4rd2zTuLkJ9rCHBCW8="
},
"boom": {
"version": "2.10.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8="
},
"brace-expansion": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI="
},
"bson": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz",
"integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw="
},
"buffer-shims": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
"integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"cjson": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/cjson/-/cjson-0.2.1.tgz",
"integrity": "sha1-c82KrWXZ4VBfmvF0TTt5wVJ2gqU="
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
"colors": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
"integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q="
},
"combined-stream": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk="
},
"commander": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"cryptiles": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g="
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
}
}
},
"debug": {
"version": "2.6.8",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw="
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"ebnf-parser": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz",
"integrity": "sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE="
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"optional": true
},
"es6-promise": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
"integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q="
},
"escodegen": {
"version": "0.0.21",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.21.tgz",
"integrity": "sha1-U9ZSz6EDA4gnlFilJmxf/HCcY8M=",
"dependencies": {
"esprima": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
"integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
}
}
},
"esprima": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz",
"integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs="
},
"estraverse": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-0.0.4.tgz",
"integrity": "sha1-AaCTLf7ldGhKWYr1pnw7+bZCjbI="
},
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
},
"extsprintf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
"integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE="
},
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
}
}
},
"glob": {
"version": "4.5.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz",
"integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8="
},
"graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
},
"har-schema": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
"integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4="
},
"har-validator": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
"integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio="
},
"hawk": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ="
},
"hoek": {
"version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
},
"http-signature": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8="
},
"iconv-lite": {
"version": "0.4.18",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz",
"integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA=="
},
"imgur": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/imgur/-/imgur-0.1.7.tgz",
"integrity": "sha1-xN1lInC1FDx2WEGFEmqBfKorLoU="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk="
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jison": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/jison/-/jison-0.4.13.tgz",
"integrity": "sha1-kEFwfWIkE2f1iDRTK58ZwsNvrHg=",
"dependencies": {
"esprima": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
"integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
}
}
},
"jison-lex": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.2.1.tgz",
"integrity": "sha1-rEuBXozOUTLrErXfz+jXB7iETf4="
},
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-stable-stringify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
"integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsonify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
},
"jsonpath": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-0.2.11.tgz",
"integrity": "sha1-v+IuBmW5cS+Oe99+Lh+MCLWUxg4="
},
"JSONSelect": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz",
"integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40="
},
"jsprim": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
"integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
}
}
},
"lex-parser": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz",
"integrity": "sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA="
},
"mime-db": {
"version": "1.27.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
"integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE="
},
"mime-types": {
"version": "2.1.15",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
"integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0="
},
"minimatch": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
"integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc="
},
"moment": {
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
"integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8="
},
"mongodb": {
"version": "2.2.29",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.29.tgz",
"integrity": "sha512-MrQvIsN6zN80I4hdFo8w46w51cIqD2FJBGsUfApX9GmjXA1aCclEAJbOHaQWjCtabeWq57S3ECzqEKg/9bdBhA=="
},
"mongodb-core": {
"version": "2.1.13",
"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.13.tgz",
"integrity": "sha512-mbcvqLLZwVcpTrsfBDY3hRNk2SDNJWOvKKxFJSc0pnUBhYojymBc/L0THfQsWwKJrkb2nIXSjfFll1mG/I5OqQ=="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"nan": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz",
"integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U="
},
"needle": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/needle/-/needle-1.6.0.tgz",
"integrity": "sha1-9SpYWJchIWGOAC+OY4TK2sItYk8="
},
"nomnom": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz",
"integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=",
"dependencies": {
"underscore": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz",
"integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA="
}
}
},
"numeral": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz",
"integrity": "sha1-StCAk21EPCVhrtnyGX7//iX05QY="
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="
},
"options": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
},
"performance-now": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
"integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU="
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
"q": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
"integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE="
},
"qs": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
"integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM="
},
"readable-stream": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
"integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE="
},
"request": {
"version": "2.81.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
"integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA="
},
"require_optional": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g=="
},
"resolve-from": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
},
"safe-buffer": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz",
"integrity": "sha512-aSLEDudu6OoRr/2rU609gRmnYboRLxgDG1z9o2Q0os7236FwvcqIOO8r8U5JUEwivZOhDaKlFO4SbPTJYyBEyQ=="
},
"semver": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
},
"slackbots": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/slackbots/-/slackbots-0.5.3.tgz",
"integrity": "sha1-fpj5oCp6seYnwAt/WjfQzHR4QQ8=",
"dependencies": {
"extend": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-2.0.1.tgz",
"integrity": "sha1-HugBBonnOV/5RIJByYZSvHWagmA="
}
}
},
"sleep": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/sleep/-/sleep-5.1.1.tgz",
"integrity": "sha1-h4+h1E0I7rDyb7IBjvhinrGjq5Q="
},
"sntp": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
"integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg="
},
"source-map": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
"optional": true
},
"sshpk": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
"integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
}
}
},
"static-eval": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-0.2.3.tgz",
"integrity": "sha1-Aj8XrJ/uQm6niMEuo5IG3Bdfiyo=",
"dependencies": {
"escodegen": {
"version": "0.0.28",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.28.tgz",
"integrity": "sha1-Dk/xcV8yh3XWyrUaxEpAbNer/9M="
},
"esprima": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
"integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
},
"estraverse": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.3.2.tgz",
"integrity": "sha1-N8K4k+8T1yPydth41g2FNRUqbEI="
}
}
},
"string_decoder": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz",
"integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=",
"dependencies": {
"safe-buffer": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
"integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c="
}
}
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
},
"tough-cookie": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
"integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0="
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"optional": true
},
"ultron": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
},
"underscore": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
"integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk="
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"uuid": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
"integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
},
"verror": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
"integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw="
},
"vow": {
"version": "0.4.16",
"resolved": "https://registry.npmjs.org/vow/-/vow-0.4.16.tgz",
"integrity": "sha1-u51U2TjV+AUg1linQOeoleMP7us="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"ws": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-1.1.4.tgz",
"integrity": "sha1-V/QNA2gy5fUFVmKjl8Tedu1mv2E="
},
"xmlhttprequest": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
"integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw="
}
}
}

View file

@ -1,33 +0,0 @@
{
"name": "hashbot",
"version": "1.0.3",
"description": "A bot for slack wich displays lbrys current hashrate via the open api.",
"main": "app.js",
"dependencies": {
"bitcoin": "^3.0.1",
"imgur": "0.1.7",
"jsonpath": "0.2.11",
"moment": "^2.17.1",
"mongodb": "^2.2.22",
"needle": "^1.0.0",
"numeral": "2.0.6",
"request": "^2.81.0",
"slackbots": "^0.5.1",
"sleep": "^5.1.1",
"xmlhttprequest": "1.8.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/lbryio/hashbot.git"
},
"author": "Fillerino",
"license": "MIT",
"bugs": {
"url": "https://github.com/lbryio/hashbot/issues"
},
"homepage": "https://github.com/lbryio/hashbot#readme"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

View file

@ -1,11 +0,0 @@
Welcome to LBRY Slack!
- LBRY is currently in open beta. To download go here: https://lbry.io/get
- Ask questions only after reading the pinned items in each respective Slack channel. If there is still an issue or a question you have please reach out in the #help channel.
- If you're a developer we encourage you to join #dev.
- No spamming or referral links are permitted, you will be banned.
- Keep it on topic in the #general channel.
- Please put NSFW material only in the #random_nsfw channel.
- To upload images and gifs please use https://spee.ch/
- Read the FAQ: http://lbry.io/faq
- Be courteous, kind, and generous and welcome to one of the best cryptocurrency communities around!