outbound SMS now working

This commit is contained in:
Dave Horton
2020-10-02 13:49:46 -04:00
parent 4da1f4f89d
commit d9f372000e
6 changed files with 102 additions and 37 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ app.use(express.urlencoded({
extended: true
}));
app.use(express.json());
app.use('/v1', unless(['/login', '/Users', '/messaging'], passport.authenticate('bearer', {
app.use('/v1', unless(['/login', '/Users', '/messaging', '/outboundSMS'], passport.authenticate('bearer', {
session: false
})));
app.use('/', routes);
+2 -1
View File
@@ -20,6 +20,7 @@ api.use('/Sbcs', isAdminScope, require('./sbcs'));
api.use('/Users', require('./users'));
api.use('/login', require('./login'));
api.use('/messaging', require('./messaging'));
api.use('/messaging', require('./sms-inbound'));
api.use('/outboundSMS', require('./sms-outbound'));
module.exports = api;
@@ -1,30 +1,10 @@
const router = require('express').Router();
const request = require('request');
const smsPartnerFn = require('../../utils/sms-partner');
const uuidv4 = require('uuid/v4');
const sysError = require('./error');
const partners = {};
let initialized = false;
let idx = 0;
function initPartners(logger) {
if (initialized) return;
initialized = true;
if (process.env.JAMBONES_MESSAGING) {
try {
const obj = JSON.parse(process.env.JAMBONES_MESSAGING);
Object.assign(partners, obj);
logger.info({
partners
}, 'Messaging partners configuration');
} catch (err) {
logger.error(err, `expected JSON for JAMBONES_MESSAGING : ${process.env.JAMBONES_MESSAGING}`);
}
}
else {
logger.info('no JAMBONES_MESSAGING env var, messaging is disabled');
}
}
async function doSendResponse(res, respondFn, body) {
if (typeof respondFn === 'number') res.sendStatus(respondFn);
@@ -36,21 +16,28 @@ async function doSendResponse(res, respondFn, body) {
}
router.post('/:partner', async(req, res) => {
const partner = req.params.partner;
const partnerName = req.params.partner;
const {
retrieveSet,
lookupAppByPhoneNumber,
logger
} = req.app.locals;
const setName = `${process.env.JAMBONES_CLUSTER_ID || 'default'}:active-fs`;
const getPartner = smsPartnerFn(logger);
// search for partner module
initPartners(logger);
const partnerData = partners[partner];
if (!partnerData || !partnerData.module || !partnerData.options) {
const arr = getPartner(partnerName);
if (!arr) {
logger.info(
`rejecting incomingSms request from unknown or badly configured partner ${partner}`
`rejecting incomingSms request from unknown or badly configured partner ${partnerName}`
);
return res.sendStatus(404);
}
const partnerData = arr[1];
if (!partnerData || !partnerData.module) {
logger.info(
`rejecting incomingSms request from unknown or badly configured partner ${partnerName}`
);
return res.sendStatus(404);
}
@@ -65,7 +52,7 @@ router.post('/:partner', async(req, res) => {
// must at least provide a filter function
if (!fromProviderFormat) {
logger.info(
`missing fromProviderFormat function in module ${partnerData.module} for partner ${partner}`
`missing fromProviderFormat function in module ${partnerData.module} for partner ${partnerName}`
);
return res.sendStatus(404);
}
@@ -74,7 +61,7 @@ router.post('/:partner', async(req, res) => {
} catch (err) {
logger.info(
err,
`failure loading module ${partnerData.module} for partner ${partner}`
`failure loading module ${partnerData.module} for partner ${partnerName}`
);
return res.sendStatus(500);
}
@@ -90,7 +77,7 @@ router.post('/:partner', async(req, res) => {
.status(480);
}
const ip = fs[idx++ % fs.length];
const serviceUrl = `http://${ip}:3000/v1/messaging/${partner}`;
const serviceUrl = `http://${ip}:3000/v1/messaging/${partnerName}`;
const messageSid = uuidv4();
const payload = await Promise.resolve(filterFn({messageSid}, req.body));
@@ -120,10 +107,7 @@ router.post('/:partner', async(req, res) => {
logger.info({payload}, `app "${app.name}" found for incoming SMS does not have an associated messaging hook`);
return res.sendStatus(404);
}
payload.applicationSid = app.application_sid;
payload.accountSid = app.account_sid;
payload.messaging_hook = app.messaging_hook;
payload.app = app;
logger.debug({body: req.body, payload}, 'filtered incoming SMS');
+42
View File
@@ -0,0 +1,42 @@
const router = require('express').Router();
const smsPartnerFn = require('../../utils/sms-partner');
const sysError = require('./error');
router.post('/', async(req, res) => {
const { logger } = req.app.locals;
const getPartner = smsPartnerFn(logger);
try {
// if partner specified use it, otherwise use first in list
const arr = getPartner(req.body.partner);
if (!Array.isArray(arr)) {
throw new Error('outboundSMS - unable to locate sms provider to use to send message');
}
const partnerData = arr[1];
if (!partnerData || !partnerData.module) {
throw new Error(`rejecting outgoingSms request for unknown or badly configured partner ${req.body.partner}`);
}
const partnerName = arr[0];
const opts = partnerData.options;
if (!opts || !opts.url) {
throw new Error(`rejecting outgoingSms request -- no HTTP url for ${req.body.partner}`);
}
// load partner module
const { sendSms } = require(partnerData.module);
if (!sendSms) {
throw new Error(`missing sendSms function in module ${partnerData.module} for partner ${partnerName}`);
}
// send the SMS
const response = await sendSms(opts, req.body);
logger.info({response, payload: req.body}, `outboundSMS - sent to ${opts.url}`);
res.status(200).json({'status': 'ok'});
} catch (err) {
sysError(logger, res, err);
}
});
module.exports = router;
+38
View File
@@ -0,0 +1,38 @@
const partners = new Map();
function initPartners(logger) {
if (process.env.JAMBONES_MESSAGING) {
try {
const obj = JSON.parse(process.env.JAMBONES_MESSAGING);
for (const [key, value] of Object.entries(obj)) {
logger.debug({config: value}, `Adding SMS provider ${key}`);
partners.set(key, value);
}
logger.info(`Configured ${partners.size} SMS partners`);
} catch (err) {
logger.error(err, `expected JSON for JAMBONES_MESSAGING : ${process.env.JAMBONES_MESSAGING}`);
}
}
else {
logger.info('no JAMBONES_MESSAGING env var, messaging is disabled');
}
}
function getPartner(logger, partner) {
if (typeof partner === 'string') {
const config = partners.get(partner);
const arr = [partner, config];
logger.debug({arr}, 'getPartner by name');
return arr;
}
else if (partners.size) {
const arr = partners.entries().next().value;
logger.debug({arr}, 'getPartner by first available');
return arr;
}
}
module.exports = (logger) => {
initPartners(logger);
return getPartner.bind(null, logger);
};
+1 -1
View File
@@ -16,7 +16,7 @@
},
"dependencies": {
"@jambonz/db-helpers": "^0.5.0",
"@jambonz/messaging-peerless": "0.0.4",
"@jambonz/messaging-peerless": "0.0.5",
"@jambonz/realtimedb-helpers": "0.2.16",
"cors": "^2.8.5",
"express": "^4.17.1",