I want to create a quite simple Shopify Custom App for my shop. This App should run when an order is created, so with a webhook product/change.
After creating the webhook, I receive errors in my terminal as soon as I update a product and the webhook is sent. I just have no idea how to correctly implement the webhook code and where. So this question here is a very basic question, how can I implement a Shopify webhook (webhook code from official Shopify dev page for Ruby) in my freshly Shopify CLI created app. Unfortunately, I can't find any help, it seems that there are so many different ways of creating webhooks. None of them is working for me so far, so I try to stick to the most common one described by shopify dev tutorials.
Steps so far:
I installed a custom app with Shopify CLI, using a Node template with the command "npm init @shopify/app@latest".
After this, with "npm run dev" I created a tunnel with ngrok. With this, I receive a url to the app, I can access the app in my Shopify Partners and install it.
There is a video tutorial of a shopify dev that I used as help, if someone is more interested Shopify dev Webhook tuorial (of 2021, so I guess a bit outdated unfortunately).
I put the following "webhook code", which uses Ruby, in a app.rb file, which I saved in my root folder of my Shopify CLI created app. The code is available in Shopify dev tutorials (Shopify dev tuorial) for Ruby (I made just very few adaptions like adding a path and adding the Shopify Secret Key:
require 'rubygems'
require 'base64'
require 'openssl'
require 'sinatra'
require 'active_support/security_utils'
# The Shopify app's API secret key, viewable from the Partner Dashboard. In a production environment, set the API secret key as an environment variable to prevent exposing it in code.
API_SECRET_KEY = 'my_api_secret_key'
helpers do
# Compare the computed HMAC digest based on the API secret key and the request contents to the reported HMAC in the headers
def verify_webhook(data, hmac_header)
calculated_hmac = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', API_SECRET_KEY, data))
ActiveSupport::SecurityUtils.secure_compare(calculated_hmac, hmac_header)
end
end
# Respond to HTTP POST requests sent to this web service
post '/webook/product_update' do
request.body.rewind
data = request.body.read
verified = verify_webhook(data, env["HTTP_X_SHOPIFY_HMAC_SHA256"])
halt 401 unless verified
# Process webhook payload
# ...
end
Next to the "app.rb" in the root folder of my App, I created a "Gemfile":
source 'https://rubygems.org'
gem 'shopify_api'
gem 'sinatra'
gem 'activesupport'
With bundle install, a Gemfile.lock is created, everything seems fine here.
I created a webhook for product_change in my Shopify Partners Admin under "Notifications". As URL, I entered the ngrok URL from terminal window (from npm run dev command, the tunnel is still open), but with adding /webook/product_update, as this I used in the function path of the webhook.
The webhook is sending sth to my app when I update a product, which is good at least.
Unfortunately, as I update a product, my app shows errors in the terminal and crashes. The same errors are appearing even if I delete the app.rb file and the Gemlock files completely.
The terminal shows these errors:
C:\ShopifyApps\test2\web\node_modules\@shopify\shopify-api\dist\error.js:13
var _this = _super.apply(this, tslib_1.__spreadArray([], tslib_1.__read(args), false)) || this;
**InvalidRequestError: Request does not contain a host query parameter**
at InvalidRequestError.ShopifyError [as constructor] (C:\ShopifyApps\test2\web\node_modules\@shopify\shopify-api\dist\error.js:13:28)
at new InvalidRequestError (C:\ShopifyApps\test2\web\node_modules\@shopify\shopify-api\dist\error.js:230:42)
at Object.getEmbeddedAppUrl (C:\ShopifyApps\test2\web\node_modules\@shopify\shopify-api\dist\utils\get-embedded-app-url.js:22:15)
at file:///C:/ShopifyApps/test2/web/index.js:187:41
I'd be very happy about any hint how to find out what is wrong. How can I connect the abb.rb file with my index.js file of my root app? I guess I need to do that. But I have no real idea unfortunately.