Hey,
I am working a shopify app on api-version 2023-04, based almost identically on a shopify-example node app from ~9 months ago, though now appears to have vanished from the internet.
All I want to do is trigger the orders/paid webhook on my app when it’s deployed on fly.io.
My app appears to work when triggered locally, but am I listening to the webhook wrong? This version should still be supported currently right?
So this works perfectly when I trigger the webhook when running the app locally (npm run dev):
npm run shopify webhook trigger -- --topic ORDERS_PAID --api-version 2023-04 --delivery-method http --client-secret=x --address http://localhost:61989/api/webhooks
However, when deployed to fly.io and I click the Order payment’s “Send test nofitication” button to trigger the webhook and fly.io noticed the webhook is called but seemingly my setup is wrong here as none of my “ORDERS_PAID” webhook JS is running:
2023-10-15T16:54:24.579 app[x] lhr [info] webhook-handlers.js
2023-10-15T16:54:25.556 app[x] lhr [info] [shopify-api/INFO] Processing webhook request | {apiVersion: 2023-04, domain: redacted, topic: orders/paid, webhookId: 123
2023-10-15T16:54:25.568 app[x] lhr [info] [shopify-app/ERROR] Failed to process webhook: Error: Could not validate request for topic orders/paid
My webhooks file:
import shopify from "./shopify.js";
import { DeliveryMethod } from "@shopify/shopify-api";
console.log('webhook-handlers.js');
export default {
CUSTOMERS_DATA_REQUEST: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: shopify.config.webhooks.path,
callback: async (topic, shop, body, webhookId) => {
},
},
CUSTOMERS_REDACT: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: shopify.config.webhooks.path,
callback: async (topic, shop, body, webhookId) => {
},
},
SHOP_REDACT: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: shopify.config.webhooks.path,
callback: async (topic, shop, body, webhookId) => {
},
},
ORDERS_PAID: {
console.log('do something');
},
};
index.js of the app:
// @ts-check
import { join } from "path";
import { readFileSync } from "fs";
import express from "express";
import serveStatic from "serve-static";
import shopify from "./shopify.js";
import webhookHandlers from "./webhook-handlers.js";
const PORT = parseInt(process.env.BACKEND_PORT || process.env.PORT, 10);
const STATIC_PATH =
process.env.NODE_ENV === "production"
? `${process.cwd()}/frontend/dist`
: `${process.cwd()}/frontend/`;
const app = express();
// Set up Shopify authentication and webhook handling
app.get(shopify.config.auth.path, shopify.auth.begin());
app.get(
shopify.config.auth.callbackPath,
shopify.auth.callback(),
shopify.redirectToShopifyOrAppRoot()
);
app.post(
shopify.config.webhooks.path,
shopify.processWebhooks({
webhookHandlers,
}),
);
// ...
Any suggestions on why fly.io behaves this way? And how I can ensure my JS is run on this webhook?
There are some suggestions in the docs that some domains will be banned, one post here referencing an app a user built on heroku being a banned domain. But helpfully shopify doesn’t list all banned domains, so no idea if I’m technically using a domain which might be shadow banned (*.fly.dev). Also a mild suggestion of using cloudflare tunnel, which I believe was in the example applicaiton, though can’t see any reference on how to easily set this up which I’m sure was referenced much more thoroughly back then.