Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tagmanager datastore partial to determine connected GA4 entities #7989

Closed
7 tasks
nfmohit opened this issue Dec 15, 2023 · 11 comments
Closed
7 tasks

Add tagmanager datastore partial to determine connected GA4 entities #7989

nfmohit opened this issue Dec 15, 2023 · 11 comments
Labels
Module: Tag Manager Google Tag Manager module related issues P2 Low priority QA: Eng Requires specialized QA by an engineer Type: Enhancement Improvement of an existing feature

Comments

@nfmohit
Copy link
Collaborator

nfmohit commented Dec 15, 2023

Feature Description

The existing integration between GTM and GA modules in Site Kit only supports UA and since UA has been removed, this integration is no longer functional. As an effort to adapt this integration to work with GA4, a new partial should be introduced in the tagmanager datastore that contains GA4 versions of the tagmanager selectors that are relevant to this integration.

One important point to note is that while the legacy integration checks for the UA property ID as the in the GTM containers, in case of GA4, the container actually keeps track of the GA4 measurement ID as form of a googtag. Some of the selectors that should be copied and adapted from the existing integration:

  1. getAnalyticsPropertyIDs -> getAnalyticsMeasurementIDs
  2. getLiveContainerAnalyticsPropertyID -> getLiveContainerAnalyticsMeasurementID
  3. getLiveContainerAnalyticsTag -> renamed to whatever is appropriate according to the implementation.
  4. getSingleAnalyticsPropertyID -> getSingleAnalyticsMeasurementID
  5. hasAnyAnalyticsPropertyID -> hasAnyAnalyticsMeasurementID
  6. hasMultipleAnalyticsPropertyIDs -> hasMultipleAnalyticsMeasurementIDs

Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

  • As per the feature description above, the following new selectors should be created to determine connected GA4 entities instead of UA properties:
    1. getLiveContainerAnalyticsTag -> getLiveContainerAnalytics4Tag: Adapt this selector so that the tag with type googtag is returned (instead of returning ua or ua_amp tags).
    2. getLiveContainerAnalyticsPropertyID -> getLiveContainerAnalytics4MeasurementID: Adapt this selector so that the measurement ID is returned from the linked Google Tag (GA4 Tag). For UA, a propertyID (tracking ID) could be set as a gaSettings variable but it is no longer possible to set the measurementID via a "Google Tag: Configuration Settings" variable. However, we should still support setting the Google Tag ID via a "Constant" variable as per this comment.
    3. getAnalyticsPropertyIDs -> getAnalytics4MeasurementIDs: Adapt this selector to return an array of measurement IDs. However, since AMP is not supported yet, this selector will only ever return at most one measurement ID for the web container only. However, let us keep the logic to fetch the internalAMPContainerID and the corresponding measurement ID intact for future compatibility purposes as per this comment.
    4. getSingleAnalyticsPropertyID -> getSingleAnalytics4MeasurementID: Adapt this selector to return the sole measurement ID that getAnalytics4MeasurementIDs above will return.
    5. hasAnyAnalyticsPropertyID -> hasAnyAnalytics4MeasurementID: Adapt this selector to return if a container has a measurement ID.
    6. hasMultipleAnalyticsPropertyIDs -> hasMultipleAnalytics4MeasurementIDs: Adapt this selector to return if multiple measurement IDs are returned for a container. This would always be false (or undefined) since we will not be supporting AMP containers for now.

Implementation Brief

Within assets/js/modules/tagmanager/datastore/versions.js, create new selectors named as per the AC and implement them as follows:

  • 1. For getLiveContainerAnalytics4Tag: Similar to getLiveContainerAnalyticsTag, use the getLiveContainerVersion selector and check for the liveContainerVersion?.tag property. If it exists, return the tag with a type of googtag.
  • 2. For getLiveContainerAnalytics4MeasurementID:
    • Fetch the Google Tag ID: Similar to getLiveContainerAnalyticsPropertyID, check for the parameter property having a key of tagId within analyticsTag. If it does, this should be the Google tag ID. If this value is wrapped within {{ }} brackets, then find a variable (using getLiveContainerVariable()) within the container with this value as the name. Iff this variable is of type c (constant), then the value of the first parameter should be the Google tag ID. This comment shows the shape of the container data returned. Ignore logic that tried to find the property ID within a gaSettings variable.
    • Find the destination / GA4 property that the above Google Tag ID "points" to. THIS IS NOT POSSIBLE EASILY via any direct API. See comment below.
    • Validate any of the IDs found using isValidMeasurementID().
  • 3. For getAnalytics4MeasurementIDs: Similar to getAnalyticsPropertyIDs, keep all logic the same but use getLiveContainerAnalytics4MeasurementID instead of getLiveContainerAnalyticsPropertyID. The second part of this selector which checks for AMP container won't ever return a measurementID since there isn't a possibility to create a GA4 googtag for containers that have the amp context as yet. However, for future compatibility purposes, let us keep this logic intact as per this comment.
  • 4-6. For the remaining 3 selectors, follow the logic of the existing selectors but use the new getAnalytics4MeasurementIDs selector instead of getAnalyticsPropertyIDs.

Test Coverage

  • Add new tests for all the selectors created above to mirror the existing tests in versions.test.js.

QA Brief

Changelog entry

@jimmymadon
Copy link
Collaborator

@nfmohit @aaemnnosttv

  1. In our current implementation, we have to cater for multiple "property IDs" because we cater for for ua and ua_amp tag types based on the usage context of the containers (either web or amp) linked to an account. From what I can see, we cannot add GA4 tags to an AMP container within the TagManager Admin UI. So am I correct in assuming we won't be supporting AMP containers in our Tag Manager integration?
Screenshot 2024-01-02 at 12 30 59
  1. If yes, then we wouldn't need all the remaining selectors other than getLiveContainerAnalytics4Tag and getLiveContainerAnalyticsPropertyID. All the remaining selectors solely exist to cater for the potential of there being a UA and and an AMP tag. However, it is possible to attach multiple GA4 tags with different measurement IDs to a container. Should we cater for this and refactor the above selectors for this?

  2. Finally, I can see that the UI allows for two types of GA4 tags, one is standard Google Tag (googtag) and one is a GA4 Event tag (gaawe). Should we look for both of these types when finding linked measurement IDs?

Screenshot 2024-01-02 at 12 35 12

@aaemnnosttv
Copy link
Collaborator

  1. From what I can see, we cannot add GA4 tags to an AMP container within the TagManager Admin UI. So am I correct in assuming we won't be supporting AMP containers in our Tag Manager integration?

@jimmymadon I wasn't aware of this, but it's not entirely surprising since GA4 support for AMP was added sometime around June, right before the start of the UA sunset. I think we'll need to ask internally if support will not be coming for it, otherwise I think we should keep that part but we'd only check for the tag in web containers, does that make sense? Essentially trying to keep it the same as today.

However, it is possible to attach multiple GA4 tags with different measurement IDs to a container. Should we cater for this and refactor the above selectors for this?

I believe this was possible with UA as well but we only check for one, correct? This is similar to existing tags where we only "capture"/report about the first one we find. Having multiple GA tags in GTM should be an edge case and trying to account for it would likely be a large lift that probably isn't worth it.

3. I can see that the UI allows for two types of GA4 tags, one is standard Google Tag (googtag) and one is a GA4 Event tag (gaawe). Should we look for both of these types when finding linked measurement IDs?

We should only be concerned with the Google Tag. The event tag is for custom events that are set up, and managed in GTM.

@mxbclang mxbclang added the P1 Medium priority label Jan 3, 2024
@jimmymadon jimmymadon removed their assignment Jan 4, 2024
@techanvil techanvil self-assigned this Jan 4, 2024
@techanvil
Copy link
Collaborator

techanvil commented Jan 4, 2024

Hey @jimmymadon, the AC here LGTM. ✅

The IB also looks good; there's just one aspect that could use clarification. Considering getLiveContainerAnalytics4MeasurementID(), I can see a question arising at execution time as to whether we should provide support for using variables, as we currently do for UA. (Actually, on reflection this could just as well be an AC-level question, but we should figure it out one way or the other :)).

Providing full support for variable use would clearly be out of scope, but it might be worth adding support for constant variables which seem to be the most straightforward case.

Alternatively, we could defer variable support and explore it more fully in a separate issue. Either way, it would be useful to make it clear what approach to take in the IB. What do you think?

Additionally, a minor point - there are a couple of typos in the IB with getLiveContainerAnalyticsMeasurementID and getAnalyticsMeasurementIDs both missing the 4 after Analytics.

@techanvil techanvil assigned jimmymadon and unassigned techanvil Jan 4, 2024
@mxbclang mxbclang added the Next Up Issues to prioritize for definition label Jan 5, 2024
@jimmymadon
Copy link
Collaborator

jimmymadon commented Jan 6, 2024

@techanvil My apologies - I had just assumed that fetching the propertyID via variables was legacy behaviour. On doing some more research, I can now confirm that it is not possible to set a GA4 measurement ID as part of a gaSettings variable anywhere in the GTM UI.
Screenshot 2024-01-06 at 20 05 27

We can set Google Tag configuration settings but these do not allow to set a measurementID parameter anywhere.
Screenshot 2024-01-06 at 20 07 30

So should we drop support for variables all together? (UPDATE: I have updated the AC and IB to reflect this decision for now.)

@jimmymadon jimmymadon assigned techanvil and unassigned jimmymadon Jan 6, 2024
@techanvil
Copy link
Collaborator

Hey @jimmymadon, while we can't use gaSettings, and Google Tag configuration settings doesn't look applicable, we can still use variables to specify the measurement ID. The simple example I noted is the Constant variable type - I've given this a test in the wild and it does work.

image

So, I was thinking we might want to provide support for constant variables and then review other potential cases later... Or, as mentioned simply defer the whole topic. But considering we do currently provide support for variables, it does feel like it would be nice to retain some support in the initial migration.

@techanvil techanvil assigned jimmymadon and unassigned techanvil Jan 8, 2024
@jimmymadon
Copy link
Collaborator

@techanvil I did try this out too but was just wondering how we would "support" this. There is no indication that the constant variable above would be a measurement ID (even if we can make out from the format of the string). I don't think we can simply assume that this string, even if it is a measurement ID, is one that needs to be tracked within this GTM container. I don't think that using variables to store the measurement ID is prescribed anywhere by GTM and is good practise (we have a Google Tag for this precise reason). The reason we already have variable support is purely because the "Google Analytics Settings" variable would always have a property ID set and we would be certain about its existence there. So IMO, dropping variable support here fully is potentially the right way to proceed unless we want to capture any other data from variables in the future.

@jimmymadon jimmymadon assigned techanvil and unassigned jimmymadon Jan 8, 2024
@techanvil
Copy link
Collaborator

techanvil commented Jan 8, 2024

Thanks @jimmymadon. I do think that it would be straightforward to support in the simple case where the variable reference is specified as the tagId value, which is easy to setup via the UI.

image

image

I don't think there's necessarily a question of good practice here, the user-defined variables are there to support specific user requirements - I think using a variable to share a measurement ID across multiple tags would be a pretty legitimate use case, as, for example both Google Tag and GA4 Event tags have a measurement ID field.

However, I do take your point that there can be more complex uses e.g. multiple variables, or the variable itself can point to other variables. Given it's a bit of an arbitrary isolated case to support, let's go ahead and drop the variable support for now, we can take a more comprehensive look for a future iteration.

It is, though, not correct to say that it's no longer possible to set the measurement ID via a variable - as mentioned I tested out setting it via a constant and it worked fine, correctly tracking events, so please can you tweak the AC accordingly? I'll send it back to AC for the purpose but the IB looks good to go.

@techanvil techanvil assigned jimmymadon and unassigned techanvil Jan 8, 2024
@jimmymadon jimmymadon assigned techanvil and unassigned jimmymadon Jan 9, 2024
@techanvil
Copy link
Collaborator

Thanks for the update @jimmymadon!

As discussed on Slack we've gone ahead with adding support for variables of type constant.

AC ✅
IB ✅

@techanvil techanvil assigned techanvil and unassigned techanvil Jan 9, 2024
@techanvil
Copy link
Collaborator

techanvil commented Jan 11, 2024

Hi @jimmymadon, apologies but while reviewing #7990 I had the realisation that we haven't quite got the IB right for the implementation of getLiveContainerAnalytics4MeasurementID().

Where I've steered us slightly wrong is talking about the tagId as though it's always a measurement ID. It's actually a Google tag ID - which might happen to be a measurement ID for the automatically created tags, but there's no guarantee of that being the case.

Here's an updated set of screenshots to illustrate this:

image

image

image

So, the implication here is that we actually need to do an additional container lookup in order to determine the measurement ID from the Google tag ID. We probably want to determine the measurement ID from the container using similar logic to that used in GoogleTagIDMismatchNotification, but should presumably fall back to the first valid measurement ID if none of them exist in the available Analytics accounts.

Note that I've screenshotted the using-a-variable scenario, but even without a variable we'd still need to do a container lookup.

Please can you update the IB accordingly, and drop me a line if you want to discuss this further?

