Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 58

Registering Webhooks for Specific Topics

Recommended resources

Hello! Welcome back to the course.

In our last lesson, we established the "why" behind webhooks. You learned that they are an efficient, event-driven alternative to constant polling, allowing your app to receive real-time notifications from Shopify. We covered the core concepts of topics, subscriptions, and payloads.

Today, we transition from theory to practice. The natural next question is: "How do I actually tell Shopify to send these notifications to my app?" This lesson is dedicated to answering that question. By the end of our session, you will be able to register a webhook for a specific topic (e.g., orders/create).

We'll focus on the hands-on process of configuring your Shopify app to subscribe to an event, laying the groundwork for the powerful, real-time features you'll build.

How an App Subscribes to Webhooks

In the previous lesson, we used the analogy of giving a delivery company your phone number. For a Shopify app, this "phone number" is a public URL endpoint, and the "act of giving it" is called registering a subscription.

There are a few ways to do this:

  1. Via the Shopify Admin UI: You can manually create a webhook subscription in your store's settings. This is useful for quick, one-off tests but is not a scalable solution for an app that will be installed on many stores.
  2. Programmatically via API: Your app can use the Admin API to create webhook subscriptions after it has been installed. This is a flexible approach for when subscriptions need to be managed dynamically.
  3. Declaratively via Configuration: The Shopify CLI allows you to declare your app's required webhook subscriptions directly in a configuration file. When you deploy your app, the CLI ensures these subscriptions are created.

For building a distributable app, the declarative and programmatic methods are the most important. We'll focus on the modern declarative approach, which is the current best practice for the Shopify CLI, and supplement it with the programmatic handler logic from the CLI template.


The Two Sides of Webhook Registration: The Subscription and The Handler

Registering a webhook in a modern Shopify app involves two distinct but connected steps:

  1. The Subscription (Configuration): You must tell Shopify which topic you are interested in and what URL (uri) to send the notification to. We'll do this declaratively.
  2. The Handler (Code): You must write the code in your Node.js application that will execute when a notification arrives at that URL. This is the function that actually does something with the webhook data.

Let's explore each part.

1. The Subscription: Declarative Registration with shopify.app.toml

The Shopify CLI uses a configuration file, shopify.app.toml, to manage your app's core settings. This is the recommended place to define webhook subscriptions that are static and apply to every store that installs your app.

This declarative approach is powerful because it makes your app's requirements explicit and lets the Shopify CLI manage the registration process for you during development and deployment.

App configuration

The official Shopify documentation on App configuration explains the structure of the shopify.app.toml file. Let's look at how webhooks are defined.

Please review this document. Start by looking at the 'App configuration file example' to see where the [webhooks] section fits. Then, scroll down to the 'Reference' section and read the details under 'webhooks' and its subsection 'subscriptions'. Focus on the topics and uri properties.

As you saw in the documentation, you can define a [[webhooks.subscriptions]] block. To subscribe to the orders/create topic, you would add the following to your shopify.app.toml file:

# In shopify.app.toml

[webhooks]
api_version = "2024-04" # Or your target API version

[[webhooks.subscriptions]]
topics = [ "orders/create" ]
uri = "/api/webhooks"
  • topics = [ "orders/create" ]: This tells Shopify we are interested in the orders/create event.
  • uri = "/api/webhooks": This is a relative path. The Shopify CLI combines this with your app's tunnel URL during development (e.g., https://your-tunnel-url.trycloudflare.com/api/webhooks) to create the full callback URL that it registers with Shopify. This endpoint is a route in your Express.js application.

2. The Handler: Processing Webhooks in Your App

Declaring the subscription is only half the story. Now we need to implement the code that runs when Shopify sends a POST request to /api/webhooks.

The Shopify app template generated by the CLI comes pre-configured with a central webhook processing system. You don't need to create the /api/webhooks route yourself; you just need to "plug in" your handler logic for the specific topic.

The following video demonstrates this process clearly. While the video might use a slightly older version of the CLI template where webhooks were configured entirely in code, the core concept of adding a handler function remains identical and is an excellent visual guide.

Handling Webhooks in Your Shopify App: HTTP + Amazon EventBridge

The video 'Handling Webhooks in Your Shopify App' by Dev With Alex provides a fantastic step-by-step guide to adding a webhook handler to a CLI-generated app. We will adapt this method for our orders/create webhook.

Watch the segment from 01:50 to 05:00. Pay close attention to how a new webhook topic (products_update in the video) and its corresponding callback function are added to the shopify.config.webhooks object. This is the pattern we will follow.

