APP_UNINSTALLED hook not being registered
Issue summary
Expected behavior
I am expecting that when I uninstall my test app, the APP_UNINSTALLED WEBHOOK gets fired.
Actual behavior
I get nothing, I get neither an error nor my console.log. I am pretty sure Shopify's backend fires the webhook, and the fact that the webhook is registered on my side as I get this response when I register it - {"APP_UNINSTALLED":{"success":true,"result":{}}}
Steps to reproduce the problem
I installed a new app to check if the mistake is on my side. I used shopify app create node. I uninstalled the default app and tried to reinstall, I got the same error. This leads me to believe the problem is on the shopify node app's side.
Reduced test case
Try uninstalling and reinstalling a new node app. The webhook is not registered.
Specifications
- Browser: Chrome
- Device: Mac Book Pro
- Operating System: Apple
Here is the relevant code:
In auth.js
const response = await Shopify.Webhooks.Registry.register({
path: "/webhooks",
topic: "APP_UNINSTALLED",
shop: session.shop,
accessToken: session.accessToken,
});
console.log(JSON.stringify(response));
if (!response["APP_UNINSTALLED"].success) {
console.log(
`Failed to register APP_UNINSTALLED webhook: ${response.result}`
);
}
index.js
Shopify.Webhooks.Registry.addHandler("APP_UNINSTALLED", {
path: "/webhooks",
webhookHandler: async (topic, shop, body) => {
console.log(topic, shop, body);
delete ACTIVE_SHOPIFY_SHOPS[shop];
},
});
app.post("/webhooks", async (req, res) => {
try {
await Shopify.Webhooks.Registry.process(req, res);
console.log(`Webhook processed, returned status code 200`);
} catch (error) {
console.log(`Failed to process webhook: ${error}`);
res.status(500).send(error.message);
}
});
Actually, if I use Postman, the /webhooks endpoint works. This means Shopify doesn't fire a APP_UNINSTALLED webhook?
@omkaark I tried the following steps and have been unable to reproduce the issue.
shopify app create node -n issue807cd issue807and modify the/webhookshandler to print a debug line
Shopify.Webhooks.Registry.addHandler("APP_UNINSTALLED", {
path: "/webhooks",
webhookHandler: async (topic, shop, body) => {
console.log(`DEBUG: ${topic}, ${shop}, ${body}`);
delete ACTIVE_SHOPIFY_SHOPS[shop];
},
});
shopify app serve- Installed the app in my development store, then delete the app
- I get the
console.logoutput
DEBUG: APP_UNINSTALLED, <shopname>.myshopify.com, {<body contents>}
Webhook processed, returned status code 200
- Install it again, delete it again
- I get the
console.logDEBUGoutput again
I got the exact same bug as @omkaark The console.log in the POST handler never gets fired inside the try.
- Console log outside of the Try when Shopify Call the registered Webhook is triggered as expected - This means Shopify call the Webhook url.
// SHOPIFY WEBHOOKS
Shopify.Webhooks.Registry.addHandler('APP_UNINSTALLED', {
path: '/api/webhooks',
webhookHandler: async(topic, shop, body) => {
console.log('webhookHandler', topic, shop, body); <== Shows in Terminal
return security.deleteAppSession();
}
});
// OAuth code
// Registry webhooks
const responses = await Shopify.Webhooks.Registry.registerAll({
shop: session.shop,
accessToken: session.accessToken,
});
// Process responses
Object.entries(responses).map(([topic, response]) => {
console.log('Webhooks.Registry.registerAll:', topic, response); <== Shows in Terminal
});
// Router
router.post('/api/webhooks', async (req, res) => {
console.log('/api/webhooks'); // <== Shows in terminal
try {
const p = await Shopify.Webhooks.Registry.process(req, res);
console.log('/api/webhooks:', p); // <== Never Shows
} catch (err) {
console.log('/api/webhooks:ERROR:', err); // <== Never Shows either
}
});
Solution: This is happening because one should not use bodyParser.json() or express.json() on the Shopify Webhook queries...
Solution found here: https://github.com/Shopify/shopify-api-node/issues/167#issuecomment-1174948817
This issue is stale because it has been open for 90 days with no activity. It will be closed if no further action occurs in 14 days.
Hi, same error here. Any solution?
I am also wondering if the path should be "/api/webhooks" or only "/webhooks".
I think the issue might be related to the APP_UNINSTALLED webhook callback address out-dated.
My question:
- Are there any suggested approach to update webhook address by shopify?
- Are there any shopify pre-written code or functions to do the auto update jobs?
- Are developers supposed to handle all webhook address update stuff, including update app uninstall webhook?
- Will there be contradictions with shopify pre-implemented code if developers implement our own logic?
TL;DR: I know is the issue of out-dated webhook address, how should I update it?
-
I have found the following issue when using ngrok tunnel server for app development.
- The callback address(URL) of the app uninstall webhook will not update for each time running
npm run dev. - However, for each time we run again the dev server, a new address is generated.
- Therefore, the webhook will call a deprecated address but not the current server handler endpoint.
- The callback address(URL) of the app uninstall webhook will not update for each time running
-
The following is the registered app/uninstalled webhook object. Once the topic is trigger, shopify will send a post request to the registered address
e.g. https://aa12-123-12-123-123ap.ngrok.io/api/webhooks
{
"id": 2258278463553,
"address": "https://aa12-123-12-123-123ap.ngrok.io/api/webhooks",
"topic": "app/uninstalled",
...
}
-
However, the domain part
aa12-123-12-123-123apwill remain unchanged until we update it whereas the app will not update it by default. And, the current server address might not be the same as the registered one. -
As a result, when we uninstall the app, shopify will call a deprecated address. That's why nothing happens.
-
I see the following code in
auth.jsand I understand it will create or update the webhooks, but I found that it never runs
app.get("/api/auth/callback", async (req, res)=>{
const responses = await Shopify.Webhooks.Registry.registerAll({
shop: session.shop,
accessToken: session.accessToken,
});
})
-
Are there any ways to auto update the address for app uninstall or we should implement the code ourself to do so?
-
Should there be any mistakes or misconceptions in my statements, please point out and correct me. Thanks
See also for docs: https://github.com/Shopify/shopify-api-node/blob/main/docs/usage/webhooks.md#note-regarding-use-of-body-parsers
See also for the issue: https://community.shopify.com/c/shopify-apis-and-sdks/uninstalled-webhook-not-firing/m-p/1141119#M65605