Skip to content
Open
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
8 changes: 8 additions & 0 deletions .changeset/project-token-rename.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'posthog': minor
'posthog-android': minor
'posthog-server': minor
'posthog-android-surveys-compose': patch
---

Add `projectToken` to `PostHogConfig` and `PostHogAndroidConfig`; `apiKey` is deprecated
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import com.posthog.surveys.PostHogSurveysResumeAwareDelegate
* implementation("com.posthog:posthog-android-surveys-compose:<version>")
*
* // app init
* val config = PostHogAndroidConfig(apiKey).apply { surveys = true }
* val config = PostHogAndroidConfig(projectToken).apply { surveys = true }
* PostHogAndroid.setup(applicationContext, config)
* ```
*
Expand Down
2 changes: 1 addition & 1 deletion posthog-android/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ unit tests covering your change, this will make your change much more likely to
2. Follow instructions here for setup https://developer.android.com/studio/run/emulator
3. Make sure you have Java 17 installed locally - `brew install openjdk@17`
4. Change the JDK in Android Studio to build using the correct version.
5. In the `posthog-android-sample` project, edit `MyApp.kt` and set the `apiKey` variable to your own PostHog Project API Key.
5. In the `posthog-android-sample` project, edit `MyApp.kt` and set the `projectToken` variable to your own PostHog project token.
6. Select `posthog-android-sample` and the device on the top bar and click run

Above all, thank you for contributing!
6 changes: 6 additions & 0 deletions posthog-android/api/posthog-android.api
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public final class com/posthog/android/PostHogAndroid$Companion {
}

public class com/posthog/android/PostHogAndroidConfig : com/posthog/PostHogConfig {
public static final field Companion Lcom/posthog/android/PostHogAndroidConfig$Companion;
public fun <init> (Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Z)V
Expand Down Expand Up @@ -46,6 +47,11 @@ public class com/posthog/android/PostHogAndroidConfig : com/posthog/PostHogConfi
public final fun setSessionReplayConfig (Lcom/posthog/android/replay/PostHogSessionReplayConfig;)V
}

public final class com/posthog/android/PostHogAndroidConfig$Companion {
public final synthetic fun invoke (Ljava/lang/String;Ljava/lang/String;ZZZLcom/posthog/android/replay/PostHogSessionReplayConfig;ZZ)Lcom/posthog/android/PostHogAndroidConfig;
public static synthetic fun invoke$default (Lcom/posthog/android/PostHogAndroidConfig$Companion;Ljava/lang/String;Ljava/lang/String;ZZZLcom/posthog/android/replay/PostHogSessionReplayConfig;ZZILjava/lang/Object;)Lcom/posthog/android/PostHogAndroidConfig;
}

public final class com/posthog/android/PostHogAutocaptureModifierKt {
public static final fun postHogAutocaptureNoCapture (Landroidx/compose/ui/Modifier;Z)Landroidx/compose/ui/Modifier;
public static synthetic fun postHogAutocaptureNoCapture$default (Landroidx/compose/ui/Modifier;ZILjava/lang/Object;)Landroidx/compose/ui/Modifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import com.posthog.internal.PostHogQueue
/**
* Android SDK configuration.
*
* @param apiKey PostHog project API key. Leading and trailing whitespace is trimmed.
* @param projectToken Your PostHog project token, which starts with `phc_`. Required, no default.
* Find it in your PostHog project settings: https://us.posthog.com/settings/project-details#variables.
* Leading and trailing whitespace is trimmed. Formerly named `apiKey`. Example:
* `PostHogAndroidConfig(projectToken = "phc_your_project_token")`.
* @param host PostHog ingestion host. Defaults to [DEFAULT_HOST].
* @property captureApplicationLifecycleEvents Whether to capture application lifecycle events
* automatically, including app installed, app updated, app opened, and app backgrounded.
Expand Down Expand Up @@ -42,7 +45,7 @@ import com.posthog.internal.PostHogQueue
public open class PostHogAndroidConfig
@JvmOverloads
constructor(
apiKey: String,
projectToken: String,
host: String = DEFAULT_HOST,
public var captureApplicationLifecycleEvents: Boolean = true,
public var captureDeepLinks: Boolean = true,
Expand All @@ -52,7 +55,7 @@ public open class PostHogAndroidConfig
public var capturePushNotificationSubscriptions: Boolean = true,
public var capturePushNotificationOpened: Boolean = true,
) : PostHogConfig(
apiKey = apiKey,
projectToken = projectToken,
host = host,
queueProvider = { config, api, endpoint, storagePrefix, executor ->
val spec =
Expand Down Expand Up @@ -93,4 +96,40 @@ public open class PostHogAndroidConfig
public var captureDeadClicks: Boolean = false

internal var replayQueueHolder: PostHogReplayQueue? = null

public companion object {
/**
* Deprecated form of the [PostHogAndroidConfig] constructor that takes `apiKey` instead
* of `projectToken`, kept so Kotlin calls such as `PostHogAndroidConfig(apiKey = "phc_...")`
* still compile. Every other parameter and default matches the constructor.
*
* ```kotlin
* val config = PostHogAndroidConfig(projectToken = "phc_your_project_token") // instead of apiKey =
* ```
*/
@Deprecated(
"Deprecated in favor of projectToken. This will be removed in the next major version.",
)
@JvmSynthetic
public operator fun invoke(
apiKey: String,
host: String = PostHogConfig.DEFAULT_HOST,
captureApplicationLifecycleEvents: Boolean = true,
captureDeepLinks: Boolean = true,
captureScreenViews: Boolean = true,
sessionReplayConfig: PostHogSessionReplayConfig = PostHogSessionReplayConfig(),
capturePushNotificationSubscriptions: Boolean = true,
capturePushNotificationOpened: Boolean = true,
): PostHogAndroidConfig =
PostHogAndroidConfig(
projectToken = apiKey,
host = host,
captureApplicationLifecycleEvents = captureApplicationLifecycleEvents,
captureDeepLinks = captureDeepLinks,
captureScreenViews = captureScreenViews,
sessionReplayConfig = sessionReplayConfig,
capturePushNotificationSubscriptions = capturePushNotificationSubscriptions,
capturePushNotificationOpened = capturePushNotificationOpened,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ internal class PostHogSharedPreferences(
sharedPreferences?.let { return it }
val prefs =
try {
context.getSharedPreferences("posthog-android-${config.apiKey}", MODE_PRIVATE)
context.getSharedPreferences("posthog-android-${config.projectToken}", MODE_PRIVATE)
} catch (e: IllegalStateException) {
config.logger.log("Shared preferences are not available until the device is unlocked (Direct Boot): $e.")
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ internal class PostHogReplayQueue internal constructor(
replayStoragePrefix: String?,
private val executor: ExecutorService,
) : PostHogQueueInterface<PostHogEvent> {
private val replayDir = replayStoragePrefix?.let { File(it, config.apiKey) }
private val replayDir = replayStoragePrefix?.let { File(it, config.projectToken) }

private val bufferQueue: PostHogReplayBufferQueue =
PostHogReplayBufferQueue(
config,
if (replayStoragePrefix != null) {
File("$replayStoragePrefix-buffer", config.apiKey)
File("$replayStoragePrefix-buffer", config.projectToken)
} else {
File(System.getProperty("java.io.tmpdir"), "posthog-replay-buffer/${config.apiKey}")
File(System.getProperty("java.io.tmpdir"), "posthog-replay-buffer/${config.projectToken}")
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,27 @@ internal class PostHogAndroidConfigTest {
private val config = PostHogAndroidConfig(API_KEY)

@Test
fun `captureApplicationLifecycleEvents sets given apiKey`() {
assertEquals(API_KEY, config.apiKey)
fun `captureApplicationLifecycleEvents sets given projectToken`() {
assertEquals(API_KEY, config.projectToken)
}

@Test
fun `trims whitespace-sensitive config values`() {
val config = PostHogAndroidConfig(" \n$API_KEY\t ")

assertEquals(API_KEY, config.projectToken)
}

@Suppress("DEPRECATION")
@Test
fun `deprecated apiKey factory and getter alias projectToken`() {
val config = PostHogAndroidConfig(apiKey = " $API_KEY ", captureDeepLinks = false, capturePushNotificationOpened = false)

assertEquals(API_KEY, config.projectToken)
assertEquals(API_KEY, config.apiKey)
assertFalse(config.captureDeepLinks)
assertFalse(config.capturePushNotificationOpened)
assertTrue(config.captureScreenViews)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ internal class PostHogAndroidTest {
PostHogAndroid.setup(context, config)

assertTrue(PostHog.isOptOut())
assertTrue(logger.messages.any { it.contains("PostHog SDK is disabled because the API key is required") })
assertTrue(logger.messages.any { it.contains("PostHog SDK is disabled because the project token is required") })
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ class MyApp : Application() {
enableStrictMode()

// Demo:
// val apiKey = "_6SG-F7I1vCuZ-HdJL3VZQqjBlaSb1_20hDPwqMNnGI"
// val projectToken = "_6SG-F7I1vCuZ-HdJL3VZQqjBlaSb1_20hDPwqMNnGI"
// ManoelTesting:
val apiKey = "phc_WKfvDfedaJEDCoUmt9pVa3OWtbbUP1W2ctxwXkt3A3n"
val projectToken = "phc_WKfvDfedaJEDCoUmt9pVa3OWtbbUP1W2ctxwXkt3A3n"
// PaulKey
// val apiKey = "phc_GavhjwMwc75N4HsaLjMTEvH8Kpsz70rZ3N0E9ho89YJ"
// val config = PostHogAndroidConfig(apiKey, host = "https://3727-86-27-112-156.ngrok-free.app").apply {
// val projectToken = "phc_GavhjwMwc75N4HsaLjMTEvH8Kpsz70rZ3N0E9ho89YJ"
// val config = PostHogAndroidConfig(projectToken, host = "https://3727-86-27-112-156.ngrok-free.app").apply {
val mockHost = BuildConfig.POSTHOG_HOST
val config =
(
if (mockHost.isNotEmpty()) {
PostHogAndroidConfig("phc_MOCK", host = mockHost)
} else {
PostHogAndroidConfig(apiKey)
PostHogAndroidConfig(projectToken)
}
).apply {
debug = true
Expand Down
3 changes: 3 additions & 0 deletions posthog-server/api/posthog-server.api
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ public class com/posthog/server/PostHogConfig {
public final fun getPersonalApiKey ()Ljava/lang/String;
public final fun getPollIntervalSeconds ()I
public final fun getPreloadFeatureFlags ()Z
public final fun getProjectToken ()Ljava/lang/String;
public final fun getProxy ()Ljava/net/Proxy;
public final fun getReleaseIdentifier ()Ljava/lang/String;
public final fun getRemoteConfig ()Z
Expand Down Expand Up @@ -215,6 +216,8 @@ public final class com/posthog/server/PostHogConfig$Builder {

public final class com/posthog/server/PostHogConfig$Companion {
public final fun builder (Ljava/lang/String;)Lcom/posthog/server/PostHogConfig$Builder;
public final synthetic fun invoke (Ljava/lang/String;Ljava/lang/String;ZZZZIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;Ljava/net/Proxy;IIIZLjava/lang/String;ILjava/util/List;)Lcom/posthog/server/PostHogConfig;
public static synthetic fun invoke$default (Lcom/posthog/server/PostHogConfig$Companion;Ljava/lang/String;Ljava/lang/String;ZZZZIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;Ljava/net/Proxy;IIIZLjava/lang/String;ILjava/util/List;ILjava/lang/Object;)Lcom/posthog/server/PostHogConfig;
}

public final class com/posthog/server/PostHogEvaluateFlagsOptions {
Expand Down
108 changes: 100 additions & 8 deletions posthog-server/src/main/java/com/posthog/server/PostHogConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@ import java.util.Collections
*/
public open class PostHogConfig constructor(
/**
* The PostHog project API key.
* Your PostHog project token, which starts with `phc_`. Required, no default.
*
* Find it in your PostHog project settings:
* https://us.posthog.com/settings/project-details#variables. Leading and trailing whitespace
* is trimmed. Formerly named `apiKey`.
*
* ```kotlin
* val config = PostHogConfig(projectToken = "phc_your_project_token")
* ```
*/
apiKey: String,
projectToken: String,
/**
* The PostHog Host
* Defaults to https://us.i.posthog.com
Expand Down Expand Up @@ -142,9 +150,31 @@ public open class PostHogConfig constructor(
public var evaluationContexts: List<String>? = null,
) {
/**
* The PostHog project API key, trimmed of leading and trailing whitespace.
* Your PostHog project token, trimmed of leading and trailing whitespace.
*
* Find it in your PostHog project settings:
* https://us.posthog.com/settings/project-details#variables. Set it through the constructor or
* [builder]; there is no default.
*
* ```kotlin
* val token = PostHogConfig(projectToken = "phc_your_project_token").projectToken
* ```
*/
public val apiKey: String = apiKey.trim()
public val projectToken: String = projectToken.trim()

/**
* Deprecated alias for [projectToken]; returns the same trimmed value.
*
* ```kotlin
* val token = config.projectToken // instead of config.apiKey
* ```
*/
@Deprecated(
"Deprecated in favor of projectToken. This will be removed in the next major version.",
ReplaceWith("projectToken"),
)
public val apiKey: String
get() = projectToken

/**
* The PostHog Host
Expand Down Expand Up @@ -269,7 +299,7 @@ public open class PostHogConfig constructor(
internal fun asCoreConfig(): com.posthog.PostHogConfig {
val coreConfig =
com.posthog.PostHogConfig(
apiKey = apiKey,
projectToken = projectToken,
host = host,
debug = debug,
sendFeatureFlagEvent = sendFeatureFlagEvent,
Expand Down Expand Up @@ -378,17 +408,79 @@ public open class PostHogConfig constructor(
/**
* Creates a Java-friendly builder.
*
* @param apiKey PostHog project API key.
* @param apiKey Your PostHog project token, which starts with `phc_`. Find it in your
* PostHog project settings: https://us.posthog.com/settings/project-details#variables.
* Example: `PostHogConfig.builder("phc_your_project_token").build()`.
* @return A new [Builder].
*/
@JvmStatic
public fun builder(apiKey: String): Builder = Builder(apiKey)

/**
* Deprecated form of the [PostHogConfig] constructor that takes `apiKey` instead of
* `projectToken`, kept so Kotlin calls such as `PostHogConfig(apiKey = "phc_...")` still
* compile. Every other parameter and default matches the constructor.
*
* ```kotlin
* val config = PostHogConfig(projectToken = "phc_your_project_token") // instead of apiKey =
* ```
*/
@Deprecated(
"Deprecated in favor of projectToken. This will be removed in the next major version.",
)
@Suppress("DEPRECATION")
@JvmSynthetic
public operator fun invoke(
apiKey: String,
host: String = DEFAULT_HOST,
debug: Boolean = false,
sendFeatureFlagEvent: Boolean = true,
preloadFeatureFlags: Boolean = true,
remoteConfig: Boolean = true,
flushAt: Int = DEFAULT_FLUSH_AT,
maxQueueSize: Int = DEFAULT_MAX_QUEUE_SIZE,
maxBatchSize: Int = DEFAULT_MAX_BATCH_SIZE,
flushIntervalSeconds: Int = DEFAULT_FLUSH_INTERVAL_SECONDS,
encryption: PostHogEncryption? = null,
onFeatureFlags: PostHogOnFeatureFlags? = null,
proxy: Proxy? = null,
featureFlagCacheSize: Int = DEFAULT_FEATURE_FLAG_CACHE_SIZE,
featureFlagCacheMaxAgeMs: Int = DEFAULT_FEATURE_FLAG_CACHE_MAX_AGE_MS,
featureFlagCalledCacheSize: Int = DEFAULT_FEATURE_FLAG_CALLED_CACHE_SIZE,
localEvaluation: Boolean = false,
personalApiKey: String? = null,
pollIntervalSeconds: Int = DEFAULT_POLL_INTERVAL_SECONDS,
evaluationContexts: List<String>? = null,
): PostHogConfig =
PostHogConfig(
projectToken = apiKey,
host = host,
debug = debug,
sendFeatureFlagEvent = sendFeatureFlagEvent,
preloadFeatureFlags = preloadFeatureFlags,
remoteConfig = remoteConfig,
flushAt = flushAt,
maxQueueSize = maxQueueSize,
maxBatchSize = maxBatchSize,
flushIntervalSeconds = flushIntervalSeconds,
encryption = encryption,
onFeatureFlags = onFeatureFlags,
proxy = proxy,
featureFlagCacheSize = featureFlagCacheSize,
featureFlagCacheMaxAgeMs = featureFlagCacheMaxAgeMs,
featureFlagCalledCacheSize = featureFlagCalledCacheSize,
localEvaluation = localEvaluation,
personalApiKey = personalApiKey,
pollIntervalSeconds = pollIntervalSeconds,
evaluationContexts = evaluationContexts,
)
}

/**
* Java-friendly builder for [PostHogConfig].
*
* @param apiKey PostHog project API key.
* @param apiKey Your PostHog project token, which starts with `phc_`. Find it in your PostHog
* project settings: https://us.posthog.com/settings/project-details#variables.
*/
public class Builder(private val apiKey: String) {
private var host: String = DEFAULT_HOST
Expand Down Expand Up @@ -647,7 +739,7 @@ public open class PostHogConfig constructor(
public fun build(): PostHogConfig {
val config =
PostHogConfig(
apiKey = apiKey,
projectToken = apiKey,
host = host,
debug = debug,
sendFeatureFlagEvent = sendFeatureFlagEvent,
Expand Down
Loading
Loading