Skip to content

Conversation

solastley
Copy link
Contributor

This PR adds the track method to the Unify Intent Client which will leverage the new Track API to allow for the logging of custom events and properties for use within Unify.

See the updated README for an in-depth explanation of the new methods.

private _autoPage: boolean;
private _autoIdentify: boolean;
private _historyMonitored: boolean;
private _autoTrackOptions?: AutoTrackOptions;
Copy link

@aaug1-unify aaug1-unify Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private field isn't referenced in the code, not sure if that's intended

I think rn using this._intentContext.clientConfig.autoTrackOptions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh good catch that would actually cause a bug

return false;

return true;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a <fieldset disabled> that might be worth considering if we are excluding disabled things

Copy link
Member

@samwaterbury samwaterbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last thing: We are also changing the header we use to pass the write key to the API. Previously, this was done using a basic auth encoding where the username was the write key and the password was empty, i.e.:

Authorization: Basic {base64(writeKey + ':')}

But now it's just X-Write-Key:

X-Write-Key: {writeKey}

The reasoning is that:

  1. This mirrors our use of X-Api-Key in other public APIs and also makes the distinction a lot clearer
  2. It should be easier for people to construct the header manually when not using a client library

So I think we should change it in this update as well. Here's an example request for reference:

curl -i -X POST https://api.unifyintent.com/analytics/v1/track \
    -H "Content-Type: application/json" \
    -H "x-write-key: wk_abc_def123" \
    -H "Origin: https://unifygtm.com" \
    -d '{
        "type": "track",
        "visitorId": "2a51f825-598b-442a-9493-cafc6a194e92",
        "sessionId": "3d570f4a-48a5-4292-910f-7a53a2d0f081",
        "timestamp": "2025-09-22T17:55:00Z",
        "sentAt": "2025-09-22T17:55:00Z",
        "context": {
            "ip": "209.247.156.154"
        },
        "name": "Clicked a big red button",
        "properties": {
            "reason": "It was there"
        }
    }'

README.md Outdated

> [!NOTE]
> See [@unifygtm/intent-react](https://www.npmjs.com/package/@unifygtm/intent-react) if you are using React.
**NOTE:**: See [@unifygtm/intent-react](https://www.npmjs.com/package/@unifygtm/intent-react) if you are using React.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**NOTE:**: See [@unifygtm/intent-react](https://www.npmjs.com/package/@unifygtm/intent-react) if you are using React.
**NOTE:** See [@unifygtm/intent-react](https://www.npmjs.com/package/@unifygtm/intent-react) if you are using React.

README.md Outdated
Comment on lines 227 to 229
1. Custom HTML data attributes (see [here](#html-data-attributes))
2. Manually via the client `track` method (see [here](#manual-tracking))
3. Automatically with CSS selectors (see [here](#automatic-tracking))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if this is the right order of recommendation or whether it should be:

  1. The track method
  2. Automatically with CSS selectors
  3. HTML data attributes

The reason is that it seems like using the track method is the most intuitive (because of how closely it mirrors other tools that provide the same method) and can be done one-off or incrementally; CSS selectors seems like the next simplest and most scalable approach; and HTML data attributes seems like the most advanced and requires the most effort.

package.json Outdated
"build:browser:s3:staging": "pnpm build:browser && aws s3 cp ./dist/js/browser/index.min.js s3://unifygtm-public/tag/v1/script-staging.js",
"build:browser:s3:testing": "pnpm build:browser && aws s3 cp ./dist/js/browser/index.min.js s3://unifygtm-public/tag/v1/script-testing.js",
"generate": "pnpm openapi-typescript '../unify/api/tsp-output/@typespec/openapi3/openapi.UnifyAnalyticsApi.yaml' -o './src/spec.ts'",
"generate": "pnpm openapi-typescript '../unify/api/spec/tsp-output/@typespec/openapi3/openapi.UnifyAnalyticsApi.json' -o './src/spec.ts'",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you prefer, you can actually now also use the URL (finally got around to hosting it properly):

https://unifyintent.com/analytics/v1/openapi.json

import { getCurrentPageProperties } from '../utils/helpers';
import Activity from './activity';

export const UNIFY_INTENT_TRACK_URL = `${UNIFY_INTENT_V1_URL}/track`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important: can you change this constant:

export const UNIFY_INTENT_V1_URL = 'https://unifyintent.com/analytics/api/v1';

To the updated value:

export const UNIFY_INTENT_V1_URL = 'https://api.unifyintent.com/analytics/v1';

The old URL will continue to work but I want to start to migrate us over to this URL for consistency with our other new public APIs.

private getBaseActivityPayload = (): AnalyticsEventBase => ({
type: this.getActivityType(),
anonymousUserId: this._intentContext.identityManager.getOrCreateVisitorId(),
visitorId: this._intentContext.identityManager.getOrCreateVisitorId(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this be breaking at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MattHsiung the API already supports the new param and the old one is optional

Comment on lines 140 to 142
export function getDomainForEmail(email: string): string | null {
return email.split('@')[1];
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export function getDomainForEmail(email: string): string | null {
return email.split('@')[1];
}
export function getDomainForEmail(email: string) {
return email.split('@').at(1);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add ?? null if you needed it to return null specifically

@solastley solastley merged commit d057a01 into main Sep 26, 2025
@solastley solastley deleted the sa--track branch September 26, 2025 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants