lbry-tipbot/bot/modules/tipbot.js

339 lines
10 KiB
JavaScript
Raw Normal View History

2017-10-25 21:12:38 +02:00
'use strict';
const bitcoin = require('bitcoin');
let config = require('config');
let spamchannel = config.get('sandboxchannel');
let regex = require('regex');
let lbrycrdConfig = config.get('lbrycrd');
const lbry = new bitcoin.Client(lbrycrdConfig);
const helpmsg = {
embed: {
description:
'__**TIPS**__\n\n' +
'**Balance**: `!tip balance`\n' +
'**Deposit Address**: `!tip deposit`\n' +
'**Withdraw**: `!tip withdraw <address> <amount>`\n' +
'**Private Tip**: `!tip private <user> <amount>`\n\n' +
'__**ROLE TIPS**__ Use this to tip everyone in a role.\n\n' +
'**Role Tip**: `!roletip <role> <amount>`\n' +
'**Private Role Tip**: `!privatetip <role> <amount>`\n\n' +
'__**MULTI TIPS**__ Use this to tip multiple people at once.\n\n' +
'**Multi Tip**: `!multitip <user> <user> <amount>`\n' +
'**Private Multi Tip** `!multitip private <user> <user> <amount>`\n' +
'**Note**: Multi tips can contain any amount of users to tip.\n\n' +
'__**FURTHER INFORMATION**__\n\n' +
'**Help**: `!tip help` *Get this message.\n' +
'Read our [Tipbot FAQ](<https://lbry.com/faq/tipbot-discord>) for more details',
2018-11-15 17:57:40 +01:00
color: 1109218
}
};
2017-10-25 21:12:38 +02:00
exports.commands = ['tip', 'multitip', 'roletip', 'tips'];
2017-10-25 21:12:38 +02:00
exports.tip = {
usage: '<subcommand>',
description: 'Tip a given user with an amount of LBC or perform wallet specific operations.',
process: async function(bot, msg, suffix) {
2018-11-15 17:57:40 +01:00
let tipper = msg.author.id.replace('!', ''),
words = msg.content
.trim()
.split(' ')
.filter(function(n) {
return n !== '';
}),
Optimise Help Msg & Wrong Channel Warning This one involves a fair amount of reworking of the way functions operate, all checks for being in private or bot sandbox have been removed from functions and that functionality is now applied through privateOrSandboxOnly(), passing the message, channel warning, function to be called and then an array of arguments, sans message, as that's automatically attached at the head as all primary functions require the message anyway. while this makes each case entry a bit longer, it does reduce code reuse and potential for old code being left in, since each function had to previously be updated individually if something happened with the way these tests were carried out. I've yet to find a way to allow us to set the export description and the help message in one fell swoop, so for now I've manually set the description. The help message itself is now broken down into pairs of subcommand and description, the subcommand will be indented once, while the description will be indented twice. The way the help function now works is to allow everything to be set at the start, without needing to hunt all the way down to find the duplicate help message. Now everything can be replaced in the main function, though this will require a bit of computation with each request presently, as I don't know if or how the exported functions can access constants defined outside them. This can be optimised later if need be and at the very least shouldn't slow things down very much with the few entries that there are. Unfortunately changing the way that the help message works does involve parameterising the help message itself for any function that requires it, but this also provides a helpful indicator of what functions might fail and fall back on the help function.
2018-02-01 11:33:18 +01:00
subcommand = words.length >= 2 ? words[1] : 'help',
2018-05-04 11:50:09 +02:00
channelwarning = 'Please use <#' + spamchannel + '> or DMs to talk to bots.',
2018-05-04 11:06:23 +02:00
MultiorRole = false;
switch (subcommand) {
case 'help':
privateOrSandboxOnly(msg, channelwarning, doHelp, [helpmsg]);
break;
case 'balance':
privateOrSandboxOnly(msg, channelwarning, doBalance, [tipper]);
break;
case 'deposit':
privateOrSandboxOnly(msg, channelwarning, doDeposit, [tipper]);
break;
case 'withdraw':
privateOrSandboxOnly(msg, channelwarning, doWithdraw, [tipper, words, helpmsg]);
break;
default:
2018-05-04 11:06:23 +02:00
doTip(bot, msg, tipper, words, helpmsg, MultiorRole);
}
}
};
2017-10-25 21:12:38 +02:00
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
exports.multitip = {
usage: '<subcommand>',
description: 'Tip multiple users simultaneously for the same amount of LBC each.',
process: async function(bot, msg, suffix) {
2018-11-15 17:57:40 +01:00
let tipper = msg.author.id.replace('!', ''),
words = msg.content
.trim()
.split(' ')
.filter(function(n) {
return n !== '';
}),
subcommand = words.length >= 2 ? words[1] : 'help',
2018-05-04 11:50:09 +02:00
channelwarning = 'Please use <#' + spamchannel + '> or DMs to talk to bots.',
2018-05-04 15:20:24 +02:00
MultiorRole = true;
switch (subcommand) {
case 'help':
privateOrSandboxOnly(msg, channelwarning, doHelp, [helpmsg]);
break;
default:
2018-05-04 11:06:23 +02:00
doMultiTip(bot, msg, tipper, words, helpmsg, MultiorRole);
break;
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
}
}
};
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
exports.roletip = {
usage: '<subcommand>',
description: 'Tip all users in a specified role an amount of LBC.',
process: async function(bot, msg, suffix) {
2018-11-15 17:57:40 +01:00
let tipper = msg.author.id.replace('!', ''),
words = msg.content
.trim()
.split(' ')
.filter(function(n) {
return n !== '';
}),
subcommand = words.length >= 2 ? words[1] : 'help',
2018-05-04 11:50:09 +02:00
channelwarning = `Please use <#${spamchannel}> or DMs to talk to bots.`,
2018-05-04 15:20:24 +02:00
MultiorRole = true;
switch (subcommand) {
case 'help':
privateOrSandboxOnly(msg, channelwarning, doHelp, [helpmsg]);
break;
default:
2018-05-04 11:06:23 +02:00
doRoleTip(bot, msg, tipper, words, helpmsg, MultiorRole);
break;
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
}
}
};
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
exports.tips = {
usage: '',
description: 'Lists all available tipbot commands with brief descriptions for each command.',
process: async function(bot, msg, suffix) {
msg.reply(helpmsg);
}
};
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
Optimise Help Msg & Wrong Channel Warning This one involves a fair amount of reworking of the way functions operate, all checks for being in private or bot sandbox have been removed from functions and that functionality is now applied through privateOrSandboxOnly(), passing the message, channel warning, function to be called and then an array of arguments, sans message, as that's automatically attached at the head as all primary functions require the message anyway. while this makes each case entry a bit longer, it does reduce code reuse and potential for old code being left in, since each function had to previously be updated individually if something happened with the way these tests were carried out. I've yet to find a way to allow us to set the export description and the help message in one fell swoop, so for now I've manually set the description. The help message itself is now broken down into pairs of subcommand and description, the subcommand will be indented once, while the description will be indented twice. The way the help function now works is to allow everything to be set at the start, without needing to hunt all the way down to find the duplicate help message. Now everything can be replaced in the main function, though this will require a bit of computation with each request presently, as I don't know if or how the exported functions can access constants defined outside them. This can be optimised later if need be and at the very least shouldn't slow things down very much with the few entries that there are. Unfortunately changing the way that the help message works does involve parameterising the help message itself for any function that requires it, but this also provides a helpful indicator of what functions might fail and fall back on the help function.
2018-02-01 11:33:18 +01:00
function privateOrSandboxOnly(message, wrongchannelmsg, fn, args) {
if (!inPrivateOrBotSandbox(message)) {
message.reply(wrongchannelmsg);
return;
}
fn.apply(null, [message, ...args]);
}
function doHelp(message, helpmsg) {
message.author.send(helpmsg);
}
2017-10-25 21:12:38 +02:00
function doBalance(message, tipper) {
lbry.getBalance(tipper, 1, function(err, balance) {
2017-10-25 21:12:38 +02:00
if (err) {
message.reply('Error getting balance.').then(message => message.delete(5000));
} else {
message.reply(`You have *${balance}* LBC`);
2017-10-25 21:12:38 +02:00
}
});
}
function doDeposit(message, tipper) {
getAddress(tipper, function(err, address) {
2017-10-25 21:12:38 +02:00
if (err) {
message.reply('Error getting your deposit address.').then(message => message.delete(5000));
} else {
message.reply(`Your address is ${address}`);
2017-10-25 21:12:38 +02:00
}
});
}
Optimise Help Msg & Wrong Channel Warning This one involves a fair amount of reworking of the way functions operate, all checks for being in private or bot sandbox have been removed from functions and that functionality is now applied through privateOrSandboxOnly(), passing the message, channel warning, function to be called and then an array of arguments, sans message, as that's automatically attached at the head as all primary functions require the message anyway. while this makes each case entry a bit longer, it does reduce code reuse and potential for old code being left in, since each function had to previously be updated individually if something happened with the way these tests were carried out. I've yet to find a way to allow us to set the export description and the help message in one fell swoop, so for now I've manually set the description. The help message itself is now broken down into pairs of subcommand and description, the subcommand will be indented once, while the description will be indented twice. The way the help function now works is to allow everything to be set at the start, without needing to hunt all the way down to find the duplicate help message. Now everything can be replaced in the main function, though this will require a bit of computation with each request presently, as I don't know if or how the exported functions can access constants defined outside them. This can be optimised later if need be and at the very least shouldn't slow things down very much with the few entries that there are. Unfortunately changing the way that the help message works does involve parameterising the help message itself for any function that requires it, but this also provides a helpful indicator of what functions might fail and fall back on the help function.
2018-02-01 11:33:18 +01:00
function doWithdraw(message, tipper, words, helpmsg) {
2017-10-25 21:12:38 +02:00
if (words.length < 4) {
return doHelp(message, helpmsg);
2017-10-25 21:12:38 +02:00
}
let address = words[2],
amount = getValidatedAmount(words[3]);
2017-10-25 21:12:38 +02:00
if (amount === null) {
2018-11-15 17:57:40 +01:00
message.reply('Invalid amount of credits specified... Cannot withdraw credits.').then(message => message.delete(5000));
2017-10-25 21:12:38 +02:00
return;
}
lbry.sendFrom(tipper, address, amount, function(err, txId) {
2017-10-25 21:12:38 +02:00
if (err) {
return message.reply(err.message).then(message => message.delete(5000));
2017-10-25 21:12:38 +02:00
}
message.reply(`${amount} LBC has been withdrawn to ${address}.
${txLink(txId)}`);
2017-10-25 21:12:38 +02:00
});
}
2018-05-04 11:06:23 +02:00
function doTip(bot, message, tipper, words, helpmsg, MultiorRole) {
2017-10-25 21:12:38 +02:00
if (words.length < 3 || !words) {
return doHelp(message, helpmsg);
2017-10-25 21:12:38 +02:00
}
let prv = false;
Added Tipbot Privacy Mode Allow for Tipbot to be used privately while still notifying the user that has received the tip, via private message. Updates the Help message for new usage instructions, fixes misspelling of 'address' and adds a Key for the [ ] and < > syntax, as some users may not understand their usage. Reworks the subcommand parsing by using a more compact Switch Function. Necessitates the use of 'break;' but is far more compact and legible, presumed the old if else block is from early development with fewer features available. Switch statement should allow for easier expansion. Modifies doTip() to avoid requiring code duplication, includes two new variables used to indicate that the tip should be done in privacy mode and where the tip value is located in the 'words' array. Significant change to sendLbc and it's function call, requirement for private message for recipient required User object, thus the function now requires the actual GuildMember object, not only the ID. While this marginally increases overhead, it should also allow access to the send() function for that Guild Member, allowing for private message to be sent. Further the addition of a privacy flag (0 for non-private, 1 for private) was added so that the function can determine whether to send a public or private response. this required updating references to the Guild Member's id to 'member.id', but otherwise operation remains the same until the transaction is completed, following which it will check the privacy flag and if it is set, will privately send the successful tip message to both author and recipient, otherwise it will simply reply via the normal '.reply()' function.
2017-11-14 18:33:17 +01:00
let amountOffset = 2;
if (words.length >= 4 && words[1] === 'private') {
prv = true;
amountOffset = 3;
Added Tipbot Privacy Mode Allow for Tipbot to be used privately while still notifying the user that has received the tip, via private message. Updates the Help message for new usage instructions, fixes misspelling of 'address' and adds a Key for the [ ] and < > syntax, as some users may not understand their usage. Reworks the subcommand parsing by using a more compact Switch Function. Necessitates the use of 'break;' but is far more compact and legible, presumed the old if else block is from early development with fewer features available. Switch statement should allow for easier expansion. Modifies doTip() to avoid requiring code duplication, includes two new variables used to indicate that the tip should be done in privacy mode and where the tip value is located in the 'words' array. Significant change to sendLbc and it's function call, requirement for private message for recipient required User object, thus the function now requires the actual GuildMember object, not only the ID. While this marginally increases overhead, it should also allow access to the send() function for that Guild Member, allowing for private message to be sent. Further the addition of a privacy flag (0 for non-private, 1 for private) was added so that the function can determine whether to send a public or private response. this required updating references to the Guild Member's id to 'member.id', but otherwise operation remains the same until the transaction is completed, following which it will check the privacy flag and if it is set, will privately send the successful tip message to both author and recipient, otherwise it will simply reply via the normal '.reply()' function.
2017-11-14 18:33:17 +01:00
}
Added Tipbot Privacy Mode Allow for Tipbot to be used privately while still notifying the user that has received the tip, via private message. Updates the Help message for new usage instructions, fixes misspelling of 'address' and adds a Key for the [ ] and < > syntax, as some users may not understand their usage. Reworks the subcommand parsing by using a more compact Switch Function. Necessitates the use of 'break;' but is far more compact and legible, presumed the old if else block is from early development with fewer features available. Switch statement should allow for easier expansion. Modifies doTip() to avoid requiring code duplication, includes two new variables used to indicate that the tip should be done in privacy mode and where the tip value is located in the 'words' array. Significant change to sendLbc and it's function call, requirement for private message for recipient required User object, thus the function now requires the actual GuildMember object, not only the ID. While this marginally increases overhead, it should also allow access to the send() function for that Guild Member, allowing for private message to be sent. Further the addition of a privacy flag (0 for non-private, 1 for private) was added so that the function can determine whether to send a public or private response. this required updating references to the Guild Member's id to 'member.id', but otherwise operation remains the same until the transaction is completed, following which it will check the privacy flag and if it is set, will privately send the successful tip message to both author and recipient, otherwise it will simply reply via the normal '.reply()' function.
2017-11-14 18:33:17 +01:00
let amount = getValidatedAmount(words[amountOffset]);
2017-10-25 21:12:38 +02:00
if (amount === null) {
2018-11-15 17:57:40 +01:00
return message.reply('Invalid amount of credits specified...').then(message => message.delete(5000));
2017-10-25 21:12:38 +02:00
}
if (message.mentions.users.first() && message.mentions.users.first().id) {
2018-05-04 15:20:24 +02:00
return sendLBC(bot, message, tipper, message.mentions.users.first().id.replace('!', ''), amount, prv, MultiorRole);
}
message.reply('Sorry, I could not find the user you are trying to tip...');
2017-10-25 21:12:38 +02:00
}
2018-05-04 11:06:23 +02:00
function doMultiTip(bot, message, tipper, words, helpmsg, MultiorRole) {
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
if (!words) {
doHelp(message, helpmsg);
return;
}
if (words.length < 4) {
2018-05-04 11:06:23 +02:00
doTip(bot, message, tipper, words, helpmsg, MultiorRole);
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
return;
}
let prv = false;
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
if (words.length >= 5 && words[1] === 'private') {
prv = true;
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
}
let [userIDs, amount] = findUserIDsAndAmount(message, words, prv);
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
if (amount == null) {
2018-11-15 17:57:40 +01:00
message.reply('Invalid amount of credits specified...').then(message => message.delete(5000));
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
return;
}
if (!userIDs) {
message.reply('Sorry, I could not find the user you are trying to tip...').then(message => message.delete(5000));
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
return;
}
for (let i = 0; i < userIDs.length; i++) {
2018-05-04 15:20:24 +02:00
sendLBC(bot, message, tipper, userIDs[i].toString(), amount, prv, MultiorRole);
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
}
}
2018-05-04 11:06:23 +02:00
function doRoleTip(bot, message, tipper, words, helpmsg, MultiorRole) {
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
if (!words || words.length < 3) {
doHelp(message, helpmsg);
return;
}
2018-12-05 02:26:51 +01:00
let isPrivateTip = words.length >= 4 && words[1] === 'private';
let amountOffset = isPrivateTip ? 3 : 2;
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
let amount = getValidatedAmount(words[amountOffset]);
2018-12-05 02:26:51 +01:00
if (amount === null) {
message.reply("I don't know how to tip that amount of LBC...").then(message => message.delete(10000));
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
return;
}
2018-12-05 02:26:51 +01:00
let roleToTip = message.mentions.roles.first();
if (roleToTip !== null) {
2018-12-05 02:32:38 +01:00
let membersOfRole = roleToTip.members.keyArray();
2018-12-05 02:26:51 +01:00
if (membersOfRole.length > 0) {
2018-12-05 02:38:48 +01:00
let userIDs = membersOfRole.map(member => member.replace('!', ''));
2018-12-05 02:26:51 +01:00
userIDs.forEach(u => {
sendLBC(bot, message, tipper, u, amount, isPrivateTip, MultiorRole);
});
} else {
2018-05-04 15:20:24 +02:00
return message.reply('Sorry, I could not find any users to tip in that role...').then(message => message.delete(10000));
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
}
} else {
2018-05-04 15:20:24 +02:00
return message.reply('Sorry, I could not find any roles in your tip...').then(message => message.delete(10000));
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
}
}
function findUserIDsAndAmount(message, words, prv) {
let idList = [];
let amount = null;
let count = 0;
let startOffset = 1;
if (prv) startOffset = 2;
let regex = new RegExp(/<@!?[0-9]+>/);
for (let i = startOffset; i < words.length; i++) {
if (regex.test(words[i])) {
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
count++;
idList.push(words[i].match(/[0-9]+/));
} else {
amount = getValidatedAmount(words[Number(count) + 1]);
break;
Adding Multi User Tipping and Role Tipping This is actually not too substantial an addition. it adds 2 additional command exports for tipbot, namely !multitip and !roletip. !multitip [private] <user>+ <amount> The more complex new feature, this command will take a list of users, seperated by spaces, and passes through to doTip() if you only list a single user. It tests each word past the ! command and private tag, checking for a user mention using the regex.test() function of the Discord.js USERS_PATTERN, using that to count the number of users mentioned in a row, then takes the first word that is not a match to be the amount. Error checking then returns the appropriate errors to the user, if any. Otherwise it proceeds to send tips to each user individually. this results in messages for every user that receives a tip, which can be messy. It will also message the author once for every user a tip is sent to, if using private mode, this isn't ideal, but would require rewriting the sendLbc() function, which is outside the scope of this commit. !roletip <role> <amount> This is a relatively simpler feature, the command taking a single role and an amount, then extracting the userIDs from the role via the Roles.members and GuildMember.user values. It will return seperate errors for a lack of a role in the message and the lack of any users in a role. Like the !multitip command, it will send tips individually to each user, with the same spam of messages either in the channel or the author's private channel.
2018-02-06 07:18:05 +01:00
}
}
return [idList, amount];
}
2018-05-04 11:06:23 +02:00
function sendLBC(bot, message, tipper, recipient, amount, privacyFlag, MultiorRole) {
getAddress(recipient.toString(), function(err, address) {
2017-10-25 21:12:38 +02:00
if (err) {
message.reply(err.message).then(message => message.delete(5000));
} else {
lbry.sendFrom(tipper, address, Number(amount), 1, null, null, function(err, txId) {
2017-10-25 21:12:38 +02:00
if (err) {
message.reply(err.message).then(message => message.delete(5000));
} else {
let tx = txLink(txId);
let msgtail = `
DM me with \`!tips\` for all available commands or read our Tipbot FAQ <https://lbry.com/faq/tipbot-discord> for more details`;
if (privacyFlag) {
let usr = message.guild.members.find('id', recipient).user;
let authmsg = `You have sent a private tip to @${usr.tag} with the amount of ${amount} LBC.
${tx}${msgtail}`;
message.author.send(authmsg);
2018-12-05 02:38:48 +01:00
if (message.author.id !== usr.id) {
let recipientmsg = `You have just been privately tipped ${amount} LBC by @${message.author.tag}.
${tx}${msgtail}`;
usr.send(recipientmsg);
}
} else {
let generalmsg = `just tipped <@${recipient}> ${amount} LBC.
${tx}${msgtail}`;
message.reply(generalmsg);
}
2017-10-25 21:12:38 +02:00
}
});
}
});
}
2017-10-25 21:12:38 +02:00
function getAddress(userId, cb) {
lbry.getAddressesByAccount(userId, function(err, addresses) {
2017-10-25 21:12:38 +02:00
if (err) {
cb(err);
} else if (addresses.length > 0) {
2017-10-25 21:12:38 +02:00
cb(null, addresses[0]);
} else {
lbry.getNewAddress(userId, function(err, address) {
2017-10-25 21:12:38 +02:00
if (err) {
cb(err);
} else {
2017-10-25 21:12:38 +02:00
cb(null, address);
}
});
}
});
}
function inPrivateOrBotSandbox(msg) {
return msg.channel.type === 'dm' || msg.channel.id === spamchannel;
2017-10-25 21:12:38 +02:00
}
function getValidatedAmount(amount) {
2018-12-05 02:26:51 +01:00
amount = amount.toLowerCase().replace('lbc', '');
2017-10-25 21:12:38 +02:00
return amount.match(/^[0-9]+(\.[0-9]+)?$/) ? amount : null;
}
function txLink(txId) {
2019-03-27 15:59:33 +01:00
return '<https://explorer.lbry.com/tx/' + txId + '>';
2017-10-25 21:44:38 +02:00
}