All Tutorials

Build a Shopify App with Node and React

Listen for store events with webhooks

Webhooks are a useful tool for apps that need to listen and act on specific events that happen in a store. You’ll be using the Koa Shopify webhooks package to register and receive Shopify webhooks. This package uses the GraphQL Admin API and the webhook subscription mutation to register webhooks, so make sure to use the supported topics for GraphQL webhook subscriptions.

Validate and register your webhook

  1. Navigate to the app section in your partner account. Click on your app and head to app setup. Scroll down to Event Subscriptions and ensure you're using the latest version of the API.

    admin alt
  2. Make sure ngrok is running, and that you’ve added the HTTPS version of your ngrok forwarding URL to your .env file:
    SHOPIFY_API_KEY='YOUR SHOPIFY API KEY FROM THE SHOPIFY PARTNERS DASHBOARD' SHOPIFY_API_SECRET_KEY='YOUR SHOPIFY API SECRET KEY FROM THE SHOPIFY PARTNERS DASHBOARD' HOST='https://YOURNGROKADDRESS.io'
  3. Install @shopify/koa-shopify-webhooks and koa-router:
    Terminal
                npm install --save @shopify/koa-shopify-webhooks koa-router@^8.0.8
    
  4. In your .server.js file, import @shopify/koa-shopify-webhooks:

    /server.js

    code contained in /server.js
    require('isomorphic-fetch'); const dotenv = require('dotenv'); const Koa = require('koa'); const next = require('next'); const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth'); const { verifyRequest } = require('@shopify/koa-shopify-auth'); const session = require('koa-session'); dotenv.config(); const { default: graphQLProxy } = require('@shopify/koa-shopify-graphql-proxy'); Add:const Router = require('koa-router'); Add:const {receiveWebhook, registerWebhook} = require('@shopify/koa-shopify-webhooks');
  5. In your server.js file, add your HOST variable to the deconstructed variables from your .env file:

    /server.js

    code contained in /server.js
    const { receiveWebhook, registerWebhook } = require('@shopify/koa-shopify-webhooks'); const getSubscriptionUrl = require('./server/getSubscriptionUrl'); const port = parseInt(process.env.PORT, 10) || 3000; const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev }); const handle = app.getRequestHandler(); const { SHOPIFY_API_SECRET_KEY, SHOPIFY_API_KEY, Add: HOST, } = process.env; app.prepare().then(() => {
  6. In your server.js file, instantiate the router:

    /server.js

    code contained in /server.js
    app.prepare().then(() => { const server = new Koa(); Add: const router = new Router(); server.use(session({ sameSite: 'none', secure: true }, server)); server.keys = [SHOPIFY_API_SECRET_KEY]; server.use( createShopifyAuth({ apiKey: SHOPIFY_API_KEY, secret: SHOPIFY_API_SECRET_KEY, scopes: ['read_products', 'write_products'],
  7. In your server.js file, register a webhook for product creation:

    /server.js

    code contained in /server.js
    async afterAuth(ctx) { const { shop, accessToken } = ctx.session; ctx.cookies.set('shopOrigin', shop, { httpOnly: false secure: true, sameSite: 'none' }); Add: const registration = await registerWebhook({ Add: address: `${HOST}/webhooks/products/create`, Add: topic: 'PRODUCTS_CREATE', Add: accessToken, Add: shop, Add: apiVersion: ApiVersion.October19 Add: }); Add: if (registration.success) { Add: console.log('Successfully registered webhook!'); Add: } else { Add: console.log('Failed to register webhook', registration.result); Add: }
  8. Stop your server, navigate to the Apps section of your Shopify Admin, and uninstall your app from your store. Apps section of the development store Admin circling the sample embedded app's garbage icon
  9. Reinstall your app on your development store:

  10. Upon registration, your server console should log: Successfully registered webhook! console alt

Create a webhook subscription and receive a webhook

Now that you’ve registered the request, you can now subscribe and receive a webhook. Since we’re using Koa router to make POST requests to the Shopify Billing API, we’ll be referencing the koa-router and multiple webhooks example.

  1. Set up your server.js file to receive webhooks when a product is created:

    /server.js

    code contained in /server.js
    await getSubscriptionUrl(ctx, accessToken); }, }), ); Add: const webhook = receiveWebhook({secret: SHOPIFY_API_SECRET_KEY}); Add: router.post('/webhooks/products/create', webhook, (ctx) => { Add: console.log('received webhook: ', ctx.state.webhook); Add: }); server.use(graphQLProxy());
  2. Send verifyRequest() and the app code through the router:

    /server.js

    code contained in /server.js
    server.use(graphQLProxy({version: ApiVersion.October19})) Remove: server.use(verifyRequest()); Remove: server.use(async (ctx) => { Remove: await handle(ctx.req, ctx.res); Remove: ctx.respond = false; Remove: ctx.res.statusCode = 200; Remove: }); Add: router.get('(.*)', verifyRequest(), async (ctx) => { Add: await handle(ctx.req, ctx.res); Add: ctx.respond = false; Add: ctx.res.statusCode = 200; Add: }); Add: server.use(router.allowedMethods()); Add: server.use(router.routes()); server.listen(port, () => {
  3. Stop and restart your server to render the changes to your server.js file.

  4. Navigate to the Products section in your development store’s Shopify admin.
  5. Click Add Product, enter at least a Title and Price, and then click Save.
  6. Your server console should now print out a success message: received webhook: { topic: 'YOURWEBHOOKTOPIC', domain: 'YOURSHOPIFYSTORE' }
  7. console alt subscription

Next steps

Congratulations on completing the tutorial! You’ve learned the basics of building a Shopify app. Want to learn more? Check out these additional resources: