diff --git a/README.md b/README.md index 79c47a66..398a8ed4 100644 --- a/README.md +++ b/README.md @@ -89,4 +89,4 @@ module.exports = { #### Running the test suite -Please [see this]](./docs/contributing.md#run-the-regression-test-suite). \ No newline at end of file +Please [see this](./docs/contributing.md#run-the-regression-test-suite). \ No newline at end of file diff --git a/lib/http-routes/api/create-call.js b/lib/http-routes/api/create-call.js index 68990a58..8c193369 100644 --- a/lib/http-routes/api/create-call.js +++ b/lib/http-routes/api/create-call.js @@ -85,6 +85,20 @@ router.post('/', async(req, res) => { } } + /** + * trunk isn't specified, + * check if from-number matches any existing numbers on Jambonz + * */ + if (target.type === 'phone' && !target.trunk) { + const {lookupCarrierByPhoneNumber} = dbUtils(this.logger, srf); + const voip_carrier_sid = await lookupCarrierByPhoneNumber(req.body.account_sid, restDial.from); + logger.info( + `createCall: selected ${voip_carrier_sid} for requested phone number: ${restDial.from || 'unspecified'})`); + if (voip_carrier_sid) { + opts.headers['X-Requested-Carrier-Sid'] = voip_carrier_sid; + } + } + /* create endpoint for outdial */ const ms = getFreeswitch(); if (!ms) throw new Error('no available Freeswitch for outbound call creation'); diff --git a/lib/tasks/dial.js b/lib/tasks/dial.js index 09a60200..023fc632 100644 --- a/lib/tasks/dial.js +++ b/lib/tasks/dial.js @@ -397,7 +397,7 @@ class TaskDial extends Task { const {req, srf} = cs; const {getSBC} = srf.locals; const {lookupTeamsByAccount, lookupAccountBySid} = srf.locals.dbHelpers; - const {lookupCarrier} = dbUtils(this.logger, cs.srf); + const {lookupCarrier, lookupCarrierByPhoneNumber} = dbUtils(this.logger, cs.srf); const sbcAddress = this.proxy || getSBC(); const teamsInfo = {}; let fqdn; @@ -462,6 +462,19 @@ class TaskDial extends Task { } } + /** + * trunk isn't specified, + * check if number matches any existing numbers + * */ + if (t.type === 'phone' && !t.trunk) { + const voip_carrier_sid = await lookupCarrierByPhoneNumber(req.body.account_sid, t.number); + this.logger.info( + `Dial:_attemptCalls: selected ${voip_carrier_sid} for requested phone number: ${t.number})`); + if (voip_carrier_sid) { + opts.headers['X-Requested-Carrier-Sid'] = voip_carrier_sid; + } + } + if (this.killed) return; const sd = placeCall({ diff --git a/lib/utils/db-utils.js b/lib/utils/db-utils.js index eb26c289..f3eb1744 100644 --- a/lib/utils/db-utils.js +++ b/lib/utils/db-utils.js @@ -20,6 +20,16 @@ WHERE vc.account_sid IS NULL AND vc.service_provider_sid = (SELECT service_provider_sid from accounts where account_sid = ?) AND vc.name = ?`; +const sqlQueryAccountPhoneNumber = `SELECT voip_carrier_sid +FROM phone_numbers pn +WHERE pn.account_sid = ? +AND pn.number = ?`; +const sqlQuerySPPhoneNumber = `SELECT voip_carrier_sid +FROM phone_numbers pn +WHERE pn.account_sid IS NULL +AND pn.service_provider_sid = +(SELECT service_provider_sid from accounts where account_sid = ?) +AND pn.number = ?`; const speechMapper = (cred) => { const {credential, ...obj} = cred; @@ -128,9 +138,22 @@ module.exports = (logger, srf) => { } }; + const lookupCarrierByPhoneNumber = async(account_sid, phoneNumber) => { + const pp = pool.promise(); + try { + const [r] = await pp.query(sqlQueryAccountPhoneNumber, [account_sid, phoneNumber]); + if (r.length) return r[0].voip_carrier_sid; + const [r2] = await pp.query(sqlQuerySPPhoneNumber, [account_sid, phoneNumber]); + if (r2.length) return r2[0].voip_carrier_sid; + } catch (err) { + logger.error({err}, `lookupPhoneNumber: Error ${account_sid}:${phoneNumber}`); + } + }; + return { lookupAccountDetails, updateSpeechCredentialLastUsed, - lookupCarrier + lookupCarrier, + lookupCarrierByPhoneNumber }; };