Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/brave-owls-identify.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"posthog-server": minor
"posthog": minor
---

feat(server): allow overriding the `$identify` event timestamp with `identify(distinctId, userProperties, userPropertiesSetOnce, timestamp)`
3 changes: 3 additions & 0 deletions posthog-server/api/posthog-server.api
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public final class com/posthog/server/PostHog : com/posthog/PostHogStateless, co
public fun identify (Ljava/lang/String;)V
public fun identify (Ljava/lang/String;Ljava/util/Map;)V
public fun identify (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public fun identify (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;)V
public fun isFeatureEnabled (Ljava/lang/String;Ljava/lang/String;)Z
public fun isFeatureEnabled (Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogFeatureFlagOptions;)Z
public fun isFeatureEnabled (Ljava/lang/String;Ljava/lang/String;Z)Z
Expand Down Expand Up @@ -419,6 +420,7 @@ public abstract interface class com/posthog/server/PostHogInterface {
public abstract fun identify (Ljava/lang/String;)V
public abstract fun identify (Ljava/lang/String;Ljava/util/Map;)V
public abstract fun identify (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public abstract fun identify (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;)V
public abstract fun isFeatureEnabled (Ljava/lang/String;Ljava/lang/String;)Z
public abstract fun isFeatureEnabled (Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogFeatureFlagOptions;)Z
public abstract fun isFeatureEnabled (Ljava/lang/String;Ljava/lang/String;Z)Z
Expand Down Expand Up @@ -460,6 +462,7 @@ public final class com/posthog/server/PostHogInterface$DefaultImpls {
public static synthetic fun group$default (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)V
public static fun identify (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;)V
public static fun identify (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/util/Map;)V
public static fun identify (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public static fun isFeatureEnabled (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;)Z
public static fun isFeatureEnabled (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogFeatureFlagOptions;)Z
public static fun isFeatureEnabled (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Z)Z
Expand Down
12 changes: 11 additions & 1 deletion posthog-server/src/main/java/com/posthog/server/PostHog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,20 @@ public class PostHog : PostHogStateless(), PostHogInterface {
userProperties: Map<String, Any>?,
userPropertiesSetOnce: Map<String, Any>?,
) {
super<PostHogStateless>.identify(
identify(distinctId, userProperties, userPropertiesSetOnce, null)
}

override fun identify(
distinctId: String,
userProperties: Map<String, Any>?,
userPropertiesSetOnce: Map<String, Any>?,
timestamp: java.util.Date?,
) {
super.identifyStateless(
distinctId,
userProperties,
userPropertiesSetOnce,
timestamp,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ public sealed interface PostHogInterface {
distinctId: String,
userProperties: Map<String, Any>?,
userPropertiesSetOnce: Map<String, Any>?,
) {
identify(
distinctId,
userProperties,
userPropertiesSetOnce,
null,
)
}

/**
* Identifies the user
* Docs https://posthog.com/docs/product-analytics/identify
* @param distinctId the distinctId
* @param userProperties the user properties, set as a "$set" property, Docs https://posthog.com/docs/product-analytics/user-properties
* @param userPropertiesSetOnce the user properties to set only once, set as a "$set_once" property, Docs https://posthog.com/docs/product-analytics/user-properties
* @param timestamp the `$identify` event timestamp override. UTC is preferred; the equivalent instant is serialized in UTC. If null, the current time is used. Docs https://posthog.com/docs/data/timestamps
*/
public fun identify(
distinctId: String,
userProperties: Map<String, Any>?,
userPropertiesSetOnce: Map<String, Any>?,
timestamp: Date?,
)

/**
Expand Down
12 changes: 12 additions & 0 deletions posthog-server/src/test/java/com/posthog/server/PostHogTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ internal class PostHogTest {
}
}

@Test
fun `identify with timestamp passes timestamp through`() {
withClient { client, server ->
client.identify("user123", mapOf("name" to "Ada"), null, java.util.Date(1234567890L))
client.flush()
val batch = assertNotNull(server.takeRequest(5, TimeUnit.SECONDS)).parseBatch()
assertEquals("\$identify", batch.firstEvent?.get("event")?.asString)
assertEquals("1970-01-15T06:56:07.890Z", batch.firstEvent?.get("timestamp")?.asString)
assertEquals(mapOf("name" to "Ada"), batch.firstEventProperties()["\$set"])
}
}

@Test
fun `capture with PostHogCaptureOptions works correctly`() {
withClient { client, server ->
Expand Down
1 change: 1 addition & 0 deletions posthog/api/posthog.api
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ public class com/posthog/PostHogStateless : com/posthog/PostHogStatelessInterfac
protected final fun getThrowableCoercer ()Lcom/posthog/internal/errortracking/ThrowableCoercer;
public fun groupStateless (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V
public fun identify (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
protected final fun identifyStateless (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;)V
protected final fun isEnabled ()Z
public fun isFeatureEnabledStateless (Ljava/lang/String;Ljava/lang/String;ZLjava/util/Map;Ljava/util/Map;Ljava/util/Map;)Z
protected fun isMinimalFlagCalledEventsEnabled ()Z
Expand Down
14 changes: 14 additions & 0 deletions posthog/src/main/java/com/posthog/PostHogStateless.kt
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,19 @@ public open class PostHogStateless protected constructor(
distinctId: String,
userProperties: Map<String, Any>?,
userPropertiesSetOnce: Map<String, Any>?,
) {
identifyStateless(distinctId, userProperties, userPropertiesSetOnce, timestamp = null)
}

/**
* Identifies the user, optionally overriding the `$identify` event timestamp
* @param timestamp the event timestamp override, or null to use the current time
*/
protected fun identifyStateless(
distinctId: String,
userProperties: Map<String, Any>?,
userPropertiesSetOnce: Map<String, Any>?,
timestamp: Date?,
) {
if (!isEnabled()) {
return
Expand All @@ -404,6 +417,7 @@ public open class PostHogStateless protected constructor(
properties = props,
userProperties = userProperties,
userPropertiesSetOnce = userPropertiesSetOnce,
timestamp = timestamp,
)
}

Expand Down
Loading