#
Step 5 - Subscribe to webhook events
Available in beta only
This is available in beta for now. Be aware that some performance issues might occur.
This is a guide to help you to understand how your quable app can register and listen to Quable PIM webhook events.
#
Webhook handling
In this tutorial, you'll discover how to subscribe to and handle Quable PIM webhook events. Webhooks serve as HTTP requests sent by applications to inform other systems about particular events in real-time. This enables seamless communication between different applications, allowing them to trigger actions on events as they occur.
#
Requirements
We'll use the quable-pim-js library to interact with the Quable PIM API.
#
1. Register webhook events
#
Define webhooks events
We'll start by defining the webhook events we want to listen to.
Open the quable.app.yml
file located at the root of your project and add the following lines:
webhook_events:
- document.create
- document.update
To ensure that our application receives notifications of document creation and updates, we have defined two webhook events:
document.create
: This event is triggered every time a new document is created.document.update
: This event is triggered every time an existing document is modified or updated.
NOTE : A maximum of 5 events can be registered per webhook.
#
Create the register method
To register the webhooks we've defined, create the following method in the app.service.ts
file. This method will handle the registration process with the Quable PIM.
import { QuableInstance } from "@prisma/client";
import { QuablePimClient } from "@quable/quable-pim-js";
private registerWebhooks = async (instance: QuableInstance, events: string[]) => {
const quablePimClient = new QuablePimClient({
apiKey: instance.authToken,
instanceName: instance.name,
});
const url = `${process.env.QUABLE_APP_HOST_URL}/webhook/events`;
const name = 'Quable App Template - Webhook';
const payload = {
active: true,
name,
url,
events,
};
const webhooks = await quablePimClient.PimApi.Webhook.getAll({
url,
name,
});
return webhooks?.length > 0
? quablePimClient.PimApi.Webhook.update(webhooks[0].id, payload)
: quablePimClient.PimApi.Webhook.create(payload);
};
The registerWebhooks
method manages the registration of webhooks on a Quable PIM instance. It accepts the instance details and a list of events to be registered. The method checks if a corresponding webhook with the same URL and name already exists. If it does, the existing webhook is updated with the provided data. Otherwise, a new webhook is created.
#
Update app service
We're going to update the installApp
method to register webhooks automatically during installation of the app:
public installApp = async (payload: Record<string, any>, events = []) => {
const response = {
statusCode: 201,
message: 'OK',
data: null,
};
try {
const { quableInstanceName, quableAuthToken } = payload.data;
if (!(await this.checkAuthToken(quableInstanceName, quableAuthToken))) {
response.statusCode = 500;
response.message = 'QuableApp could not be installed on your PIM. Please check your information and try again.';
return response;
}
let instance = await databaseService.quableInstance.findFirst({
where: { name: quableInstanceName },
});
const instanceData = {
authToken: quableAuthToken,
name: quableInstanceName,
};
instance = instance
? await databaseService.quableInstance.update({
where: { id: instance.id },
data: instanceData,
})
: await databaseService.quableInstance.create({ data: instanceData });
await this.registerWebhooks(instance, events);
response.message = `QuableApp installed on ${instance.name}.quable.com`;
} catch (error) {
response.statusCode = 500;
response.message = error.message;
}
return response;
};
The updated installApp
method will automatically register webhooks for the given instance on successfull installation.
#
Update app controller
Update installApp
method with the following :
public installApp = async (req: any, res: Response) => {
const webhookEvents = req.app.settings?.webhook_events || [];
const response = await appService.installApp(req.body, webhookEvents);
return res.status(response.statusCode).send(response);
};
This updated implementation will retrieve the webhooks defined in the quable.app.yml
file and pass them to the appService.installApp
method for registration.
#
2. Listen to webhook events
Once we've configured the webhook events, we need to set up a listener to capture the events triggered by the webhooks. This means creating a controller and routes in our application.
#
Webhook controller
We'll create a controller for handling incoming requests. Create a file named webhook.controller.ts
inside the controllers folder and paste the following code:
import { Request, Response } from "express";
class WebhookController {
public onWebhookReceived = async (req: Request, res: Response) => {
console.log(req.body);
return res.status(200).send({});
};
}
export const webhookController = new WebhookController();
#
Webhook routes
Create a new file named webhook.routes.ts
in the routes
directory and paste the following code:
import { webhookController } from "src/controllers/webhook.controller";
import { Router } from "express";
const webhookRouter = Router();
webhookRouter.post("/events", webhookController.onWebhookReceived);
export default webhookRouter;
After defining the routes, you must register the route in index.ts
:
import webhookRouter from "./routes/webhook.routes";
/*
... code ...
*/
app.use("/webhook", webhookRouter);
Note: To ensure our webhook route is accessible without authentication, we must add it to the list of unprotected routes. Locate the helper/session/route.ts
file and update the unProtectedRoutes variable to include webhook route:
const unProtectedRoutes = [
"/install",
"/uninstall",
"/permission",
"/webhook/events",
];
Open your partner portal dashboard application page to uninstall and reinstall you application to register webhooks
Once a document has been updated or created, we'll receive a request webhook endpoint with a similar payload.
{
uuid: '0963114b-c3d9-4a5e-9a33-ccc493b73649',
code: 'document.update',
links: [
{
rel: 'self',
href: '/api/events/0963114b-c3d9-4a5e-9a33-ccc492b73629'
}
],
created_at: '2023-11-03T08:58:00+00:00',
created_by: 'quable',
resource: {
code: 'vans-sh-8-hi',
type: 'document',
document_type_code: 'product',
links: [ [Object] ],
locales: { updated: [Array], inherited: [Array] },
updated_items: []
},
process: { correlationId: 'bca5bc9d-6250-4049-8o22-7bfd2f9ce9f1' }
}
Done ✅!
This guide has taken you through the process of setting up Quable PIM webhook events. You've also learned some useful tips for effectively managing and responding to these events. By following these steps, you can smoothly integrate webhooks and receive real-time updates in your Quable application.