Your app must respond to [mandatory webhook topics](/docs/apps/webhooks/configuration/mandatory-webhooks). In addition, your app can register [optional webhook topics](/docs/api/admin-rest/current/resources/webhook#event-topics).
To set up webhooks first we need to configure `shopifyApp` with 2 pieces: 1. The webhooks you want to subscribe to. In this example we subscribe to the `APP_UNINSTALLED` topic. 1. The code to register the `APP_UNINSTALLED` topic after a merchant installs you app. Here `shopifyApp` provides an `afterAuth` hook. > Note: You can't register mandatory topics using this package, you must [configure those in the Partner Dashboard](/docs/apps/webhooks/configuration/mandatory-webhooks) instead.
import {shopifyApp, DeliveryMethod} from '@shopify/shopify-app-remix/server';
const shopify = shopifyApp({
apiKey: 'abcde1234567890',
// ...etc
webhooks: {
APP_UNINSTALLED: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: '/webhooks',
},
},
hooks: {
afterAuth: async ({session}) => {
shopify.registerWebhooks({session});
},
},
});
export const authenticate = shopify.authenticate;
Legitimate webhook requests are always `POST`s signed by Shopify, so you must authenticate them before taking any action. For each `callbackUrl` in your configuration, you must set up an `action` that uses the `authenticate.webhook` function to authenticate the request. Please keep in mind that webhook endpoints should respond as quickly as possible. If you need to run a long-running job, then consider using background tasks. > Caution: Webhook endpoints **must** respond with an `HTTP 200` code, or Shopify will retry.
import {ActionFunction} from '@remix-run/node';
import db from '../db.server';
import {authenticate} from '~/shopify.server';
export const action: ActionFunction = async ({request}) => {
const {topic, shop, session} = await authenticate.webhook(request);
switch (topic) {
case 'APP_UNINSTALLED':
if (session) {
await db.session.deleteMany({where: {shop}});
}
break;
case 'CUSTOMERS_DATA_REQUEST':
case 'CUSTOMERS_REDACT':
case 'SHOP_REDACT':
default:
throw new Response('Unhandled webhook topic', {status: 404});
}
throw new Response();
};