diff --git a/lib/tasks/dial.js b/lib/tasks/dial.js index d7e7ed26..67f3ca82 100644 --- a/lib/tasks/dial.js +++ b/lib/tasks/dial.js @@ -12,6 +12,7 @@ const assert = require('assert'); const placeCall = require('../utils/place-outdial'); const sessionTracker = require('../session/session-tracker'); const DtmfCollector = require('../utils/dtmf-collector'); +const dbUtils = require('../utils/db-utils'); const debug = require('debug')('jambonz:feature-server'); function parseDtmfOptions(logger, dtmfCapture) { @@ -294,6 +295,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 sbcAddress = this.proxy || getSBC(); const teamsInfo = {}; let fqdn; @@ -339,6 +341,13 @@ class TaskDial extends Task { this.logger.error({err}, 'Error looking up account by sid'); } } + if (t.type === 'phone' && t.trunk) { + const voip_carrier_sid = await lookupCarrier(cs.accountSid, t.trunk); + this.logger.info(`Dial:_attemptCalls: selected ${voip_carrier_sid} for requested carrier: ${t.trunk})`); + if (voip_carrier_sid) { + opts.headers['X-Requested-Carrier-Sid'] = voip_carrier_sid; + } + } const sd = placeCall({ logger: this.logger, application: cs.application, diff --git a/lib/tasks/specs.json b/lib/tasks/specs.json index a5e3e701..37b3f605 100644 --- a/lib/tasks/specs.json +++ b/lib/tasks/specs.json @@ -328,7 +328,8 @@ "sipUri": "string", "auth": "#auth", "vmail": "boolean", - "tenant": "string" + "tenant": "string", + "trunk": "string" }, "required": [ "type" diff --git a/lib/utils/db-utils.js b/lib/utils/db-utils.js index 2095a607..4129cd90 100644 --- a/lib/utils/db-utils.js +++ b/lib/utils/db-utils.js @@ -10,6 +10,16 @@ const sqlSpeechCredentialsForSP = `SELECT * FROM speech_credentials WHERE service_provider_sid = (SELECT service_provider_sid from accounts where account_sid = ?)`; +const sqlQueryAccountCarrierByName = `SELECT voip_carrier_sid +FROM voip_carriers vc +WHERE vc.account_sid = ? +AND vc.name = ?`; +const sqlQuerySPCarrierByName = `SELECT voip_carrier_sid +FROM voip_carriers vc +WHERE vc.account_sid IS NULL +AND vc.service_provider_sid = +(SELECT service_provider_sid from accounts where account_sid = ?) +AND vc.name = ?`; const speechMapper = (cred) => { const {credential, ...obj} = cred; @@ -77,8 +87,21 @@ module.exports = (logger, srf) => { } }; + const lookupCarrier = async(account_sid, carrierName) => { + const pp = pool.promise(); + try { + const [r] = await pp.query(sqlQueryAccountCarrierByName, [account_sid, carrierName]); + if (r.length) return r[0].voip_carrier_sid; + const [r2] = await pp.query(sqlQuerySPCarrierByName, [account_sid, carrierName]); + if (r2.length) return r2[0].voip_carrier_sid; + } catch (err) { + logger.error({err}, `lookupCarrier: Error ${account_sid}:${carrierName}`); + } + }; + return { lookupAccountDetails, - updateSpeechCredentialLastUsed + updateSpeechCredentialLastUsed, + lookupCarrier }; };