Removed Slackbot, moved to old_slack, master will contain discord ver.
This commit is contained in:
parent
36f5e18324
commit
94f305cfd2
17 changed files with 0 additions and 1933 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
node_modules
|
||||
.idea/
|
15
LICENSE
15
LICENSE
|
@ -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.
|
24
README.md
24
README.md
|
@ -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
85
app.js
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
318
bots/claimbot.js
318
bots/claimbot.js
|
@ -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('&', '&').replace('<', '<').replace('>', '>');
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
186
bots/gifbot.js
186
bots/gifbot.js
|
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
|
@ -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, ",");
|
||||
}
|
104
bots/modbot.js
104
bots/modbot.js
|
@ -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}×tamp=${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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
216
bots/pricebot.js
216
bots/pricebot.js
|
@ -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.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
252
bots/statbot.js
252
bots/statbot.js
|
@ -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
BIN
miner.png
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
622
package-lock.json
generated
622
package-lock.json
generated
|
@ -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="
|
||||
}
|
||||
}
|
||||
}
|
33
package.json
33
package.json
|
@ -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"
|
||||
}
|
BIN
picklerick.png
BIN
picklerick.png
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
BIN
rickshutup.png
BIN
rickshutup.png
Binary file not shown.
Before Width: | Height: | Size: 27 KiB |
|
@ -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!
|
Loading…
Add table
Reference in a new issue