Problem
I'm trying to send GA4 events from an application that only has voice UI - there is no html file - thus no where to inject the necessary scripts to install GA4, as per the Google install documentation. I have all of the events set up - however, I don't know how to get and pass in the Client ID per voice assistant device (Alexa) that we would need to successfully send the analytics events and params.
Attempt to fix
What I've attempted to do is use the jsdom npm package to set something up like this -
const dom = new JSDOM(`<!doctype html>
<head>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-xxxx"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){
dataLayer.push(arguments)
}
gtag('js', new Date());
gtag('config', 'G-XXXXXX');
gtag('get', 'G-XXXXXX', 'client_id', (clientID) => {
console.log(clientID)
globalThis.clientId = clientID
return clientID
});
</script>
</head>
</html>
`, { runScripts: "dangerously", resources: "usable" });
if (typeof dom.window !== 'undefined') {
console.log(dom.window.dataLayer);
}
When I log the results (i just run node my-file.ts to test this), we do have data in the dataLayer with the arguments passed into gtag() -
[
[Arguments] { '0': 'js', '1': 2024-01-24T16:46:22.068Z },
[Arguments] { '0': 'config', '1': 'G-XXXXXX' },
[Arguments] {
'0': 'get',
'1': 'G-XXXXXX',
'2': 'client_id',
'3': [Function (anonymous)]
}
]
[Function (anonymous)] is where I would expect the clientID to log, save to a global variable, and return.
So, what happens when we call the anonymous function, like so
console.log(dom.window.dataLayer[2][3]()); ?
This logs undefined.
The value of client_id is also undefined.
I understand that we're just passing in arguments to gtag() that don't really do anything.
So, how would I get the clientID and access to the gtag() function in a 'headless' environment? Is it even possible? Am I doing something incorrectly that doesn't first render the javascript from the googletagmanager.com/gtag url before we set up the other script?