Skip to content

Conversation

@mgryszko
Copy link
Contributor

@mgryszko mgryszko commented Nov 4, 2025

PR Description

TikTok Pageview events are missing event_id, which makes them harder to inspect and correlate to RudderStack page calls.

If the PR is approved, please update the documentation for TikTok Ads Device Mode Integration, Page section.

Linear task (optional)

Cross Browser Tests

Please confirm you have tested for the following browsers:

  • Chrome
  • Firefox
  • IE11

Sanity Suite

  • All sanity suite test cases pass locally

Security

  • The code changed/added as part of this pull request won't create any security issues with how the software is being used.

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced TikTok Ads integration with improved page event tracking, properly extracting event_id from multiple sources with priority handling and including partner information.
  • Tests

    • Added comprehensive test coverage for page event handling and event_id source prioritization to ensure reliable data mapping.

@mgryszko mgryszko requested a review from a team as a code owner November 4, 2025 14:38
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 4, 2025

📝 Walkthrough

Walkthrough

This pull request adds page-level event tracking to the TikTok Ads integration. A new pageMapping constant is introduced to configure event_id source resolution, a getPageResponse utility function prepares page event properties, and the page handler is updated to use this utility with partner name enrichment.

Changes

Cohort / File(s) Summary
Test Suite Updates
packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
Renamed test descriptions for consistency (tiktokads → TikTokAds); replaced single "send pageview" test with multiple tests validating event_id extraction from properties.eventId, properties.event_id, and messageId with priority ordering; extended assertions to verify window.ttq.page is called with event_id and partner_name.
Constants Definition
packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
Added new pageMapping constant mirroring trackMapping structure to map page-level event_id sources (properties.eventId, properties.event_id, messageId); updated exports to include pageMapping.
Utility Functions
packages/analytics-js-integrations/src/integrations/TiktokAds/util.js
Added getPageResponse(message) function to build page event properties using pageMapping and append partner_name; updated exports to include getPageResponse alongside getTrackResponse.
Browser Integration
packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
Updated page handler to import and use getPageResponse utility; changed from direct window.ttq.page() call to computing updatedProperties via getPageResponse(message) before passing to page method.

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant Browser as browser.js
    participant Util as util.js
    participant Constants as constants.js
    participant SDK as window.ttq

    App->>Browser: page(rudderElement)
    Browser->>Util: getPageResponse(message)
    Util->>Constants: pageMapping
    Constants-->>Util: pageMapping config
    Util->>Util: Extract event_id from<br/>properties.eventId,<br/>properties.event_id,<br/>or messageId
    Util->>Util: Add partner_name<br/>Remove undefined values
    Util-->>Browser: updatedProperties
    Browser->>SDK: window.ttq.page(updatedProperties)
    SDK-->>App: Event tracked
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

The changes follow consistent patterns established by existing track functionality, with pageMapping directly mirroring trackMapping and getPageResponse mirroring getTrackResponse. Test additions are homogeneous and repetitive. The integration in browser.js is straightforward method refactoring.

Pre-merge checks

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: sending Rudder event identifiers (eventId/event_id/messageId) as TikTok event_id, which is the primary objective of this PR.
Description check ✅ Passed The pull request description includes all required sections with proper completion: PR Description explaining the problem and solution, Cross Browser Tests confirmed for all three required browsers (Chrome, Firefox, IE11), Sanity Suite confirmed passed, and Security assessment completed.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js (1)

74-79: Consider extracting the common event_id mapping to reduce duplication.

The event_id mapping in pageMapping (lines 74-78) is identical to the first entry in trackMapping (lines 19-23). While the separation of page and track mappings is reasonable for clarity, you could extract the common event_id mapping entry to reduce duplication.

For example:

+const eventIdMapping = {
+  destKey: 'event_id',
+  sourceKeys: ['properties.eventId', 'properties.event_id', 'messageId'],
+};
+
 const trackMapping = [
-  {
-    destKey: 'event_id',
-    sourceKeys: ['properties.eventId', 'properties.event_id', 'messageId'],
-  },
+  eventIdMapping,
   {
     destKey: 'test_event_code',
     sourceKeys: 'testEventCode',
   },
   // ... rest of mappings
 ];

-const pageMapping = [
-  {
-    destKey: 'event_id',
-    sourceKeys: ['properties.eventId', 'properties.event_id', 'messageId'],
-  },
-];
+const pageMapping = [eventIdMapping];
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e143bf6 and 62adf95.

📒 Files selected for processing (4)
  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js (4 hunks)
  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js (2 hunks)
  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js (2 hunks)
  • packages/analytics-js-integrations/src/integrations/TiktokAds/util.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/002-javascript-typescript.mdc)

Code must work in browsers AND service workers (no Node.js APIs)

Files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/util.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
packages/*/src/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place all package source code under packages/[package-name]/src/

Files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/util.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Adhere to the repository’s ESLint configuration for JavaScript/TypeScript code

Files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/util.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
packages/analytics-js-integrations/src/integrations/*/browser.js

📄 CodeRabbit inference engine (CLAUDE.md)

