index.js 6.41 KB
var ym = require('yahoomessenger');
var http = require('http');
var url = require('url');
var winston = require('winston');
var strftime = require('strftime');
//var strptime = require('micro-strptime').strptime;
var request = require('request');
var striptags = require('striptags');
var moment = require('moment');
var xmlparser = require('xml2js').parseString;
var fs = require('fs');
var ini = require('ini');

var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8'));

var keepalive_interval = 60 * 1000;
var last_message_hash = '';
var log_level = 'info';
var isOnline = false;

if (config.globals.log_level) {
    log_level = config.globals.log_level;
}

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({
      timestamp: function() {
        return strftime('%F %T', new Date());
      },
      level: log_level
    }),
    new (winston.transports.DailyRotateFile)({
      filename: __dirname + '/logs/log',
      timestamp: function() {
        return strftime('%F %T', new Date());
      },
      level: log_level
    })
  ]
});

function onReady(){
  ym.login(config.globals.username, config.globals.password);
}

function onLoginSuccessful(data) {
    logger.info('Login successful as ' + data.firstname + ' ' + data.lastname + ' (' + data.user_id + ')', {data: data});
    isOnline = true;
}

function sendMessage(destination, message) {
    if (isOnline) {
        logger.info('Sending YM message', {from: config.globals.username, to: destination, message: message});
        ym.sendPM(destination, message);
    }
    else {
        logger.warn('YM is not online yet, retrying to send message in 2 secs', {to: destination, msg: message});
        setTimeout(
            function() {
                sendMessage(destination, message);
            },
            2000
        )
    }
}

function sendIgnoreResponse(destination, message) {
    sendMessage(destination, "Pesan anda diabaikan, silahkan diulang beberapa saat lagi jika diperlukan: " + message);
}

function onPm(data) {
    logger.info('Incoming message via YM', {data: data});
    var message = striptags(data.message);

    var message_hash = data.sender + ': ' + data.message;
    if (message_hash == last_message_hash) {
        logger.warn('Ignoring duplicate message', {data: data});
        return;
    }
    last_message_hash = message_hash;

    var greeting_prefix = "Pesan anda telah diterima dan akan segera diproses:";
    if (config.globals.greeting_prefix) {
        greeting_prefix = config.globals.greeting_prefix;
    }

    ym.sendPM(data.sender, greeting_prefix + ' ' + message);

    forwardMessageToEvo(data.sender, message, formatTimestamp(data.time));
}

function onOfflinePM(data) {
    logger.info('Offline YM message', {data: data});
    sendIgnoreResponse(data.sender, data.message);
}

function onBuddyAddRequest(data) {
    logger.info('onBuddyAddRequest()', {data: data});
    ym.acceptAddBuddy(data.username);
    logger.info('Accept buddy add request: ' + data.username, {data: data});
}

function onHttpIncomingMessage(request, response) {
    var qs = url.parse(request.url, true).query;
    logger.verbose("onHttpIncomingMessage()", {qs: qs});

    // abaikan balikan ping
    if (qs.to == config.globals.ping_ym_id) {
        return;
    }

    var destination = qs.to.replace(config.globals.msisdn_suffix, '');
    logger.info('Sending YM message from ' + config.globals.username + ' to ' + destination + ': ' + qs.msg);
    sendMessage(destination, qs.msg);
    response.end('OK');
}

function formatTimestamp(ts) {
    /*
    var _ts = strptime(ts, '%A %b %d %Y %H:%M:%S GMT%z');
    return strftime('%F %T', _ts);
    */
    return moment(ts, 'ddd MMM D YYYY HH:mm:ss Z').format('YYYY-MM-DD HH:mm:ss')
}

function forwardMessageToEvo(sender, message, ts) {
    var msisdn = sender + config.globals.msisdn_suffix;
    var opts = {
        url: config.globals.evo_url,
        qs: {
            msg: message,
            msisdn: msisdn,
            smsc: config.globals.smsc,
            ts: ts
        }
    };

    logger.verbose("Forwarding message to evo", {request_opts: opts});
    request(opts, function(err, response, body) {
        if (err) {
            logger.warn('Error forwarding to evo: ' + err);
            return;
        }

        if (response.statusCode != 200) {
            logger.warn('HTTP Status from evo: ' + response.statusCode, {status: response.statusCode, body: body});
            return;
        }

        logger.verbose('Got response from evo', {body: body});

        xmlparser(body, function(xmlerr, parsedResponse) {
            if (xmlerr) {
                logger.verbose('Evo response not in xml format');
                return;
            }

            return;

            logger.info('Evo response in xml format', {response: parsedResponse});
            if (parsedResponse.response.text) {
                sendMessage(sender, parsedResponse.response.text[0].trim());
            }
        });


    });


    // kirim ping 1 detik setelah pesan agar segera diproses
    if (config.globals.send_ping_to_evo == '1') {
        setTimeout(function() {

            var pingOpts = {
                url: config.globals.evo_url,
                qs: {
                    msg: 'S.' + config.globals.ping_pin,
                    msisdn: config.globals.ping_ym_id + config.globals.msisdn_suffix,
                    smsc: config.globals.smsc,
                    ts: strftime('%F %T')
                }
            };

            logger.verbose('Sending ping message', {opts: pingOpts});

            request(pingOpts, function(err, response, body) {
                if (err) {
                    logger.warn('Error send PING to evo: ' + err);
                    return;
                }
            });
        }, 1000);
    }
}

function createHttpServer() {
    logger.verbose('createHttpServer()');

    var httpServer = http.createServer(onHttpIncomingMessage);
    httpServer.listen(config.globals.listen_port, function(){
        logger.info("HTTP server listening on " + config.globals.listen_port);
    });
}

createHttpServer();
ym.on('ready', onReady);
ym.on('loginSuccessful', onLoginSuccessful);
ym.on('pm', onPm);
ym.on('buddyAddRequest', onBuddyAddRequest);

setTimeout(
    function() {
        ym.newInstance();
    },
    3000
);

setInterval(
    function() {
        if (!isOnline) {
            return;
        }
        logger.verbose('Sending keepalive packet');
        ym.keepAlive();
    },
    keepalive_interval
);