"use strict"; const request = require('request'); const uuidv4 = require('uuid/v4'); const moment = require('moment'); const config = require('komodo-sdk/config'); const logger = require('komodo-sdk/logger'); const modems = require('./modems'); const partnerLastSeen = require('./partner-last-seen'); const history = require('./history'); async function _getApproriateHandlerByLastSeen(partnerNumber) { logger.verbose('Looking for last seen on for partner number ' + partnerNumber); const lastSeenFrom = await partnerLastSeen.get(partnerNumber); return lastSeenFrom; } function _getApproriateHandlerByForced() { if (!config.sending_handler || !config.sending_handler.length) return; const sendingHandlerCount = config.sending_handler.length; const idx = Math.floor(Math.random() * sendingHandlerCount); return config.sending_handler[idx]; } async function _getApproriateHandler(partnerNumber, origin) { let handlerToUse; if (config.handler_chooser_algorithm === 'FORCED') { handlerToUse = _getApproriateHandlerByForced(); logger.verbose('Config file mentioned to using FORCED handler chooser algorithm', { handler_to_use: handlerToUse}); } else { handlerToUse = await _getApproriateHandlerByLastSeen(partnerNumber); logger.verbose('Config file mentioned to using LAST-SEEN handler chooser algorithm', { handler_to_use: handlerToUse}); } if (!modems.getModemConfig(handlerToUse, config.modems)) { const handlerWithSameOrigin = modems.getModemConfig(origin, config.modems); if (handlerWithSameOrigin) { logger.verbose('Invalid approriate handler, using handler from the same ORIGIN request by CORE to send sms') handlerToUse = origin; } else { logger.verbose('Invalid approriate handler, using default handler to send sms') handlerToUse = config.default_modem; } } return handlerToUse; } function _send(destinationNumber, msg, handlerName) { /* if (msg.length > 160 && !config.do_not_trim_long_sms) { logger.verbose('Message trim to 160 chars'); msg = msg.slice(0, 156) + ' ...'; } */ if (msg.length > 160) { const newMsg = msg.slice(0, 160); const remainingMsg = msg.slice(160); _send(destinationNumber, newMsg, handlerName); setTimeout(() => { _send(destinationNumber, remainingMsg, handlerName); }, 2000); return; } const modem = modems.getModemConfig(handlerName, config.modems); if (!modem) { logger.warn('Not knowing modem to use. Ignoring message', { destination_number: destinationNumber, msg: msg, handler_name: handlerName }); return; } if (!modem.url || !modem.apikey) { logger.warn('Invalid modem configuration', { config: modem, handler_name: handlerName }); return; } const reqId = uuidv4(); history.push({ ts: moment().format('YYYY-MM-DD HH:mm:ss'), modem: { name: handlerName, }, direction: 'OUTGOING', partner: destinationNumber, message: msg, }); const requestOptions = { url: modem.url, qs: { msg: msg, number: destinationNumber, reqid: reqId, apikey: modem.apikey } } logger.info('Sending message to modem handler', { req_id: reqId, destination_number: destinationNumber, msg: msg, msg_length: msg.length, handler_name: handlerName }); request(requestOptions, function(err, res, body) { if (err) { logger.warn('Error requesting to modem handler. ' + err.toString(), { req_id: reqId, handler_name: handlerName }); } else if (res.statusCode != 200) { logger.warn('Modem handler not responding with HTTP status code 200.', { http_status_code: res.statusCode, req_id: reqId, handler_name: handlerName }); } else { logger.verbose('Message sent to handler', { req_id: reqId, handler_name: handlerName, response_body: body }); } }) } async function send(partner, msg, origin) { if (!partner) return; if (typeof msg !== 'string') { logger.warn('Message to send is not a string, ignoring message'); return; } msg = msg.trim(); if (!msg) return; const destinationNumber = modems.removeSuffixFromNumber(partner, config); logger.verbose('Choosing handler name', { partner, destinationNumber, msg, origin }); let handlerName = ( await _getApproriateHandler(destinationNumber) ); _send(destinationNumber, msg, handlerName); } exports.send = send;