var request = require('request'); var xpath = require('xpath'); var parse5 = require('parse5'); var xmlser = require('xmlserializer'); var dom = require('xmldom').DOMParser; var xml2js = require('xml2js').parseString; var argv = require('minimist')(process.argv.slice(2), {string: ['requestid', 'destination']}); var strftime = require('strftime'); var fs = require('fs'); var ini = require('ini'); var winston = require('winston'); var config; var logger = new winston.Logger({ transports: [ new (winston.transports.Console)() ] }); function setLogger(_logger) { logger = _logger; } function advice(data, callback) { if (!data.trxid && !data.destination) { logger.warn('Webreport advice request without data. Canceling', {data: data}); return; } if (data.config) { config = data.config; } else { try { config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8')); } catch(err) { logger.warn('Error loading config file'); return; } } login(data, callback); }; function login(data, callback) { var jar = request.jar(); var options = { url: 'http://103.11.75.142:9009/dealer/index.php/admin/login', jar: jar, followAllRedirects: true, form: { username: config.webreport.username, password: config.webreport.password, Submit: 'Login', }, }; //console.log('Requesting', options); request.post(options, function(error, httpResponse, body) { if (error) { logger.warn('Error retrieving login', {options: options, error: error, body: body}); return; } if (body.search('Incorrect username') >= 0) { logger.warn('Salah username / password', {options: options}); return; } getTrxStatusPage(data, jar, callback); }); } function getTrxStatusPage(data, jar, callback) { var options = { url: 'http://103.11.75.142:9009/dealer/index.php/transaction/index', jar: jar, followAllRedirects: true, form: { startdate: '1970-01-01', enddate: strftime('%F'), pdate: '', trxid: '', destmisdn: '', type: 0, ts: '', submit: 'Find', }, }; if (data.trxid) { options.form.trxid = data.trxid; } if (data.destination) { options.form.destmisdn = data.destination; } //console.log(options); request.post(options, function(error, httpResponse, body) { if (error) { logger.warn('Error retrieving trx status page', {data: data, options: options, err: error}); return; } body = body.replace(/<\/thead>\s<\/tbody>/, "</thead>\n<tbody>"); var document = parse5.parse(body); var xhtml = xmlser.serializeToString(document); var doc = new dom().parseFromString(xhtml); var select = xpath.useNamespaces({"x": "http://www.w3.org/1999/xhtml"}); var nodes = select('//x:*[@id="dirlist"]/x:tbody/x:tr/x:td', doc); var status = {}; try { status = { trxId: nodes[0].firstChild.data, trxDate: nodes[1].firstChild.data, updateDate: nodes[2].firstChild.data, product: nodes[3].firstChild.data, amount: nodes[4].firstChild.data, msisdn: nodes[5].firstChild.data, reffId: nodes[6].firstChild.data, status: nodes[7].firstChild.data, response: nodes[8].toString(), } } catch(errStatus) { logger.warn('Error parsing status', {data: data, status: status}); if (callback) { callback(); } return; } status.response = status.response.replace('<td>', ''); status.response = status.response.replace('</td>', ''); status.response = status.response.replace(/\n/g, ''); status.response = status.response.trim(); //status.response_raw = status.response; xml2js(status.response, function (err, result) { if (err) { logger.warn('Gagal parsing XML', {err: err, status: status, doc: doc}); if (callback) { status.response = {}; callback(status); } return; } try { status.response = result.result; } catch(e) { logger.warn('Exception on get status.response', {e: e, result: result}); } if (!callback) { logger.warn('Invalid callback on checkstatus', {status: status}); } else { logger.verbose('Calling callbackFromWebReport', {data: data, status: status, body: body}) callback(status); } }); }); } if (require.main === module) { var data = { trxid: argv.trxid, destination: argv.destination, } if (argv.trxid) { data.trxid = argv.trxid; } if (argv.destination) { data.destinaton = argv.destination; } advice(data); } exports.setLogger = setLogger; exports.advice = advice;