diff --git a/app.js b/app.js index 724c708..f300143 100644 --- a/app.js +++ b/app.js @@ -16,6 +16,7 @@ function init() { require('./helpers/utils/erc20_utils'); require('./server'); require('./modules/checkTwitterFollow'); + require('./modules/apiTester'); require('./modules/checkTwitterRetweet'); require('./modules/checkAdamantContacts'); require('./modules/checkAll'); diff --git a/config.json b/config.json index c0b50eb..613eb6e 100644 --- a/config.json +++ b/config.json @@ -102,6 +102,14 @@ "access_token_secret": "" }, + /** Interval in minutes to test Twitter API. Because of different reasons Twitter may temporary block API requests. + To continue, you need manually login into your Twitter account and solve captcha. + This parameter allows to automatically check if Twitter API works well every twitter_api_test_interval minutes. + In case of error the bot will notify you. Also you can run "/test twitterapi" command manually. + 0 means disabled. + **/ + "twitter_api_test_interval": 600, + /** ADAMANT accounts to accept control commands from. Control commands from other accounts will not be executed. **/ "admin_accounts": [ "U1123..." diff --git a/modules/apiTester.js b/modules/apiTester.js new file mode 100644 index 0000000..b404f5d --- /dev/null +++ b/modules/apiTester.js @@ -0,0 +1,24 @@ +const config = require('./configReader'); +const log = require('../helpers/log'); +const notify = require('../helpers/notify'); +const twitterapi = require('./twitterapi'); + +async function testTwitterAPI() { + let testResult = await twitterapi.testApi(); + let output; + if (testResult.success) { + output = "Twitter API functions well."; + log.info(output); + } else { + output = `Error while making Twitter API request: ${testResult.message}`; + output += "\n"; + output += `Make sure Twitter didn't block your API credentials. If so, you need to manually login into your Twitter account and solve captcha.`; + notify(output, 'error'); + } +} + +if (config.twitter_api_test_interval) { + setInterval(() => { + testTwitterAPI(); + }, config.twitter_api_test_interval * 60 * 1000); +} diff --git a/modules/commandTxs.js b/modules/commandTxs.js index 2a15498..20b58ab 100644 --- a/modules/commandTxs.js +++ b/modules/commandTxs.js @@ -3,6 +3,7 @@ const $u = require('../helpers/utils'); const config = require('./configReader'); const log = require('../helpers/log'); const notify = require('../helpers/notify'); +const twitterapi = require('./twitterapi'); module.exports = async (cmd, tx, itx) => { @@ -26,7 +27,7 @@ module.exports = async (cmd, tx, itx) => { isNonAdmin: true }, true); if (config.notify_non_admins) { - $u.sendAdmMsg(tx.senderId, `I won't execute admin commands as you are not an admin. Connect with my master.`); + $u.sendAdmMsg(tx.senderId, `I won't execute admin commands as you are not an admin. Contact my master.`); } return; } @@ -153,6 +154,36 @@ async function calc(arr) { } +async function test(param) { + + param = param[0].trim(); + if (!param || !["twitterapi"].includes(param)) { + return { + msgNotify: ``, + msgSendBack: 'Wrong arguments. Command works like this: */test twitterapi*.', + notifyType: 'log' + } + } + + let output; + + if (param === "twitterapi") { + let testResult = await twitterapi.testApi(); + if (testResult.success) { + output = "Twitter API functions well."; + } else { + output = `Error while making Twitter API request: ${testResult.message}`; + } + } + + return { + msgNotify: ``, + msgSendBack: `${output}`, + notifyType: 'log' + } + +} + function version() { return { msgNotify: ``, @@ -161,13 +192,33 @@ function version() { } } +function balances() { + let output = ""; + config.known_crypto.forEach(crypto => { + if (Store.user[crypto].balance && Store.user[crypto].balance !== undefined) { + output += `${$u.thousandSeparator(+Store.user[crypto].balance.toFixed(8), true)} _${crypto}_`; + output += "\n"; + } + }); + + return { + msgNotify: ``, + msgSendBack: `My crypto balances: +${output}`, + notifyType: 'log' + } +} + const commands = { help, rates, calc, - version + version, + balances, + test } const admin_commands = [ - "" + "test", + "balances" ] \ No newline at end of file diff --git a/modules/configReader.js b/modules/configReader.js index 15f8273..b6e84f7 100644 --- a/modules/configReader.js +++ b/modules/configReader.js @@ -59,6 +59,10 @@ const fields = { type: Object, default: {} }, + twitter_api_test_interval: { + type: Number, + default: 600 + }, slack: { type: String, default: null diff --git a/modules/twitterapi.js b/modules/twitterapi.js index 1ae1a94..0c146e7 100644 --- a/modules/twitterapi.js +++ b/modules/twitterapi.js @@ -110,7 +110,7 @@ async function getAccountTimeline(account) { async function getAccountInfo(account) { const accountSN = $u.getTwitterScreenName(account); - console.log(`Getting user info for @${accountSN}..`) + // console.log(`Getting user info for @${accountSN}..`) return await Twitter.get('users/show', {screen_name: accountSN}) .then(function (data) { @@ -128,6 +128,33 @@ async function getAccountInfo(account) { module.exports = { + async testApi() { + + let testResult = { + success: false, + message: "" + } + + try { + + const testAccount = "@TwitterDev"; + let result = await getAccountInfo(testAccount); + + if (result && result.id_str === '2244994945') { + testResult.success = true; + } else { + testResult.success = false; + testResult.message = "Request *users/show* for @TwitterDev didn't return expected value."; + } + return testResult; + + } catch (e) { + testResult.success = false; + testResult.message = "Exception while making *users/show* request."; + return testResult; + } + + }, // Search for predefined toFollowIds — save Twitter API requests // followAccount should be in "twitter_follow" param in config async checkIfAccountFollowing(twitterAccount, followAccount) { diff --git a/package.json b/package.json index dd6c195..e086b0e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "adamant-bountybot", - "version": "0.8.1", - "description": "", + "version": "1.0.0", + "description": "ADAMANT Bounty bot — a software that allows you to carry out bounty campaigns & crypto airdrops, with automatic task verifications and payouts.", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1"