diff --git a/CHANGELOG.md b/CHANGELOG.md index b9dc7ea31..49d402858 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Note: For changes to the API, see https://shopify.dev/changelog?filter=api ## Unreleased +- [#1237](https://github.com/Shopify/shopify-api-ruby/pull/1237) Skip mandatory webhook topic registration/unregistrations ## 13.2.0 diff --git a/lib/shopify_api/webhooks/registry.rb b/lib/shopify_api/webhooks/registry.rb index b19265b5e..e52204cc9 100644 --- a/lib/shopify_api/webhooks/registry.rb +++ b/lib/shopify_api/webhooks/registry.rb @@ -5,6 +5,11 @@ module ShopifyAPI module Webhooks class Registry @registry = T.let({}, T::Hash[String, Registration]) + MANDATORY_TOPICS = T.let([ + "shop/redact", + "customers/redact", + "customers/data_request", + ].freeze, T::Array[String]) class << self extend T::Sig @@ -17,6 +22,8 @@ class << self metafield_namespaces: T.nilable(T::Array[String])).void end def add_registration(topic:, delivery_method:, path:, handler: nil, fields: nil, metafield_namespaces: nil) + return if mandatory_webhook_topic?(topic) + @registry[topic] = case delivery_method when :pub_sub Registrations::PubSub.new(topic: topic, path: path, fields: fields, @@ -101,6 +108,8 @@ def register_all(session:) ).returns(T::Hash[String, T.untyped]) end def unregister(topic:, session:) + return { "response": nil } if mandatory_webhook_topic?(topic) + client = Clients::Graphql::Admin.new(session: session) webhook_id = get_webhook_id(topic: topic, client: client) @@ -213,6 +222,13 @@ def send_register_request(client, registration, webhook_id) def registration_sucessful?(body, mutation_name) !body.dig("data", mutation_name, "webhookSubscription").nil? end + + # Mandatory webhooks are subscribed to via the partner dashboard not the API + # https://shopify.dev/docs/apps/webhooks/configuration/mandatory-webhooks + sig { params(topic: String).returns(T::Boolean) } + def mandatory_webhook_topic?(topic) + MANDATORY_TOPICS.include?(topic) + end end end end diff --git a/test/webhooks/registry_test.rb b/test/webhooks/registry_test.rb index 2c966fc1b..1d0ab4783 100644 --- a/test/webhooks/registry_test.rb +++ b/test/webhooks/registry_test.rb @@ -206,6 +206,17 @@ def test_unregister_fail_with_user_errors assert_equal("Failed to delete webhook from Shopify: some error", exception.message) end + def test_unregister_to_mandatory_topics_are_skipped + ShopifyAPI::Clients::Graphql::Admin.expects(:new).never + + ShopifyAPI::Webhooks::Registry::MANDATORY_TOPICS.each do |topic| + ShopifyAPI::Webhooks::Registry.unregister( + topic: topic, + session: @session, + ) + end + end + def test_get_webhook_id_success stub_request(:post, @url) .with(body: JSON.dump({ query: queries[:fetch_id_query], variables: nil })) @@ -262,6 +273,24 @@ def test_get_webhook_id_with_graphql_errors assert_equal("Failed to fetch webhook from Shopify: some error", exception.message) end + def test_registrations_to_mandatory_topics_are_ignored + ShopifyAPI::Webhooks::Registry.clear + + ShopifyAPI::Webhooks::Registrations::Http.expects(:new).never + + ShopifyAPI::Webhooks::Registry::MANDATORY_TOPICS.each do |topic| + ShopifyAPI::Webhooks::Registry.add_registration( + topic: topic, + delivery_method: :http, + path: "some_path_under_the_rainbow", + handler: TestHelpers::FakeWebhookHandler.new( + lambda do |topic, shop, body| + end, + ), + ) + end + end + private def do_registration_test(delivery_method, path, fields: nil, metafield_namespaces: nil)