diff --git a/posthog/src/main/java/com/posthog/java/PostHog.java b/posthog/src/main/java/com/posthog/java/PostHog.java index 5b4191f..2a6d209 100644 --- a/posthog/src/main/java/com/posthog/java/PostHog.java +++ b/posthog/src/main/java/com/posthog/java/PostHog.java @@ -76,8 +76,8 @@ private void startQueueManager() { // TODO handle interrupts? (via addShutdownHook) } - private void enqueue(String distinctId, String event, Map properties) { - JSONObject eventJson = getEventJson(event, distinctId, properties); + private void enqueue(String distinctId, String event, Map properties, Instant timestamp) { + JSONObject eventJson = getEventJson(event, distinctId, properties, timestamp); queueManager.add(eventJson); } @@ -89,7 +89,19 @@ private void enqueue(String distinctId, String event, Map proper * @param properties an array with any event properties you'd like to set. */ public void capture(String distinctId, String event, Map properties) { - enqueue(distinctId, event, properties); + enqueue(distinctId, event, properties, Instant.now()); + } + + /** + * + * @param distinctId which uniquely identifies your user in your database. Must + * not be null or empty. + * @param event name of the event. Must not be null or empty. + * @param properties an array with any event properties you'd like to set. + * @param timestamp the timestamp of the event. + */ + public void capture(String distinctId, String event, Map properties, Instant timestamp) { + enqueue(distinctId, event, properties, timestamp); } /** @@ -99,11 +111,22 @@ public void capture(String distinctId, String event, Map propert * @param event name of the event. Must not be null or empty. */ public void capture(String distinctId, String event) { - enqueue(distinctId, event, null); + enqueue(distinctId, event, null, Instant.now()); } /** - * + * + * @param distinctId which uniquely identifies your user in your database. Must + * not be null or empty. + * @param event name of the event. Must not be null or empty. + * @param timestamp the timestamp of the event. + */ + public void capture(String distinctId, String event, Instant timestamp) { + enqueue(distinctId, event, null, timestamp); + } + + /** + * * @param distinctId which uniquely identifies your user in your * database. Must not be null or empty. * @param properties an array with any person properties you'd like to @@ -119,7 +142,7 @@ public void identify(String distinctId, Map properties, Map properties) { put("$set", properties); } }; - enqueue(distinctId, "$set", props); + enqueue(distinctId, "$set", props, Instant.now()); } /** @@ -179,16 +202,16 @@ public void setOnce(String distinctId, Map properties) { put("$set_once", properties); } }; - enqueue(distinctId, "$set_once", props); + enqueue(distinctId, "$set_once", props, Instant.now()); } - private JSONObject getEventJson(String event, String distinctId, Map properties) { + private JSONObject getEventJson(String event, String distinctId, Map properties, Instant timestamp) { JSONObject eventJson = new JSONObject(); try { // Ensure that we generate an identifier for this event such that we can e.g. // deduplicate server-side any duplicates we may receive. eventJson.put("uuid", UUID.randomUUID().toString()); - eventJson.put("timestamp", Instant.now().toString()); + eventJson.put("timestamp", timestamp.toString()); eventJson.put("distinct_id", distinctId); eventJson.put("event", event); eventJson.put("$lib", "posthog-java"); diff --git a/posthog/src/test/java/com/posthog/java/PostHogTest.java b/posthog/src/test/java/com/posthog/java/PostHogTest.java index daa82a6..e59d5b7 100644 --- a/posthog/src/test/java/com/posthog/java/PostHogTest.java +++ b/posthog/src/test/java/com/posthog/java/PostHogTest.java @@ -60,6 +60,21 @@ public void testCaptureSimple() { + "\"}").isEqualTo(new JSONObject(json, "distinct_id", "event", "timestamp").toString()); } + @Test + public void testCaptureSimpleWithTimestamp() { + String providedInstantExpected = "2024-04-25T02:02:02Z"; + Instant timestamp = Instant.parse(providedInstantExpected); + ph.capture("test id", "test event", timestamp); + ph.shutdown(); + assertEquals(1, sender.calls.size()); + assertEquals(1, sender.calls.get(0).size()); + JSONObject json = sender.calls.get(0).get(0); + // Assert JSON includes the expected distinct_id, event, and timestamp, ignoring + // any extraneus properties. + assertThatJson("{\"distinct_id\":\"test id\",\"event\":\"test event\",\"timestamp\":\"" + providedInstantExpected + + "\"}").isEqualTo(new JSONObject(json, "distinct_id", "event", "timestamp").toString()); + } + @Test public void testEnsureEventHasGeneratedUuid() { // To ensure we have a way to deduplicate events that may be ingested multiple @@ -100,6 +115,26 @@ public void testCaptureWithProperties() { + "\"}").isEqualTo(new JSONObject(json, "distinct_id", "event", "properties", "timestamp").toString()); } + @Test + public void testCaptureWithPropertiesAndTimestamp() { + String providedInstantExpected = "2024-04-25T02:02:02Z"; + Instant timestamp = Instant.parse(providedInstantExpected); + ph.capture("test id", "test event", new HashMap() { + { + put("movie_id", 123); + put("category", "romcom"); + } + }, + timestamp); + ph.shutdown(); + assertEquals(1, sender.calls.size()); + assertEquals(1, sender.calls.get(0).size()); + JSONObject json = sender.calls.get(0).get(0); + assertThatJson("{\"distinct_id\":\"test id\",\"event\":\"test event\"" + + ",\"properties\":{\"movie_id\":123,\"category\":\"romcom\"},\"timestamp\":\"" + providedInstantExpected + + "\"}").isEqualTo(new JSONObject(json, "distinct_id", "event", "properties", "timestamp").toString()); + } + @Test public void testCaptureIncludesLibProperty() { ph.capture("test id", "test event", new HashMap() {