lib/middleware.js
/**
   * Given the dialed DID/phone number, retrieve the application to invoke
   */
Given the dialed DID/phone number, retrieve the application to invoke
Given the dialed DID / phone number retrieve the application to invoke
async function retrieveApplication(req, res, next) {
    const logger = req.locals.logger;
    const {accountInfo, account_sid, rootSpan} = req.locals;
    const {span} = rootSpan.startChildSpan('lookupApplication');
    try {
      let app;
      if (req.locals.application_sid) app = await lookupAppBySid(req.locals.application_sid);
      else if (req.locals.originatingUser) {
        const arr = /^(.*)@(.*)/.exec(req.locals.originatingUser);
        if (arr) {
          const sipRealm = arr[2];
          logger.debug(`looking for device calling app for realm ${sipRealm}`);
          app = await lookupAppByRealm(sipRealm);
          if (app) logger.debug({app}, `retrieved device calling app for realm ${sipRealm}`);
        }
      }
      else if (req.locals.msTeamsTenant) {
        app = await lookupAppByTeamsTenant(req.locals.msTeamsTenant);
        if (app) logger.debug({app}, `retrieved app for ms teams tenant ${req.locals.msTeamsTenant}`);
      }
      else {
        const uri = parseUri(req.uri);
        const arr = /context-(.*)/.exec(uri?.user);
        if (arr) {
          const {retrieveKey, deleteKey} = srf.locals.dbHelpers;
          try {
            const obj = JSON.parse(await retrieveKey(arr[1]));
            logger.info({obj}, 'retrieved application and tasks for a transferred call from realtimedb');
            app = Object.assign(obj, {transferredCall: true});
            deleteKey(arr[1]).catch(() => {});
          } catch (err) {
            logger.error(err, `Error retrieving transferred call app for ${arr[1]}`);
          }
        }
        else {
          const voip_carrier_sid = req.get('X-Voip-Carrier-Sid');
          app = await lookupAppByPhoneNumber(req.locals.calledNumber, voip_carrier_sid);
          if (!app) {
            app = await lookupAppByRegex(req.locals.calledNumber, account_sid);
          }
        }
      }
      span.setAttributes({
        'app.hook': app?.call_hook?.url,
        'application_sid': req.locals.application_sid
      });
      span.end();
      if (!app || !app.call_hook || !app.call_hook.url) {
        logger.info(`rejecting call to ${req.locals.calledNumber}: no application or webhook url`);
        return res.send(480, {
          headers: {
            'X-Reason': 'no configured application'
          }
        });
      }
      if ('WS' === app.call_hook?.method ||
        app.call_hook?.url.startsWith('ws://') || app.call_hook?.url.startsWith('wss://')) {
        app.requestor = new WsRequestor(logger, account_sid, app.call_hook, accountInfo.account.webhook_secret) ;
        app.notifier = app.requestor;
        app.call_hook.method = 'WS';
      }
      else {
        app.requestor = new HttpRequestor(logger, account_sid, app.call_hook, accountInfo.account.webhook_secret);
        if (app.call_status_hook) app.notifier = new HttpRequestor(logger, account_sid, app.call_status_hook,
          accountInfo.account.webhook_secret);
        else app.notifier = {request: () => {}};
      }
      req.locals.application = app;
      const obj = Object.assign({}, app);
      delete obj.requestor;
      delete obj.notifier;
      const {call_hook, call_status_hook, ...appInfo} = obj;  
      logger.info({app: appInfo}, `retrieved application for incoming call to ${req.locals.calledNumber}`);
      req.locals.callInfo = new CallInfo({
        req,
        app,
        direction: CallDirection.Inbound,
        traceId: rootSpan.traceId
      });
      next();
    } catch (err) {
      span.end();
      logger.error(err, `${req.get('Call-ID')} Error looking up application for ${req.calledNumber}`);
      res.send(500);
    }
  }
