Skip to content

Commit

Permalink
feat: add option to retrigger webhook
Browse files Browse the repository at this point in the history
  • Loading branch information
FreekBes committed Jan 28, 2025
1 parent 9ddad9c commit 8055606
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 31 deletions.
48 changes: 42 additions & 6 deletions src/routes/admin/apisearcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,13 @@ export const setupAPISearchRoutes = function(app: Express, prisma: PrismaClient)
skip: offset,
});
return res.json({
data: webhooks,
// Replace delivery_id with id (for apisearcher compatibility)
data: webhooks.map((webhook) => {
return {
...webhook,
id: webhook.delivery_id,
};
}),
meta: {
pagination: {
total: await prisma.intraWebhook.count(),
Expand All @@ -709,7 +715,13 @@ export const setupAPISearchRoutes = function(app: Express, prisma: PrismaClient)
},
});
return res.json({
data: webhooks,
// Replace delivery_id with id (for apisearcher compatibility)
data: webhooks.map((webhook) => {
return {
...webhook,
id: webhook.delivery_id,
};
}),
meta: {
pagination: {
total: webhooks.length,
Expand Down Expand Up @@ -743,7 +755,13 @@ export const setupAPISearchRoutes = function(app: Express, prisma: PrismaClient)
skip: offset,
});
return res.json({
data: webhooks,
// Replace delivery_id with id (for apisearcher compatibility)
data: webhooks.map((webhook) => {
return {
...webhook,
id: webhook.delivery_id,
};
}),
meta: {
pagination: {
total: webhookCount,
Expand Down Expand Up @@ -775,7 +793,13 @@ export const setupAPISearchRoutes = function(app: Express, prisma: PrismaClient)
},
});
return res.json({
data: webhooks,
// Replace delivery_id with id (for apisearcher compatibility)
data: webhooks.map((webhook) => {
return {
...webhook,
id: webhook.delivery_id,
};
}),
meta: {
pagination: {
total: webhookCount,
Expand Down Expand Up @@ -807,7 +831,13 @@ export const setupAPISearchRoutes = function(app: Express, prisma: PrismaClient)
},
});
return res.json({
data: webhooks,
// Replace delivery_id with id (for apisearcher compatibility)
data: webhooks.map((webhook) => {
return {
...webhook,
id: webhook.delivery_id,
};
}),
meta: {
pagination: {
total: webhookCount,
Expand Down Expand Up @@ -843,7 +873,13 @@ export const setupAPISearchRoutes = function(app: Express, prisma: PrismaClient)
},
});
return res.json({
data: webhooks,
// Replace delivery_id with id (for apisearcher compatibility)
data: webhooks.map((webhook) => {
return {
...webhook,
id: webhook.delivery_id,
};
}),
meta: {
pagination: {
total: webhookCount,
Expand Down
21 changes: 21 additions & 0 deletions src/routes/admin/hooksmgmt.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Express } from 'express';
import { PrismaClient } from '@prisma/client';
import { CatchupOperation, startCatchupOperation } from '../hooks/catchup';
import { handleWebhook } from '../hooks';

const catchupOperation: CatchupOperation = {
ongoing: false,
Expand All @@ -20,6 +21,26 @@ export const setupWebhookManagementRoutes = function(app: Express, prisma: Prism
return res.render('admin/hooks/history.njk');
});

app.get('/admin/hooks/retrigger/:deliveryId', async (req, res) => { // :deliveryId is at the end of the path because the apisearcher requires this
const deliveryId = req.params.deliveryId;
const webhook = await prisma.intraWebhook.findUnique({
where: {
delivery_id: deliveryId,
},
});
if (!webhook) {
return res.status(404).json({ error: 'Webhook not found' });
}
try {
await handleWebhook(prisma, webhook.model, JSON.parse(webhook.body), null, deliveryId);
return res.status(200).json({ status: 'ok' });
}
catch (err) {
console.error('Failed to retrigger webhook:', err);
return res.status(500).json({ error: 'Failed to retrigger webhook', details: err });
}
});

app.get('/admin/hooks/secrets', async (req, res) => {
const secrets = await prisma.intraWebhookSecret.findMany();
return res.render('admin/hooks/secrets.njk', { secrets });
Expand Down
50 changes: 27 additions & 23 deletions src/routes/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,32 @@ export const respondWebHookHandledStatus = async function(prisma: PrismaClient,
return res.status(200).json({ status: status }); // Always return 200 OK, we save the webhook in our database anyways and can easily trigger it again from our side
};

export const handleWebhook = async function(prisma: PrismaClient, modelType: string, body: { [key: string]: any }, res: Response | null, deliveryId: string): Promise<Response<any, Record<string, any>> | null> {
if (!body) {
throw new Error("Missing body");
}
if (typeof body !== 'object') {
throw new Error("Invalid body");
}
switch (modelType) {
case "location": // location close
const location: Location = body as Location;
return await handleLocationCloseWebhook(prisma, location, res, deliveryId);
case "projects_user": // project or exam validation
const projectUser: ProjectUser = body as ProjectUser;
return await handleProjectsUserUpdateWebhook(prisma, projectUser, res, deliveryId);
case "scale_team": // scale team (evaluation) update
const scaleTeam: ScaleTeam = body as ScaleTeam;
return await handleScaleTeamUpdateWebhook(prisma, scaleTeam, res, deliveryId);
case "pool": // pool point_given
const pointGiven: PointGiven = body as PointGiven;
return await handlePointGivenWebhook(prisma, pointGiven, res, deliveryId);
default:
console.warn("Unknown model type", modelType);
return await (res ? respondWebHookHandledStatus(prisma, deliveryId, res, WebhookHandledStatus.Error) : null);
}
};

export const setupWebhookRoutes = function(app: Express, prisma: PrismaClient): void {
app.post('/hooks/intra', async (req, res) => {
// Handle all Intra webhooks
Expand Down Expand Up @@ -106,29 +132,7 @@ export const setupWebhookRoutes = function(app: Express, prisma: PrismaClient):

// Actually handle the webhook, but do catch any errors
try {
if (!req.body) {
throw new Error("Missing body");
}
if (typeof req.body !== 'object') {
throw new Error("Invalid body");
}
switch (webhookHeaders.modelType) {
case "location": // location close
const location: Location = req.body as Location;
return await handleLocationCloseWebhook(prisma, location, res, webhookHeaders.deliveryId);
case "projects_user": // project or exam validation
const projectUser: ProjectUser = req.body as ProjectUser;
return await handleProjectsUserUpdateWebhook(prisma, projectUser, res, webhookHeaders.deliveryId);
case "scale_team": // scale team (evaluation) update
const scaleTeam: ScaleTeam = req.body as ScaleTeam;
return await handleScaleTeamUpdateWebhook(prisma, scaleTeam, res, webhookHeaders.deliveryId);
case "pool": // pool point_given
const pointGiven: PointGiven = req.body as PointGiven;
return await handlePointGivenWebhook(prisma, pointGiven, res, webhookHeaders.deliveryId);
default:
console.warn("Unknown model type", webhookHeaders.modelType);
return await respondWebHookHandledStatus(prisma, webhookHeaders.deliveryId, res, WebhookHandledStatus.Error);
}
return handleWebhook(prisma, webhookHeaders.modelType, req.body, res, webhookHeaders.deliveryId);
}
catch (err) {
console.error("Failed to handle webhook", err);
Expand Down
8 changes: 6 additions & 2 deletions templates/admin/hooks/history.njk
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<table class="table table-striped" id="results">
<thead>
<tr>
<th scope="col" data-key="delivery_id" data-format="code">Delivery ID</th>
<th scope="col" data-key="id" data-format="code">Delivery ID</th>
<th scope="col" data-key="received_at" data-format="datetime">Received at</th>
<th scope="col" data-key="handled_at" data-format="datetime">Handled at</th>
<th scope="col" data-key="model">Model</th>
Expand Down Expand Up @@ -60,7 +60,11 @@ const apiSearcher = new ApiSearcherTable({
pageNav: '#pagenav',
noPoints: true,
actions: [
// TODO: add option to retrigger the webhook
{
name: 'Retrigger',
url: window.location.origin + '/admin/hooks/retrigger/', // id will be appended
background: true, // background request, set to false to open in the same tab instead
}
]
});
</script>
Expand Down

0 comments on commit 8055606

Please sign in to comment.