From 94f305cfd234990310cd32e486b5a24703266aae Mon Sep 17 00:00:00 2001 From: Fillerino Date: Wed, 25 Oct 2017 19:51:26 +0200 Subject: [PATCH] Removed Slackbot, moved to old_slack, master will contain discord ver. --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 2 - LICENSE | 15 -- README.md | 24 -- app.js | 85 ------- bots/claimbot.js | 318 ------------------------ bots/gifbot.js | 186 -------------- bots/hashbot.js | 65 ----- bots/modbot.js | 104 -------- bots/pricebot.js | 216 ---------------- bots/statbot.js | 252 ------------------- miner.png | Bin 22110 -> 0 bytes package-lock.json | 622 ---------------------------------------------- package.json | 33 --- picklerick.png | Bin 11688 -> 0 bytes rickshutup.png | Bin 27783 -> 0 bytes slack-greeting.md | 11 - 17 files changed, 1933 deletions(-) delete mode 100644 .DS_Store delete mode 100644 .gitignore delete mode 100644 LICENSE delete mode 100644 README.md delete mode 100644 app.js delete mode 100644 bots/claimbot.js delete mode 100644 bots/gifbot.js delete mode 100644 bots/hashbot.js delete mode 100644 bots/modbot.js delete mode 100644 bots/pricebot.js delete mode 100644 bots/statbot.js delete mode 100644 miner.png delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 picklerick.png delete mode 100644 rickshutup.png delete mode 100644 slack-greeting.md diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index d9865a752a8e7869a45277786f9c022d1fd99682..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK&2AGh5FWRo-SC@ANbPYiNF35CO)DaVkV2XqA^}1K!2wXa+eFF2b~nmyh#&;z z!aD$Oz@zX4JO~c}-;7PQ`QwNX@UWAAIxsVUVPy(s#ACp1ZKI>E!cH{)+Rm)r&{1)Jum+%^N(IR?zPF zMt>5=;koYlPlL|rxN!X_j#4j(I)jY)i)TU9jz_h47_}3L^T0})-o6{ZpM3Z%sglB`CUVW-Z}OWD~8hU=y#1>)!t=z^|HkV3|E!a3Sq3Zv{}lr&S8vs8 zNXeY73(4_W>!O^Xu&~`!qqv|l$FV4U6z`yj;F-$`uxfCs5j_z5M?h$>m1W?sGVlwF Cq|Utn diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 944c283..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.idea/ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index c6ccaeb..0000000 --- a/LICENSE +++ /dev/null @@ -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. diff --git a/README.md b/README.md deleted file mode 100644 index 37717ba..0000000 --- a/README.md +++ /dev/null @@ -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= CHANNEL= node bot.js -``` diff --git a/app.js b/app.js deleted file mode 100644 index 72991dd..0000000 --- a/app.js +++ /dev/null @@ -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); - } - } - }); -}); diff --git a/bots/claimbot.js b/bots/claimbot.js deleted file mode 100644 index 2bbc265..0000000 --- a/bots/claimbot.js +++ /dev/null @@ -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); - } - }); - }); -} \ No newline at end of file diff --git a/bots/gifbot.js b/bots/gifbot.js deleted file mode 100644 index ab88df5..0000000 --- a/bots/gifbot.js +++ /dev/null @@ -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(' - 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); - }); - }); - } - }); -} diff --git a/bots/hashbot.js b/bots/hashbot.js deleted file mode 100644 index 2b4a01c..0000000 --- a/bots/hashbot.js +++ /dev/null @@ -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, ","); -} diff --git a/bots/modbot.js b/bots/modbot.js deleted file mode 100644 index 738915b..0000000 --- a/bots/modbot.js +++ /dev/null @@ -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); - } - } - } - }); - } -} - diff --git a/bots/pricebot.js b/bots/pricebot.js deleted file mode 100644 index bfad9c7..0000000 --- a/bots/pricebot.js +++ /dev/null @@ -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.'); - } - }); - } -} diff --git a/bots/statbot.js b/bots/statbot.js deleted file mode 100644 index 262a47e..0000000 --- a/bots/statbot.js +++ /dev/null @@ -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.'); - } - }); - } -} diff --git a/miner.png b/miner.png deleted file mode 100644 index 6bf095aed0c8c26dcb8cf2c9efc51732c0fa9b23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22110 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

?BVe53*#KDoD^F>fxy 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