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

Partial HTTP API for delegation #47

Open
martinthomson opened this issue Oct 10, 2024 · 1 comment
Open

Partial HTTP API for delegation #47

martinthomson opened this issue Oct 10, 2024 · 1 comment

Comments

@martinthomson
Copy link
Member

This is for #31 and #32/#38, in part. It's the option where the delegation occurs using JS, but the HTTP API is used for the delegated piece.

Top-level (or delegate) calls:

let handle = attribution.delegateConversion({
  epsilon: 1000,
  logic: "last-touch",
  intermediarySites: ["example.com", "bar.example"],
  maxValue: 100,
  filterData: 7,
});

The top-level site passes handle to other frames.

The intermediary site would call whatever API it prefers like fbq('track', handle).

let pixel = document.createElement('img');
pixel.style.display = "none";
pixel.src = `https://example.com/track?delegation=${handle.id}`;
// the src might include other information from the handle,
// which can reflect the attributes passed to the call above
document.body.appendChild(pixel);

The browser then loads the pixel.

GET /track?delegation=<delegation-ID>
Host: example.com

Note: The delegation ID should be hard to guess, so maybe 120 bits of entropy in a string (UUID is awful, but that’s a fine basis for this). That ID would only be valid for a short while, which could be slightly longer than the page lifetime to allow for conversions that are followed by navigation or windows being closed. That allows us to avoid permissions checks and whatnot: knowing the delegation ID is proof that you are authorized to generate a conversion report.

The origin of the site that receives the delegation would need to match one of the listed intermediary sites.

Option 1: Redirect-only

This option might be more natural to some, but it comes with drawbacks. It uses redirects and custom header fields to perform the attribution.

The response includes instructions from the server. This would apply to any response that it gets with these headers, but of course, the site won't know how to identify the delegation without being told the ID.

302 Whatever
Location: https://example.com/save-conversion
Some-Custom-Header: delegation=<delegation-ID>,\
   aggregator=agg.example,histogramSize=20

The browser then follows the redirect.

GET /save-conversion HTTP/9000
Host: example.com
Other-Custom-Header: :MASSIVEBINARYBLOB_USING_BASE_64:

The server then needs to produce an image response.

200 OK
Content-Type: image/gif

IMAGE DATA HERE DOESN'T MATTER BECAUSE IT ISN'T VISIBLE

Option 2: Use link relations:

This is a little more efficient. The response points to where conversion reports should be sent.

200 OK
Content-Type: image/gif
Link: <https://example.com/save-conversion>;rel=attribution; \
  delegation=<delegation-ID>;aggregator=agg.example;histogramSize=20

PIXEL DATA

The browser then loads that resource, posting the conversion report there according to its understanding of the link relation.

POST /save-conversion HTTP/9000
Host: example.com
Content-Type: application/conversion-report
Content-Length: ...

MASSIVEBINARYBLOB_DOES_NOT_NEED_TO_BE_BASE_64_ENCODED

The server response can be empty then.

200 OK
Content-Length: 0

This are essentially the same as the pure redirect, but it avoids the inefficiency of a base64 conversion for the report.

The one obvious drawback is that it doesn’t guarantee that when the browser says the image is loaded, the report has been submitted. That's something that we could integrate into the imaging loading algorithm if necessary.

@martinthomson
Copy link
Member Author

I meant to say...

This shape should work for the non-delegated version of the API.

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

No branches or pull requests

1 participant