Commit 8bc7350a5bd06b4a5589f6a8d47fccb83f935756
1 parent
bb4825f3bc
Exists in
master
xml2js
Showing 2 changed files with 15 additions and 1 deletions Inline Diff
index.js
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 |
package.json
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 |