eliecerthoms1

inbound-conference-event.js

Oct 20th, 2023
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { twilio, validateTwilioSignature } from '../../../shared/twilio';
  2. import { getBaseUrl } from '../../../shared/utils';
  3. import { fetchInboundCallBySid, fetchParticipantByCallSid } from '../phone-call-actions';
  4. import { TWILIO_CONFERENCE_STATUS_EVENTS } from '../phone-calls-model';
  5. import * as qs from 'querystring';
  6. import { twiml } from 'twilio';
  7.  
  8. /**
  9.  * @param {object} event - 8base event.
  10.  * @param {object} ctx - 8base context.
  11.  */
  12. export default async function(event, ctx) {
  13.   console.log('call: inbound-conference-event Running Inbound Calls conference status Webhook...');
  14.   const { callSid } = event.pathParameters;
  15.   const body = qs.parse(event.body);
  16.   const url = `${getBaseUrl(ctx)}/webhook/inbound-call/${callSid}/conference/event`;
  17.   const signature = event.headers['X-Twilio-Signature'];
  18.   const options = { checkPermissions: false };
  19.  
  20.   //rqstbin({from: "inbound-conference-event", msg: "got here!"})
  21.  
  22.   let twilioClient = await twilio(body.AccountSid);
  23.  
  24.   if (validateTwilioSignature(signature, url, body) === false) {
  25.     console.log('call: inbound-conference-event twilio signature failure [' + signature + ']');
  26.     return {
  27.       statusCode: 401,
  28.       body: JSON.stringify({
  29.         message: 'Unauthorized request',
  30.       }),
  31.     };
  32.   }
  33.  
  34.   console.log(`call: inbound-conference-event Conference ${callSid}:`, body.StatusCallbackEvent);
  35.  
  36.   if (body.StatusCallbackEvent === TWILIO_CONFERENCE_STATUS_EVENTS.PARTICIPANT_JOIN) {
  37.     console.log('call: inbound-conference-event PARTICIPANT JOIN body;', JSON.stringify(body));
  38.     /**
  39.      * If the participant that is joining the conference is the same that
  40.      * started the call (customer), then call the agents in the company.
  41.      */
  42.     if (body.CallSid === callSid) {
  43.       let call = null;
  44.  
  45.       try {
  46.         call = await fetchInboundCallBySid(callSid, ctx, options);
  47.         console.log(
  48.           'call: inbound-conference-event fetched inbound call by SID',
  49.           JSON.stringify(call),
  50.         );
  51.       } catch (e) {
  52.         console.log('call: inbound-conference-event Could not fetch inbound call:', e.message);
  53.  
  54.         const response = new twiml.VoiceResponse();
  55.  
  56.         response.say(`Could not fetch inbound call: ${e.message}`);
  57.         return {
  58.           statusCode: 200,
  59.           body: response.toString(),
  60.         };
  61.       }
  62.  
  63.       try {
  64.         console.log('call: inbound-conference-event will invoke: distribute-inbound-call ');
  65.         await ctx.invokeFunction(
  66.           'distribute-inbound-call',
  67.           {
  68.             data: {
  69.               callSid: callSid,
  70.               callId: call.id,
  71.               from: `+${call.to.number.code}${call.to.number.number}`,
  72.               agencyId: call.agency.id,
  73.               campaign: call.to.campaign,
  74.             },
  75.           },
  76.           { waitForResponse: false },
  77.         );
  78.       } catch (e) {
  79.         console.log(
  80.           'call: inbound-conference-event error invoking distribute-inbound-call',
  81.           JSON.stringify(e),
  82.         );
  83.  
  84.         const response = new twiml.VoiceResponse();
  85.  
  86.         response.say(`Could contact with any agent: ${e.message}`);
  87.         return {
  88.           statusCode: 200,
  89.           body: response.toString(),
  90.         };
  91.       }
  92.  
  93.       /**
  94.        * If the participant that is joining the call is one of the
  95.        * initially called agents, then hang up all the other calls.
  96.        */
  97.     } else {
  98.       let call = null;
  99.       let participants = null;
  100.       let conference = null;
  101.  
  102.       try {
  103.         conference = await twilioClient.conferences(body.ConferenceSid).fetch();
  104.         console.log(
  105.           'call: inbound-conference-event fetched twilio conference:',
  106.           JSON.stringify(conference),
  107.         );
  108.       } catch (e) {
  109.         console.log('call: inbound-conference-event Could not fetch twilio conference:', e.message);
  110.       }
  111.  
  112.       try {
  113.         call = await fetchParticipantByCallSid(body.CallSid, ctx, { checkPermissions: false });
  114.         console.log(
  115.           'call: inbound-conference-event fetched participant by callSID',
  116.           JSON.stringify(call),
  117.         );
  118.       } catch (e) {
  119.         console.log(
  120.           'call: inbound-conference-event  error fetching participant by call sid',
  121.           JSON.stringify(e),
  122.         );
  123.         const response = new twiml.VoiceResponse();
  124.  
  125.         response.say(`Could not fetch the phone call participant: ${e.message}`);
  126.         return {
  127.           statusCode: 200,
  128.           body: response.toString(),
  129.         };
  130.       }
  131.       if (conference && conference.status !== 'completed') {
  132.         try {
  133.           console.log('call: inbound-conference-event participant BODY', JSON.stringify(body));
  134.           participants = await twilioClient.conferences(body.ConferenceSid).participants.list();
  135.  
  136.           console.log('call: inbound-conference-event participants list', participants);
  137.         } catch (error) {
  138.           console.log(
  139.             'call: inbound-conference-event Could not fetch the participants list',
  140.             JSON.stringify(error),
  141.           );
  142.         }
  143.       }
  144.  
  145.       if (call.isInitialParticipant) {
  146.         console.log(
  147.           'call: inbound-conference-event, is initial participant, will invoke: hangup-initial-calls ',
  148.         );
  149.         try {
  150.           await ctx.invokeFunction(
  151.             'hangup-initial-calls',
  152.             {
  153.               data: {
  154.                 callSid: callSid,
  155.                 participantCallSid: body.CallSid,
  156.               },
  157.             },
  158.             { waitForResponse: false },
  159.           );
  160.           console.log('call: inbound-conference-event hung up call');
  161.         } catch (e) {
  162.           console.log(
  163.             'call: inbound-conference-event  error hanging up initial calls',
  164.             JSON.stringify(e),
  165.           );
  166.  
  167.           const response = new twiml.VoiceResponse();
  168.  
  169.           response.say(`Could not hang up other calls: ${e.message}`);
  170.           return {
  171.             statusCode: 200,
  172.             body: response.toString(),
  173.           };
  174.         }
  175.       }
  176.     }
  177.   }
  178.  
  179.   /**
  180.    * If a participant leaves the conference we check at least if
  181.    * 2 others are connected, if not then the call ends.
  182.    */
  183.   if (body.StatusCallbackEvent === TWILIO_CONFERENCE_STATUS_EVENTS.PARTICIPANT_LEAVE) {
  184.     console.log('call: inbound-conference-event PARTICIPANT LEAVE body;', JSON.stringify(body));
  185.     let conference = null;
  186.  
  187.     try {
  188.       conference = await twilioClient.conferences(body.ConferenceSid).fetch();
  189.       console.log(
  190.         'call: inbound-conference-event fetched twilio conference:',
  191.         JSON.stringify(conference),
  192.       );
  193.     } catch (e) {
  194.       console.log('call: inbound-conference-event Could not fetch twilio conference:', e.message);
  195.     }
  196.  
  197.     if (conference && conference.status !== 'completed') {
  198.       let participants = [];
  199.  
  200.       try {
  201.         participants = await twilioClient.conferences(body.ConferenceSid).participants.list();
  202.         console.log(
  203.           'call: inbound-conference-event fetched twilio participants:',
  204.           JSON.stringify(participants),
  205.         );
  206.       } catch (e) {
  207.         console.log('call: inbound-conference-event Could not fetch call participants', e.message);
  208.  
  209.         const response = new twiml.VoiceResponse();
  210.  
  211.         response.say(`Could not fetch call participants: ${e.message}`);
  212.         return {
  213.           statusCode: 200,
  214.           body: response.toString(),
  215.         };
  216.       }
  217.  
  218.       if (participants.length < 2) {
  219.         try {
  220.           await twilioClient.conferences(body.ConferenceSid).update({ status: 'completed' });
  221.           console.log('call: inbound-conference-event set conference as completed');
  222.         } catch (e) {
  223.           console.log('call: inbound-conference-event Could not end conference:', e.message);
  224.  
  225.           const response = new twiml.VoiceResponse();
  226.  
  227.           response.say(`Could not end conference: ${e.message}`);
  228.           return {
  229.             statusCode: 200,
  230.             body: response.toString(),
  231.           };
  232.         }
  233.       }
  234.     }
  235.   }
  236.  
  237.   return {
  238.     statusCode: 200,
  239.     body: JSON.stringify({
  240.       message: 'Conference status updated successfully',
  241.     }),
  242.   };
  243. }
  244.  
Advertisement
Add Comment
Please, Sign In to add comment