Conversation
A consumer that hashes the personal data at capture time and sends later, e.g. through a queue, could neither queue the Event (User holds the raw PII until getPayload() runs) nor hand the finished payload back to the client, which only accepted an Event. Event::toPayload() now returns a Payload: the wire-ready form of the event (name, id, the normalized and hashed data, the pixels and the test event code), made of scalars, arrays and Pixel objects only so it serializes without any tricks. Client::sendPayload() sends it, and sendEvent() is a one-line delegation to it. sendPayload() lives on a new PayloadClientInterface that Client also implements, rather than on ClientInterface, so existing implementors of ClientInterface keep working and the backwards compatibility check stays green. Closes #15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #15.
A consumer that hashes the personal data at capture time and sends later (e.g. through a queue) could neither queue the
Event—Userholds the raw PII untilgetPayload()runs — nor hand a finished payload back to the client, which only accepted anEvent. The bundle works around that today with aPreparedEventsubclass that smuggles a payload through an object designed to produce one (MetaConversionsApiBundle#49).Event::toPayload(): Payload— the wire-ready form of the event:eventName,eventId, the normalized + hasheddata, thepixelsand thetestEventCode. Scalars, arrays andPixelobjects only, so it round-trips throughserialize()(tested) and the Symfony serializer without tricks.eventName/eventIdare duplicated fromdataon purpose so log sites don't narrowmixed.Client::sendPayload(Payload $payload)does the sending;sendEvent()is now a one-line delegation to it, so both paths produce byte-identical requests (tested).Pixel::$accessTokenis already nullable).Interface decision
sendPayload()lives on a newPayloadClientInterfacethatClientalso implements, rather than being added toClientInterface. The issue allows either; I went with the second interface because.github/workflows/backwards-compatibility-check.yamlruns Roave with no baseline on every PR, and adding a method toClientInterfacewould turn that job permanently red for this PR (and CLAUDE.md asks to avoid public BC breaks). Verified locally: Roave reports no BC breaks fromorigin/masterto this branch. If you'd rather take the documented break and keep a single interface, it's a three-line flip — say so.One behavioural nuance
sendEvent()on an event without pixels still logs the same error and sends nothing (the guard moved intosendPayload(), so the payload path behaves identically). The only difference: the payload is now built before the guard, so an event with an invalidaction_sourceand no pixels throws fromtoPayload()instead of being silently skipped — arguably the more correct outcome.Test plan
EventTest::it_converts_to_a_payload— hashed data, pixels, test event code;eventName/eventIdmatchdata; the raw email never appears in the serialized payloadClientTest::it_sends_payload— postsdataonce per pixel with the pixel's token andtest_event_codeClientTest::it_sends_the_same_request_for_an_event_and_its_payloadClientTest::it_does_not_send_payload_when_it_has_no_pixelsPayloadTest—serialize()/unserialize()round trip incl. a token-less pixelAfter this is released
The bundle deletes
PreparedEvent; itsSendEventmessage carries aPayloadbuilt with token-less pixels, and the handler resolves the tokens and callssendPayload()onPayloadClientInterface.