Shopify / shopify-api-ruby

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

Error registering mandatory webhooks through ShopifyAPI::Webhooks::Registry#register #1123

Closed m11o closed 1 year ago

m11o commented 1 year ago

Issue summary

I encountered an error when using this gem to register webhooks for mandatory webhooks (customers/redact, customers/data_request, shop/redact). According to Shopify's documentation, these webhooks can only be set up through the Shopify admin dashboard and cannot be registered via API. However, since the code for receiving and subscribing to webhooks is shared in this gem, attempting to register these webhooks through the code leads to an error.

The error message I received is:

"Argument 'topic' on Field 'webhookSubscriptionCreate' has an invalid value (SHOP_REDACT). Expected type 'WebhookSubscriptionTopic!'."

Here's the code I used to register the webhook:

ShopifyApp.configure do |config|
  config.webhooks = [
    { topic: 'app/uninstalled',  path: 'shopify_app/webhooks/app_uninstalled' },
    { topic: 'customers/create', path: 'shopify_app/webhooks/customers_create' },

    # Mandatory Webhooks
    # ref: https://shopify.dev/apps/webhooks/configuration/mandatory-webhooks
    { topic: 'shop/redact',            path: 'shopify_app/webhooks/shop_redact' },
    { topic: 'customers/data_request', path: 'shopify_app/webhooks/customers_data_request' },
    { topic: 'customers/redact',       path: 'shopify_app/webhooks/customers_redact' },
  ]

  # ... do something
end

Rails.application.config.after_initialize do
  # ... do something

  ShopifyApp::WebhooksManager.add_registrations
end

# After a shop installs our app.
ShopifyApp::WebhooksManagerJob.perform_later(shop_domain: 'domain', shop_token: 'token')
# => Argument 'topic' on Field 'webhookSubscriptionCreate' has an invalid value (SHOP_REDACT). Expected type 'WebhookSubscriptionTopic!'.

The simple code is:

session = ShopifyAPI::Auth::Session.new(shop: 'domain', access_token: 'token')
ShopifyAPI::Webhooks::Registry.register(topic: 'shop/redact', session: session)

Expected behavior

Topics excluding mandatory webhooks which we register webhooks can be registered.

Actual behavior

The bellow error occurred.

"Argument 'topic' on Field 'webhookSubscriptionCreate' has an invalid value (SHOP_REDACT). Expected type 'WebhookSubscriptionTopic!'."

Steps to reproduce the problem

  1. Subscribe to mandatory webhooks through shopify-api-ruby gem.
m11o commented 1 year ago

This may be related to https://github.com/Shopify/shopify_app/issues/1659

nelsonwittwer commented 1 year ago

It looks live we've got some work to do to clarify how mandatory webhooks are meant to be configured.

I haven't been able to reproduce this error following the pattern of handling mandatory GDPR webhooks with our app template.

It seems like the template vs your config has a different pattern for path vs address. I didn't dive too far into the differences between the two, but I wonder if there is something there. Can you try to modify your config to follow how our latest app templates work?

kirillplatonov commented 1 year ago

@nelsonwittwer the issue is still there. I was able to reproduce it with a clean app generated with shopify-app-template-ruby. Below are exact steps to reproduce it:

  1. Generate a new app with CLI 3.0 and ruby template.
  2. Run npm run dev and connect the Shopify app and dev store.
  3. Setup env variables for Rails:
    npm run shopify app env pull
    mv .env web/.env
    cd web
    bundle add dotenv-rails
  4. Run rails console and make sure make sure GDPR webhooks are loaded by calling ShopifyApp.configuration.webhooks. It should return the following output:
    => [{:topic=>"app/uninstalled", :address=>"api/webhooks/app_uninstalled"},
    {:topic=>"shop/redact", :address=>"api/webhooks/shop_redact"},
    {:topic=>"customers/redact", :address=>"api/webhooks/customers_redact"},
    {:topic=>"customers/data_request", :address=>"api/webhooks/customers_data_request"}]
  5. Try recreating webhooks:
    session = ShopifyAPI::Auth::Session.new(shop: Shop.last.shopify_domain, access_token: Shop.last.shopify_token)
    ShopifyApp::WebhooksManager.recreate_webhooks!(session: session)

    This will raise an error:

    /shopify_api-12.5.0/lib/shopify_api/webhooks/registry.rb:154:in `get_webhook_id': 
    Failed to fetch webhook from Shopify: Argument 'topics' on Field 'webhookSubscriptions' has 
    an invalid value (SHOP_REDACT). Expected type '[WebhookSubscriptionTopic!]' (ShopifyAPI::Errors::WebhookRegistrationError)

We definitely need GPDR webhooks to be present in the registry in order to have a handler for them too. But they shouldn't be used when we trying to register webhook via API.

Can we reopen and merge PR by @m11o with the fix for this problem? https://github.com/Shopify/shopify-api-ruby/pull/1124

nelsonwittwer commented 1 year ago

Should be fixed with this app gem PR

schonert commented 1 year ago

Just upgraded to v 13 and experiencing this. Done a clean bundle install to ensure the latest gems.

/Users/..../.asdf/installs/ruby/3.0.4/lib/ruby/gems/3.0.0/gems/shopify_api-13.0.0/lib/shopify_api/webhooks/registry.rb:154:in 
  `get_webhook_id': Failed to fetch webhook from Shopify: 
    Argument 'topics' on Field 'webhookSubscriptions' has an invalid value (SHOP_REDACT). 
      Expected type '[WebhookSubscriptionTopic!]'. (ShopifyAPI::Errors::WebhookRegistrationError)

Snapshot of shopify_app form gemlock

# Gemfile.lcok
  ...
  shopify_app (21.5.0)
      activeresource
      addressable (~> 2.7)
      browser_sniffer (~> 2.0)
      jwt (>= 2.2.3)
      rails (> 5.2.1)
      redirect_safely (~> 1.0)
      shopify_api (~> 13.0)
      sprockets-rails (>= 2.0.0)
  ...

Not sure how to move forward from here. Also - getting this while running the recreate_webhooks! from the shopify_app (also latest).

schonert commented 1 year ago

Just realised it's not just shop/redact. Similar errors for customers/redact and customers/data_request