packages/analytics-js-integrations/src/integrations/*/browser.js: Device mode integrations must be implemented at packages/analytics-js-integrations/src/integrations/[name]/browser.js
Each integration implementation must provide init(), isLoaded(), isReady(), and event handler methods

Files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
packages/*/__tests__/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place unit tests under packages/[package-name]/tests/

Files:

  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
packages/*/__tests__/**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Jest for tests and MSW for HTTP mocking

Files:

  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
🧠 Learnings (17)
📚 Learning: 2024-10-08T15:52:59.819Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1754
File: packages/analytics-js-common/src/utilities/page.ts:1-34
Timestamp: 2024-10-08T15:52:59.819Z
Learning: The compatibility issue with `globalThis` in `packages/analytics-js-common/src/utilities/page.ts` is handled elsewhere in the codebase as per user `saikumarrs`.

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/util.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
📚 Learning: 2024-10-09T06:41:05.073Z
Learnt from: MoumitaM
Repo: rudderlabs/rudder-sdk-js PR: 1876
File: packages/analytics-js/src/app/RudderAnalytics.ts:0-0
Timestamp: 2024-10-09T06:41:05.073Z
Learning: The `trackPageLifecycleEvents` method in `packages/analytics-js/src/app/RudderAnalytics.ts` does not require refactoring as the current implementation is preferred.

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/util.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
📚 Learning: 2025-08-27T06:40:15.058Z
Learnt from: CR
Repo: rudderlabs/rudder-sdk-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-27T06:40:15.058Z
Learning: Applies to packages/analytics-js-integrations/src/integrations/*/browser.js : Each integration implementation must provide init(), isLoaded(), isReady(), and event handler methods

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2025-08-27T06:40:15.058Z
Learnt from: CR
Repo: rudderlabs/rudder-sdk-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-27T06:40:15.058Z
Learning: Applies to packages/analytics-js-integrations/src/integrations/*/browser.js : Device mode integrations must be implemented at packages/analytics-js-integrations/src/integrations/[name]/browser.js

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2024-11-09T06:40:30.520Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1823
File: packages/analytics-js-common/src/types/LoadOptions.ts:0-0
Timestamp: 2024-11-09T06:40:30.520Z
Learning: In the `packages/analytics-js-common/src/types/LoadOptions.ts` file, the `dataplanes` property within the `SourceConfigResponse` type has been removed as it is no longer necessary.

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
📚 Learning: 2024-10-28T08:03:12.163Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1902
File: packages/analytics-js-plugins/src/utilities/eventsDelivery.ts:0-0
Timestamp: 2024-10-28T08:03:12.163Z
Learning: In `packages/analytics-js-plugins/src/utilities/eventsDelivery.ts`, the issue regarding inconsistent error handling approaches in `getDMTDeliveryPayload` is no longer valid.

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
📚 Learning: 2025-08-27T06:40:15.058Z
Learnt from: CR
Repo: rudderlabs/rudder-sdk-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-27T06:40:15.058Z
Learning: Applies to packages/analytics-js/src/**/*.{js,ts,tsx} : Use preact/signals-core for reactive state in the core SDK (analytics-js)

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
📚 Learning: 2024-08-26T09:34:28.341Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1823
File: examples/integrations/Ninetailed/sample-apps/app-using-v1.1-cdn/src/App.js:18-18
Timestamp: 2024-08-26T09:34:28.341Z
Learning: When reviewing the `examples/integrations/Ninetailed/sample-apps/app-using-v1.1-cdn/src/App.js` file, ignore the assignment pattern `let e = (window.rudderanalytics = window.rudderanalytics || []);` as it is a standard snippet.

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
📚 Learning: 2024-07-27T07:02:57.329Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1708
File: packages/analytics-js/__tests__/nativeSdkLoader.js:31-33
Timestamp: 2024-07-27T07:02:57.329Z
Learning: The loading snippet in `packages/analytics-js/__tests__/nativeSdkLoader.js` is a standard part of the SDK, and no changes are desired on it.

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js
  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2024-11-08T06:57:00.859Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1907
File: CODEOWNERS:3-12
Timestamp: 2024-11-08T06:57:00.859Z
Learning: The paths `/packages/analytics-js-integrations/scripts/`, `/packages/analytics-js-common/src/types/Integration.ts`, `/packages/analytics-v1.1/src/utils/IntegrationsData.js`, `/packages/sanity-suite/public/v1.1/integrations/`, and `/packages/sanity-suite/public/v3/integrations/` do not need ownership assignment changes in the `CODEOWNERS` file.

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
📚 Learning: 2025-08-27T06:40:15.058Z
Learnt from: CR
Repo: rudderlabs/rudder-sdk-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-27T06:40:15.058Z
Learning: Applies to packages/!(analytics-js-common)/**/src/**/*.{ts,tsx} : Prefer shared TypeScript types from analytics-js-common across packages

Applied to files:

  • packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js
  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2024-11-08T12:31:40.009Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1823
