Skip to content

Instantly share code, notes, and snippets.

@cryptcoin-junkey
Created August 17, 2018 02:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cryptcoin-junkey/34ff006508bb9982dc34b5d68b96a99b to your computer and use it in GitHub Desktop.
Save cryptcoin-junkey/34ff006508bb9982dc34b5d68b96a99b to your computer and use it in GitHub Desktop.
A part of Tipple. (Command parser. Licensed under MIT.)
import express = require('express');
import twit = require('twit');
import report_queue = require('./report-queue');
import utils = require('./utils');
import tip = require('./tip');
const bodyParser = require('body-parser');
const app = express();
const crypto = require('crypto');
const config = require("./config.json");
//app.set('port', (process.env.PORT || 8080));
app.set('port', 8080);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// For health checks by load-balancers.
app.get('/', (_request: express.Request, response: express.Response) => {
response.status(200);
response.send('"healthy"');
});
// For challenge response check (CRC)
app.get(config.expressWatchPath, (request, response) => {
const crc_token = request.query.crc_token
if (crc_token) {
const hash = crypto.createHmac('sha256', config.TWITTER_CONSUMER_SECRET).update(crc_token).digest('base64');
console.log(`receive crc check. token=${crc_token} responce=${hash}`);
response.status(200);
response.send({
response_token: 'sha256=' + hash
});
} else {
const errorMessage = 'Error: crc_token missing from request.';
response.status(400);
response.send(errorMessage);
console.error(errorMessage);
}
});
const isSelfTweet = (for_user_id: string, tweet: twit.Twitter.Status) => {
if (for_user_id === tweet.user.id_str) {
console.log(`Tweeted by botself: TweetID ${tweet.id_str}.`);
return false;
}
return true;
};
const randomTail = () =>
"....".substring(Math.random() * 4) + "!!!".substring(Math.random() * 3)
const parseTweet = (tweet: twit.Twitter.Status) => {
if (!tweet.text) {
console.warn(`Can't parse the tweet.text: ${tweet}`);
return;
}
const parse = tweet.text.match(/^\s*(@\S+\s+)*(.*)$/);
if (!parse || !parse[2]) {
console.warn(`Can't parse the tweet: ${tweet.text}`);
return;
}
const cmd = parse[2] as string;
switch (true) {
case /^TIP(\s.*)?$/i.test(cmd):
{
const match = cmd.match(/TIP\s+@(.*)\s+(([1-9]\d*|0)(\.\d+)?).*$/i);
if (match != null) {
tip
.doIt(tweet.user.id_str, match[1], +(match[2]))
.then(() => {
if (match[1] === 'tipxrp') {
report_queue.reply(`@${tweet.user.screen_name} Thank you for your donation${randomTail()}!`, tweet.id_str);
} else {
report_queue.reply(`@${tweet.user.screen_name} Sent ${match[2]}XRP to @${match[1]}${randomTail()}`, tweet.id_str);
}
})
.catch ((error: any) =>
report_queue.reply(`@${tweet.user.screen_name} Fail to send. (msg: ${error.message})`, tweet.id_str));
} else {
report_queue.reply(`@${tweet.user.screen_name} Couldn't parse your command${randomTail()}`, tweet.id_str);
console.warn(`Can't parse the cmd tweet: ${cmd}`);
}
}
break;
case /^GIVEME(\s.*)?$/i.test(cmd):
report_queue.reply(`@${tweet.user.screen_name} Faucet will not be implemented. Sorry${randomTail()}`, tweet.id_str);
break;
case /BALANCE(\s.*)?$/i.test(cmd):
utils
.getBalance(tweet.user.id_str)
.then ((balance: any) =>
report_queue.reply(`@${tweet.user.screen_name} You have ${balance}XRP${randomTail()}`, tweet.id_str));
break;
case /^DEPOSIT(\s.*)?$/i.test(cmd):
utils
.getWalletAddress(tweet.user.id_str)
.then (address =>
report_queue.reply(`@${tweet.user.screen_name} Your XRP address/desination tag is ${address[0]} / ${address[1]}${randomTail()}`, tweet.id_str));
break;
case /^WITHDRAW(\s.*)?$/i.test(cmd):
{
const match = cmd.match(/^WITHDRAW\s+(([1-9]\d*|0)(\.\d+)?)\s+((r\S{33})(\?dt=(\d+))?)(\s.*)?$/i);
if (match != null) {
utils
.requestWithdraw(tweet.user.id_str, match[5], +(match[1]), match[7] ? +(match[7]) : 0)
.then(result =>
report_queue.reply(`@${tweet.user.screen_name} Accepted your withdrawal request : ${result[0]}XRP (incl. tx fee ${result[1]})${randomTail()}`, tweet.id_str))
.catch(error => {
report_queue.reply(`@${tweet.user.screen_name} Error in your withdrawal. (msg: ${error.message})${randomTail()}`, tweet.id_str);
console.error(error);
});
} else {
report_queue.reply(`@${tweet.user.screen_name} Couldn't parse your command${randomTail()}`, tweet.id_str);
console.warn(`Can't parse the cmd tweet: ${cmd}`);
}
}
break;
case /^GETCODE(\s.*)?$/i.test(cmd):
report_queue.reply(`@${tweet.user.screen_name} Invitation program will not be implemented. Sorry${randomTail()}`, tweet.id_str);
break;
case /^INVITED(\s.*)?$/i.test(cmd):
report_queue.reply(`@${tweet.user.screen_name} Invitation program will not be implemented. Sorry${randomTail()}`, tweet.id_str);
break;
//TODO: implment
case /^FOLLOWME(\s.*)?$/i.test(cmd):
// robot.logger.info "followed ${tweet.user.screen_name}!"
// console.dir msg.message.user
// robot.adapter.join msg.message.user
break;
case /^HELP(\s.*)?$/i.test(cmd):
console.log(`Tweet: test comand.`);
report_queue.reply(`@${tweet.user.screen_name} Please open https://tipxrp.monaco-ex.org/ ${randomTail()}`, tweet.id_str);
break;
default:
console.log(`Tweet: ${tweet.text}`);
break;
}
};
app.post(config.expressWatchPath, (request, response) => {
const tweet_create_events = request.body.tweet_create_events;
if (tweet_create_events) {
tweet_create_events.filter((x: twit.Twitter.Status) => isSelfTweet(request.body.for_user_id, x))
.map((x: twit.Twitter.Status) => parseTweet(x));
} else {
console.log(`Skipped: ${JSON.stringify(request.body, null, " ")}`);
}
console.log('====');
response.send('200 OK');
});
require('./cron').doIt();
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment