Shopify / shopify-api-ruby

ShopifyAPI is a lightweight gem for accessing the Shopify admin REST and GraphQL web services.
MIT License
1.05k stars 467 forks source link

ShopifyAPI::Errors::NoWebhookHandler for mandatory webhooks #1328

Closed overallduka closed 3 weeks ago

overallduka commented 1 month ago

Issue summary

Before opening this issue, I have:

After upgrading my shopify_app to 22.2.1 and shopify_api to 14.3.0 I continue seeing the ShopifyAPI::Errors::NoWebhookHandler for mandatory webhooks like customers/redact.

Worth to say that I have upgraded from a very old versio to 14.0.1 first and the same error happened, I upgraded to 14.3.0 in hope it was fixed, but the error continues.

ShopifyAPI::Errors::NoWebhookHandler
No webhook handler found for topic: customers/redact.

I did found a issue about this which mentions that old versions were working:

https://github.com/Shopify/shopify_app/issues/1756

But it seems that new versions of the API are not handling it okay.

Expected behavior

The mandatory webhhoks should be handled okay.

Actual behavior

The error.

Steps to reproduce the problem

  1. Create a new app
  2. Simulate a webhook call (yarn shopify webhook trigger)

Debug logs

shopify_api (14.3.0) lib/shopify_api/webhooks/registry.rb in process at line 193
sorbet-runtime (0.5.11478) lib/types/private/methods/call_validation_2_7.rb in bind_call at line 687
sorbet-runtime (0.5.11478) lib/types/private/methods/call_validation_2_7.rb in block in create_validator_procedure_fast1 at line 687
shopify_app (22.2.1) app/controllers/shopify_app/webhooks_controller.rb in receive at line 10
actionpack (6.0.6.1) lib/action_controller/metal/basic_implicit_render.rb in send_action at line 6
actionpack (6.0.6.1) lib/abstract_controller/base.rb in process_action at line 195
actionpack (6.0.6.1) lib/action_controller/metal/rendering.rb in process_action at line 30

My customer redact job:

class CustomersRedactJob < ApplicationJob
  extend ShopifyAPI::Webhooks::Handler

  queue_as :default

  class << self
    def handle(topic:, shop:, body:)
      perform_later(topic: topic, shop_domain: shop, webhook: body)
    end
  end
...

I've tried use the new extend ShopifyAPI::Webhooks::WebhookHandler but the problem remains.

paulomarg commented 1 month ago

Thank you for raising this, we'll look into it!

sle-c commented 1 month ago

hi @overallduka, this PR https://github.com/Shopify/shopify-app-template-ruby/pull/137 should fix the issue. You can follow the file changes to register your webhook handler. You might need to change https://github.com/Shopify/shopify-app-template-ruby/pull/137/files#diff-426ab93ca0ca0b0481e4a62a91efe2750cdfc3436c977eb33537962cb54c2bc3R83 to your custom redaction job. See webhook documentation for more details on how to add webhook handlers to your app.

overallduka commented 1 month ago

Thanks @sle-c ! It worked after add the add_privacy_webhooks method to shopify initializer, and now is receiving correctly the mandatory webhooks.

Just one adjustment that needs to be done in the documentation:

Here: https://github.com/Shopify/shopify-api-ruby/blob/main/docs/usage/webhooks.md#create-a-webhook-handler

Where it says:

module WebhookHandler
  extend ShopifyAPI::Webhooks::WebhookHandler

  class << self
    def handle_webhook(data:)
      puts "Received webhook! topic: #{data.topic} shop: #{data.shop} body: #{data.body} webhook_id: #{data.webhook_id} api_version: #{data.api_version"
    end
  end
end

It should be:

module WebhookHandler
  extend ShopifyAPI::Webhooks::WebhookHandler

  class << self
    def handle(data:)
      puts "Fired handle_webhook"
      puts "Received webhook! topic: #{data.topic} shop: #{data.shop} body: #{data.body} webhook_id: #{data.webhook_id} api_version: #{data.api_version}"
      perform_later(topic: data.topic, shop_domain: data.shop, webhook: data.body)
    end
  end
end

The handle_webhook method does not exist in ShopifyAPI::Webhooks::WebhookHandler, it should be handle, also had a little syntax error.

richpeck commented 3 weeks ago

Thanks @sle-c ! It worked after add the add_privacy_webhooks method to shopify initializer, and now is receiving correctly the mandatory webhooks.

Just one adjustment that needs to be done in the documentation:

Here: https://github.com/Shopify/shopify-api-ruby/blob/main/docs/usage/webhooks.md#create-a-webhook-handler

Where it says:

module WebhookHandler
  extend ShopifyAPI::Webhooks::WebhookHandler

  class << self
    def handle_webhook(data:)
      puts "Received webhook! topic: #{data.topic} shop: #{data.shop} body: #{data.body} webhook_id: #{data.webhook_id} api_version: #{data.api_version"
    end
  end
end

It should be:

module WebhookHandler
  extend ShopifyAPI::Webhooks::WebhookHandler

  class << self
    def handle(data:)
      puts "Fired handle_webhook"
      puts "Received webhook! topic: #{data.topic} shop: #{data.shop} body: #{data.body} webhook_id: #{data.webhook_id} api_version: #{data.api_version}"
      perform_later(topic: data.topic, shop_domain: data.shop, webhook: data.body)
    end
  end
end

The handle_webhook method does not exist in ShopifyAPI::Webhooks::WebhookHandler, it should be handle, also had a little syntax error.

+1 on this - very confusing.

lizkenyon commented 2 weeks ago

Thanks for flagging I put up a PR to resolve this! We also welcome PRs for docs, or any updates, so feel free to open a PR for this sort of thing!