Topics covering webhook creation & management, event handling, Pub/Sub, and Eventbridge, in Shopify apps.
Hi all,
I am developing a custom public app.
In the app, once a button is clicked, a bulk operation is sent to fetch all stores products.
The bulk operation work good, it checked that i get a valid url to download a JSONL after setting a timeout of a few seconds.
Of course, the timeout is not a legit solution so I am trying to register a webhook for the bulk finish and handle the response there.
I have read all the suggested docs, been through all posts that contain "bulk" and "webhook" wordkeys, but i could not make it work.
I read and walked through GraphQL Admin API docs, Node.js Client Library, as well as some of the more specific and in-depth examples here, Shopify Dev Youtube channel .
I created the project with the Shopify CLI so the infrastructure should be battle tested.
I will attach my code snippets below, explain where they are in the code and hope someone can spot a mistake.
below handler is written in the server/index.ts just below the APP_UNINSTALLED handler that comes out of the box from Shopify
Shopify.Webhooks.Registry.addHandler('BULK_OPERATIONS_FINISH', {
path: "/webhooks",
webhookHandler: async (topic, shop, body) => {
console.log('in BULK_OPERATIONS_FINISH webhookHandler', body)
},
});
below register in written inside the "/auth/callback" as suggested in the node lib docs.
const integrateResponse: any = await Shopify.Webhooks.Registry.register({
shop: session.shop,
accessToken: session.accessToken,
path: '/webhooks',
topic: 'BULK_OPERATIONS_FINISH',
});
if (!integrateResponse["BULK_OPERATIONS_FINISH"].success) {
console.log(`Failed to register BULK_OPERATIONS_FINISH webhook: ${integrateResponse.result}`);
} else {
console.log('integrateResponse', integrateResponse) //this in does print so i know the register is successful
}
below query is called upon a button clicked.
a status "CREATED" is always printed
const client = await shopifyGraphqlClient(req, res);
const bulkQueryString = `mutation {
bulkOperationRunQuery(
query: """
{
products {
edges {
node {
id
title
}
}
}
}
"""
)
{
bulkOperation {
id
status
}
userErrors {
field
message
}
}
}`
//should be subscribed to a webhook or get part data with intervals
const bulkResult: any = await client.query({data: bulkQueryString});
const status = bulkResult.body.data.bulkOperationRunQuery.bulkOperation.status;
const errors = bulkResult.body.data.bulkOperationRunQuery.useErrors;
console.log('bulk operation status', status)
below are https POST listeners inside the "createServer" function that is called on app init.
tried few attempts but none of them are invoked
app.post("/webhooks", async (req, res) => {
try {
console.log('in post webhooks', req, res)
await Shopify.Webhooks.Registry.process(req, res);
console.log(`Webhook processed, returned status code 200`);
} catch (error) {
console.log(`Failed to process webhook: ${error}`);
if (!res.headersSent) {
res.status(500).send(error.message);
}
}
});
app.post("/bulk_operations/finish", async (req, res) => {
try {
console.log('in post /bulk_operations/finish', req, res)
await Shopify.Webhooks.Registry.process(req, res);
console.log(`Webhook processed, returned status code 200`);
} catch (error) {
console.log(`Failed to process webhook: ${error}`);
if (!res.headersSent) {
res.status(500).send(error.message);
}
}
});
app.post("bulk_operations/finish", async (req, res) => {
try {
console.log('in post bulk_operations/finish', req, res)
await Shopify.Webhooks.Registry.process(req, res);
console.log(`Webhook processed, returned status code 200`);
} catch (error) {
console.log(`Failed to process webhook: ${error}`);
if (!res.headersSent) {
res.status(500).send(error.message);
}
}
});
I'll mention again that i can get the answer from the Graphql bulk query if i put a timeout after calling it, so we know it fetches the data properly, but a proper solution should be a webhook.
would appreciate any help. Thanks!
Hey,
I'm having the same problem.
I'm creating bulk operations in the GraphiQL app, getting a created status back, and when I query the current bulk operation a little later, it confirms the status is complete, but no BULK_OPERATIONS_FINISH webhook is firing in my app which is registered correctly. This is obviously a problem if I need to queue bulk operation requests and initiate the next one upon completion of the previous. Does anyone on the Shopify team have an idea of what is happening here? Is anyone else having any issues?
Thanks,
Curtis
Hello,
I was wondering if you found a solution to this since you posted your message?
Thanks,
Anton
I'm here for the same reason - webhook not returning, but a manual query shows that it is complete
I dont want to manually poll to see if its completed or not
Hello,
I found the issue with mywebhook. I was using two different tokens to fire the event and register the webhook.
A.
Hi all,
Sorry, I intended to post an update on my situation sooner but never got around to it. If I remember correctly, my issues turned out to be specific to the GraphiQL app, and strangely enough, any job I triggered in my app did end up getting the BULK_OPERATIONS_FINISH webhook fire.
Curtis