Commit 8bc7350a5bd06b4a5589f6a8d47fccb83f935756

Authored by Adhidarma Hadiwinoto
1 parent bb4825f3bc
Exists in master

xml2js

Showing 2 changed files with 15 additions and 1 deletions Inline Diff

1 var http = require('http'); 1 var http = require('http');
2 var url = require('url'); 2 var url = require('url');
3 var winston = require('winston'); 3 var winston = require('winston');
4 var strftime = require('strftime'); 4 var strftime = require('strftime');
5 //var strptime = require('micro-strptime').strptime; 5 //var strptime = require('micro-strptime').strptime;
6 var request = require('request'); 6 var request = require('request');
7 var striptags = require('striptags'); 7 var striptags = require('striptags');
8 var moment = require('moment'); 8 var moment = require('moment');
9 var xmlparser = require('xml2js').parseString;
9 var fs = require('fs'); 10 var fs = require('fs');
10 var ini = require('ini'); 11 var ini = require('ini');
11 12
12 var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8')); 13 var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8'));
13 14
14 var keepalive_interval = 60 * 1000; 15 var keepalive_interval = 60 * 1000;
15 var last_message_hash = ''; 16 var last_message_hash = '';
16 var log_level = 'info'; 17 var log_level = 'info';
17 18
18 if (config.globals.log_level) { 19 if (config.globals.log_level) {
19 log_level = config.globals.log_level; 20 log_level = config.globals.log_level;
20 } 21 }
21 22
22 var logger = new (winston.Logger)({ 23 var logger = new (winston.Logger)({
23 transports: [ 24 transports: [
24 new (winston.transports.Console)({ 25 new (winston.transports.Console)({
25 timestamp: function() { 26 timestamp: function() {
26 return strftime('%F %T', new Date()); 27 return strftime('%F %T', new Date());
27 }, 28 },
28 level: log_level 29 level: log_level
29 }), 30 }),
30 new (winston.transports.DailyRotateFile)({ 31 new (winston.transports.DailyRotateFile)({
31 filename: __dirname + '/logs/log', 32 filename: __dirname + '/logs/log',
32 timestamp: function() { 33 timestamp: function() {
33 return strftime('%F %T', new Date()); 34 return strftime('%F %T', new Date());
34 }, 35 },
35 level: log_level 36 level: log_level
36 }) 37 })
37 ] 38 ]
38 }); 39 });
39 40
40 41
41 var ym = require('yahoomessenger'); 42 var ym = require('yahoomessenger');
42 ym.newInstance(); 43 ym.newInstance();
43 44
44 function onReady(){ 45 function onReady(){
45 ym.login(config.globals.username, config.globals.password); 46 ym.login(config.globals.username, config.globals.password);
46 } 47 }
47 48
48 function onLoginSuccessful(data) { 49 function onLoginSuccessful(data) {
49 logger.info('Login successful as ' + data.firstname + ' ' + data.lastname + ' (' + data.user_id + ')', {data: data}); 50 logger.info('Login successful as ' + data.firstname + ' ' + data.lastname + ' (' + data.user_id + ')', {data: data});
50 } 51 }
51 52
52 function sendMessage(destination, message) { 53 function sendMessage(destination, message) {
53 logger.info('Sending YM message', {from: config.globals.username, to: destination, message: message}); 54 logger.info('Sending YM message', {from: config.globals.username, to: destination, message: message});
54 ym.sendPM(destination, message); 55 ym.sendPM(destination, message);
55 } 56 }
56 57
57 function sendIgnoreResponse(destination, message) { 58 function sendIgnoreResponse(destination, message) {
58 sendMessage(destination, "Pesan anda diabaikan, silahkan diulang beberapa saat lagi jika diperlukan: " + message); 59 sendMessage(destination, "Pesan anda diabaikan, silahkan diulang beberapa saat lagi jika diperlukan: " + message);
59 } 60 }
60 61
61 function onPm(data) { 62 function onPm(data) {
62 logger.info('Incoming message via YM', {data: data}); 63 logger.info('Incoming message via YM', {data: data});
63 var message = striptags(data.message); 64 var message = striptags(data.message);
64 65
65 var message_hash = data.sender + ': ' + data.message; 66 var message_hash = data.sender + ': ' + data.message;
66 if (message_hash == last_message_hash) { 67 if (message_hash == last_message_hash) {
67 logger.warn('Ignoring duplicate message', {data: data}); 68 logger.warn('Ignoring duplicate message', {data: data});
68 return; 69 return;
69 } 70 }
70 last_message_hash = message_hash; 71 last_message_hash = message_hash;
71 72
72 var greeting_prefix = "Pesan anda telah diterima dan akan segera diproses:"; 73 var greeting_prefix = "Pesan anda telah diterima dan akan segera diproses:";
73 if (config.globals.greeting_prefix) { 74 if (config.globals.greeting_prefix) {
74 greeting_prefix = config.globals.greeting_prefix; 75 greeting_prefix = config.globals.greeting_prefix;
75 } 76 }
76 77
77 ym.sendPM(data.sender, greeting_prefix + ' ' + message); 78 ym.sendPM(data.sender, greeting_prefix + ' ' + message);
78 79
79 forwardMessageToEvo(data.sender, message, formatTimestamp(data.time)); 80 forwardMessageToEvo(data.sender, message, formatTimestamp(data.time));
80 } 81 }
81 82
82 function onOfflinePM(data) { 83 function onOfflinePM(data) {
83 logger.info('Offline YM message', {data: data}); 84 logger.info('Offline YM message', {data: data});
84 sendIgnoreResponse(data.sender, data.message); 85 sendIgnoreResponse(data.sender, data.message);
85 } 86 }
86 87
87 function onBuddyAddRequest(data) { 88 function onBuddyAddRequest(data) {
88 logger.info('onBuddyAddRequest()', {data: data}); 89 logger.info('onBuddyAddRequest()', {data: data});
89 ym.acceptAddBuddy(data.username); 90 ym.acceptAddBuddy(data.username);
90 logger.info('Accept buddy add request: ' + data.username, {data: data}); 91 logger.info('Accept buddy add request: ' + data.username, {data: data});
91 } 92 }
92 93
93 function onHttpIncomingMessage(request, response) { 94 function onHttpIncomingMessage(request, response) {
94 var qs = url.parse(request.url, true).query; 95 var qs = url.parse(request.url, true).query;
95 logger.verbose("onHttpIncomingMessage()", {qs: qs}); 96 logger.verbose("onHttpIncomingMessage()", {qs: qs});
96 97
97 // abaikan balikan ping 98 // abaikan balikan ping
98 if (qs.to == config.globals.ping_ym_id) { 99 if (qs.to == config.globals.ping_ym_id) {
99 return; 100 return;
100 } 101 }
101 102
102 var destination = qs.to.replace(config.globals.msisdn_suffix, ''); 103 var destination = qs.to.replace(config.globals.msisdn_suffix, '');
103 logger.info('Sending YM message from ' + config.globals.username + ' to ' + destination + ': ' + qs.msg); 104 logger.info('Sending YM message from ' + config.globals.username + ' to ' + destination + ': ' + qs.msg);
104 sendMessage(destination, qs.msg); 105 sendMessage(destination, qs.msg);
105 response.end('OK'); 106 response.end('OK');
106 } 107 }
107 108
108 function formatTimestamp(ts) { 109 function formatTimestamp(ts) {
109 /* 110 /*
110 var _ts = strptime(ts, '%A %b %d %Y %H:%M:%S GMT%z'); 111 var _ts = strptime(ts, '%A %b %d %Y %H:%M:%S GMT%z');
111 return strftime('%F %T', _ts); 112 return strftime('%F %T', _ts);
112 */ 113 */
113 return moment(ts, 'ddd MMM D YYYY HH:mm:ss Z').format('YYYY-MM-DD HH:mm:ss') 114 return moment(ts, 'ddd MMM D YYYY HH:mm:ss Z').format('YYYY-MM-DD HH:mm:ss')
114 } 115 }
115 116
116 function forwardMessageToEvo(sender, message, ts) { 117 function forwardMessageToEvo(sender, message, ts) {
117 var msisdn = sender + config.globals.msisdn_suffix; 118 var msisdn = sender + config.globals.msisdn_suffix;
118 var opts = { 119 var opts = {
119 url: config.globals.evo_url, 120 url: config.globals.evo_url,
120 qs: { 121 qs: {
121 msg: message, 122 msg: message,
122 msisdn: msisdn, 123 msisdn: msisdn,
123 smsc: config.globals.smsc, 124 smsc: config.globals.smsc,
124 ts: ts 125 ts: ts
125 } 126 }
126 }; 127 };
127 128
128 logger.verbose("Forwarding message to evo", {request_opts: opts}); 129 logger.verbose("Forwarding message to evo", {request_opts: opts});
129 request(opts, function(err, response, body) { 130 request(opts, function(err, response, body) {
130 if (err) { 131 if (err) {
131 logger.warn('Error forwarding to evo: ' + err); 132 logger.warn('Error forwarding to evo: ' + err);
132 return; 133 return;
133 } 134 }
134 135
135 if (response.statusCode == 200) { 136 if (response.statusCode != 200) {
136 logger.warn('HTTP Status from evo: ' + response.statusCode, {status: response.statusCode, body: body}); 137 logger.warn('HTTP Status from evo: ' + response.statusCode, {status: response.statusCode, body: body});
138 return;
137 } 139 }
140
138 logger.verbose('Got response from evo', {body: body}); 141 logger.verbose('Got response from evo', {body: body});
142
143 xmlparser(body, function(xmlerr, parsedResponse) {
144 if (xmlerr) {
145 logger.verbose('Evo response not in xml format');
146 return;
147 }
148 logger.info('Evo response in xml format', {response: parsedResponse});
149 });
150
151
139 }); 152 });
140 153
141 154
142 // kirim ping 1 detik setelah pesan agar segera diproses 155 // kirim ping 1 detik setelah pesan agar segera diproses
143 if (config.globals.send_ping_to_evo == '1') { 156 if (config.globals.send_ping_to_evo == '1') {
144 setTimeout(function() { 157 setTimeout(function() {
145 158
146 var pingOpts = { 159 var pingOpts = {
147 url: config.globals.evo_url, 160 url: config.globals.evo_url,
148 qs: { 161 qs: {
149 msg: 'S.' + config.globals.ping_pin, 162 msg: 'S.' + config.globals.ping_pin,
150 msisdn: config.globals.ping_ym_id + config.globals.msisdn_suffix, 163 msisdn: config.globals.ping_ym_id + config.globals.msisdn_suffix,
151 smsc: config.globals.smsc, 164 smsc: config.globals.smsc,
152 ts: strftime('%F %T') 165 ts: strftime('%F %T')
153 } 166 }
154 }; 167 };
155 168
156 logger.verbose('Sending ping message', {opts: pingOpts}); 169 logger.verbose('Sending ping message', {opts: pingOpts});
157 170
158 request(pingOpts, function(err, response, body) { 171 request(pingOpts, function(err, response, body) {
159 if (err) { 172 if (err) {
160 logger.warn('Error send PING to evo: ' + err); 173 logger.warn('Error send PING to evo: ' + err);
161 return; 174 return;
162 } 175 }
163 }); 176 });
164 }, 1000); 177 }, 1000);
165 } 178 }
166 } 179 }
167 180
168 function createHttpServer() { 181 function createHttpServer() {
169 logger.verbose('createHttpServer()'); 182 logger.verbose('createHttpServer()');
170 183
171 var httpServer = http.createServer(onHttpIncomingMessage); 184 var httpServer = http.createServer(onHttpIncomingMessage);
172 httpServer.listen(config.globals.listen_port, function(){ 185 httpServer.listen(config.globals.listen_port, function(){
173 logger.info("HTTP server listening on " + config.globals.listen_port); 186 logger.info("HTTP server listening on " + config.globals.listen_port);
174 }); 187 });
175 } 188 }
176 189
177 createHttpServer(); 190 createHttpServer();
178 ym.on('ready', onReady); 191 ym.on('ready', onReady);
179 ym.on('loginSuccessful', onLoginSuccessful); 192 ym.on('loginSuccessful', onLoginSuccessful);
180 ym.on('pm', onPm); 193 ym.on('pm', onPm);
181 ym.on('buddyAddRequest', onBuddyAddRequest); 194 ym.on('buddyAddRequest', onBuddyAddRequest);
182 195
183 setInterval(function() { 196 setInterval(function() {
184 logger.verbose('Sending keepalive packet'); 197 logger.verbose('Sending keepalive packet');
185 ym.keepAlive(); 198 ym.keepAlive();
186 }, keepalive_interval); 199 }, keepalive_interval);
187 200
1 { 1 {
2 "name": "evo-ym-center", 2 "name": "evo-ym-center",
3 "version": "0.0.1", 3 "version": "0.0.1",
4 "description": "EVO YM Center", 4 "description": "EVO YM Center",
5 "main": "index.js", 5 "main": "index.js",
6 "scripts": { 6 "scripts": {
7 "test": "mocha test" 7 "test": "mocha test"
8 }, 8 },
9 "repository": { 9 "repository": {
10 "type": "git", 10 "type": "git",
11 "url": "http://gitlab.kodesumber.com/adhisimon/evo-ym-center.git" 11 "url": "http://gitlab.kodesumber.com/adhisimon/evo-ym-center.git"
12 }, 12 },
13 "keywords": [ 13 "keywords": [
14 "evo", 14 "evo",
15 "guchi", 15 "guchi",
16 "gentong", 16 "gentong",
17 "yahoo", 17 "yahoo",
18 "ym", 18 "ym",
19 "ppob" 19 "ppob"
20 ], 20 ],
21 "author": "Adhidarma Hadiwinoto <gua@adhisimon.org>", 21 "author": "Adhidarma Hadiwinoto <gua@adhisimon.org>",
22 "license": "BSD", 22 "license": "BSD",
23 "dependencies": { 23 "dependencies": {
24 "ini": "~1.3.4", 24 "ini": "~1.3.4",
25 "micro-strptime": "~0.2.2", 25 "micro-strptime": "~0.2.2",
26 "moment": "^2.11.2", 26 "moment": "^2.11.2",
27 "request": "~2.65.0", 27 "request": "~2.65.0",
28 "strftime": "~0.9.2", 28 "strftime": "~0.9.2",
29 "striptags": "~2.0.4", 29 "striptags": "~2.0.4",
30 "url": "~0.11.0", 30 "url": "~0.11.0",
31 "winston": "~1.1.1", 31 "winston": "~1.1.1",
32 "xml2js": "^0.4.16",
32 "yahoomessenger": "~0.1.3-Beta" 33 "yahoomessenger": "~0.1.3-Beta"
33 } 34 }
34 } 35 }
35 36