APIs & Integrations

lsmith77
Contributor

How to integrate a self-developed cookie consent banner with Hubspot tracking code?

On https://diversifier.witty.works we have a simple consent banner that we custom developed. If the user gives their consent we use Google Tag Manager to dynamically load Google Analytics etc.

 

Now we want to integrate the Hubspot tracking code, mainly to track form submissions but also do possibly track other aspects.

 

Note we have configured Hubspot according to EU GDPR laws, ie. opt-in.

 

However looking over the API I only see a way to opt-out but not to opt-in:

https://developers.hubspot.com/docs/api/events/cookie-banner

0 Upvotes
6 Replies 6
mthomas65
Member

How to integrate a self-developed cookie consent banner with Hubspot tracking code?

I think there may be a way to integrate Cookiebot with Hubspot. Check out this link for more information.

0 Upvotes
piersg
Key Advisor

How to integrate a self-developed cookie consent banner with Hubspot tracking code?

I believe it's possible to integrate Cookiebot with Hubspot: link

0 Upvotes
lsmith77
Contributor

How to integrate a self-developed cookie consent banner with Hubspot tracking code?

Yeah we are using this integration for www.witty.works .. diversifier.witty.works is a legacy website and I am just trying to find the cheapest (both in USD and time) path to integrate hubspot replacing mailchimp

0 Upvotes
lsmith77
Contributor

How to integrate a self-developed cookie consent banner with Hubspot tracking code?

Thank you. This would mean we need to customize the cookie banner setup for diversifier.witty.works (since we have a cookiebot based setup for www.witty.works), so that we can have a different configuration there. This could then indeed work but it is incredibly hacky, quite dissapointing that Hubspot doesn't support this use case but once again thank you for outlining how it can at least be done!

0 Upvotes
piersg
Key Advisor

How to integrate a self-developed cookie consent banner with Hubspot tracking code?

Hi @lsmith77 (thanks @dennisedson).

 

The way I managed this was by customising the Hubspot cookie banner like this:

piersg_1-1641833645562.png

 

And creating a custom global module that looks like this:

piersg_0-1641833508258.png

 

And wrote some JS to simultaneously set local session storage and push to GTM dataLayer to set users' cookie preferences. To set the users Hubspot preferences I basically fake a click of accept or decline.

 

// set session storage cookie function (e.g. for cookie consent) 
var consentArr = ['consent_functionality', 'consent_analytics', 'consent_advertising'];
var cookieToggles = document.getElementsByClassName('cookie-toggle');
function setLocalCookie(name, value) {
  localStorage.setItem(name, value);
  dataLayer.push({
    event: name+'_event',
    [`${name}`]: value,
  });
}
// mutation observer to detect when HS cookie banner is added to the DOM, then add event listeners when it is
const observer = new MutationObserver(mutations => {
  mutations.forEach(({ addedNodes }) => {
    addedNodes.forEach(node => {
      // For each added node
      if(node.nodeType === 1 && node.tagName === 'DIV' && node.classList.contains('hs-cookie-notification-position-bottom')) {
        document.getElementById('hs-eu-confirmation-button').onclick = function(e) {
          // if click is a real click: when the user clicks on a button the event has a real screenX and screenY based on the button position but when you 'click' the button via code the event's position is 0
          if(e.screenX && e.screenX != 0 && e.screenY && e.screenY != 0){
            for (i = 0; i < consentArr.length; i++) {
              setLocalCookie(consentArr[i], true);
            }
            for (i = 0; i < cookieToggles.length; i++) {
              cookieToggles[i].checked = true;
            }
            observer.disconnect();
          }
        }
        document.getElementById('hs-eu-decline-button').addEventListener('click', function(e) {
          for (i = 0; i < consentArr.length; i++) {
            setLocalCookie(consentArr[i], false);
          }
        });
        var cookieLink = document.querySelector('#hs-eu-policy-wording a[href="http://www.mews.com/#cookieCentre"]');
        if (cookieLink != null) {
          cookieLink.addEventListener('click', function(e) {
            e.preventDefault();
            document.getElementById('preferences-modal').classList.remove('hide');
            observer.disconnect();
          });
        }
        // if website is in iframe decline cookies
        if (inIframe() === true) {
          document.getElementById('hs-eu-decline-button').click();
        } 
      }
    })
  })
})
  
window.addEventListener('load', (event) => {
  
  // Starts the monitoring
  observer.observe(document.documentElement, {
    childList: true,
    subtree: true
  })

  // open modal from privacy settings link in footer
  var footerCookie = document.getElementById('footer-cookie');
  if (footerCookie != null) {
    footerCookie.addEventListener('click', function() {
      document.getElementById('preferences-modal').classList.remove('hide');
    });
  }
  // cookie preferences centre scripts
  var acceptAll = document.getElementById('accept_all');
  var acceptSelect = document.getElementById('accept_select');

  // on page load change toggles to 'checked'/on if the cookie consent item exists and is true in session storage
  for (i = 0; i < consentArr.length; i++) {
    let cookieBool = localStorage.getItem(consentArr[i]);
    if (cookieBool === 'true') {
      var type = consentArr[i].replace('consent_','');
      document.querySelector('.cookie-toggle[data-id='+type+']').checked = true;
    }
  }

  // when accept all button is clicked in preferences modal, set all consent items in session storage to true and toggle toggles to true
  acceptAll.addEventListener('click', function() {
    for (i = 0; i < consentArr.length; i++) {
      setLocalCookie(consentArr[i], true);
    }
    for (i = 0; i < cookieToggles.length; i++) {
      cookieToggles[i].checked = true;
    }
    document.getElementById('preferences-modal').classList.add('hide');
          
    // fake 'click' the HS cookie banner accept button
    if (document.getElementById("hs-eu-confirmation-button") != null) {
      document.getElementById('hs-eu-confirmation-button').click();
    }
  });

  // when accept select button is clicked in preferences modal, set only the chosen consent items in session storage to true and toggle those toggles to true
  acceptSelect.addEventListener('click', function() {
    for (i = 0; i < cookieToggles.length; i++) {
      var cookieToggle = cookieToggles[i];
      var id = cookieToggle.dataset.id;
      if (cookieToggle.checked) {
        setLocalCookie('consent_'+id, true);
        // if analytics is a selected option, 'click' the HS cookie banner accept button
        if (id === 'analytics' && document.getElementById('hs-eu-confirmation-button') != null) {
          document.getElementById('hs-eu-confirmation-button').click();
        }
      } else {
        setLocalCookie('consent_'+id, false);
        // if analytics is NOT a selected option, 'click' the HS cookie banner decline button
        if (document.getElementById('hs-eu-decline-button') != null) {
          document.getElementById('hs-eu-decline-button').click();
        }
      }
    }
    document.getElementById('preferences-modal').classList.add('hide');
  });

  var close = document.querySelectorAll('.close-modal, .overlay');
  close.forEach(el => el.addEventListener('click', function(e){
    e.preventDefault();
    document.getElementById('preferences-modal').classList.add('hide');
    document.body.style.overflow = 'auto';
  }));
});

 

 

 

In GTM I set up custom JS variables to read local storage e.g.

function() {
  var consent_advertising = localStorage.getItem('consent_advertising');
  return consent_advertising;
}

and triggers based on those variables (for persisting choices in a session), and triggers based on the dataLayer events (to change permissions based on choices the instant preferences are selected, i.e. before session storage is useful).

dennisedson
HubSpot Product Team
HubSpot Product Team

How to integrate a self-developed cookie consent banner with Hubspot tracking code?

@piersg , how would you tackle this?

0 Upvotes