97 lines
2.5 KiB
TypeScript
97 lines
2.5 KiB
TypeScript
|
/* Cron job for scheduled webhook events triggers */
|
||
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||
|
|
||
|
import dayjs from "@calcom/dayjs";
|
||
|
import { defaultHandler } from "@calcom/lib/server";
|
||
|
import prisma from "@calcom/prisma";
|
||
|
|
||
|
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||
|
const apiKey = req.headers.authorization || req.query.apiKey;
|
||
|
if (process.env.CRON_API_KEY !== apiKey) {
|
||
|
res.status(401).json({ message: "Not authenticated" });
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// get jobs that should be run
|
||
|
const jobsToRun = await prisma.webhookScheduledTriggers.findMany({
|
||
|
where: {
|
||
|
startAfter: {
|
||
|
lte: dayjs().toISOString(),
|
||
|
},
|
||
|
},
|
||
|
});
|
||
|
|
||
|
// run jobs
|
||
|
for (const job of jobsToRun) {
|
||
|
try {
|
||
|
await fetch(job.subscriberUrl, {
|
||
|
method: "POST",
|
||
|
body: job.payload,
|
||
|
});
|
||
|
} catch (error) {
|
||
|
console.log(`Error running webhook trigger (retry count: ${job.retryCount}): ${error}`);
|
||
|
|
||
|
// if job fails, retry again for 5 times.
|
||
|
if (job.retryCount < 5) {
|
||
|
await prisma.webhookScheduledTriggers.update({
|
||
|
where: {
|
||
|
id: job.id,
|
||
|
},
|
||
|
data: {
|
||
|
retryCount: {
|
||
|
increment: 1,
|
||
|
},
|
||
|
startAfter: dayjs()
|
||
|
.add(5 * (job.retryCount + 1), "minutes")
|
||
|
.toISOString(),
|
||
|
},
|
||
|
});
|
||
|
return res.json({ ok: false });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const parsedJobPayload = JSON.parse(job.payload) as {
|
||
|
id: number; // booking id
|
||
|
endTime: string;
|
||
|
scheduledJobs: string[];
|
||
|
triggerEvent: string;
|
||
|
};
|
||
|
|
||
|
// clean finished job
|
||
|
await prisma.webhookScheduledTriggers.delete({
|
||
|
where: {
|
||
|
id: job.id,
|
||
|
},
|
||
|
});
|
||
|
|
||
|
const booking = await prisma.booking.findUnique({
|
||
|
where: { id: parsedJobPayload.id },
|
||
|
select: { id: true, scheduledJobs: true },
|
||
|
});
|
||
|
if (!booking) {
|
||
|
console.log("Error finding booking in webhook trigger:", parsedJobPayload);
|
||
|
return res.json({ ok: false });
|
||
|
}
|
||
|
|
||
|
//remove scheduled job from bookings once triggered
|
||
|
const updatedScheduledJobs = booking.scheduledJobs.filter((scheduledJob) => {
|
||
|
return scheduledJob !== job.jobName;
|
||
|
});
|
||
|
|
||
|
await prisma.booking.update({
|
||
|
where: {
|
||
|
id: booking.id,
|
||
|
},
|
||
|
data: {
|
||
|
scheduledJobs: updatedScheduledJobs,
|
||
|
},
|
||
|
});
|
||
|
}
|
||
|
|
||
|
res.json({ ok: true });
|
||
|
}
|
||
|
|
||
|
export default defaultHandler({
|
||
|
POST: Promise.resolve({ default: handler }),
|
||
|
});
|