eliecerthoms1

participant-status.js

Oct 20th, 2023
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { updateParticipant } from '../phone-call-actions';
  2. import { twilio, validateTwilioSignature } from '../../../shared/twilio';
  3. import { getBaseUrl } from '../../../shared/utils';
  4. import * as qs from 'querystring';
  5. import { twiml } from 'twilio';
  6.  
  7. /**
  8.  * Participant status webhook handler.
  9.  *
  10.  * @param {object} event - The cloud function's event data.
  11.  * @param {object} ctx - The cloud function's context api.
  12.  *
  13.  * @returns {Promise} The webhook result.
  14.  */
  15. export default async function(event, ctx) {
  16.   const body = qs.parse(event.body);
  17.   const { participantId } = event.pathParameters;
  18.   const signature = event.headers['X-Twilio-Signature'];
  19.   const url = `${getBaseUrl(ctx)}/webhook/participant/${participantId}/status`;
  20.   const options = { checkPermissions: false };
  21.   const status = body.CallStatus;
  22.   let participant = null;
  23.   let call = null;
  24.  
  25.   let twilioClient = await twilio(body.AccountSid);
  26.   console.log('call: participant-status triggered');
  27.  
  28.   if (validateTwilioSignature(signature, url, body) === false) {
  29.     console.log('call: participant-status Invalid twilio signature [' + signature + ']');
  30.  
  31.     return {
  32.       statusCode: 401,
  33.       body: JSON.stringify({
  34.         message: 'Unauthorized request',
  35.       }),
  36.     };
  37.   }
  38.  
  39.   console.log('call: participant-status Call', body.CallSid + ':', status);
  40.  
  41.   if (status === 'completed') {
  42.     try {
  43.       call = await twilioClient.calls(body.CallSid).fetch();
  44.     } catch (e) {
  45.       console.log('call: participant-status Could not fetch phone call from twilio:', e.message);
  46.     }
  47.   }
  48.  
  49.   try {
  50.     participant = await updateParticipant(
  51.       {
  52.         status: status,
  53.         callSid: body.CallSid,
  54.         ...(body.CallDuration ? { duration: parseInt(body.CallDuration) } : {}),
  55.         ...(status === 'in-progress'
  56.           ? {
  57.             answeredAt: new Date().toISOString(),
  58.           }
  59.           : {}),
  60.         ...(status === 'completed' || status === 'busy' || status === 'no-answered'
  61.           ? {
  62.             completedAt: new Date().toISOString(),
  63.           }
  64.           : {}),
  65.         ...(call && call.price
  66.           ? {
  67.             price: Math.abs(parseFloat(call.price)),
  68.             priceUnit: call.priceUnit || 'USD',
  69.           }
  70.           : {}),
  71.       },
  72.       { id: participantId },
  73.       ctx,
  74.       options,
  75.     );
  76.     console.log('call: participant-status updated participant', JSON.stringify(participant));
  77.   } catch (e) {
  78.     console.log('call: Could not update participant status:', e.message);
  79.  
  80.     // return {
  81.     //   statusCode: 500,
  82.     //   body: JSON.stringify({
  83.     //     message: `Could not update participant status: ${e.message}`,
  84.     //   }),
  85.     // };
  86.     const response = new twiml.VoiceResponse();
  87.  
  88.     response.say(`Could not update participant status: ${e.message}`);
  89.  
  90.     return {
  91.       statusCode: 200,
  92.       body: response.toString(),
  93.     };
  94.   }
  95.  
  96.   /**
  97.    * If the status type is no-answer,
  98.    * then notify the user of a missed call.
  99.    *
  100.    */
  101.   console.log('call: participant-status status', JSON.stringify(status));
  102.   if (status === 'no-answer') {
  103.     console.log(
  104.       'call: participant-status participant inboundcall',
  105.       JSON.stringify(participant.inboundCall),
  106.     );
  107.     if (participant.inboundCall) {
  108.       const call = participant.inboundCall;
  109.       const { lead } = call;
  110.  
  111.       try {
  112.         await ctx.invokeFunction(
  113.           'create-notification-task',
  114.           {
  115.             id: call.agency.id,
  116.             type: ['MISSED_CALL'],
  117.             data: {
  118.               email: participant.user.email,
  119.               ...(lead
  120.                 ? {
  121.                   leadId: lead.id,
  122.                 }
  123.                 : {}),
  124.             },
  125.           },
  126.           { waitForResponse: false },
  127.         );
  128.       } catch (e) {
  129.         console.log('call: participant-status Could not send notification:', e.message);
  130.  
  131.         // return {
  132.         //   statusCode: 500,
  133.         //   body: JSON.stringify({
  134.         //     message: `Could not send notification: ${e.message}`,
  135.         //   }),
  136.         // };
  137.  
  138.         const response = new twiml.VoiceResponse();
  139.  
  140.         response.say(`Could not send notification: ${e.message}`);
  141.  
  142.         return {
  143.           statusCode: 200,
  144.           body: response.toString(),
  145.         };
  146.       }
  147.     }
  148.   }
  149.   console.log(`call: participant-status end Call ${body.CallSid}: ${body.CallStatus}`);
  150.   return {
  151.     statusCode: 200,
  152.     body: JSON.stringify({
  153.       message: `Call ${body.CallSid}: ${body.CallStatus}`,
  154.     }),
  155.   };
  156. }
  157.  
Advertisement
Add Comment
Please, Sign In to add comment