insert call to db when making a call
This commit is contained in:
parent
f628addd80
commit
30d186d37d
@ -1,20 +1,68 @@
|
||||
import type { BlitzApiRequest, BlitzApiResponse } from "blitz";
|
||||
import Twilio from "twilio";
|
||||
import { getConfig } from "blitz";
|
||||
import twilio from "twilio";
|
||||
|
||||
import db from "../../../../db";
|
||||
import type { ApiError } from "../../../_types";
|
||||
import db, { Direction } from "../../../../db";
|
||||
import appLogger from "../../../../integrations/logger";
|
||||
|
||||
const { serverRuntimeConfig } = getConfig();
|
||||
const logger = appLogger.child({ route: "/api/webhook/call" });
|
||||
|
||||
export default async function incomingCallHandler(req: BlitzApiRequest, res: BlitzApiResponse) {
|
||||
console.log("req.body", req.body);
|
||||
|
||||
const isOutgoingCall = true;
|
||||
const url = `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/incoming-message`;
|
||||
const twilioSignature = req.headers["X-Twilio-Signature"] || req.headers["x-twilio-signature"];
|
||||
if (!twilioSignature || Array.isArray(twilioSignature)) {
|
||||
const statusCode = 400;
|
||||
const apiError: ApiError = {
|
||||
statusCode,
|
||||
errorMessage: "Invalid header X-Twilio-Signature",
|
||||
};
|
||||
logger.error(apiError);
|
||||
|
||||
res.status(statusCode).send(apiError);
|
||||
return;
|
||||
}
|
||||
|
||||
const isOutgoingCall = req.body.From.startsWith("client:");
|
||||
if (isOutgoingCall) {
|
||||
const recipient = req.body.To;
|
||||
const organizationId = req.body.From.slice("client:".length).split("__")[0];
|
||||
const phoneNumber = await db.phoneNumber.findFirst({
|
||||
where: { organizationId },
|
||||
select: { number: true },
|
||||
include: { organization: true },
|
||||
});
|
||||
const twiml = new Twilio.twiml.VoiceResponse();
|
||||
if (
|
||||
!phoneNumber ||
|
||||
!phoneNumber.organization.twilioAuthToken ||
|
||||
!twilio.validateRequest(phoneNumber.organization.twilioAuthToken, twilioSignature, url, req.body)
|
||||
) {
|
||||
const statusCode = 400;
|
||||
const apiError: ApiError = {
|
||||
statusCode,
|
||||
errorMessage: "Invalid webhook",
|
||||
};
|
||||
logger.error(apiError);
|
||||
|
||||
res.status(statusCode).send(apiError);
|
||||
return;
|
||||
}
|
||||
|
||||
await db.phoneCall.create({
|
||||
data: {
|
||||
id: req.body.CallSid,
|
||||
from: phoneNumber.number,
|
||||
to: req.body.To,
|
||||
status: req.body.CallStatus,
|
||||
direction: Direction.Outbound,
|
||||
duration: "", // TODO
|
||||
organizationId: phoneNumber.organization.id,
|
||||
phoneNumberId: phoneNumber.id,
|
||||
},
|
||||
});
|
||||
const twiml = new twilio.twiml.VoiceResponse();
|
||||
const dial = twiml.dial({
|
||||
answerOnBridge: true,
|
||||
callerId: phoneNumber!.number,
|
||||
@ -24,8 +72,42 @@ export default async function incomingCallHandler(req: BlitzApiRequest, res: Bli
|
||||
|
||||
res.setHeader("content-type", "text/xml");
|
||||
return res.status(200).send(twiml.toString());
|
||||
} else {
|
||||
const phoneNumbers = await db.phoneNumber.findMany({
|
||||
where: { number: req.body.To },
|
||||
include: { organization: true },
|
||||
});
|
||||
if (phoneNumbers.length === 0) {
|
||||
// phone number is not registered by any organization
|
||||
res.status(500).end();
|
||||
return;
|
||||
}
|
||||
|
||||
const phoneNumber = phoneNumbers.find((phoneNumber) => {
|
||||
// if multiple organizations have the same number
|
||||
// find the organization currently using that phone number
|
||||
// maybe we shouldn't let multiple organizations use the same phone number
|
||||
const authToken = phoneNumber.organization.twilioAuthToken ?? "";
|
||||
return twilio.validateRequest(authToken, twilioSignature, url, req.body);
|
||||
});
|
||||
if (!phoneNumber) {
|
||||
const statusCode = 400;
|
||||
const apiError: ApiError = {
|
||||
statusCode,
|
||||
errorMessage: "Invalid webhook",
|
||||
};
|
||||
logger.error(apiError);
|
||||
|
||||
res.status(statusCode).send(apiError);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO send notification
|
||||
// TODO db.phoneCall.create(...);
|
||||
}
|
||||
|
||||
// TODO queue job to update duration when call ends
|
||||
|
||||
res.status(500).end();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user