mirror of
https://github.com/LBRYFoundation/lbry-tipbot.git
synced 2025-08-23 16:57:24 +00:00
merged tipbot into hashbot, generic framework for more bots
This commit is contained in:
parent
cfbbba8e31
commit
215260259c
5 changed files with 302 additions and 57 deletions
37
app.js
Normal file
37
app.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
var SlackBot = require('slackbots');
|
||||||
|
|
||||||
|
['SLACK_TOKEN', 'RPCUSER', 'RPCPASSWORD'].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'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var tipbot = require('./tipbot');
|
||||||
|
tipbot.init(process.env.RPCUSER, process.env.RPCPASSWORD);
|
||||||
|
|
||||||
|
var hashbot = require('./hashbot');
|
||||||
|
hashbot.init(slackbot, process.env.MINING_CHANNEL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
slackbot.on('start', function() {
|
||||||
|
slackbot.on('message', function(data) {
|
||||||
|
if (data.text) {
|
||||||
|
var command = data.text.trim().split(' ')[0];
|
||||||
|
|
||||||
|
if (command === hashbot.command) {
|
||||||
|
hashbot.respond(slackbot, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === tipbot.command) {
|
||||||
|
tipbot.respond(slackbot, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
57
bot.js
57
bot.js
|
@ -1,57 +0,0 @@
|
||||||
var SlackBot = require('slackbots');
|
|
||||||
var needle = require('needle');
|
|
||||||
|
|
||||||
var SLACK_TOKEN = process.env.SLACK_TOKEN;
|
|
||||||
var CHANNEL = process.env.CHANNEL;
|
|
||||||
|
|
||||||
if (!SLACK_TOKEN) {
|
|
||||||
throw new Error('SLACK_TOKEN env var required');
|
|
||||||
}
|
|
||||||
if (!CHANNEL) {
|
|
||||||
throw new Error('CHANNEL env var required');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var bot = new SlackBot({
|
|
||||||
token: SLACK_TOKEN,
|
|
||||||
name: 'hashbot'
|
|
||||||
});
|
|
||||||
|
|
||||||
function numberWithCommas(x) {
|
|
||||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getData() {
|
|
||||||
needle.get('https://explorer.lbry.io/api/getmininginfo', function(error, response) {
|
|
||||||
// if (!error && response.statusCode == 200) {
|
|
||||||
// console.log(response.body);
|
|
||||||
// }
|
|
||||||
|
|
||||||
var data = response.body,
|
|
||||||
hashrate = Math.round(data.networkhashps / 1000000000),
|
|
||||||
difficulty = numberWithCommas(Math.round(data.difficulty)),
|
|
||||||
block = numberWithCommas(data.blocks);
|
|
||||||
|
|
||||||
bot.postMessageToChannel(CHANNEL,
|
|
||||||
// 'Blockchain stats:\n' +
|
|
||||||
'Hashrate: ' + hashrate + ' GH/s\n' +
|
|
||||||
'Difficulty: ' + difficulty + '\n' +
|
|
||||||
'Current block: ' + block + '\n' +
|
|
||||||
'_Source: https://explorer.lbry.io_'
|
|
||||||
);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.on('start', function() {
|
|
||||||
// more information about additional params https://api.slack.com/methods/chat.postMessage
|
|
||||||
bot.on('message', function(data) {
|
|
||||||
if (data.text && data.text.trim() === '!hash') {
|
|
||||||
getData();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Post every hour
|
|
||||||
setInterval(getData, 3600000);
|
|
||||||
getData();
|
|
||||||
});
|
|
64
hashbot.js
Normal file
64
hashbot.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
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);
|
||||||
|
}, 3600000);
|
||||||
|
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/getmininginfo', function(error, response) {
|
||||||
|
if (error || response.statusCode !== 200) {
|
||||||
|
slackbot.postMessage(channel, 'Explorer API is not available');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var data = response.body,
|
||||||
|
hashrate = Math.round(data.networkhashps / 1000000000),
|
||||||
|
difficulty = numberWithCommas(Math.round(data.difficulty)),
|
||||||
|
block = numberWithCommas(data.blocks);
|
||||||
|
|
||||||
|
slackbot.postMessage(channel,
|
||||||
|
// 'Blockchain stats:\n' +
|
||||||
|
'Hashrate: ' + hashrate + ' GH/s\n' +
|
||||||
|
'Difficulty: ' + difficulty + '\n' +
|
||||||
|
'Current block: ' + block + '\n' +
|
||||||
|
'_Source: https://explorer.lbry.io_'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function numberWithCommas(x) {
|
||||||
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
"description": "A bot for slack wich displays lbrys current hashrate via the open api.",
|
"description": "A bot for slack wich displays lbrys current hashrate via the open api.",
|
||||||
"main": "bot.js",
|
"main": "bot.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bitcoin": "^3.0.1",
|
||||||
"needle": "^1.0.0",
|
"needle": "^1.0.0",
|
||||||
"slackbots": "^0.5.1"
|
"slackbots": "^0.5.1"
|
||||||
},
|
},
|
||||||
|
|
200
tipbot.js
Normal file
200
tipbot.js
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
var lbry;
|
||||||
|
|
||||||
|
var command = '!tip';
|
||||||
|
|
||||||
|
module.exports={
|
||||||
|
command: command,
|
||||||
|
init: init,
|
||||||
|
respond: respond
|
||||||
|
};
|
||||||
|
|
||||||
|
function init(rpcuser, rpcpassword) {
|
||||||
|
if (lbry) {
|
||||||
|
throw new Error('init was already called once');
|
||||||
|
}
|
||||||
|
|
||||||
|
var bitcoin = require('bitcoin');
|
||||||
|
lbry = new bitcoin.Client({
|
||||||
|
host: 'localhost',
|
||||||
|
'port': 9245,
|
||||||
|
'user': rpcuser,
|
||||||
|
'pass': rpcpassword
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function respond(bot, data) {
|
||||||
|
var tipper = data.user,
|
||||||
|
channel = data.channel,
|
||||||
|
words = data.text.trim().split(' ');
|
||||||
|
|
||||||
|
if (!lbry) {
|
||||||
|
bot.postMessage(channel, 'Failed to connect to lbrycrd');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (words[0] !== command) {
|
||||||
|
// wtf?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var subcommand = words.length >= 2 ? words[1] : 'help';
|
||||||
|
|
||||||
|
if (subcommand === 'help') {
|
||||||
|
doHelp(bot, channel);
|
||||||
|
}
|
||||||
|
else if (subcommand === 'balance') {
|
||||||
|
doBalance(bot, channel, tipper);
|
||||||
|
}
|
||||||
|
else if (subcommand === 'deposit') {
|
||||||
|
doDeposit(bot, channel, tipper);
|
||||||
|
}
|
||||||
|
else if (subcommand === 'withdraw') {
|
||||||
|
doWithdraw(bot, channel, tipper, words);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
doTip(bot, channel, tipper, words);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function doBalance(bot, channel, tipper) {
|
||||||
|
lbry.getBalance(tipper, 1, function(err, balance) {
|
||||||
|
if (err) {
|
||||||
|
bot.postMessage(channel, 'Error getting balance');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bot.postMessage(channel, 'You have *' + balance + '* LBC');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function doDeposit(bot, channel, tipper) {
|
||||||
|
getAddress(tipper, function(err, address) {
|
||||||
|
if (err) {
|
||||||
|
bot.postMessage(channel, 'Error getting deposit address');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bot.postMessage(channel, 'Your address is ' + address);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function doWithdraw(bot, channel, tipper, words) {
|
||||||
|
if (words.length < 4) {
|
||||||
|
doHelp(bot, channel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var address = words[2],
|
||||||
|
amount = words[3];
|
||||||
|
|
||||||
|
if (!validateAmount(amount)) {
|
||||||
|
bot.postMessage(channel, 'I dont know how to withdraw that many credits');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbry.sendFrom(tipper, address, amount, function(err, txId) {
|
||||||
|
if (err) {
|
||||||
|
bot.postMessage(channel, err.message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bot.postMessage(channel, 'You withdrew ' + amount + ' to ' + address + ' (' + txLink(txId) + ')');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function doTip(bot, channel, tipper, words) {
|
||||||
|
if (words.length < 3) {
|
||||||
|
doHelp(bot, channel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = words[1],
|
||||||
|
amount = words[2];
|
||||||
|
|
||||||
|
if (!validateAmount(amount)) {
|
||||||
|
bot.postMessage(channel, 'I dont know how to tip that many credits');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.match(/^<@U[^>]+>$/)) {
|
||||||
|
var id = user.substr(2,user.length-3);
|
||||||
|
sendLbc(bot, channel, tipper, id, amount);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bot.getUser(user).then(function(data) {
|
||||||
|
if (data.id) {
|
||||||
|
sendLbc(bot, channel, tipper, data.id, amount);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
bot.postMessage(channel, 'Sorry, I dont know that person');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function doHelp(bot, channel) {
|
||||||
|
bot.postMessage(channel,
|
||||||
|
'`' + command + ' help`: this message\n' +
|
||||||
|
'`' + command + ' balance`: get your balance\n' +
|
||||||
|
'`' + command + ' deposit`: get address for deposits\n' +
|
||||||
|
'`' + command + ' withdraw ADDRESS AMOUNT`: withdraw AMOUNT credits to ADDRESS\n' +
|
||||||
|
'`' + command + ' USER AMOUNT`: send AMOUNT credits to USER\n'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function sendLbc(bot, channel, tipper, id, amount) {
|
||||||
|
getAddress(id, function(err, address){
|
||||||
|
if (err){
|
||||||
|
bot.postMessage(channel, err.message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lbry.sendFrom(tipper, address, amount, 1, null, null, function(err, txId){
|
||||||
|
if (err) {
|
||||||
|
bot.postMessage(channel, err.message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bot.postMessage(channel, 'Wubba lubba dub dub! <@' + tipper + '> tipped <@' + id + '> ' + amount + ' (' + txLink(txId) + ')');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function getAddress(userId, cb) {
|
||||||
|
lbry.getAddressesByAccount(userId, function(err, addresses) {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
}
|
||||||
|
else if(addresses.length > 0) {
|
||||||
|
cb(null, addresses[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lbry.getNewAddress(userId, function(err, address) {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cb(null, address);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function validateAmount(amount) {
|
||||||
|
return amount.match(/^[0-9]+(\.[0-9]+)?$/);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function txLink(txId) {
|
||||||
|
return "<https://explorer.lbry.io/tx/" + txId + "|tx>";
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue