API Call to Hubspot using Google Tag Manager Server Side Tagging

I’m trying to make API calls to Hubspot based activity on the website without compromising PII. Also hubspot doesn’t support CORS policy and won’t accept API calls client side.

So I’m trying to use a Server Side Google Tag Manager Container for this.

How it’s set up:

- a GA event is created on form submissions using normal client side GTM

- that event is sent to the server container and is parsed through the Universal Analytics client.

- there is an event called Submitted

- I have a GET (I also tried POST) to https://api.hubapi.com/v1/contact/utk/{{hubspot-user-token}}/profile?{{hubspotapikey}}

- {{hubspot-user-token}} is taken from the GA event and is a dynamic variable

- {{hubspotapikey}} is a constant variable

The tag fires, but I keep getting a 404 response.

I haven’t tried the new api, because there doesn’t seem to be a way to get the Contact Id from hubspot user token (if there is, let me know as well).

What is wrong with my API call? How would I make a hubspot API call from Google Tag Manager Server Side Container?

And more importantly, how could I read the response in Google Tag Manager Server Side?

GTM server tags have built in http response tags, but it may need a custom tag template using Node JS.

@miljkovicmisa , happen to see anything out of place here?

Hello @YizSeg , hi @dennisedson thanks for tagging, indeed I do see something out of place here, it is the endpoint, not sure if @YizSeg made a bad copy/paste but it is missing the first path of “contacts”.
The right API endpoint would be the following:

https://api.hubapi.com/contacts/v1/contact/utk/{HUBSPOTUTK}/profile
Here is the complete legacy documentation for the API link.
Apart from the above which should solve the 404 error, I’m concerned about the way the API call is made, it certainly should not be exposed client side (so we are definatelly talking about a middleman here to take care of the authentication).

The whole usecase of this call is very strange to me, why would you get into trouble to collect this data when it’s already collected by hubspot and gtag. If the scope is to do something more then I would go about it in two ways:
1. Create a custom google tag event and trigger it (I have done this with third party scripts that I needed to enable/disable based on the cookies selected in the hubspot cookie banner).
Here a link with details
or
2. Create a custom event from HubSpot and trigger it based on user action.
Here a link with more details

Again all of the above depend on what you would like to achieve which is not clear in your question.
Some more details about your usecase would help me give you the right direction.
If my answer was helpful please mark it as a solution.

g’day @miljkovicmisa , it was a bad copy and paste it actually looks more like

https://api.hubapi.com/contacts/v1/contact/utk/{{hubspotutk}}/profile?hapikey={{Hubspot API Key}}

Is the api key added through headers or a different way?

This actually isn’t exposed client side (especially since Hubspot doesn’t allow for CORS), this is part of Google Tag Manager’s server container, which is processed in a separate cloud server and is owned.

This is what I’m trying to achieve. I want to do 2 things:

(1) I want to send the persona of a contact to Google Analytics as a custom dimension when a form is submitted and as part of the pageview.

In order to do that, I need to get the utk, and retrieve the persona, and then send that as part of Google Analytics tag, all without exposing anything.

So I have page views and special events being implemented through the GTM server container where I can process the information and send it to Google Analytics properly.

(2) I also want to be able to send the hubspot Id and persona to Google Analytics when a contact becomes an SQL or Opportunity. I can do this via webhooks in workflows, however I need the google CID to be a property in the contact.

Instead of changing all the forms to include it, I need to take the user token to return the contact id, and then update the contact with the google cid.

Again, all of this can be done in the GTM server container which is operating within an owned cloud server, so it’s owned, so it exposes nothing.

Great @YizSeg , thanks for sharing your usecase, in that case you should be able to debug the hubspotutk and actually see what you’re getting by the time the call is done,it’s possible that your {{hubspot-user-token}} is an empty string or something else…this is probably why the api is returning 404, maybe you could share some pieces of your code so we can debug it?

it’s possible @miljkovicmisa

This the script that I’m using. It’s on Google Tag Manager Server Side Container.

// Enter your template code here.

const sendHttpGet = require(‘sendHttpGet’);

const setResponseStatus = require(‘setResponseStatus’);

const setResponseBody = require(‘setResponseBody’);

const getAllEventData = require(‘getAllEventData’);

const hostname = ‘api.hubapi.com’;

const path = ‘/contacts/v1/contact/utk/’;

const utk = data.userToken;

const url = [‘https://’,hostname,path,utk,‘/profile?hapikey=’,data.apiKey].join(‘’);

//send http request

sendHttpGet (url, (statusCode, headers, body) => {

if (statusCode >= 200 && statusCode <300) {

setResponseStatus(statusCode);

setResponseBody(body);

data.gtmOnSuccess();

} else {

setResponseStatus(statusCode);

setResponseBody(body);

data.gtmOnFailure();

}

});

This is the tag template file. data.userToken is set on the tag level, I have the apikey stored a constant variable and I just put it in there. It means that if I share the template, the apikey isn’t exposed.

The data.userToken is also an input field on the tag level. It’s sent through a google analytics call that adds the usertoken as a custom dimension, and I have the variable cd2 to capture that. This way the tag, when set, takes the apikey from the gtm variable and the usertoken automatically from the incoming server event data from google analytics.

I’ve tested this code, and I’m still not getting any response. I’m not even getting an indication on hubspot that an API call has been made.

Also given that I can add a input fields and how would I say for each property - key in data.setProperties, append to the url property=key1&property=key2?

You can also check the source of this HubSpot GTM Server Side tag GitHub - stape-io/hubspot-tag: HubSpot Tag for Google Tag Manager Server Side · GitHub

Maybe it will help you.

And a blog post about how to use it is here Hubspot Server-Side Tracking Connection Guide

In your tag you try to use get user data from hubspot check this off documentation Server-side tagging APIs  |  Google Tag Manager - Server-side  |  Google for Developers

sendHttpRequest('https://zzz.com/collect', (statusCodeZZZ, headersZZZ, bodyZZZ) => {
 let bodyZxZ = {};
 bodyZxZ.name = bodyZZZ.name;

 sendHttpRequest('https://xxxx.com/collect', (statusCodeXXX, headersXXX, bodyXXX) => {

 setResponseStatus(statusCodeXXX);
 setResponseBody(bodyXXX);
 setResponseHeader('cache-control', headers['cache-control']);
 }, {headers: {key: 'value'}, method: 'POST', timeout: 500}, bodyZxZ);
}, {headers: {key: 'value'}, method: 'POST', timeout: 500}, {});