Commit 2307442a0dfdc5a42e309b02e19371b5affed0b3
1 parent
7370d6a4ae
Exists in
master
coba bugfix
Showing 1 changed file with 6 additions and 1 deletions Inline Diff
index.js
1 | var ym = require('yahoomessenger'); | 1 | var ym = require('yahoomessenger'); |
2 | var http = require('http'); | 2 | var http = require('http'); |
3 | var url = require('url'); | 3 | var url = require('url'); |
4 | var winston = require('winston'); | 4 | var winston = require('winston'); |
5 | var strftime = require('strftime'); | 5 | var strftime = require('strftime'); |
6 | //var strptime = require('micro-strptime').strptime; | 6 | //var strptime = require('micro-strptime').strptime; |
7 | var request = require('request'); | 7 | var request = require('request'); |
8 | var striptags = require('striptags'); | 8 | var striptags = require('striptags'); |
9 | var moment = require('moment'); | 9 | var moment = require('moment'); |
10 | var xmlparser = require('xml2js').parseString; | 10 | var xmlparser = require('xml2js').parseString; |
11 | var fs = require('fs'); | 11 | var fs = require('fs'); |
12 | var ini = require('ini'); | 12 | var ini = require('ini'); |
13 | 13 | ||
14 | var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8')); | 14 | var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8')); |
15 | 15 | ||
16 | var keepalive_interval = 60 * 1000; | 16 | var keepalive_interval = 60 * 1000; |
17 | var last_message_hash = ''; | 17 | var last_message_hash = ''; |
18 | var log_level = 'info'; | 18 | var log_level = 'info'; |
19 | var isOnline = false; | 19 | var isOnline = false; |
20 | 20 | ||
21 | if (config.globals.log_level) { | 21 | if (config.globals.log_level) { |
22 | log_level = config.globals.log_level; | 22 | log_level = config.globals.log_level; |
23 | } | 23 | } |
24 | 24 | ||
25 | var logger = new (winston.Logger)({ | 25 | var logger = new (winston.Logger)({ |
26 | transports: [ | 26 | transports: [ |
27 | new (winston.transports.Console)({ | 27 | new (winston.transports.Console)({ |
28 | timestamp: function() { | 28 | timestamp: function() { |
29 | return strftime('%F %T', new Date()); | 29 | return strftime('%F %T', new Date()); |
30 | }, | 30 | }, |
31 | level: log_level | 31 | level: log_level |
32 | }), | 32 | }), |
33 | new (winston.transports.DailyRotateFile)({ | 33 | new (winston.transports.DailyRotateFile)({ |
34 | filename: __dirname + '/logs/log', | 34 | filename: __dirname + '/logs/log', |
35 | timestamp: function() { | 35 | timestamp: function() { |
36 | return strftime('%F %T', new Date()); | 36 | return strftime('%F %T', new Date()); |
37 | }, | 37 | }, |
38 | level: log_level | 38 | level: log_level |
39 | }) | 39 | }) |
40 | ] | 40 | ] |
41 | }); | 41 | }); |
42 | 42 | ||
43 | function onReady(){ | 43 | function onReady(){ |
44 | ym.login(config.globals.username, config.globals.password); | 44 | ym.login(config.globals.username, config.globals.password); |
45 | } | 45 | } |
46 | 46 | ||
47 | function onLoginSuccessful(data) { | 47 | function onLoginSuccessful(data) { |
48 | logger.info('Login successful as ' + data.firstname + ' ' + data.lastname + ' (' + data.user_id + ')', {data: data}); | 48 | logger.info('Login successful as ' + data.firstname + ' ' + data.lastname + ' (' + data.user_id + ')', {data: data}); |
49 | isOnline = true; | 49 | isOnline = true; |
50 | } | 50 | } |
51 | 51 | ||
52 | function sendMessage(destination, message) { | 52 | function sendMessage(destination, message) { |
53 | if (isOnline) { | 53 | if (isOnline) { |
54 | 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}); |
55 | ym.sendPM(destination, message); | 55 | ym.sendPM(destination, message); |
56 | } | 56 | } |
57 | else { | 57 | else { |
58 | logger.warn('YM is not online yet, retrying to send message in 2 secs', {to: destination, msg: message}); | 58 | logger.warn('YM is not online yet, retrying to send message in 2 secs', {to: destination, msg: message}); |
59 | setTimeout( | 59 | setTimeout( |
60 | sendMessage, | 60 | sendMessage, |
61 | 2000, | 61 | 2000, |
62 | destination, message | 62 | destination, message |
63 | ) | 63 | ) |
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | function sendIgnoreResponse(destination, message) { | 67 | function sendIgnoreResponse(destination, message) { |
68 | sendMessage(destination, "Pesan anda diabaikan, silahkan diulang beberapa saat lagi jika diperlukan: " + message); | 68 | sendMessage(destination, "Pesan anda diabaikan, silahkan diulang beberapa saat lagi jika diperlukan: " + message); |
69 | } | 69 | } |
70 | 70 | ||
71 | function onPm(data) { | 71 | function onPm(data) { |
72 | logger.info('Incoming message via YM', {data: data}); | 72 | logger.info('Incoming message via YM', {data: data}); |
73 | var message = striptags(data.message); | 73 | var message = striptags(data.message); |
74 | 74 | ||
75 | var message_hash = data.sender + ': ' + data.message; | 75 | var message_hash = data.sender + ': ' + data.message; |
76 | if (message_hash == last_message_hash) { | 76 | if (message_hash == last_message_hash) { |
77 | logger.warn('Ignoring duplicate message', {data: data}); | 77 | logger.warn('Ignoring duplicate message', {data: data}); |
78 | return; | 78 | return; |
79 | } | 79 | } |
80 | last_message_hash = message_hash; | 80 | last_message_hash = message_hash; |
81 | 81 | ||
82 | var greeting_prefix = "Pesan anda telah diterima dan akan segera diproses:"; | 82 | var greeting_prefix = "Pesan anda telah diterima dan akan segera diproses:"; |
83 | if (config.globals.greeting_prefix) { | 83 | if (config.globals.greeting_prefix) { |
84 | greeting_prefix = config.globals.greeting_prefix; | 84 | greeting_prefix = config.globals.greeting_prefix; |
85 | } | 85 | } |
86 | 86 | ||
87 | ym.sendPM(data.sender, greeting_prefix + ' ' + message); | 87 | ym.sendPM(data.sender, greeting_prefix + ' ' + message); |
88 | 88 | ||
89 | forwardMessageToEvo(data.sender, message, formatTimestamp(data.time)); | 89 | forwardMessageToEvo(data.sender, message, formatTimestamp(data.time)); |
90 | } | 90 | } |
91 | 91 | ||
92 | function onOfflinePM(data) { | 92 | function onOfflinePM(data) { |
93 | logger.info('Offline YM message', {data: data}); | 93 | logger.info('Offline YM message', {data: data}); |
94 | sendIgnoreResponse(data.sender, data.message); | 94 | sendIgnoreResponse(data.sender, data.message); |
95 | } | 95 | } |
96 | 96 | ||
97 | function onBuddyAddRequest(data) { | 97 | function onBuddyAddRequest(data) { |
98 | logger.info('onBuddyAddRequest()', {data: data}); | 98 | logger.info('onBuddyAddRequest()', {data: data}); |
99 | ym.acceptAddBuddy(data.username); | 99 | ym.acceptAddBuddy(data.username); |
100 | logger.info('Accept buddy add request: ' + data.username, {data: data}); | 100 | logger.info('Accept buddy add request: ' + data.username, {data: data}); |
101 | } | 101 | } |
102 | 102 | ||
103 | function onHttpIncomingMessage(request, response) { | 103 | function onHttpIncomingMessage(request, response) { |
104 | var qs = url.parse(request.url, true).query; | 104 | var qs = url.parse(request.url, true).query; |
105 | logger.verbose("onHttpIncomingMessage()", {qs: qs}); | 105 | logger.verbose("onHttpIncomingMessage()", {qs: qs}); |
106 | 106 | ||
107 | // abaikan balikan ping | 107 | // abaikan balikan ping |
108 | if (qs.to == config.globals.ping_ym_id) { | 108 | if (qs.to == config.globals.ping_ym_id) { |
109 | return; | 109 | return; |
110 | } | 110 | } |
111 | 111 | ||
112 | var destination = qs.to.replace(config.globals.msisdn_suffix, ''); | 112 | var destination = qs.to.replace(config.globals.msisdn_suffix, ''); |
113 | logger.info('Sending YM message from ' + config.globals.username + ' to ' + destination + ': ' + qs.msg); | 113 | logger.info('Sending YM message from ' + config.globals.username + ' to ' + destination + ': ' + qs.msg); |
114 | sendMessage(destination, qs.msg); | 114 | sendMessage(destination, qs.msg); |
115 | response.end('OK'); | 115 | response.end('OK'); |
116 | } | 116 | } |
117 | 117 | ||
118 | function formatTimestamp(ts) { | 118 | function formatTimestamp(ts) { |
119 | /* | 119 | /* |
120 | var _ts = strptime(ts, '%A %b %d %Y %H:%M:%S GMT%z'); | 120 | var _ts = strptime(ts, '%A %b %d %Y %H:%M:%S GMT%z'); |
121 | return strftime('%F %T', _ts); | 121 | return strftime('%F %T', _ts); |
122 | */ | 122 | */ |
123 | return moment(ts, 'ddd MMM D YYYY HH:mm:ss Z').format('YYYY-MM-DD HH:mm:ss') | 123 | return moment(ts, 'ddd MMM D YYYY HH:mm:ss Z').format('YYYY-MM-DD HH:mm:ss') |
124 | } | 124 | } |
125 | 125 | ||
126 | function forwardMessageToEvo(sender, message, ts) { | 126 | function forwardMessageToEvo(sender, message, ts) { |
127 | var msisdn = sender + config.globals.msisdn_suffix; | 127 | var msisdn = sender + config.globals.msisdn_suffix; |
128 | var opts = { | 128 | var opts = { |
129 | url: config.globals.evo_url, | 129 | url: config.globals.evo_url, |
130 | qs: { | 130 | qs: { |
131 | msg: message, | 131 | msg: message, |
132 | msisdn: msisdn, | 132 | msisdn: msisdn, |
133 | smsc: config.globals.smsc, | 133 | smsc: config.globals.smsc, |
134 | ts: ts | 134 | ts: ts |
135 | } | 135 | } |
136 | }; | 136 | }; |
137 | 137 | ||
138 | logger.verbose("Forwarding message to evo", {request_opts: opts}); | 138 | logger.verbose("Forwarding message to evo", {request_opts: opts}); |
139 | request(opts, function(err, response, body) { | 139 | request(opts, function(err, response, body) { |
140 | if (err) { | 140 | if (err) { |
141 | logger.warn('Error forwarding to evo: ' + err); | 141 | logger.warn('Error forwarding to evo: ' + err); |
142 | return; | 142 | return; |
143 | } | 143 | } |
144 | 144 | ||
145 | if (response.statusCode != 200) { | 145 | if (response.statusCode != 200) { |
146 | logger.warn('HTTP Status from evo: ' + response.statusCode, {status: response.statusCode, body: body}); | 146 | logger.warn('HTTP Status from evo: ' + response.statusCode, {status: response.statusCode, body: body}); |
147 | return; | 147 | return; |
148 | } | 148 | } |
149 | 149 | ||
150 | logger.verbose('Got response from evo', {body: body}); | 150 | logger.verbose('Got response from evo', {body: body}); |
151 | 151 | ||
152 | xmlparser(body, function(xmlerr, parsedResponse) { | 152 | xmlparser(body, function(xmlerr, parsedResponse) { |
153 | if (xmlerr) { | 153 | if (xmlerr) { |
154 | logger.verbose('Evo response not in xml format'); | 154 | logger.verbose('Evo response not in xml format'); |
155 | return; | 155 | return; |
156 | } | 156 | } |
157 | 157 | ||
158 | return; | 158 | return; |
159 | 159 | ||
160 | logger.info('Evo response in xml format', {response: parsedResponse}); | 160 | logger.info('Evo response in xml format', {response: parsedResponse}); |
161 | if (parsedResponse.response.text) { | 161 | if (parsedResponse.response.text) { |
162 | sendMessage(sender, parsedResponse.response.text[0].trim()); | 162 | sendMessage(sender, parsedResponse.response.text[0].trim()); |
163 | } | 163 | } |
164 | }); | 164 | }); |
165 | 165 | ||
166 | 166 | ||
167 | }); | 167 | }); |
168 | 168 | ||
169 | 169 | ||
170 | // kirim ping 1 detik setelah pesan agar segera diproses | 170 | // kirim ping 1 detik setelah pesan agar segera diproses |
171 | if (config.globals.send_ping_to_evo == '1') { | 171 | if (config.globals.send_ping_to_evo == '1') { |
172 | setTimeout(function() { | 172 | setTimeout(function() { |
173 | 173 | ||
174 | var pingOpts = { | 174 | var pingOpts = { |
175 | url: config.globals.evo_url, | 175 | url: config.globals.evo_url, |
176 | qs: { | 176 | qs: { |
177 | msg: 'S.' + config.globals.ping_pin, | 177 | msg: 'S.' + config.globals.ping_pin, |
178 | msisdn: config.globals.ping_ym_id + config.globals.msisdn_suffix, | 178 | msisdn: config.globals.ping_ym_id + config.globals.msisdn_suffix, |
179 | smsc: config.globals.smsc, | 179 | smsc: config.globals.smsc, |
180 | ts: strftime('%F %T') | 180 | ts: strftime('%F %T') |
181 | } | 181 | } |
182 | }; | 182 | }; |
183 | 183 | ||
184 | logger.verbose('Sending ping message', {opts: pingOpts}); | 184 | logger.verbose('Sending ping message', {opts: pingOpts}); |
185 | 185 | ||
186 | request(pingOpts, function(err, response, body) { | 186 | request(pingOpts, function(err, response, body) { |
187 | if (err) { | 187 | if (err) { |
188 | logger.warn('Error send PING to evo: ' + err); | 188 | logger.warn('Error send PING to evo: ' + err); |
189 | return; | 189 | return; |
190 | } | 190 | } |
191 | }); | 191 | }); |
192 | }, 1000); | 192 | }, 1000); |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | function createHttpServer() { | 196 | function createHttpServer() { |
197 | logger.verbose('createHttpServer()'); | 197 | logger.verbose('createHttpServer()'); |
198 | 198 | ||
199 | var httpServer = http.createServer(onHttpIncomingMessage); | 199 | var httpServer = http.createServer(onHttpIncomingMessage); |
200 | httpServer.listen(config.globals.listen_port, function(){ | 200 | httpServer.listen(config.globals.listen_port, function(){ |
201 | logger.info("HTTP server listening on " + config.globals.listen_port); | 201 | logger.info("HTTP server listening on " + config.globals.listen_port); |
202 | }); | 202 | }); |
203 | } | 203 | } |
204 | 204 | ||
205 | createHttpServer(); | 205 | createHttpServer(); |
206 | ym.on('ready', onReady); | 206 | ym.on('ready', onReady); |
207 | ym.on('loginSuccessful', onLoginSuccessful); | 207 | ym.on('loginSuccessful', onLoginSuccessful); |
208 | ym.on('pm', onPm); | 208 | ym.on('pm', onPm); |
209 | ym.on('buddyAddRequest', onBuddyAddRequest); | 209 | ym.on('buddyAddRequest', onBuddyAddRequest); |
210 | 210 | ||
211 | setTimeout(function() { | 211 | setTimeout(function() { |
212 | ym.newInstance, | 212 | function () { |
213 | ym.newInstance(); | ||
214 | }, | ||
213 | 3000 | 215 | 3000 |
214 | }) | 216 | }) |
215 | 217 | ||
216 | setInterval(function() { | 218 | setInterval(function() { |
219 | if (!isOnline) { | ||
220 | return; | ||
221 | } | ||
217 | logger.verbose('Sending keepalive packet'); | 222 | logger.verbose('Sending keepalive packet'); |
218 | ym.keepAlive(); | 223 | ym.keepAlive(); |
219 | }, keepalive_interval); | 224 | }, keepalive_interval); |
220 | 225 |