eliecerthoms1

phone-call-actions.js

Oct 20th, 2023
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { twilio } from '../../shared/twilio';
  2. import {
  3.   AGENCY_PHONE_CALL_SETTINGS_QUERY,
  4.   CREATE_INBOUND_PHONE_CALL,
  5.   CREATE_PHONE_CALL_RECORDING,
  6.   FETCH_PHONE_CALL_LIST,
  7.   LEAD_PHONE_NUMBER_QUERY,
  8.   UPDATE_INBOUND_PHONE_CALL,
  9.   UPDATE_PHONE_CALL,
  10.   FETCH_PHONE_CALL,
  11.   FETCH_USER,
  12.   FETCH_INBOUND_PHONE_CALL,
  13.   FETCH_USERS_FOR_CALL,
  14.   CREATE_PHONE_CALL_PARTICIPANT,
  15.   UPDATE_PHONE_CALL_PARTICIPANT,
  16.   FETCH_PHONE_CALL_PARTICIPANT,
  17.   FETCH_PHONE_CALL_PARTICIPANTS,
  18.   ACTIVE_USERS_QUERY,
  19.   CREATE_VOICEMAIL_MUTATION,
  20.   INBOUND_CALL_INFO_QUERY,
  21. } from './phone-call-queries';
  22. import { USER_STATUSES } from '../user/user-model';
  23. import { CallParticipantStatus } from '@cobuildlab/lead-volt-share';
  24. import { normalize8baseReferenceConnect } from '@cobuildlab/8base-utils';
  25. import { twiml } from 'twilio';
  26. import { getBaseUrl } from '../../shared/utils';
  27. const { LANDLINE_PHONE } = process.env;
  28.  
  29. /**
  30.  * Create a new phone call recording record in the database.
  31.  *
  32.  * @param {object} context - 8base's context object.
  33.  * @param {object} data - Phone call recording data to store.
  34.  * @param {object} options - Options object to configure the request.
  35.  *
  36.  * @returns {Promise} The request result.
  37.  */
  38. export const createPhoneCallRecording = async (context, data, options = {}) => {
  39.   const { phoneCallRecordingCreate } = await context.api.gqlRequest(
  40.     CREATE_PHONE_CALL_RECORDING,
  41.     { data },
  42.     options,
  43.   );
  44.   console.log('call: Created Phone Call Recording:', JSON.stringify(phoneCallRecordingCreate));
  45.  
  46.   return phoneCallRecordingCreate;
  47. };
  48.  
  49. /**
  50.  * Fetches phone calls.
  51.  *
  52.  * @param {object} context - 8base's context object.
  53.  * @param {object} filter - Filter object to limit the phone calls retrieved.
  54.  * @param {number} first - How many results must retrieve.
  55.  * @param {number} skip - How many results must skip before getting the results.
  56.  * @param {object} options - Options object to configure the request.
  57.  *
  58.  * @returns {Promise} The request result.
  59.  */
  60. export const fetchPhoneCalls = async (context, filter, first = 1, skip = 0, options = {}) => {
  61.   const { phoneCallsList } = await context.api.gqlRequest(
  62.     FETCH_PHONE_CALL_LIST,
  63.     { filter, first, skip },
  64.     options,
  65.   );
  66.   console.log('call: Fetched Phone Calls:', JSON.stringify(phoneCallsList));
  67.  
  68.   return phoneCallsList;
  69. };
  70.  
  71. /**
  72.  *
  73.  * @param {string} id - The phoneCall id.
  74.  * @param {object} ctx - The 8base's context object.
  75.  * @param {object} options - Options object passed to the gqlRequest function.
  76.  */
  77. export const fetchPhoneCall = async (id, ctx, options = {}) => {
  78.   const { phoneCall } = await ctx.api.gqlRequest(FETCH_PHONE_CALL, { id }, options);
  79.   console.log('call: Fetched Phone Call:', JSON.stringify(phoneCall));
  80.   return phoneCall;
  81. };
  82.  
  83. /**
  84.  * Fetches a phone call filtered by its call sid.
  85.  *
  86.  * @param {string} callSid - The twilio call sid.
  87.  * @param {object} ctx - The cloud function's context api.
  88.  * @param {object} options - The options to configure the request.
  89.  *
  90.  * @returns {Promise} The phone call object.
  91.  */
  92. export async function fetchPhoneCallBySid(callSid, ctx, options = {}) {
  93.   const { phoneCall } = await ctx.api.gqlRequest(FETCH_PHONE_CALL, { callSid }, options);
  94.   console.log('call: Fetched Phone Call by sid:', JSON.stringify(phoneCall));
  95.  
  96.   return phoneCall;
  97. }
  98.  
  99. /**
  100.  * @param {string }callSid - Call sid.
  101.  */
  102. export async function fetchCallResorce(callSid) {
  103.   let call;
  104.   try {
  105.     call = await twilio.calls(callSid).fetch();
  106.   } catch (error) {
  107.     console.log('call: fetchCallResourceError: ', callSid);
  108.     console.log(JSON.stringify(error, null, 2));
  109.   }
  110.   return call;
  111. }
  112. /**
  113.  * @param {object} data - Phone call data to create.
  114.  * @param {object} context - 8base context.
  115.  * @param {object} options - 8base graphql request options.
  116.  * @returns {Promise<{id:string}>}
  117.  */
  118. export async function createInboundPhoneCall(data, context, options) {
  119.   normalize8baseReferenceConnect(data, 'to');
  120.   normalize8baseReferenceConnect(data, 'agency');
  121.  
  122.   if (data.lead) {
  123.     normalize8baseReferenceConnect(data, 'lead');
  124.   }
  125.  
  126.   const { inboundPhoneCallCreate } = await context.api.gqlRequest(
  127.     CREATE_INBOUND_PHONE_CALL,
  128.     { data },
  129.     options,
  130.   );
  131.  
  132.   console.log('call: createInboundPhoneCall', JSON.stringify(inboundPhoneCallCreate));
  133.  
  134.   return inboundPhoneCallCreate;
  135. }
  136.  
  137. /**
  138.  * @param {object} filter - The filter object to find a call.
  139.  * @param {string} filter.id - The id of the call.
  140.  * @param {string} filter.callSid - The id of the call in twilio.
  141.  * @param {object} data - Phone call data to update.
  142.  * @param {object} ctx - 8base context.
  143.  * @param {object} options - 8base graphql request options.
  144.  */
  145. export async function updatePhoneCall(filter, data, ctx, options = {}) {
  146.   const { phoneCallUpdate } = await ctx.api.gqlRequest(
  147.     UPDATE_PHONE_CALL,
  148.     {
  149.       data,
  150.       filter,
  151.     },
  152.     options,
  153.   );
  154.  
  155.   console.log('call: Updated Phone Call:', JSON.stringify(phoneCallUpdate));
  156.  
  157.   return phoneCallUpdate;
  158. }
  159. /**
  160.  * @param {object} filter - The filter to find the call to update.
  161.  * @param {string} filter.id - The id of the inbound phone call.
  162.  * @param {string} filter.callSid - The id of the call in twilio.
  163.  * @param {object} data - Phone call data to update.
  164.  * @param {object} ctx - 8base context.
  165.  * @param {object} options - 8base graphql request options.
  166.  *
  167.  * @returns {Promise} The inbound phone call object.
  168.  */
  169. export async function updateInboundPhoneCall(filter, data, ctx, options = {}) {
  170.   try {
  171.     const { phoneCallUpdate } = await ctx.api.gqlRequest(
  172.       UPDATE_INBOUND_PHONE_CALL,
  173.       {
  174.         filter,
  175.         data,
  176.       },
  177.       options,
  178.     );
  179.     console.log('call: Inbound Phone Call Update:', JSON.stringify(phoneCallUpdate));
  180.  
  181.     return phoneCallUpdate;
  182.   } catch (error) {
  183.     console.log('call: updateInboundPhoneCall: Error updating inbound phone call:', error);
  184.     throw error; // Rethrow the error to propagate it to the caller
  185.   }
  186. }
  187. /**
  188.  * @param {object} context - 8base context.
  189.  * @param {string} id - Phone call data to update.
  190.  * @param {object} options - 8base graphql request options.
  191.  * @returns {Promise<[{recordCalls:boolean,automaticCalls:boolean},Error]>} - Promise tuple of succes and error.
  192.  */
  193. export async function fetchAgencyPhoneCallSettings(context, id, options = {}) {
  194.   let data = null;
  195.   let error = null;
  196.   try {
  197.     const { agency } = await context.api.gqlRequest(
  198.       AGENCY_PHONE_CALL_SETTINGS_QUERY,
  199.       { id },
  200.       options,
  201.     );
  202.     data = agency.phoneCallSettings;
  203.   } catch (e) {
  204.     error = e;
  205.   }
  206.   console.log('call: Agency Phone Call Settings:', JSON.stringify(data));
  207.   if (error) {
  208.     console.log('call: Error fetching Agency Phone Call Settings:', JSON.stringify(error));
  209.   }
  210.  
  211.   return [data, error];
  212. }
  213.  
  214. /**
  215.  * @param fromNumber
  216.  * @param toNumber
  217.  * @param agencyId
  218.  * @param ctx
  219.  * @param options
  220.  */
  221. export async function fetchInboundCallInfo(fromNumber, toNumber, agencyId, ctx, options = {}) {
  222.   const first = 1;
  223.   const leadFilter = {
  224.     parsedPhone: { number: { equals: fromNumber } },
  225.   };
  226.   const agencyFilter = {
  227.     agency: {
  228.       id: {
  229.         equals: agencyId,
  230.       },
  231.       agencyAgencyUserRelation: {
  232.         some: {
  233.           user: {
  234.             currentStatus: {
  235.               status: {
  236.                 equals: 'ACTIVE',
  237.               },
  238.             },
  239.           },
  240.         },
  241.       },
  242.     },
  243.     number: {
  244.       number: {
  245.         equals: toNumber,
  246.       },
  247.     },
  248.   };
  249.  
  250.   const responses = await ctx.api.gqlRequest(
  251.     INBOUND_CALL_INFO_QUERY,
  252.     {
  253.       first,
  254.       leadFilter,
  255.       agencyFilter,
  256.     },
  257.     options,
  258.   );
  259.  
  260.   console.log('call: RESPONSES FROM PHONE CALL ACTIONS', JSON.stringify(responses));
  261.  
  262.   const leadPhoneNumbersList = responses.leadPhoneNumbersList.items[0];
  263.   console.log('call: leadPhoneNumbersList', JSON.stringify(leadPhoneNumbersList));
  264.   const agencyInfo = responses.phoneNumbersList;
  265.   console.log('call: agencyInfo', JSON.stringify(agencyInfo));
  266.  
  267.   const agencyUsers = agencyInfo.items[0].agency.agencyAgencyUserRelation;
  268.   console.log('call: agencyUsers.items', JSON.stringify(agencyUsers.items));
  269.   const activeUsers = [];
  270.  
  271.   agencyUsers.items.forEach((data) => {
  272.     if (data.user.currentStatus && data.user.currentStatus.status === 'ACTIVE') {
  273.       activeUsers.push({ id: data.user.id });
  274.     }
  275.   });
  276.  
  277.   const activeUsersWithCount = { count: activeUsers.length, items: activeUsers };
  278.   console.log('call: activeUsersWithCount', JSON.stringify(activeUsersWithCount));
  279.  
  280.   return [leadPhoneNumbersList, agencyInfo.items[0], activeUsersWithCount];
  281. }
  282.  
  283. /**
  284.  * Fetches a lead phone number registry
  285.  * filtering by the number part.
  286.  *
  287.  * @param {string} number - The number to fetch.
  288.  * @param {string} agency - The agency id.
  289.  * @param {object} ctx - 8base context.
  290.  * @param {object} options - Options to configure the query.
  291.  *
  292.  * @returns {Promise<{id:string,phone:{code: string,number: string},lead: {id: string,firstName: string,lastName: string}}>} - The phone number object.
  293.  */
  294. export async function fetchLeadPhoneFromNumber(number, agency, ctx, options = {}) {
  295.   const first = 1;
  296.   const filter = {
  297.     OR: [
  298.       { phone: { number: { equals: number } } },
  299.       { parsedPhone: { number: { equals: number } } },
  300.     ],
  301.     lead: {
  302.       campaign: {
  303.         agency: {
  304.           id: {
  305.             equals: agency,
  306.           },
  307.         },
  308.       },
  309.     },
  310.   };
  311.  
  312.   const { leadPhoneNumbersList } = await ctx.api.gqlRequest(
  313.     LEAD_PHONE_NUMBER_QUERY,
  314.     {
  315.       first,
  316.       filter,
  317.     },
  318.     options,
  319.   );
  320.  
  321.   const [phone] = leadPhoneNumbersList.items;
  322.  
  323.   console.log('call: Fetched lead phone number:', JSON.stringify(phone));
  324.  
  325.   return phone;
  326. }
  327.  
  328. /**
  329.  * @param {string} userId - The user id.
  330.  * @param {object} context - 8base context.
  331.  * @param {object} options - 8base graphql request options.
  332.  */
  333. export async function fetchUser(userId, context, options = {}) {
  334.   return await context.api.gqlRequest(FETCH_USER, { userId }, options);
  335. }
  336.  
  337. /**
  338.  * Fetches a lead from an inbound call registry.
  339.  *
  340.  * @param {string} id - The id of the call.
  341.  * @param {object} ctx - The cloud function's context api.
  342.  * @param {object} options - The options to configure the request.
  343.  *
  344.  * @returns {Promise<{id:string,callSid:string,agency:{ id:string, phoneCallSettings:{recordCalls:boolean,voicemail:boolean }}}>} The lead object or null.
  345.  */
  346. export async function fetchInboundCall(id, ctx, options = {}) {
  347.   const { inboundPhoneCall } = await ctx.api.gqlRequest(
  348.     FETCH_INBOUND_PHONE_CALL,
  349.     {
  350.       id,
  351.     },
  352.     options,
  353.   );
  354.  
  355.   console.log('call: Fetched inbound call:', JSON.stringify(inboundPhoneCall));
  356.  
  357.   return inboundPhoneCall;
  358. }
  359.  
  360. /**
  361.  * Fetches an inbound call by sid.
  362.  *
  363.  * @param {string} sid - The twilio call sid.
  364.  * @param {object} ctx - The cloud function's context api.
  365.  * @param {object} options - The options to configure the request.
  366.  *
  367.  * @returns {Promise} The inbound call object.
  368.  */
  369. export async function fetchInboundCallBySid(sid, ctx, options = {}) {
  370.   const { inboundPhoneCall } = await ctx.api.gqlRequest(
  371.     FETCH_INBOUND_PHONE_CALL,
  372.     {
  373.       callSid: sid,
  374.     },
  375.     options,
  376.   );
  377.  
  378.   console.log('call: Inbound call fetched by SID:', JSON.stringify(inboundPhoneCall));
  379.  
  380.   return inboundPhoneCall;
  381. }
  382.  
  383. /**
  384.  * Fetch users available for calling.
  385.  *
  386.  * @param {string} agency - The agency id.
  387.  * @param {string} campaign - The campaign.
  388.  * @param {object} ctx - The cloud function's context api.
  389.  * @param {object} options - The options to configure the request.
  390.  *
  391.  * @returns {Promise} The id of the users to call.
  392.  */
  393. export async function fetchUserIdsToCall(agency, campaign, ctx, options = {}) {
  394.   const first = 5;
  395.   const filter = {
  396.     ...(campaign
  397.       ? {
  398.         OR: [
  399.           {
  400.             userAgencyUserRelation: {
  401.               some: {
  402.                 agency: {
  403.                   id: { equals: agency },
  404.                 },
  405.               },
  406.             },
  407.             currentStatus: {
  408.               status: {
  409.                 equals: USER_STATUSES.ACTIVE,
  410.               },
  411.             },
  412.             assigneesCampaignRelation: {
  413.               some: { id: { equals: campaign } },
  414.             },
  415.           },
  416.           {
  417.             userAgencyUserRelation: {
  418.               some: {
  419.                 agency: {
  420.                   id: { equals: agency },
  421.                 },
  422.               },
  423.             },
  424.             currentStatus: {
  425.               status: {
  426.                 equals: USER_STATUSES.ACTIVE,
  427.               },
  428.             },
  429.           },
  430.         ],
  431.       }
  432.       : {
  433.         userAgencyUserRelation: {
  434.           some: {
  435.             agency: {
  436.               id: { equals: agency },
  437.             },
  438.           },
  439.         },
  440.         currentStatus: {
  441.           status: {
  442.             equals: USER_STATUSES.ACTIVE,
  443.           },
  444.         },
  445.       }),
  446.   };
  447.  
  448.   const { usersList } = await ctx.api.gqlRequest(
  449.     FETCH_USERS_FOR_CALL,
  450.     {
  451.       first,
  452.       filter,
  453.     },
  454.     options,
  455.   );
  456.  
  457.   console.log('call: Users to call:', JSON.stringify(usersList.items));
  458.  
  459.   return usersList.items.map((item) => item.id);
  460. }
  461.  
  462. /**
  463.  * Creates a new PhoneCallParticipant record.
  464.  *
  465.  * @param {object} data - The data object to create the participant.
  466.  * @param {string} data.user - The user id.
  467.  * @param {string} data.callSid - The participant call sid.
  468.  * @param {string} data.inboundCall - The inbound call id.
  469.  * @param {string} data.outboundCall - The outbound call id.
  470.  * @param {object} ctx - The could function's context api.
  471.  * @param {object} options - The options to configure the request.
  472.  *
  473.  * @returns {Promise} The phone call participant object.
  474.  */
  475. export async function createParticipant(data, ctx, options = {}) {
  476.   if (data.user) {
  477.     normalize8baseReferenceConnect(data, 'user');
  478.   }
  479.  
  480.   if (data.inboundCall) {
  481.     normalize8baseReferenceConnect(data, 'inboundCall');
  482.   }
  483.  
  484.   if (data.outboundCall) {
  485.     normalize8baseReferenceConnect(data, 'outboundCall');
  486.   }
  487.  
  488.   const { phoneCallParticipantCreate } = await ctx.api.gqlRequest(
  489.     CREATE_PHONE_CALL_PARTICIPANT,
  490.     {
  491.       data,
  492.     },
  493.     options,
  494.   );
  495.  
  496.   console.log('call: Created phone call participant:', JSON.stringify(phoneCallParticipantCreate));
  497.  
  498.   return phoneCallParticipantCreate;
  499. }
  500.  
  501. /**
  502.  * Updates a specific call participant status.
  503.  *
  504.  * @param {object} data - The data to update the participant.
  505.  * @param {object} filter - The filter object to find the participant.
  506.  * @param {string} filter.id - The id of the participant in 8base.
  507.  * @param {string} filter.callSid - The id of the participant's call in twilio.
  508.  * @param {object} ctx - The cloud function's context object.
  509.  * @param {object} options - The options to configure the request.
  510.  *
  511.  * @returns {Promise} The participant object.
  512.  */
  513. export async function updateParticipant(data, filter, ctx, options) {
  514.   const { phoneCallParticipantUpdate } = await ctx.api.gqlRequest(
  515.     UPDATE_PHONE_CALL_PARTICIPANT,
  516.     {
  517.       data,
  518.       filter,
  519.     },
  520.     options,
  521.   );
  522.  
  523.   console.log('call: phoneCallParticipantUpdate:', JSON.stringify(phoneCallParticipantUpdate));
  524.  
  525.   return phoneCallParticipantUpdate;
  526. }
  527.  
  528. /**
  529.  * Fetch phone call participant by its call sid.
  530.  *
  531.  * @param {string} callSid - The participant call sid.
  532.  * @param {object} ctx - The cloud function's context.
  533.  * @param {object} options - The options to configure the request.
  534.  *
  535.  * @returns {Promise} The phone call participant object.
  536.  */
  537. export async function fetchParticipantByCallSid(callSid, ctx, options) {
  538.   const { phoneCallParticipant } = await ctx.api.gqlRequest(
  539.     FETCH_PHONE_CALL_PARTICIPANT,
  540.     {
  541.       callSid,
  542.     },
  543.     options,
  544.   );
  545.   console.log('call: phoneCallParticipant', JSON.stringify(phoneCallParticipant));
  546.  
  547.   return phoneCallParticipant;
  548. }
  549.  
  550. /**
  551.  * Fetches the participants of the call that
  552.  * didn't pick up the call.
  553.  *
  554.  * @param {string} callSid - The sid of the inbound call.
  555.  * @param {string} participantCallSid - The call sid of the participant that answered the call.
  556.  * @param {object} ctx - The cloud function's context.
  557.  * @param {object} options - The options to configure the request.
  558.  *
  559.  * @returns {Promise} The participants initially called when receiving the call.
  560.  */
  561. export async function fetchParticipantsToHangup(callSid, participantCallSid, ctx, options) {
  562.   const filter = {
  563.     callSid: {
  564.       not_equals: participantCallSid,
  565.     },
  566.     isInitialParticipant: {
  567.       equals: true,
  568.     },
  569.     status: {
  570.       equals: CallParticipantStatus.ringing,
  571.     },
  572.     OR: [
  573.       {
  574.         inboundCall: {
  575.           callSid: {
  576.             equals: callSid,
  577.           },
  578.         },
  579.       },
  580.       {
  581.         outboundCall: {
  582.           callSid: {
  583.             equals: callSid,
  584.           },
  585.         },
  586.       },
  587.     ],
  588.   };
  589.  
  590.   const { phoneCallParticipantsList } = await ctx.api.gqlRequest(
  591.     FETCH_PHONE_CALL_PARTICIPANTS,
  592.     {
  593.       filter,
  594.     },
  595.     options,
  596.   );
  597.   // Log the participants to be hung up
  598.   console.log(
  599.     'call: Participants to be hung up on:',
  600.     JSON.stringify(phoneCallParticipantsList.items),
  601.   );
  602.   return phoneCallParticipantsList.items;
  603. }
  604.  
  605. /**
  606.  * @param {object}ctx - 8base context.
  607.  * @param {{checkPermissions:boolean} | undefined} options - Options.
  608.  * @param {string} agency - Agency Id.
  609.  * @returns {Promise<{items:{id:string},count:number}>} - Result.
  610.  */
  611. export async function fetchActiveUsers(ctx, options = {}, agency) {
  612.   const { usersList } = await ctx.api.gqlRequest(
  613.     ACTIVE_USERS_QUERY,
  614.     {
  615.       agency,
  616.     },
  617.     options,
  618.   );
  619.  
  620.   console.log('call: Active Users:', JSON.stringify(usersList));
  621.  
  622.   return usersList;
  623. }
  624.  
  625. /**
  626.  * @param {object}ctx - 8base context.
  627.  * @param {{checkPermissions:boolean} | undefined} options - Options.
  628.  * @param {string} data - Agency Id.
  629.  * @returns {Promise<{id:string}>} - Result.
  630.  */
  631. export async function createVoiceMail(ctx, options = {}, data) {
  632.   const { voiceMailCreate } = await ctx.api.gqlRequest(
  633.     CREATE_VOICEMAIL_MUTATION,
  634.     {
  635.       data,
  636.     },
  637.     options,
  638.   );
  639.  
  640.   return voiceMailCreate;
  641. }
  642.  
  643. /**
  644.  * @param {object} ctx - Comntext.
  645.  * @param {string} callId - Call id.
  646.  * @param allowVoicemail
  647.  * @param voicemailUrl
  648.  * @param {boolean} voicemail - Call id.
  649.  * @returns {string} Response string.
  650.  */
  651. export async function getCallDropResponse(ctx, callId, allowVoicemail, voicemailUrl = null) {
  652.   const response = new twiml.VoiceResponse();
  653.  
  654.   if (allowVoicemail || !LANDLINE_PHONE) {
  655.     if (voicemailUrl) {
  656.       response.play(voicemailUrl);
  657.  
  658.       await ctx.invokeFunction(
  659.         'send-email-task',
  660.         {
  661.           id: null,
  662.           voicemailNotification: true,
  663.         },
  664.         { waitForResponse: false },
  665.       );
  666.     } else {
  667.       response.say('Sorry there is no agents avialable right now, please leave a message.', {
  668.         voice: 'woman',
  669.       });
  670.     }
  671.     response.record({
  672.       timeout: 5, // after 5 secongs of silence the record ends
  673.       action: `${getBaseUrl(ctx)}/webhook/calls/voicemail/${callId}`,
  674.     });
  675.   } else {
  676.     response.say(
  677.       'It looks like all of our agents are busy, we will redirect you to a landline please wait',
  678.       {
  679.         voice: 'woman',
  680.       },
  681.     );
  682.     response.dial(LANDLINE_PHONE);
  683.   }
  684.  
  685.   console.log(
  686.     `call: phone-call-actions voicemail URL: ${getBaseUrl(ctx)}/webhook/calls/voicemail/${callId}`,
  687.   );
  688.   console.log('call: inbound-call-start getCallDropResponse', response.toString());
  689.  
  690.   return response.toString();
  691. }
  692.  
Advertisement
Add Comment
Please, Sign In to add comment