Fixed tipping, tipping message, better error handeling, README and LICENSE.

This commit is contained in:
filipnyquist 2018-07-05 11:37:04 +02:00
parent b0df0addbf
commit 559478cc40
4 changed files with 104 additions and 26 deletions

15
LICENSE Normal file
View file

@ -0,0 +1,15 @@
The MIT License (MIT)
Copyright (c) 2018 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.

42
README.md Normal file
View file

@ -0,0 +1,42 @@
# Twitter tipbot - A twitter tipbot for LBRY
This repo contains the twitter tipbot used by LBRY. This bot allows users to tip each other LBC on twitter.
## Installation
### Prerequisites
* Lbrycrd-daemon
* Node.js v8+
* Yarn
* A twitter application on the tipbot account
>To get started you should clone the git:
```
git clone https://github.com/lbryio/twitter-tipbot
```
>Install all modules with yarn:
```
yarn install
```
>Rename default.example.json to default.json and enter the twitter tokens and daemon settings.
>Run the bot with:
```
node index.js
```
## Contributing
Contributions to this project are welcome, encouraged, and compensated. For more details, see [lbry.io/faq/contributing](https://lbry.io/faq/contributing)
## License
This project is MIT Licensed © [LBRYio](https://github.com/lbryio)
## Security
We take security seriously. Please contact security@lbry.io regarding any security issues.
Our PGP key is [here](https://keybase.io/lbry/key.asc) if you need it.
## Contact
The primary contact for this project is [@filipnyquist](https://github.com/filipnyquist) (filip@lbry.io)

View file

@ -1,4 +1,8 @@
{ {
"bot":{
"handle": "@devlbctipbot",
"requiredConfirms": 2
},
"twitter": { "twitter": {
"consumer_key": "****", "consumer_key": "****",
"consumer_secret": "****", "consumer_secret": "****",

View file

@ -37,12 +37,13 @@ const T = new Twit({
strictSSL: true // optional - requires SSL certificates to be valid. strictSSL: true // optional - requires SSL certificates to be valid.
}); });
var stream = T.stream("statuses/filter", { track: "@devlbctipbot" }); const stream = T.stream("statuses/filter", { track: config.get("bot.handle") });
logger.info("Started LBRY twitter tipbot."); logger.info("Started LBRY twitter tipbot.");
stream.on("tweet", function(tweet) { stream.on("tweet", function(tweet) {
if(tweet.user.screen_name === config.get("bot.handle").substring(1)) return;
let msg = checkTrunc(tweet); let msg = checkTrunc(tweet);
msg = msg.slice(msg.indexOf("@devlbctipbot")).split(" "); msg = msg.slice(msg.indexOf(config.get("bot.handle"))).split(" ");
checkTweet(tweet, msg); checkTweet(tweet, msg);
}); });
@ -63,6 +64,9 @@ function checkTweet(tweet, msg) {
case "tip": case "tip":
doTip(tweet, msg); doTip(tweet, msg);
break; break;
case "terms":
doTerms(tweet, msg);
break;
} }
} }
@ -70,7 +74,8 @@ async function doHelp(tweet, msg) {
try { try {
let post = await T.post("statuses/update", { let post = await T.post("statuses/update", {
status: status:
"All commands should be called with @ devlbctipbot \n" + `@${tweet.user.screen_name} `+
"All commands should be called with @ + subcommand \n" +
"help - Shows this command. \n" + "help - Shows this command. \n" +
"balance - Get your balance. \n" + "balance - Get your balance. \n" +
"deposit - Get address for your deposits. \n" + "deposit - Get address for your deposits. \n" +
@ -85,12 +90,15 @@ async function doHelp(tweet, msg) {
logger.error(e); logger.error(e);
} }
} }
async function doTerms(tweet, msg){
// ADD terms
}
async function doBalance(tweet, msg) { async function doBalance(tweet, msg) {
try { try {
const balance = await lbry.getBalance(tweet.user.id_str, 3); const balance = await lbry.getBalance(id(tweet.user.id_str), config.get("bot.requiredConfirms")); // Amount of confirms before we can use it.
const post = await T.post("statuses/update", { const post = await T.post("statuses/update", {
status: `You have ${balance} LBC.`, in_reply_to_status_id: tweet.id_str,
in_reply_to_status_id: tweet.id_str status: `@${tweet.user.screen_name} You have ${balance} LBC.`
}); });
logger.info( logger.info(
`Sent balance command to ${tweet.user.screen_name}, tweet id: ${ `Sent balance command to ${tweet.user.screen_name}, tweet id: ${
@ -104,7 +112,7 @@ async function doBalance(tweet, msg) {
async function doDeposit(tweet, msg) { async function doDeposit(tweet, msg) {
try { try {
const post = await T.post("statuses/update", { const post = await T.post("statuses/update", {
status: `Your deposit address is ${await getAddress(tweet.user.id_str)}.`, status: `@${tweet.user.screen_name} Your deposit address is ${await getAddress(id(tweet.user.id_str))}.`,
in_reply_to_status_id: tweet.id_str in_reply_to_status_id: tweet.id_str
}); });
logger.info( logger.info(
@ -117,18 +125,19 @@ async function doDeposit(tweet, msg) {
} }
} }
async function doWithdraw(tweet, msg) { async function doWithdraw(tweet, msg) {
try {
if (msg.length < 4) return doHelp(tweet, msg); if (msg.length < 4) return doHelp(tweet, msg);
let address = msg[2]; let address = msg[2];
let amount = getValidatedAmount(msg[3]); let amount = getValidatedAmount(msg[3]);
if (amount === null) { if (amount === null) {
return await T.post("statuses/update", { return await T.post("statuses/update", {
status: `I don´t know how to withdraw that many credits...`, status: `@${tweet.user.screen_name} I don´t know how to withdraw that many credits...`,
in_reply_to_status_id: tweet.id_str in_reply_to_status_id: tweet.id_str
}); });
} }
let txId = await lbry.sendFrom(tweet.user.id_str, address, amount); let txId = await lbry.sendFrom(id(tweet.user.id_str), address, amount);
await T.post("statuses/update", { await T.post("statuses/update", {
status: `You withdrew ${amount} LBC to ${address}. \n${txLink(txId)}`, status: `@${tweet.user.screen_name} You withdrew ${amount} LBC to ${address}. \n${txLink(txId)}`,
in_reply_to_status_id: tweet.id_str in_reply_to_status_id: tweet.id_str
}); });
logger.info( logger.info(
@ -136,7 +145,6 @@ async function doWithdraw(tweet, msg) {
tweet.user.screen_name tweet.user.screen_name
} withdraw ${amount} LBC to ${address}, tweet id: ${tweet.id_str}` } withdraw ${amount} LBC to ${address}, tweet id: ${tweet.id_str}`
); );
try {
} catch (e) { } catch (e) {
logger.error(e); logger.error(e);
} }
@ -149,25 +157,35 @@ async function doTip(tweet, msg) {
const amount = getValidatedAmount(msg[3]); const amount = getValidatedAmount(msg[3]);
if (amount === null) { if (amount === null) {
return await T.post("statuses/update", { return await T.post("statuses/update", {
status: `I don´t know how to tip that many credits...`, status: `@${tweet.user.screen_name} I don´t know how to tip that many credits...`,
in_reply_to_status_id: tweet.id_str in_reply_to_status_id: tweet.id_str
}); });
} }
const userToTip = userToTip(tweet, msg); const userToTip = tweet.entities.user_mentions.find(u => `@${u.screen_name}` === msg[2]).id_str;
const userToTipAddress = getAddress(userToTip);
if (userToTip === null) { if (userToTip === null) {
return await T.post("statuses/update", { return await T.post("statuses/update", {
status: `I could not find that user...`, status: `@${tweet.user.screen_name} I could not find that user...`,
in_reply_to_status_id: tweet.id_str in_reply_to_status_id: tweet.id_str
}); });
} }
const txId = await lbry.sendFrom( const balanceFromUser = await lbry.getBalance(id(tweet.user.id_str), config.get("bot.requiredConfirms"));
tweet.user.id_str, if (balanceFromUser < amount) {
userToTipAddress, return await T.post("statuses/update", {
Number(amount), status: `@${tweet.user.screen_name} You tried to tip, but you are missing ${amount-balanceFromUser} LBC.`,
null, in_reply_to_status_id: tweet.id_str
null });
}
const txId = await lbry.move(
id(tweet.user.id_str),
id(userToTip),
Number(amount)
); );
await T.post("statuses/update", {
status: `@${tweet.user.screen_name} Tipped ${
msg[2]
} ${amount} LBC! \n See https://lbry.io/faq/tipbot-twitter for more information.`,
in_reply_to_status_id: tweet.id_str
});
logger.info( logger.info(
`@${tweet.user.screen_name}(${tweet.user.id_str}) tipped ${ `@${tweet.user.screen_name}(${tweet.user.id_str}) tipped ${
msg[2] msg[2]
@ -188,11 +206,6 @@ async function getAddress(userId) {
logger.error(e); logger.error(e);
} }
} }
function userToTip(tweet, msg) {
const username = msg[2];
const users = tweet.entities.user_mentions;
return users.find(u => `@${u.screen_name}` === username).id_str;
}
function getValidatedAmount(amount) { function getValidatedAmount(amount) {
amount = amount.trim(); amount = amount.trim();
if (amount.toLowerCase().endsWith("lbc")) { if (amount.toLowerCase().endsWith("lbc")) {
@ -207,3 +220,7 @@ function checkTrunc(tweet) {
if (tweet.truncated) return tweet.extended_tweet.full_text; if (tweet.truncated) return tweet.extended_tweet.full_text;
return tweet.text; return tweet.text;
} }
function id(usrId){
return `t-${usrId}`;
}