From 238179db5d58c8ccc15757a5590a68c8119c38ee Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Thu, 3 Aug 2023 17:36:31 +1000 Subject: [PATCH] add callback method in controller when auto include filter decides not to insert javascript --- README.md | 8 ++++++++ lib/intercom-rails/auto_include_filter.rb | 18 ++++++++++++++++-- lib/intercom-rails/config.rb | 1 + spec/auto_include_filter_spec.rb | 7 +++++++ spec/config_spec.rb | 5 +++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2e3d8a7..5508e4c 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,14 @@ By default Intercom will be automatically inserted in development and production config.enabled_environments = ["production"] ``` +### Controller callback + +When using automatic insertion of Intercom Javascript, you can have a callback method in your controller should the criteria to automatically insert javascript is unmet. The callback is `intercom_javascript_excluded` by default, but you can configure to a more appropriate name for all controllers in your application. + +```ruby + config.exclude_javascript_callback = :intercom_javascript_excluded +``` + ### Manually Inserting the Intercom Javascript Some situations may require manually inserting the Intercom script tag. If you simply wish to place the Intercom javascript in a different place within the page or, on a page without a closing `` tag: diff --git a/lib/intercom-rails/auto_include_filter.rb b/lib/intercom-rails/auto_include_filter.rb index fdb30ed..65a9060 100644 --- a/lib/intercom-rails/auto_include_filter.rb +++ b/lib/intercom-rails/auto_include_filter.rb @@ -15,10 +15,14 @@ class Filter def self.filter(controller) return if BLOCKED_CONTROLLER_NAMES.include?(controller.class.name) + auto_include_filter = new(controller) - return unless auto_include_filter.include_javascript? - auto_include_filter.include_javascript! + if auto_include_filter.include_javascript? + auto_include_filter.include_javascript! + else + auto_include_filter.exclude_javascript + end # User defined method to whitelist the script sha-256 when using CSP if defined?(CoreExtensions::IntercomRails::AutoInclude.csp_sha256_hook) == 'method' @@ -44,6 +48,11 @@ def include_javascript? intercom_script_tag.valid? end + def exclude_javascript + callback = exclude_javascript_callback + controller.send(callback) if controller.respond_to?(callback) + end + def csp_sha256 intercom_script_tag.csp_sha256 end @@ -89,6 +98,11 @@ def show_everywhere? IntercomRails.config.include_for_logged_out_users end + def exclude_javascript_callback + IntercomRails.config.exclude_javascript_callback || + :intercom_javascript_excluded + end + def enabled_for_environment? enabled_environments = IntercomRails.config.enabled_environments return true if enabled_environments.nil? diff --git a/lib/intercom-rails/config.rb b/lib/intercom-rails/config.rb index 1093b2d..4340e82 100644 --- a/lib/intercom-rails/config.rb +++ b/lib/intercom-rails/config.rb @@ -110,6 +110,7 @@ def self.reset! config_accessor :hide_default_launcher config_accessor :api_base config_accessor :encrypted_mode + config_accessor :exclude_javascript_callback def self.api_key=(*) warn "Setting an Intercom API key is no longer supported; remove the `config.api_key = ...` line from config/initializers/intercom.rb" diff --git a/spec/auto_include_filter_spec.rb b/spec/auto_include_filter_spec.rb index aec9a0e..c7b177a 100644 --- a/spec/auto_include_filter_spec.rb +++ b/spec/auto_include_filter_spec.rb @@ -255,4 +255,11 @@ def current_user expect(response.body).to include('nonce="aaaa"') end end + + context 'when intercom script is not injected' do + it 'invokes callback on controller' do + expect(controller).to receive(:intercom_javascript_excluded) + get :without_user + end + end end diff --git a/spec/config_spec.rb b/spec/config_spec.rb index c84fd26..d573088 100644 --- a/spec/config_spec.rb +++ b/spec/config_spec.rb @@ -66,6 +66,11 @@ expect(IntercomRails.config.encrypted_mode).to eq(true) end + it 'gets/sets controller callback' do + IntercomRails.config.exclude_javascript_callback = :callback + expect(IntercomRails.config.exclude_javascript_callback).to eq(:callback) + end + it 'raises error if current user not a proc' do expect { IntercomRails.config.user.current = 1 }.to raise_error(ArgumentError) end