shellphone.app/src/pages/api/webhook/incoming-sms.ts
m5r 6a12d0cd93 list conversations
send sms
begin webhooks
2021-07-21 00:28:56 +08:00

77 lines
2.2 KiB
TypeScript

import type { NextApiRequest, NextApiResponse } from "next";
import twilio from "twilio";
import type { ApiError } from "../_types";
import appLogger from "../../../../lib/logger";
import { Customer, findCustomerByPhoneNumber } from "../../../database/customer";
import { insertSms } from "../../../database/sms";
import { SmsType } from "../../../database/_types";
import { encrypt } from "../../../database/_encryption";
const logger = appLogger.child({ route: "/api/webhook/incoming-sms" });
export default async function incomingSmsHandler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "POST") {
const statusCode = 405;
const apiError: ApiError = {
statusCode,
errorMessage: `Method ${req.method} Not Allowed`,
};
logger.error(apiError);
res.setHeader("Allow", ["POST"]);
res.status(statusCode).send(apiError);
return;
}
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;
}
console.log("req.body", req.body);
try {
const phoneNumber = req.body.To;
const customer = await findCustomerByPhoneNumber(phoneNumber);
const url = "https://phone.mokhtar.dev/api/webhook/incoming-sms";
const isRequestValid = twilio.validateRequest(customer.authToken!, twilioSignature, url, req.body);
if (!isRequestValid) {
const statusCode = 400;
const apiError: ApiError = {
statusCode,
errorMessage: "Invalid webhook",
};
logger.error(apiError);
res.status(statusCode).send(apiError);
return;
}
await insertSms({
customerId: customer.id,
to: req.body.To,
from: req.body.From,
type: SmsType.RECEIVED,
sentAt: req.body.DateSent,
content: encrypt(req.body.Body, customer.encryptionKey),
});
} catch (error) {
const statusCode = error.statusCode ?? 500;
const apiError: ApiError = {
statusCode,
errorMessage: error.message,
};
logger.error(error);
res.status(statusCode).send(apiError);
}
}