clean setTwilioWebhooks and twilio webhook verification

This commit is contained in:
m5r 2021-08-30 19:24:05 +08:00
parent e77e7d17e0
commit 6a2e76857b
5 changed files with 39 additions and 26 deletions

View File

@ -2,6 +2,7 @@ import { BlitzApiRequest, BlitzApiResponse } from "blitz";
import db from "db";
import twilio from "twilio";
import setTwilioWebhooks from "../onboarding/api/queue/set-twilio-webhooks";
export default async function ddd(req: BlitzApiRequest, res: BlitzApiResponse) {
/*await Promise.all([
@ -49,7 +50,12 @@ export default async function ddd(req: BlitzApiRequest, res: BlitzApiResponse) {
console.log("messagesReceived", messagesReceived.sort((a, b) => a.dateCreated.getTime() - b.dateCreated.getTime()));
// console.log("messagesReceived", messagesReceived);*/
setTimeout(() => {
res.status(200).end();
}, 1000 * 60 * 5);
/*setTwilioWebhooks.enqueue({
phoneNumberId: "PNb77c9690c394368bdbaf20ea6fe5e9fc",
organizationId: "95267d60-3d35-4c36-9905-8543ecb4f174",
});*/
// setTimeout(() => {
res.status(200).end();
// }, 1000 * 60 * 5);
}

View File

@ -5,6 +5,7 @@ import twilio from "twilio";
import appLogger from "../../../../integrations/logger";
import db from "../../../../db";
import insertIncomingMessageQueue from "../queue/insert-incoming-message";
import { smsUrl } from "../../../../integrations/twilio";
type ApiError = {
statusCode: number;
@ -53,13 +54,12 @@ export default async function incomingMessageHandler(req: BlitzApiRequest, res:
return;
}
const url = `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/incoming-message`;
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);
return twilio.validateRequest(authToken, twilioSignature, smsUrl, req.body);
});
if (!phoneNumber) {
const statusCode = 400;

View File

@ -4,7 +4,7 @@ import type twilio from "twilio";
import type { ApplicationInstance } from "twilio/lib/rest/api/v2010/account/application";
import db from "../../../../db";
import getTwilioClient from "../../../../integrations/twilio";
import getTwilioClient, { getTwiMLName, smsUrl, voiceUrl } from "../../../../integrations/twilio";
type Payload = {
organizationId: string;
@ -45,7 +45,7 @@ async function getTwimlApplication(
): Promise<ApplicationInstance> {
try {
if (organizationTwimlAppSid) {
return updateTwimlApplication(twilioClient, organizationTwimlAppSid);
return await updateTwimlApplication(twilioClient, organizationTwimlAppSid);
}
} catch {
// twiml app with sid `organizationTwimlAppSid` probably doesn't exist anymore
@ -59,33 +59,23 @@ async function getTwimlApplication(
return twilioClient.applications.create({
friendlyName: getTwiMLName(),
smsUrl: `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/incoming-message`,
smsUrl,
smsMethod: "POST",
voiceUrl: `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/call`,
voiceUrl,
voiceMethod: "POST",
});
}
async function updateTwimlApplication(twilioClient: twilio.Twilio, twimlAppSid: string) {
await twilioClient.applications.get(twimlAppSid).update({
smsUrl: `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/incoming-message`,
friendlyName: getTwiMLName(),
smsUrl,
smsMethod: "POST",
voiceUrl: `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/call`,
voiceUrl,
voiceMethod: "POST",
});
return twilioClient.applications.get(twimlAppSid).fetch();
}
function getTwiMLName() {
switch (serverRuntimeConfig.app.baseUrl) {
case "local.shellphone.app":
return "Shellphone LOCAL";
case "dev.shellphone.app":
return "Shellphone DEV";
case "www.shellphone.app":
return "Shellphone";
}
}
export default setTwilioWebhooks;

View File

@ -5,6 +5,7 @@ import type { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
import db, { CallStatus, Direction } from "../../../../db";
import appLogger from "../../../../integrations/logger";
import { voiceUrl } from "../../../../integrations/twilio";
const { serverRuntimeConfig } = getConfig();
const logger = appLogger.child({ route: "/api/webhook/call" });
@ -17,7 +18,6 @@ type ApiError = {
export default async function incomingCallHandler(req: BlitzApiRequest, res: BlitzApiResponse) {
console.log("req.body", req.body);
const url = `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/call`;
const twilioSignature = req.headers["X-Twilio-Signature"] || req.headers["x-twilio-signature"];
if (!twilioSignature || Array.isArray(twilioSignature)) {
const statusCode = 400;
@ -42,7 +42,7 @@ export default async function incomingCallHandler(req: BlitzApiRequest, res: Bli
if (
!phoneNumber ||
!phoneNumber.organization.twilioAuthToken ||
!twilio.validateRequest(phoneNumber.organization.twilioAuthToken, twilioSignature, url, req.body)
!twilio.validateRequest(phoneNumber.organization.twilioAuthToken, twilioSignature, voiceUrl, req.body)
) {
const statusCode = 400;
const apiError: ApiError = {
@ -93,7 +93,7 @@ export default async function incomingCallHandler(req: BlitzApiRequest, res: Bli
// 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);
return twilio.validateRequest(authToken, twilioSignature, voiceUrl, req.body);
});
if (!phoneNumber) {
const statusCode = 400;

View File

@ -1,4 +1,4 @@
import { NotFoundError } from "blitz";
import { getConfig, NotFoundError } from "blitz";
import twilio from "twilio";
import type { Organization } from "db";
@ -19,3 +19,20 @@ export default function getTwilioClient(organization: MinimalOrganization | null
accountSid: organization.twilioAccountSid,
});
}
const { serverRuntimeConfig } = getConfig();
export const smsUrl = `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/incoming-message`;
export const voiceUrl = `https://${serverRuntimeConfig.app.baseUrl}/api/webhook/call`;
export function getTwiMLName() {
switch (serverRuntimeConfig.app.baseUrl) {
case "local.shellphone.app":
return "Shellphone LOCAL";
case "dev.shellphone.app":
return "Shellphone DEV";
case "www.shellphone.app":
return "Shellphone";
}
}