From b1584fc1dc531b312dc6020fadc1c14bd153a557 Mon Sep 17 00:00:00 2001 From: Oscar Bazaldua <511911+oscb@users.noreply.github.com> Date: Fri, 18 Aug 2023 09:14:55 -0700 Subject: [PATCH] fix: sentAt set at batch upload time (#932) `sentAt` is not set at batch upload time once per the whole batch. Individual event `sentAt` property is stripped when doing batch uploading. --- .changeset/odd-nails-collect.md | 5 +++ .../__tests__/batched-dispatcher.test.ts | 43 ++++++++++++++++--- .../plugins/segmentio/batched-dispatcher.ts | 12 +++++- 3 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 .changeset/odd-nails-collect.md diff --git a/.changeset/odd-nails-collect.md b/.changeset/odd-nails-collect.md new file mode 100644 index 000000000..583621d79 --- /dev/null +++ b/.changeset/odd-nails-collect.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-next': patch +--- + +`sentAt` is not set at batch upload time once per the whole batch. Individual event `sentAt` property is stripped when doing batch uploading. diff --git a/packages/browser/src/plugins/segmentio/__tests__/batched-dispatcher.test.ts b/packages/browser/src/plugins/segmentio/__tests__/batched-dispatcher.test.ts index 11bc67e9b..56e2e2a67 100644 --- a/packages/browser/src/plugins/segmentio/__tests__/batched-dispatcher.test.ts +++ b/packages/browser/src/plugins/segmentio/__tests__/batched-dispatcher.test.ts @@ -49,7 +49,9 @@ describe('Batching', () => { beforeEach(() => { jest.resetAllMocks() jest.restoreAllMocks() - jest.useFakeTimers() + jest.useFakeTimers({ + now: new Date('9 Jun 1993 00:00:00Z').getTime(), + }) }) afterEach(() => { @@ -92,7 +94,7 @@ describe('Batching', () => { Array [ "https://https://api.segment.io/b", Object { - "body": "{\\"batch\\":[{\\"event\\":\\"first\\"},{\\"event\\":\\"second\\"},{\\"event\\":\\"third\\"}]}", + "body": "{\\"batch\\":[{\\"event\\":\\"first\\"},{\\"event\\":\\"second\\"},{\\"event\\":\\"third\\"}],\\"sentAt\\":\\"1993-06-09T00:00:00.000Z\\"}", "headers": Object { "Content-Type": "text/plain", }, @@ -150,7 +152,7 @@ describe('Batching', () => { Array [ "https://https://api.segment.io/b", Object { - "body": "{\\"batch\\":[{\\"event\\":\\"first\\"},{\\"event\\":\\"second\\"}]}", + "body": "{\\"batch\\":[{\\"event\\":\\"first\\"},{\\"event\\":\\"second\\"}],\\"sentAt\\":\\"1993-06-09T00:00:10.000Z\\"}", "headers": Object { "Content-Type": "text/plain", }, @@ -185,7 +187,7 @@ describe('Batching', () => { Array [ "https://https://api.segment.io/b", Object { - "body": "{\\"batch\\":[{\\"event\\":\\"first\\"}]}", + "body": "{\\"batch\\":[{\\"event\\":\\"first\\"}],\\"sentAt\\":\\"1993-06-09T00:00:10.000Z\\"}", "headers": Object { "Content-Type": "text/plain", }, @@ -199,7 +201,38 @@ describe('Batching', () => { Array [ "https://https://api.segment.io/b", Object { - "body": "{\\"batch\\":[{\\"event\\":\\"second\\"}]}", + "body": "{\\"batch\\":[{\\"event\\":\\"second\\"}],\\"sentAt\\":\\"1993-06-09T00:00:21.000Z\\"}", + "headers": Object { + "Content-Type": "text/plain", + }, + "keepalive": false, + "method": "post", + }, + ] + `) + }) + + it('removes sentAt from individual events', async () => { + const { dispatch } = batch(`https://api.segment.io`, { + size: 2, + }) + + await dispatch(`https://api.segment.io/v1/t`, { + event: 'first', + sentAt: new Date('11 Jun 1993 00:01:00Z'), + }) + + await dispatch(`https://api.segment.io/v1/t`, { + event: 'second', + sentAt: new Date('11 Jun 1993 00:02:00Z'), + }) + + expect(fetch).toHaveBeenCalledTimes(1) + expect(fetch.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "https://https://api.segment.io/b", + Object { + "body": "{\\"batch\\":[{\\"event\\":\\"first\\"},{\\"event\\":\\"second\\"}],\\"sentAt\\":\\"1993-06-09T00:00:00.000Z\\"}", "headers": Object { "Content-Type": "text/plain", }, diff --git a/packages/browser/src/plugins/segmentio/batched-dispatcher.ts b/packages/browser/src/plugins/segmentio/batched-dispatcher.ts index 35995d115..1fb172d6a 100644 --- a/packages/browser/src/plugins/segmentio/batched-dispatcher.ts +++ b/packages/browser/src/plugins/segmentio/batched-dispatcher.ts @@ -60,13 +60,23 @@ export default function batch( const writeKey = (batch[0] as SegmentEvent)?.writeKey + // Remove sentAt from every event as batching only needs a single timestamp + const updatedBatch = batch.map((event) => { + const { sentAt, ...newEvent } = event as SegmentEvent + return newEvent + }) + return fetch(`https://${apiHost}/b`, { keepalive: pageUnloaded, headers: { 'Content-Type': 'text/plain', }, method: 'post', - body: JSON.stringify({ batch, writeKey }), + body: JSON.stringify({ + writeKey, + batch: updatedBatch, + sentAt: new Date().toISOString(), + }), }) }