@techanvil techanvil assigned jimmymadon and unassigned techanvil Jan 11, 2024
@mxbclang mxbclang added P2 Low priority and removed P1 Medium priority labels Jan 12, 2024
@ivonac4 ivonac4 added the QA: Eng Requires specialized QA by an engineer label Jan 16, 2024
@mxbclang mxbclang added Next Up Issues to prioritize for definition and removed Next Up Issues to prioritize for definition labels Jan 19, 2024
@mxbclang
Copy link

@jimmymadon This is going to be scheduled for Sprint 120 – can you please prioritize making these IB updates? Thanks!

@jimmymadon
Copy link
Collaborator

jimmymadon commented Jan 29, 2024

As summarised in Slack Thread 1 and Slack Thread 2, it is not possible to have an exact 1:1 mapping between selectors mentioned in the AC of this issue.

The selectors being adapted here were originally planned to be used in #7990 which attempted to adapt the following two UA-GTM integration screens that were shown to the user when setting up Google Tag Manager:

  1. When GA is not connected, but the selected Tag Manager container had a tag that was a valid UA trackingId (UA Property ID):
    Screenshot 2024-01-06 at 20 59 03

    This was achieved using the getLiveContainerAnalyticsPropertyID selector which fetched the Property ID from the selected GTM container's live version:

    if ( analyticsTag?.parameter ) {
    // Check if property ID is provided directly on the tag first.
    let propertyID = analyticsTag.parameter.find(
    ( { key } ) => key === 'trackingId'
    )?.value;

    As the IB of this issue mentions, we can fetch the googtag from the current GTM Container. To determine if and which GA4 "destinations" (i.e. web data streams) this Google Tag is pointing to, we need the tag's own unique accountId and containerId which gets created when the Google Tag is created. Then we could use getGoogleTagContainerDestinations(accountId, containerId) which uses the container-destinations endpoint to fetch the destinations. However, the accountId and containerId we get when we do the getLiveContainerVersion query returns the GTM accountId and containerId which isn't the tag's unique IDs that we are looking for. So there is no direct API support for us to fetch a Google Tag's information.

    Result of `getLiveContainerVersion`

    We could potentially loop through all of the current user's accounts and containers and list all possible destinations, and check if any of those destinations is connected to the Google Tag that is found above. This would be very inefficient and unnecessary for the purpose here which is to inform the user that their currently selected GTM config contains a GA4 property.

    So we have decided to modify the AC of Adapt GTM integration with GA to support GA4 #7990 such that, if we find a Google Tag in the current GTM container, we can simply validate it to check if the format matches a valid Google Tag. If it does, we can tell the user that their configuration contains a Google Tag which could be connected to a GA4 property - so they should consider "Connecting Analytics". We will not check if the Google Tag points to an actual GA4 web data stream until perhaps direct API support is available to find these details from a Google Tag ID.

  2. When GA is already connected, and the selected Tag Manager container had a tag that was a valid UA trackingId which matched the existing propertyId saved in Analytics settings:
    Screenshot 2024-01-06 at 20 58 18

    In this case, the user was informed that only the GTM snippet would be inserted and the Analytics snippet would not be inserted. This was to prevent duplicate events from firing. However, GA4 prevents duplicate events from firing regardless of another snippet with the same config being inserted. Also, inserting the GA4 snippet is coupled with inserting code that enables the tracking of custom dimensions introduced with the News Key Metrics feature. This means it is essential that this snippet is inserted until we manage to decouple these two behaviours.

    Thus it makes no sense to inform users about this scenario anymore. Even if the GA4 config overlaps with a tag from their GTM container, both snippets can be introduced to their site safely without any adverse effects. So in issue Adapt GTM integration with GA to support GA4 #7990, we will no longer require this screen to be displayed. In fact, we will remove functionality which prevented the duplicate snippets being inserted in issue Prevent analytics-4 from outputting tags when GTM takes over #7991.

So in summary:

@jimmymadon jimmymadon closed this as not planned Won't fix, can't repro, duplicate, stale Jan 29, 2024
@ivonac4 ivonac4 removed the Next Up Issues to prioritize for definition label Jan 30, 2024
@mxbclang mxbclang changed the title [GTM + GA4] Add tagmanager datastore partial to determine connected GA4 entities Add tagmanager datastore partial to determine connected GA4 entities Feb 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Module: Tag Manager Google Tag Manager module related issues P2 Low priority QA: Eng Requires specialized QA by an engineer Type: Enhancement Improvement of an existing feature
Projects
None yet
Development

No branches or pull requests

6 participants