Based on the pattern in the video, you would find the shopifyApp configuration in your main server file (likely web/index.js). Inside the webhooks object, you can add your handler.

The Shopify API library for Node.js provides an object containing all webhook topics, which ensures you use the correct topic names. Here's how you would add a handler for orders/create:

// In web/index.js (or your main server file)
import { WebhookTopic } from "@shopify/shopify-api";

// ... inside the shopifyApp() configuration object

  webhooks: {
    path: "/api/webhooks",
    // Add your new handler here
    [WebhookTopic.OrdersCreate]: {
      deliveryMethod: DeliveryMethod.Http,
      callbackUrl: "/api/webhooks",
      callback: async (topic, shop, body, webhookId) => {
        console.log("--- New order received! ---");
        const payload = JSON.parse(body);
        console.log(`Shop: ${shop}`);
        console.log("Payload:", payload);
        console.log("--------------------------");
        // In the next lesson, we'll do more than just log this.
      },
    },
    // Keep the existing mandatory GDPR webhooks...
  },

// ... rest of the file

A key point: The body of the webhook often arrives as a string. You need to use JSON.parse(body) to convert it into a JavaScript object you can work with.


Hands-On: Register and Test Your First Webhook

Now, let's put it all together.

1. Define the Handler:

  • Open your Shopify app project in your code editor.
  • Navigate to web/index.js.
  • Locate the webhooks property within the shopifyApp() configuration object.
  • Add the handler for WebhookTopic.OrdersCreate as shown in the code block above. Make sure to import WebhookTopic from @shopify/shopify-api.

2. Declare the Subscription:

  • Open the shopify.app.toml file at the root of your project.
  • Add the [webhooks] and [[webhooks.subscriptions]] sections as shown earlier to subscribe to orders/create.

3. Test the Webhook:

  • Run your app with npm run dev.
  • In a separate terminal, you can now use the Shopify CLI to simulate an orders/create event. This is an incredibly useful feature for local development, as you don't need to create real orders.

Handling Webhooks in Your Shopify App: HTTP + Amazon EventBridge

The same video from Dev With Alex also shows exactly how to use the CLI to trigger a test webhook. Let's watch how it's done.

Watch the segment from 05:50 to 07:25. Observe the npm run shopify webhook trigger command and the prompts that follow. This will guide you through testing your own webhook.

Now, run the command yourself:

npm run shopify webhook trigger

Follow the interactive prompts:

  • API Version: Choose the same one you set in shopify.app.toml.
  • Topic: Search for and select orders/create.
  • Delivery Method: Choose HTTP.
  • Address: Your dev server will be running on a Cloudflare tunnel. The CLI should detect this and suggest the correct address (e.g., https://your-app-name.trycloudflare.com/api/webhooks). Confirm this.

After you run the command, you should see the console.log messages from your handler appear in the terminal where your dev server is running. Congratulations, you've successfully registered and received your first webhook!

Test your understanding!

You now need to be notified whenever a customer's record is updated in the store. What two specific changes would you need to make to your application code and configuration to achieve this?

Show answer
  1. In shopify.app.toml: You would add another subscription for the customers/update topic.
    [[webhooks.subscriptions]]
    topics = [ "customers/update" ]
    uri = "/api/webhooks"
    
  2. In web/index.js: You would add a new handler for WebhookTopic.CustomersUpdate inside the webhooks configuration object, with its own callback function to process the customer data.

Conclusion

In this lesson, we bridged the gap from theory to practice. You now have the essential skill of registering a webhook, a fundamental building block for any app that needs to react to store events.

Key Takeaways:

  • Webhook registration in a modern Shopify app involves a declarative subscription in shopify.app.toml and a programmatic handler in your web/index.js file.
  • The shopify.app.toml file tells Shopify what event to watch for and where to send the notification.
  • The handler function in your code defines what to do with the notification when it arrives.
  • The Shopify CLI is your best friend for local testing, allowing you to trigger fake webhook events with the webhook trigger command, saving you from having to perform real actions in your store.

Next Steps

Right now, our webhook handler simply logs the incoming payload to the console. While this proves our connection works, it's not very useful. Furthermore, our endpoint is public, and we haven't verified that the requests are actually coming from Shopify.

In the next lesson, we will focus on building out a proper handler. You will learn how to create a webhook handler endpoint in Express.js to process incoming webhook payloads, which will include the most critical step in webhook security: verifying the HMAC signature to ensure the data is authentic and secure.