File: packages/analytics-js-integrations/src/integrations/Sprig/browser.js:10-22
Timestamp: 2024-11-08T12:31:40.009Z
Learning: Tests for the constructor in `packages/analytics-js-integrations/src/integrations/Sprig/browser.js` are not required.

Applied to files:

  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2024-10-08T15:52:59.819Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1708
File: packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts:10-11
Timestamp: 2024-10-08T15:52:59.819Z
Learning: The misuse of `IHttpClient` in type assertions within the file `packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts` has been corrected by the user.

Applied to files:

  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2024-11-08T13:17:51.356Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1823
File: packages/analytics-js-common/src/utilities/retryQueue/utilities.ts:0-0
Timestamp: 2024-11-08T13:17:51.356Z
Learning: The issue regarding missing test coverage for the `findOtherQueues` function in `packages/analytics-js-common/src/utilities/retryQueue/utilities.ts` is no longer applicable.

Applied to files:

  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2024-11-08T12:33:43.273Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1823
File: packages/analytics-js-integrations/src/integrations/Sprig/browser.js:36-38
Timestamp: 2024-11-08T12:33:43.273Z
Learning: Tests for the `isReady` function in `packages/analytics-js-integrations/src/integrations/Sprig/browser.js` are not required.

Applied to files:

  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2024-10-07T05:43:26.038Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1823
File: packages/analytics-js-integrations/__tests__/integrations/Amplitude/browser.test.js:193-194
Timestamp: 2024-10-07T05:43:26.038Z
Learning: In the Amplitude integration tests (`browser.test.js`), the tests no longer rely on `appVersion`, so including `appVersion` in the mocked navigator object is unnecessary.

Applied to files:

  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
📚 Learning: 2024-10-08T06:50:02.860Z
Learnt from: saikumarrs
Repo: rudderlabs/rudder-sdk-js PR: 1823
File: packages/analytics-js/__tests__/components/utilities/consent.test.ts:1-1
Timestamp: 2024-10-08T06:50:02.860Z
Learning: In `packages/analytics-js/__tests__/components/utilities/consent.test.ts`, the relative import path `../../../src/state` correctly refers to the `index.ts` file in the `/state` directory.

Applied to files:

  • packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js
🧬 Code graph analysis (2)
packages/analytics-js-integrations/src/integrations/TiktokAds/util.js (2)
packages/analytics-js-integrations/src/utils/utils.js (1)
  • constructPayload (563-577)
packages/analytics-js-integrations/src/integrations/TiktokAds/constants.js (2)
  • pageMapping (74-79)
  • PARTNER_NAME (17-17)
packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js (1)
packages/analytics-js-integrations/src/integrations/TiktokAds/util.js (2)
  • getPageResponse (68-74)
  • message (7-7)
🔇 Additional comments (5)
packages/analytics-js-integrations/src/integrations/TiktokAds/util.js (2)

1-1: LGTM!

The import of pageMapping is correct and necessary for the new getPageResponse function.


68-76: LGTM!

The getPageResponse function follows the same pattern as getTrackResponse, ensuring consistency across the codebase. The implementation correctly constructs page properties using pageMapping, adds the partner name, and filters out undefined/null values.

packages/analytics-js-integrations/src/integrations/TiktokAds/browser.js (2)

11-11: LGTM!

The import of getPageResponse is correct and necessary for the updated page method.


102-106: LGTM!

The page method now correctly constructs properties using getPageResponse and passes them to window.ttq.page, enabling TikTok event_id on Pageview events. This addresses the PR objective of enabling inspection and correlation with RudderStack page calls.

packages/analytics-js-integrations/__tests__/integrations/TikTokAds/browser.test.js (1)

32-96: LGTM! Excellent test coverage.

The new page tests comprehensively verify event_id extraction from all three sources (properties.event_id, properties.eventId, and messageId) with correct precedence rules. Each test confirms that partner_name is included and that window.ttq.page is called with the properly constructed payload.

@mgryszko
Copy link
Contributor Author

mgryszko commented Nov 5, 2025

@maheshkutty @chandumlg SonarQube step failed due to

ERROR Failed to query JRE metadata: GET https://api.sonarcloud.io/analysis/jres?os=linux&arch=x86_64 failed with HTTP 401. Please check the property sonar.token or the environment variable SONAR_TOKEN.

As this is something I cannot fix, can you please have a look at the GitHub workflow?

@chandumlg chandumlg requested review from saikumarrs and removed request for chandumlg November 11, 2025 18:52
@saikumarrs
Copy link
Member

@maheshkutty @chandumlg SonarQube step failed due to

ERROR Failed to query JRE metadata: GET https://api.sonarcloud.io/analysis/jres?os=linux&arch=x86_64 failed with HTTP 401. Please check the property sonar.token or the environment variable SONAR_TOKEN.

As this is something I cannot fix, can you please have a look at the GitHub workflow?

Hello @mgryszko
Thanks for raising the PR.

As GitHub secrets are not accessible on forks, the workflow failure is expected. We can ignore the failures for now.

@mgryszko
Copy link
Contributor Author

@saikumarrs is there a chance to merge it and release it after your Black Friday code freeze (Dec 2nd)?

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.

2 participants