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'; 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 }) ] }); var ym = require('yahoomessenger'); ym.newInstance(); 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}); } function sendMessage(destination, message) { logger.info('Sending YM message', {from: config.globals.username, to: destination, message: message}); ym.sendPM(destination, message); } 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; } logger.info('Evo response in xml format', {response: parsedResponse}); }); }); // 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); setInterval(function() { logger.verbose('Sending keepalive packet'); ym.keepAlive(); }, keepalive_interval);