App reviews, troubleshooting, and recommendations
I'm able to successfully create a Google PubSub subscription in the after_auth block in shopify.server.js.
However, the issue is that the subscription is lost if I restart my server for any reason.
I would like to be able to register subscriptions when the server starts and not have to refresh a page or re-install the app.
Is there a way to register code somewhere that runs only once when the server starts or does anyone have any recommendations for dealing with this type of thing?
Thanks.
Your domain url changes on every server restart and your webhook subscription is only triggered upon installation. This problem only occurs on local development. At the moment, my solution that I could come up with was to have a command script to delete the previous webhook and re-subscribe all webhooks again whenever I restart my server.
import { json } from "@remix-run/node";
import { cors } from "remix-utils/cors";
import { authenticate, unauthenticated } from "../shopify.server";
import dbConnect from "@/db";
import { Session } from "@/modules/session/session.model";
export const loader = async ({ request, response }) => {
await authenticate.admin(request);
return cors(request, response);
}
const webhookTopics = [
'app/uninstalled',
'orders/updated',
// 'orders/create',
'products/update',
'products/delete',
'inventory_levels/update',
'inventory_items/create',
];
export const action = async ({ request }) => {
await dbConnect()
try {
const storeList = await Session.find()
for (const store of storeList) {
const { admin } = await unauthenticated.admin(store.shop);
const subscribedWebhook = await admin.rest.get({
path: `webhooks.json`
});
const subscribedWebhookResponse = await subscribedWebhook.json();
let deleteWebhook = false
// Delete Existing Webhook, Temporary comment incase we need to resubscribe
deleteWebhook = true
for (const currentWebhook of subscribedWebhookResponse.webhooks) {
const deletedWebhook = await admin.rest.delete({
path: `webhooks/${currentWebhook.id}.json`
});
const deletedWebhookResponse = await deletedWebhook.json();
console.log(`Deleted webhook ${currentWebhook.topic}`)
}
for (const topic of webhookTopics) {
let exist = false
subscribedWebhookResponse.webhooks.map(existingWebhook => {
if (existingWebhook.topic === topic && deleteWebhook == false) {
exist = true
}
})
if (exist) {
console.log(`Skip existing webhook ${topic}`)
continue
}
const webhookEndpoint = `${process.env.URL}/webhooks`;
const webhookData = {
webhook: {
topic: topic,
address: webhookEndpoint,
format: 'json',
},
};
const response = await admin.rest.post({
path: `webhooks.json`,
data: webhookData
});
const responseData = await response.json();
if (response.ok) {
console.log(`Webhook for ${topic} successfully created with ID: ${responseData.webhook.id}`);
} else {
console.error(`Failed to create webhook for ${topic}. Error: ${JSON.stringify(responseData)}`);
}
}
}
return cors(request, json({ status: 'success', data: "" }));
} catch (err) {
console.error(err);
return cors(request, json({
status: 'error',
message: 'error'
}, {
status: 500
}));
}
};
Learn how to expand your operations internationally with Shopify Academy’s learning path...
By Shopify Feb 4, 2025Hey Community, happy February! Looking back to January, we kicked off the year with 8....
By JasonH Feb 3, 2025Expand into selling wholesale with Shopify Academy’s learning path, B2B on Shopify: Lau...
By Shopify Jan 28, 2025