Commit efddc0f1c5822ac5a1f49441b340f198b17c30da
1 parent
455edfea58
Exists in
master
ready to test
Showing 6 changed files with 282 additions and 0 deletions Side-by-side Diff
.gitignore
evo-im.js
... | ... | @@ -0,0 +1,118 @@ |
1 | +var strftime = require('strftime'); | |
2 | +var request = require('request'); | |
3 | +var xmlparser = require('xml2js').parseString; | |
4 | +var http = require('http'); | |
5 | +var url = require('url'); | |
6 | + | |
7 | +var config; | |
8 | +var logger; | |
9 | + | |
10 | +function start(options) { | |
11 | + if (options && options.config) { | |
12 | + config = options.config; | |
13 | + } | |
14 | + | |
15 | + if (options && options.logger) { | |
16 | + logger = options.logger; | |
17 | + } | |
18 | + | |
19 | + createHttpServer(); | |
20 | +} | |
21 | + | |
22 | +function formatTimestamp(ms) { | |
23 | + return strftime('%F %T', new Date(ms)); | |
24 | +} | |
25 | + | |
26 | +function onMessage(sender, message, ts, sendMessage) { | |
27 | + var opts = { | |
28 | + url: config.globals.evo_url, | |
29 | + qs: { | |
30 | + msg: message, | |
31 | + msisdn: sender, | |
32 | + smsc: config.globals.smsc, | |
33 | + ts: formatTimestamp(ts) | |
34 | + } | |
35 | + }; | |
36 | + | |
37 | + logger.verbose("Forwarding message to evo", {request_opts: opts}); | |
38 | + request(opts, function(err, response, body) { | |
39 | + if (err) { | |
40 | + logger.warn('Error forwarding to evo: ' + err); | |
41 | + return; | |
42 | + } | |
43 | + | |
44 | + if (response.statusCode != 200) { | |
45 | + logger.warn('HTTP Status from evo: ' + response.statusCode, {status: response.statusCode, body: body}); | |
46 | + return; | |
47 | + } | |
48 | + | |
49 | + logger.verbose('Got response from evo', {body: body}); | |
50 | + | |
51 | + xmlparser(body, function(xmlerr, parsedResponse) { | |
52 | + if (xmlerr) { | |
53 | + logger.verbose('Evo response not in xml format'); | |
54 | + return; | |
55 | + } | |
56 | + | |
57 | + return; | |
58 | + | |
59 | + logger.info('Evo response in xml format', {response: parsedResponse}); | |
60 | + if (parsedResponse.response.text) { | |
61 | + sendMessage(sender, parsedResponse.response.text[0].trim()); | |
62 | + } | |
63 | + }); | |
64 | + }); | |
65 | + | |
66 | + // kirim ping 1 detik setelah pesan agar segera diproses | |
67 | + if (config.globals.send_ping_to_evo == '1') { | |
68 | + setTimeout(function() { | |
69 | + | |
70 | + var pingOpts = { | |
71 | + url: config.globals.evo_url, | |
72 | + qs: { | |
73 | + msg: 'S.' + config.globals.ping_pin, | |
74 | + msisdn: config.globals.ping_ym_id + config.globals.msisdn_suffix, | |
75 | + smsc: config.globals.smsc, | |
76 | + ts: strftime('%F %T') | |
77 | + } | |
78 | + }; | |
79 | + | |
80 | + logger.verbose('Sending ping message', {opts: pingOpts}); | |
81 | + | |
82 | + request(pingOpts, function(err, response, body) { | |
83 | + if (err) { | |
84 | + logger.warn('Error send PING to evo: ' + err); | |
85 | + return; | |
86 | + } | |
87 | + }); | |
88 | + }, 1000); | |
89 | + } | |
90 | +} | |
91 | + | |
92 | +function onHttpIncomingMessage(request, response) { | |
93 | + var qs = url.parse(request.url, true).query; | |
94 | + logger.verbose("onHttpIncomingMessage()", {qs: qs}); | |
95 | + | |
96 | + // abaikan balikan ping | |
97 | + if (qs.to == config.globals.ping_ym_id) { | |
98 | + return; | |
99 | + } | |
100 | + | |
101 | + var destination = qs.to.replace(config.globals.msisdn_suffix, ''); | |
102 | + logger.info('Sending YM message from ' + config.globals.username + ' to ' + destination + ': ' + qs.msg); | |
103 | + sendMessage(destination, qs.msg); | |
104 | + response.end('OK'); | |
105 | +} | |
106 | + | |
107 | +function createHttpServer() { | |
108 | + logger.verbose('createHttpServer()'); | |
109 | + | |
110 | + var httpServer = http.createServer(onHttpIncomingMessage); | |
111 | + httpServer.listen(config.globals.listen_port, function(){ | |
112 | + logger.info("HTTP server listening on " + config.globals.listen_port); | |
113 | + }); | |
114 | +} | |
115 | + | |
116 | +exports.start = start; | |
117 | +exports.formatTimestamp = formatTimestamp; | |
118 | +exports.onMessage = onMessage; |
index.js
... | ... | @@ -0,0 +1,82 @@ |
1 | +var telegram = require('node-telegram-bot-api'); | |
2 | +var logger = require('./logger.js').start(); | |
3 | +var evo = require('./evo-im.js'); | |
4 | + | |
5 | +var config = require('./config.json'); | |
6 | + | |
7 | +evo.start({ | |
8 | + config: config, | |
9 | + logger: logger | |
10 | +}); | |
11 | + | |
12 | +var chat_ids = {}; | |
13 | + | |
14 | +var options = { | |
15 | + webHook: { | |
16 | + port: config.globals.webhook_port, | |
17 | + key: __dirname+'/key.pem', | |
18 | + cert: __dirname+'/crt.pem' | |
19 | + } | |
20 | +}; | |
21 | + | |
22 | +var bot = new telegram(config.globals.token, options); | |
23 | +bot.setWebHook(config.globals.webhook_prefix + config.globals.token, __dirname+'/crt.pem'); | |
24 | + | |
25 | +function deleteChatId(from) { | |
26 | + delete chat_ids[from]; | |
27 | +} | |
28 | + | |
29 | +function sendMessage(destination, message) { | |
30 | + logger.info('Sending reply to ' + destination + ': ' + message); | |
31 | + var chat_id = chat_ids[destination]; | |
32 | + bot.sendMessage(chat_id, message); | |
33 | +} | |
34 | + | |
35 | +function createHttpResponseServer(){ | |
36 | + var httpServer = http.createServer(function(request,response){ | |
37 | + var qs = url.parse(request.url, true).query; | |
38 | + logger.info('Incoming request from SMSIN server:', {qs: qs}) | |
39 | + //logger.info(qs); | |
40 | + response.end('OK'); | |
41 | + | |
42 | + sendMessage(qs.PhoneNumber, qs.text); | |
43 | + }); | |
44 | + httpServer.listen(config.globals.listen_port, function(){ | |
45 | + logger.info("listening on " + config.globals.listen_port); | |
46 | + }) | |
47 | +} | |
48 | +createHttpResponseServer(); | |
49 | + | |
50 | +bot.getMe().then(function (me) { | |
51 | + logger.info('Hi my name is %s!', me.username); | |
52 | +}); | |
53 | + | |
54 | +bot.on('text', function (msg) { | |
55 | + logger.info(msg); | |
56 | + | |
57 | + var from = msg.from.username.toUpperCase() + config.globals.msisdn_suffix; | |
58 | + | |
59 | + var now = Math.floor(new Date().getTime()/1000); | |
60 | + | |
61 | + if (now - msg.date > config.globals.message_max_age){ | |
62 | + var message = "Pesan anda diabaikan, silahkan diulang beberapa saat lagi jika diperlukan: " + msg.text; | |
63 | + logger.info(message, {msg: msg}) | |
64 | + //bot.sendMessage(msg.chat.id, message); | |
65 | + sendMessage(from, message); | |
66 | + return; | |
67 | + } | |
68 | + | |
69 | + chat_ids[from] = msg.chat.id; | |
70 | + | |
71 | + var greeting_prefix = "Pesan anda telah diterima:"; | |
72 | + if (config.globals.greeting_prefix) { | |
73 | + greeting_prefix = config.globals.greeting_prefix; | |
74 | + } | |
75 | + | |
76 | + bot.sendMessage(msg.chat.id, greeting_prefix + ' ' + msg.text); | |
77 | + setTimeout( | |
78 | + evo.onMessage, | |
79 | + 300, | |
80 | + from, msg.text, msg.date * 1000, sendMessage | |
81 | + ); | |
82 | +}); |
logger.js
... | ... | @@ -0,0 +1,48 @@ |
1 | +var strftime = require('strftime'); | |
2 | +var winston = require('winston'); | |
3 | +var fs = require('fs'); | |
4 | + | |
5 | +var loggerTimestamp = function() { | |
6 | + return strftime('%F %T', new Date()); | |
7 | +} | |
8 | + | |
9 | +function start(options) { | |
10 | + var logDir = __dirname + '/logs' | |
11 | + | |
12 | + var logLevel = 'debug'; | |
13 | + if (options && options.logLevel) { | |
14 | + logLevel = options.logLevel; | |
15 | + } | |
16 | + | |
17 | + if (!fs.existsSync(logDir)) { | |
18 | + fs.mkdirSync(logDir); | |
19 | + } | |
20 | + | |
21 | + var logger = new winston.Logger({ | |
22 | + transports: [ | |
23 | + new (winston.transports.Console)({ | |
24 | + timestamp: function() { | |
25 | + return strftime('%F %T', new Date()); | |
26 | + }, | |
27 | + level: 'verbose', | |
28 | + }), | |
29 | + | |
30 | + new(require('winston-daily-rotate-file')) ({ | |
31 | + name: './log-file-txt', | |
32 | + filename: logDir + '/log.txt', | |
33 | + timestamp: loggerTimestamp, | |
34 | + formatter: function(options) { | |
35 | + return options.timestamp() | |
36 | + +' ' + options.level.toUpperCase() | |
37 | + +' ' + (undefined !== options.message ? options.message : '') | |
38 | + + (options.meta && Object.keys(options.meta).length ? '\n\t' + JSON.stringify(options.meta) : '' ); | |
39 | + }, | |
40 | + level: logLevel, | |
41 | + }), | |
42 | + ] | |
43 | + }); | |
44 | + | |
45 | + return logger; | |
46 | +} | |
47 | + | |
48 | +exports.start = start; |
logs/empty
package.json
... | ... | @@ -0,0 +1,30 @@ |
1 | +{ | |
2 | + "name": "evo-telegram-center", | |
3 | + "version": "1.0.0", | |
4 | + "description": "Telegram Center for EVO", | |
5 | + "main": "index.js", | |
6 | + "scripts": { | |
7 | + "test": "mocha" | |
8 | + }, | |
9 | + "repository": { | |
10 | + "type": "git", | |
11 | + "url": "git@gitlab.kodesumber.com:reload97/evo-telegram-center.git" | |
12 | + }, | |
13 | + "keywords": [ | |
14 | + "evo", | |
15 | + "telegram", | |
16 | + "ppob", | |
17 | + "reload97", | |
18 | + "r97" | |
19 | + ], | |
20 | + "author": "Adhidarma Hadiwinoto <me@adhisimon.org>", | |
21 | + "license": "ISC", | |
22 | + "dependencies": { | |
23 | + "node-telegram-bot-api": "^0.23.3", | |
24 | + "request": "^2.73.0", | |
25 | + "strftime": "^0.9.2", | |
26 | + "winston": "^2.2.0", | |
27 | + "winston-daily-rotate-file": "^1.1.5", | |
28 | + "xml2js": "^0.4.17" | |
29 | + } | |
30 | +} |