async function retrieveApplication ( req , res , next ) { const logger = req . locals . logger ; const { accountInfo , account_sid , rootSpan } = req . locals ; const { span } = rootSpan . startChildSpan ( 'lookupApplication' ) ; try { let app ; if ( req . locals . application_sid ) app = await lookupAppBySid ( req . locals . application_sid ) ; else if ( req . locals . originatingUser ) { const arr = / ^(.*)@(.*) / . exec ( req . locals . originatingUser ) ; if ( arr ) { const sipRealm = arr [ 2 ] ; logger . debug ( ` ${ sipRealm } ` ) ; app = await lookupAppByRealm ( sipRealm ) ; if ( app ) logger . debug ( { app } , ` ${ sipRealm } ` ) ; } } else if ( req . locals . msTeamsTenant ) { app = await lookupAppByTeamsTenant ( req . locals . msTeamsTenant ) ; if ( app ) logger . debug ( { app } , ` ${ req . locals . msTeamsTenant } ` ) ; } else { const uri = parseUri ( req . uri ) ; const arr = / context-(.*) / . exec ( uri ?. user ) ; if ( arr ) { const { retrieveKey , deleteKey } = srf . locals . dbHelpers ; try { const obj = JSON . parse ( await retrieveKey ( arr [ 1 ] ) ) ; logger . info ( { obj } , 'retrieved application and tasks for a transferred call from realtimedb' ) ; app = Object . assign ( obj , { transferredCall : true } ) ; deleteKey ( arr [ 1 ] ) . catch ( ( ) => { } ) ; } catch ( err ) { logger . error ( err , ` ${ arr [ 1 ] } ` ) ; } } else { const voip_carrier_sid = req . get ( 'X-Voip-Carrier-Sid' ) ; app = await lookupAppByPhoneNumber ( req . locals . calledNumber , voip_carrier_sid ) ; if ( ! app ) { app = await lookupAppByRegex ( req . locals . calledNumber , account_sid ) ; } } } span . setAttributes ( { 'app.hook' : app ?. call_hook ?. url , 'application_sid' : req . locals . application_sid } ) ; span . end ( ) ; if ( ! app || ! app . call_hook || ! app . call_hook . url ) { logger . info ( ` ${ req . locals . calledNumber } ` ) ; return res . send ( 480 , { headers : { 'X-Reason' : 'no configured application' } } ) ; } if ( 'WS' === app . call_hook ?. method || app . call_hook ?. url . startsWith ( 'ws://' ) || app . call_hook ?. url . startsWith ( 'wss://' ) ) { app . requestor = new WsRequestor ( logger , account_sid , app . call_hook , accountInfo . account . webhook_secret ) ; app . notifier = app . requestor ; app . call_hook . method = 'WS' ; } else { app . requestor = new HttpRequestor ( logger , account_sid , app . call_hook , accountInfo . account . webhook_secret ) ; if ( app . call_status_hook ) app . notifier = new HttpRequestor ( logger , account_sid , app . call_status_hook , accountInfo . account . webhook_secret ) ; else app . notifier = { request : ( ) => { } } ; } req . locals . application = app ; const obj = Object . assign ( { } , app ) ; delete obj . requestor ; delete obj . notifier ; const { call_hook , call_status_hook , ... appInfo } = obj ; logger . info ( { app : appInfo } , ` ${ req . locals . calledNumber } ` ) ; req . locals . callInfo = new CallInfo ( { req , app , direction : CallDirection . Inbound , traceId : rootSpan . traceId } ) ; next ( ) ; } catch ( err ) { span . end ( ) ; logger . error ( err , ` ${ req . get ( 'Call-ID' ) } ${ req . calledNumber } ` ) ; res . send ( 500 ) ; } }
Given the dialed DID/phone number, retrieve the application to invoke
Given the dialed DID / phone number retrieve the application to invoke
// this is a transfer from another feature server /* lookup by call_routes.regex */ /**
      * create a requestor that we will use for all http requests we make during the call.
      * also create a notifier for call status events (if not needed, its a no-op).
      */ // eslint-disable-next-line no-unused-vars // mask sensitive data like user/pass on webhook