Commit efddc0f1c5822ac5a1f49441b340f198b17c30da
1 parent
455edfea58
Exists in
master
ready to test
Showing 6 changed files with 282 additions and 0 deletions Inline Diff
.gitignore
File was created | 1 | node_modules/ | |
2 | logs/log* | ||
3 | log.txt | ||
4 | run.sh | ||
5 |
evo-im.js
File was created | 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; | ||
119 |
index.js
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 | }); | ||
83 |
logger.js
File was created | 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; | ||
49 |
logs/empty
package.json
File was created | 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 | } | ||
31 |