diff --git a/lib/modem.js b/lib/modem.js index cf4f750..7364c7d 100644 --- a/lib/modem.js +++ b/lib/modem.js @@ -13,6 +13,7 @@ const logger = require('komodo-sdk/logger'); const mutex = require('./mutex'); const common = require('./common'); const sms = require('./sms'); +const reportSender = require('./report-sender'); const modemInfo = { manufacturer: null, @@ -51,7 +52,8 @@ async function readSMS(slot) { parser.on('data', async (data) => { if (data) { const smsObject = sms.extract(data.toString().trim()); - console.log('SMS', smsObject); // eslint-disable-line no-console + // console.log('SMS', smsObject); // eslint-disable-line no-console + reportSender.incomingSMS(smsObject); } mutex.releaseLockWaitForOK(); }); diff --git a/lib/report-sender.js b/lib/report-sender.js new file mode 100644 index 0000000..1588bfd --- /dev/null +++ b/lib/report-sender.js @@ -0,0 +1,33 @@ +'use strict'; + +const request = require('request'); + +const config = require('komodo-sdk/config'); +const logger = require('komodo-sdk/logger'); + +function incomingSMS(message) { + if (!config || !config.report_url || !config.report_url.incoming_sms) return; + + const requestOptions = { + url: config.report_url.incoming_sms, + qs: { + modem: config.name, + number: message.from, + msg: message.message, + }, + }; + + logger.info('Sending report via HTTP', requestOptions); + request(requestOptions, (err, res, body) => { + if (err) { + logger.warn(`Error sending report via HTTP. ${err.toString()}`); + return; + } + + if (res.statusCode !== 200) { + logger.warn(`Error sending report via HTTP. Server respond with HTTP status code ${res.statusCode}`, { http_status_code: res.statusCode, body }); + } + }); +} + +exports.incomingSMS = incomingSMS; diff --git a/lib/sms.js b/lib/sms.js index 16cb3e9..819cd10 100644 --- a/lib/sms.js +++ b/lib/sms.js @@ -7,13 +7,15 @@ function extract(raw) { const lines = raw.trim().split(/[\n\r]+/m); if (!lines) return null; - const metadata = lines[0].split(',') || []; + const metadata = lines[0].split(',').map(el => el.replace(/"/g, '')) || []; - const ts = moment(`20${metadata[3]} ${metadata[4]}`, 'YYYY/MM/DD HH:mmm:ss').format('YYYY-MM-DD HH:mm:ss'); + const tsFromRaw = `${metadata[3]} ${metadata[4].replace(/\+\d+/, '')}`; + const ts = moment(tsFromRaw, 'YY/MM/DD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'); const result = { metadata: { - from: metadata[1], + status: metadata[0].replace(/^.+: /, ''), + from: metadata[1].replace(/^\+/, ''), ts, raw: lines[0], }, diff --git a/package-lock.json b/package-lock.json index a5142a4..5fd5bd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3934,6 +3934,60 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "should": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", + "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", + "dev": true, + "requires": { + "should-equal": "^2.0.0", + "should-format": "^3.0.3", + "should-type": "^1.4.0", + "should-type-adaptors": "^1.0.1", + "should-util": "^1.0.0" + } + }, + "should-equal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", + "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", + "dev": true, + "requires": { + "should-type": "^1.4.0" + } + }, + "should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "dev": true, + "requires": { + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" + } + }, + "should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "dev": true + }, + "should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dev": true, + "requires": { + "should-type": "^1.3.0", + "should-util": "^1.0.0" + } + }, + "should-util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", + "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", + "dev": true + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", diff --git a/package.json b/package.json index 7e6bcde..39d6ceb 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "devDependencies": { "eslint": "^5.16.0", "eslint-config-airbnb-base": "^13.2.0", - "eslint-plugin-import": "^2.18.2" + "eslint-plugin-import": "^2.18.2", + "should": "^13.2.3" }, "dependencies": { "@serialport/parser-delimiter": "^2.0.2", @@ -29,6 +30,7 @@ "komodo-sdk": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git", "locks": "^0.2.2", "moment": "^2.24.0", + "request": "^2.88.0", "serialport": "^7.1.5", "serialport-gsm": "^3.2.0" } diff --git a/test/sms.js b/test/sms.js new file mode 100644 index 0000000..28c238a --- /dev/null +++ b/test/sms.js @@ -0,0 +1,28 @@ +'use strict'; + +/* global describe it */ + +require('should'); + +const sms = require('../lib/sms'); + +describe('#sms', () => { + describe('#extract', () => { + const raw = '+CMGR: "REC UNREAD","+6282210008543",,"19/07/26,13:21:16+28"\r\nsudah bisa?'; + const messageParsed = sms.extract(raw); + + it('should return raw correctly', () => { + messageParsed.raw.should.equal(raw); + }); + + it('should return correct metadata', () => { + messageParsed.metadata.status.should.equal('REC UNREAD'); + messageParsed.metadata.from.should.equal('6282210008543'); + messageParsed.metadata.ts.should.equal('2019-07-26 13:21:16'); + }); + + it('should return correct message', () => { + messageParsed.message.should.equal('sudah bisa?'); + }); + }); +});