Webhook persistence using Shopify Node library's Shopify.Webhooks.Registry

ConspireAgency
Shopify Expert
26 1 12

One thing I noticed while transitioning to using the official Shopify Node API library is that in the registering and processing of webhooks that if the server restarts then webhooks stop getting processed properly and you get an error like below when you receive a webhook:

 

Failed to process webhook: Error: No webhook is registered for topic draft_orders/update

 

 

Which would be a problem if a bunch of people installed your app -> server restarts for some reason -> your webhooks all start failing.  I'm registering and processing the Webhooks using code generated via the CLI.

Webhooks are processed properly if you install the app, the webhooks register and your server doesn't restart.  The issue only arises when the server restarts.  The app keeps receiving webhooks on the proper events at "/webhooks", which indicated to me that on the server side there's a check before processing a webhook that compares the incoming webhook topic to the topics the library stores upon initial registration.  Shopify is sending the correct webhooks to the correct endpoint, which points to an issue of persistence after server restart on the app server side.

Looking at the node library in shopify-api/webhooks/registry.js in the "process" function there's indeed a check of the incoming topic vs a store called WebhooksRegistry

 

webhookEntry = WebhooksRegistry.webhookRegistry.find(function (entry) { return entry.topic === graphqlTopic_1; });
var WebhooksRegistry = {
    webhookRegistry: [],

 

 

This seems to be the culprit of why on restart the registered webhooks wouldn't be persisted. 

Has anyone else run into this?  Was looking at the limited documentation (new library, understandable) and didn't find anything... so here I am digging through the library itself pondering the best solution.

 

Cheers!

Conspire Agency //
Los Angeles, California //
https://conspireagency.com
View my showreel: https://www.youtube.com/watch?v=E9upo48FQUg
Replies 2 (2)
ConspireAgency
Shopify Expert
26 1 12

UPDATE

Figured out a temporary hack-y solution by checking Shopify.Webhooks.Registry.webhookRegistry contents on the "/webhooks" route.  If it didn't have anything registered then I set this variable to what should have been registered on initial install.

Not that it makes a world of difference, but thought it would also be worth mentioning that my webhook registration takes place in afterAuth and my app uses offline tokens.

router.post("/webhooks", async (ctx) => {
    try {
      console.log("received a webhook");
      if(!Shopify.Webhooks.Registry.webhookRegistry.length > 0){
        console.log('need to set registered webhooks TODO HACKY SOLUTION');
        setShopifyWebhookRegistry();
      }
      await Shopify.Webhooks.Registry.process(ctx.req, ctx.res);
      console.log(`Webhook processed, returned status code 200`);
    } catch (error) {
      console.log(`Failed to process webhook: ${error}`);
    }
  });

 

I had already setup a helper function that pulls from an array to clean up the webhook registration process.  So what I did is modify that array slightly to resemble what Shopify.Webhooks.Registry.webhookRegistry expects.

const webhooks = [
    {
        path: '/webhooks',
        topic: 'DRAFT_ORDERS_CREATE',
        webhookHandler: handleWebhookRequest
    },
    {
        path: '/webhooks',
        topic: 'DRAFT_ORDERS_UPDATE',
        webhookHandler: handleWebhookRequest
    },
    {
        path: '/webhooks',
        topic: 'APP_SUBSCRIPTIONS_UPDATE',
        webhookHandler: handleWebhookRequest
    },
    {
        path: '/webhooks',
        topic: 'APP_UNINSTALLED',
        webhookHandler: handleWebhookRequest
    }
];

 

Then run this function from the first code snippet

export function setShopifyWebhookRegistry(){
    Shopify.Webhooks.Registry.webhookRegistry = webhooks;
}

 

This works, but overall feels pretty hack-y and isn't super clean.  Would love to get second opinions.

Conspire Agency //
Los Angeles, California //
https://conspireagency.com
View my showreel: https://www.youtube.com/watch?v=E9upo48FQUg
samuelkaizen
Tourist
6 0 0

Thanks for posting, I am seeing exactly the same issue when my server restarts. This is a major issue.