Skip to content

feat(topsort): support offsite click and impression tracking#3830

Open
barbmarcio wants to merge 3 commits into
segmentio:mainfrom
barbmarcio:topsort-offsite-click-tracking
Open

feat(topsort): support offsite click and impression tracking#3830
barbmarcio wants to merge 3 commits into
segmentio:mainfrom
barbmarcio:topsort-offsite-click-tracking

Conversation

@barbmarcio

Copy link
Copy Markdown

Summary

Offsite (and organic) click and impression events could not be sent to Topsort through the Segment integration. The destination's click and impression actions marked resolvedBidId as a required field, so Segment's payload validation rejected any event without one — returning 400: The root value is missing the required field 'resolvedBidId' — even though the Topsort /v2/events API itself accepts offsite events with no resolved bid (they're attributed via entity, externalCampaignId/externalVendorId and channel: "offsite").

On top of that, there was no mapping for dsp_metadata anywhere in the actions, so customers had no way to forward the DSP click identifiers (e.g. gclid for Google, or the Meta equivalent) that Topsort needs to send offsite conversions back to Google/Meta for optimization.

Changes

  • Made resolvedBidId optional (required: false) on the click and impression actions. Onsite sponsored events continue to send it exactly as before; offsite/organic events can now omit it.
  • Added a free-form dsp_metadata object field (mapped from $.properties.dsp_metadata) to the click and impression actions. It's free-form because the accepted keys vary per advertising platform.
  • Updated/added tests to cover offsite events (no resolvedBidId, with dsp_metadata) and regenerated types and snapshots.

This is a non-breaking change — it only loosens an existing constraint and adds a new optional field. No existing onsite mappings are affected.

Testing

  • yarn cloud jest --testPathPattern="topsort" — all 10 suites pass (32 tests).
  • Lint and typecheck pass for the changed files.

Make resolvedBidId optional and add a dsp_metadata field to the Topsort
click and impression actions so offsite (and organic) events can be sent
via Segment. Previously resolvedBidId was required by the destination's
payload validation, which rejected offsite events that legitimately have
no resolved bid, and there was no mapping for dsp_metadata at all.
@barbmarcio barbmarcio requested a review from a team as a code owner June 15, 2026 15:32
…trings

Address PR review: rename the dsp_metadata mapping field to dspMetadata
(camelCase, matching codebase convention) while still sending dsp_metadata
in the API payload. Add NormalizeDspMetadata to coerce non-string values to
strings, since the Report Events API expects a map of string to string and a
single non-string value would otherwise 422 the whole batch.
@joe-ayoub-segment joe-ayoub-segment requested a review from Copilot July 1, 2026 13:14
@joe-ayoub-segment

joe-ayoub-segment commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Hi @barbmarcio thanks for the PR.

Functionally it looks fine to me.
I'm not familiar with the Topsort API so need you to clarify: Should there be some sort of validation to ensure that at least one of resolvedBidId or dspMetadata are provided?

Can you add some proof of testing? you can run the local testing tool using this command:

./bin/run serve

You can then use the UI in the browser to send some test events. Or you can use postman.

One more thing - do you work for Topsort? Can you send me an email to jayoub@twilio.com please? I can't accept a PR from someone who is not from Topsort, or without having someone from Topsort approve the PR.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Enables Topsort click/impression actions to accept offsite/organic events by making resolvedBidId optional and adds forwarding of DSP click identifiers via dsp_metadata.

Changes:

  • Make resolvedBidId optional for click and impression actions to unblock offsite/organic events.
  • Add dspMetadata input field and transform it to dsp_metadata with string coercion before sending to Topsort.
  • Update tests and snapshots to cover offsite events and DSP metadata coercion.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/destination-actions/src/destinations/topsort/pageviews/tests/snapshots/snapshot.test.ts.snap Snapshot update to reflect dsp_metadata output shape.
packages/destination-actions/src/destinations/topsort/impression/index.ts Makes resolvedBidId optional; adds dspMetadata mapping and normalizes into dsp_metadata.
packages/destination-actions/src/destinations/topsort/impression/generated-types.ts Updates payload types for optional resolvedBidId and new dspMetadata.
packages/destination-actions/src/destinations/topsort/impression/tests/index.test.ts Adds test coverage for offsite impressions and dspMetadata coercion behavior.
packages/destination-actions/src/destinations/topsort/impression/tests/snapshots/snapshot.test.ts.snap Snapshot update to include dsp_metadata.
packages/destination-actions/src/destinations/topsort/functions.ts Adds NormalizeDspMetadata helper for string coercion.
packages/destination-actions/src/destinations/topsort/click/index.ts Makes resolvedBidId optional; adds dspMetadata mapping and normalizes into dsp_metadata.
packages/destination-actions/src/destinations/topsort/click/generated-types.ts Updates payload types for optional resolvedBidId and new dspMetadata.
packages/destination-actions/src/destinations/topsort/click/tests/index.test.ts Adds test coverage for offsite clicks and dspMetadata coercion behavior.
packages/destination-actions/src/destinations/topsort/click/tests/snapshots/snapshot.test.ts.snap Snapshot update to include dsp_metadata.

Comment thread packages/destination-actions/src/destinations/topsort/functions.ts
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