Webhookobject
object
Contains functions for verifying Shopify webhooks.
Verifies requests coming from Shopify webhooks.
Anchor to request
request
Request
required
Promise<<ConfigArg, Resources, Topics>>
Was this section helpful?
Update a metafield when a product is updated
/app/routes/**.ts
import {type ActionFunctionArgs} from '@remix-run/node';
import {authenticate} from '../shopify.server';
export const action = async ({request}: ActionFunctionArgs) => {
const {topic, admin, payload, session} = await authenticate.webhook(request);
// Webhook requests can trigger after an app is uninstalled
// If the app is already uninstalled, the session may be undefined.
if (!session) {
throw new Response();
}
switch (topic) {
case 'PRODUCTS_UPDATE':
await admin.graphql(
`#graphql
mutation setMetafield($productId: ID!, $time: String!) {
metafieldsSet(metafields: {
ownerId: $productId
namespace: "my-app",
key: "webhook_received_at",
value: $time,
type: "string",
}) {
metafields {
key
value
}
}
}
`,
{
variables: {
productId: payload.admin_graphql_api_id,
time: new Date().toISOString(),
},
},
);
}
return new Response();
};
Anchor to examplesExamples
Anchor to example-webhook-admin-contextWebhook admin context
Use the admin
object in the context to interact with the Admin API.
Was this section helpful?
Webhook admin context
/app/routes/webhooks.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export async function action({ request }: ActionFunctionArgs) {
const { admin } = await authenticate.webhook(request);
// Webhook requests can trigger after an app is uninstalled
// If the app is already uninstalled, the session may be undefined.
if (!session) {
throw new Response();
}
const response = await admin?.graphql(
`#graphql
mutation populateProduct($input: ProductInput!) {
productCreate(input: $input) {
product {
id
}
}
}`,
{ variables: { input: { title: "Product Name" } } }
);
const productData = await response.json();
return json({ data: productData.data });
}
Anchor to example-apiversionapiVersion
Anchor to example-webhook-api-versionWebhook API version
Get the API version used for webhook request.
Was this section helpful?
Webhook API version
/app/routes/webhooks.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { apiVersion } = await authenticate.webhook(request);
return new Response();
};
Anchor to example-payloadpayload
Anchor to example-webhook-payloadWebhook payload
Get the request's POST payload.
Was this section helpful?
Webhook payload
/app/routes/webhooks.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { payload } = await authenticate.webhook(request);
return new Response();
};
Anchor to example-sessionsession
Anchor to example-protecting-against-uninstalled-appsProtecting against uninstalled apps
Was this section helpful?
Protecting against uninstalled apps
/app/routes/webhooks.tsx
import type { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "~/shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { session } = await authenticate.webhook(request);
// Webhook requests can trigger after an app is uninstalled
// If the app is already uninstalled, the session may be undefined.
if (!session) {
throw new Response();
}
// Handle webhook request
console.log("Received webhook webhook");
return new Response();
};
Anchor to example-webhook-shopWebhook shop
Get the shop that triggered a webhook.
Was this section helpful?
Webhook shop
/app/routes/webhooks.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { shop } = await authenticate.webhook(request);
return new Response();
};
Anchor to example-subtopicsubTopic
Anchor to example-webhook-sub-topicWebhook sub-topic
Get the webhook sub-topic.
Was this section helpful?
Webhook sub-topic
/app/routes/webhooks.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { subTopic } = await authenticate.webhook(request);
return new Response();
};
Anchor to example-webhook-topicWebhook topic
Get the event topic for the webhook.
Was this section helpful?
Webhook topic
/app/routes/webhooks.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { topic } = await authenticate.webhook(request);
switch (topic) {
case "APP_UNINSTALLED":
// Do something when the app is uninstalled.
break;
}
return new Response();
};
Anchor to example-webhookidwebhookId
Anchor to example-webhook-idWebhook ID
Get the webhook ID.
Was this section helpful?
Webhook ID
/app/routes/webhooks.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { webhookId } = await authenticate.webhook(request);
return new Response();
};