Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { updateParticipant } from '../phone-call-actions';
- import { twilio, validateTwilioSignature } from '../../../shared/twilio';
- import { getBaseUrl } from '../../../shared/utils';
- import * as qs from 'querystring';
- import { twiml } from 'twilio';
- /**
- * Participant status webhook handler.
- *
- * @param {object} event - The cloud function's event data.
- * @param {object} ctx - The cloud function's context api.
- *
- * @returns {Promise} The webhook result.
- */
- export default async function(event, ctx) {
- const body = qs.parse(event.body);
- const { participantId } = event.pathParameters;
- const signature = event.headers['X-Twilio-Signature'];
- const url = `${getBaseUrl(ctx)}/webhook/participant/${participantId}/status`;
- const options = { checkPermissions: false };
- const status = body.CallStatus;
- let participant = null;
- let call = null;
- let twilioClient = await twilio(body.AccountSid);
- console.log('call: participant-status triggered');
- if (validateTwilioSignature(signature, url, body) === false) {
- console.log('call: participant-status Invalid twilio signature [' + signature + ']');
- return {
- statusCode: 401,
- body: JSON.stringify({
- message: 'Unauthorized request',
- }),
- };
- }
- console.log('call: participant-status Call', body.CallSid + ':', status);
- if (status === 'completed') {
- try {
- call = await twilioClient.calls(body.CallSid).fetch();
- } catch (e) {
- console.log('call: participant-status Could not fetch phone call from twilio:', e.message);
- }
- }
- try {
- participant = await updateParticipant(
- {
- status: status,
- callSid: body.CallSid,
- ...(body.CallDuration ? { duration: parseInt(body.CallDuration) } : {}),
- ...(status === 'in-progress'
- ? {
- answeredAt: new Date().toISOString(),
- }
- : {}),
- ...(status === 'completed' || status === 'busy' || status === 'no-answered'
- ? {
- completedAt: new Date().toISOString(),
- }
- : {}),
- ...(call && call.price
- ? {
- price: Math.abs(parseFloat(call.price)),
- priceUnit: call.priceUnit || 'USD',
- }
- : {}),
- },
- { id: participantId },
- ctx,
- options,
- );
- console.log('call: participant-status updated participant', JSON.stringify(participant));
- } catch (e) {
- console.log('call: Could not update participant status:', e.message);
- // return {
- // statusCode: 500,
- // body: JSON.stringify({
- // message: `Could not update participant status: ${e.message}`,
- // }),
- // };
- const response = new twiml.VoiceResponse();
- response.say(`Could not update participant status: ${e.message}`);
- return {
- statusCode: 200,
- body: response.toString(),
- };
- }
- /**
- * If the status type is no-answer,
- * then notify the user of a missed call.
- *
- */
- console.log('call: participant-status status', JSON.stringify(status));
- if (status === 'no-answer') {
- console.log(
- 'call: participant-status participant inboundcall',
- JSON.stringify(participant.inboundCall),
- );
- if (participant.inboundCall) {
- const call = participant.inboundCall;
- const { lead } = call;
- try {
- await ctx.invokeFunction(
- 'create-notification-task',
- {
- id: call.agency.id,
- type: ['MISSED_CALL'],
- data: {
- email: participant.user.email,
- ...(lead
- ? {
- leadId: lead.id,
- }
- : {}),
- },
- },
- { waitForResponse: false },
- );
- } catch (e) {
- console.log('call: participant-status Could not send notification:', e.message);
- // return {
- // statusCode: 500,
- // body: JSON.stringify({
- // message: `Could not send notification: ${e.message}`,
- // }),
- // };
- const response = new twiml.VoiceResponse();
- response.say(`Could not send notification: ${e.message}`);
- return {
- statusCode: 200,
- body: response.toString(),
- };
- }
- }
- }
- console.log(`call: participant-status end Call ${body.CallSid}: ${body.CallStatus}`);
- return {
- statusCode: 200,
- body: JSON.stringify({
- message: `Call ${body.CallSid}: ${body.CallStatus}`,
- }),
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment