Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IAF branch from master #221

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ android.enableJetifier=true
# URL to Klaviyo server
klaviyoServerUrl=https://a.klaviyo.com

# URL to Klaviyo CDN (serving assets such as klaviyo.js)
klaviyoCdnUrl=https://static.klaviyo.com

# Klaviyo API Revision
klaviyoApiRevision=2024-10-15

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,60 +11,60 @@ import com.klaviyo.core.config.getPackageInfoCompat
import com.klaviyo.core.model.fetchOrCreate
import java.util.UUID

internal object DeviceProperties {
object DeviceProperties {

private const val DEVICE_ID_KEY = "device_id"

/**
* UUID for this Device + SDK installation
* should only be generated one time, stored for the life of the app installation
*/
val deviceId: String by lazy {
internal val deviceId: String by lazy {
Registry.dataStore.fetchOrCreate(DEVICE_ID_KEY) { UUID.randomUUID().toString() }
}

val manufacturer: String by lazy {
internal val manufacturer: String by lazy {
Build.BRAND
}

val model: String by lazy {
internal val model: String by lazy {
Build.MODEL
}

val platform: String by lazy {
internal val platform: String by lazy {
"Android"
}

val osVersion: String by lazy {
internal val osVersion: String by lazy {
Build.VERSION.SDK_INT.toString()
}

val appVersion: String by lazy {
internal val appVersion: String by lazy {
packageInfo.versionName
}

val appVersionCode: String by lazy {
internal val appVersionCode: String by lazy {
packageInfo.getVersionCodeCompat().toString()
}

val sdkVersion: String
internal val sdkVersion: String
get() = KlaviyoConfig.sdkVersion

val sdkName: String
internal val sdkName: String
get() = KlaviyoConfig.sdkName

val backgroundDataEnabled: Boolean by lazy {
internal val backgroundDataEnabled: Boolean by lazy {
!activityManager.isBackgroundRestrictedCompat()
}

val notificationPermissionGranted: Boolean
internal val notificationPermissionGranted: Boolean
get() = NotificationManagerCompat.from(Registry.config.applicationContext).areNotificationsEnabled()

val applicationId: String by lazy {
internal val applicationId: String by lazy {
Registry.config.applicationContext.packageName
}

val applicationLabel: String by lazy {
internal val applicationLabel: String by lazy {
Registry.config.applicationContext.packageManager.getApplicationLabel(
Registry.config.applicationContext.applicationInfo
).toString()
Expand All @@ -83,7 +83,7 @@ internal object DeviceProperties {
Registry.config.applicationContext.getSystemService(ActivityManager::class.java)
}

fun buildEventMetaData(): Map<String, String?> = mapOf(
internal fun buildEventMetaData(): Map<String, String?> = mapOf(
"Device ID" to deviceId,
"Device Manufacturer" to manufacturer,
"Device Model" to model,
Expand All @@ -98,7 +98,7 @@ internal object DeviceProperties {
"Push Token" to Klaviyo.getPushToken()
)

fun buildMetaData(): Map<String, String?> = mapOf(
internal fun buildMetaData(): Map<String, String?> = mapOf(
"device_id" to deviceId,
"manufacturer" to manufacturer,
"device_model" to model,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.klaviyo.analytics.networking

import com.klaviyo.analytics.model.Event
import com.klaviyo.analytics.model.Profile
import com.klaviyo.analytics.networking.requests.AggregateEventPayload
import com.klaviyo.analytics.networking.requests.ApiRequest

typealias ApiObserver = (request: ApiRequest) -> Unit
Expand Down Expand Up @@ -76,4 +77,9 @@ interface ApiClient {
* @param observer
*/
fun offApiRequest(observer: ApiObserver)

/**
* For sending aggregate analytics for IAF - not to be called directly
*/
fun enqueueAggregateEvent(payload: AggregateEventPayload)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import android.os.Looper
import com.klaviyo.analytics.model.Event
import com.klaviyo.analytics.model.EventMetric
import com.klaviyo.analytics.model.Profile
import com.klaviyo.analytics.networking.requests.AggregateEventApiRequest
import com.klaviyo.analytics.networking.requests.AggregateEventPayload
import com.klaviyo.analytics.networking.requests.EventApiRequest
import com.klaviyo.analytics.networking.requests.KlaviyoApiRequest
import com.klaviyo.analytics.networking.requests.KlaviyoApiRequest.Status
Expand Down Expand Up @@ -66,7 +68,13 @@ internal object KlaviyoApiClient : ApiClient {
enqueueRequest(PushTokenApiRequest(token, profile))
}

override fun enqueueAggregateEvent(payload: AggregateEventPayload) {
Registry.log.verbose("Enqueuing Aggregate Event request")
enqueueRequest(AggregateEventApiRequest(payload))
}

override fun enqueueUnregisterPushToken(apiKey: String, token: String, profile: Profile) {
Registry.log.verbose("Enqueuing unregister token request")
enqueueRequest(UnregisterPushTokenApiRequest(apiKey, token, profile))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.klaviyo.analytics.networking.requests

import com.klaviyo.core.Registry
import org.json.JSONObject

typealias AggregateEventPayload = JSONObject
internal class AggregateEventApiRequest(
queuedTime: Long? = null,
uuid: String? = null
) : KlaviyoApiRequest(PATH, RequestMethod.POST, queuedTime, uuid) {

companion object {
private const val PATH = "onsite/track-analytics"
}

override val type: String = "Create Aggregate Event"
override var query: Map<String, String> = mapOf(
COMPANY_ID to Registry.config.apiKey
)

override val successCodes: IntRange get() = HTTP_ACCEPTED..HTTP_ACCEPTED

constructor(payload: AggregateEventPayload) : this() {
body = payload
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.klaviyo.analytics.DevicePropertiesTest
import com.klaviyo.analytics.model.Event
import com.klaviyo.analytics.model.EventMetric
import com.klaviyo.analytics.model.Profile
import com.klaviyo.analytics.networking.KlaviyoApiClient.HandlerUtil as HandlerUtil
import com.klaviyo.analytics.networking.KlaviyoApiClient.HandlerUtil
import com.klaviyo.analytics.networking.requests.ApiRequest
import com.klaviyo.analytics.networking.requests.EventApiRequest
import com.klaviyo.analytics.networking.requests.KlaviyoApiRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.klaviyo.analytics.networking.requests
import com.klaviyo.analytics.DevicePropertiesTest
import com.klaviyo.analytics.model.Profile
import com.klaviyo.fixtures.BaseTest
import org.json.JSONObject
import org.junit.Assert
import org.junit.Before
import org.junit.Test
Expand Down Expand Up @@ -30,6 +31,53 @@ internal abstract class BaseApiRequestTest<T> : BaseTest() where T : KlaviyoApiR
.setEmail(EMAIL)
.setPhoneNumber(PHONE)

open val stubAggregateEventPayload = JSONObject(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hrm, where is this used?

"""
{
"type": "aggregateEventTracked",
"data": {
"metric_group": "signup-forms",
"events": [
{
"metric": "stepSubmit",
"log_to_statsd": true,
"log_to_s3": true,
"log_to_metrics_service": true,
"metric_service_event_name": "submitted_form_step",
"event_details": {
"form_version_c_id": "1",
"is_client": true,
"submitted_fields": {
"source": "Local Form",
"email": "[email protected]",
"consent_method": "Klaviyo Form",
"consent_form_id": "64CjgW",
"consent_form_version": 3,
"sent_identifiers": {},
"sms_consent": true,
"step_name": "Email Opt-In"
},
"step_name": "Email Opt-In",
"step_number": 1,
"action_type": "Submit Step",
"form_id": "64CjgW",
"form_version_id": 3,
"form_type": "POPUP",
"device_type": "DESKTOP",
"hostname": "localhost",
"href": "http://localhost:4001/onsite/js/",
"page_url": "http://localhost:4001/onsite/js/",
"first_referrer": "http://localhost:4001/onsite/js/",
"referrer": "http://localhost:4001/onsite/js/",
"cid": "ODZjYjJmMjUtNjliMC00ZGVlLTllM2YtNDY5YTlmNjcwYmUz"
}
}
]
}
}
""".trimIndent()
)

abstract fun makeTestRequest(): T

@Before
Expand Down
3 changes: 3 additions & 0 deletions sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ subprojects {
localProperties.load(new FileInputStream(rootProject.file("local.properties")))
}
def serverTarget = localProperties["localKlaviyoServerUrl"] ?: klaviyoServerUrl
def cdnUrl = localProperties["localKlaviyoCdnUrl"] ?: klaviyoCdnUrl
def apiRevision = localProperties["localKlaviyoApiRevision"] ?: klaviyoApiRevision

defaultConfig {
Expand Down Expand Up @@ -47,11 +48,13 @@ subprojects {
minifyEnabled false
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
buildConfigField "String", "KLAVIYO_SERVER_URL", "\"${serverTarget}\""
buildConfigField "String", "KLAVIYO_CDN_URL", "\"${cdnUrl}\""
buildConfigField "String", "KLAVIYO_API_REVISION", "\"${apiRevision}\""
}
debug {
debuggable = true
buildConfigField "String", "KLAVIYO_SERVER_URL", "\"${serverTarget}\""
buildConfigField "String", "KLAVIYO_CDN_URL", "\"${cdnUrl}\""
buildConfigField "String", "KLAVIYO_API_REVISION", "\"${apiRevision}\""
}
}
Expand Down
1 change: 1 addition & 0 deletions sdk/core/src/main/java/com/klaviyo/core/config/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.klaviyo.core.networking.NetworkMonitor
interface Config {
val isDebugBuild: Boolean
val baseUrl: String
val baseCdnUrl: String
val apiRevision: String
val sdkName: String
val sdkVersion: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ object KlaviyoConfig : Config {

override var baseUrl: String = BuildConfig.KLAVIYO_SERVER_URL
private set

override var baseCdnUrl: String = BuildConfig.KLAVIYO_CDN_URL
private set
override var apiRevision: String = BuildConfig.KLAVIYO_API_REVISION
private set
override lateinit var sdkName: String private set
Expand Down
1 change: 1 addition & 0 deletions sdk/messaging/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
38 changes: 38 additions & 0 deletions sdk/messaging/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
project.description = 'In-app messaging functionality for the Klaviyo SDK suite'
evaluationDependsOn(':sdk')

def ext = rootProject.ext

android {
namespace "${klaviyoGroupId}.messaging"

publishing {
singleVariant(ext.publishBuildVariant) {
withSourcesJar()
withJavadocJar()
}
}
}

dependencies {
implementation project(':sdk:core')
implementation project(':sdk:analytics')

implementation AndroidX.webkit

testImplementation project(':sdk:fixtures')
}

afterEvaluate {
publishing {
publications {
// Creates a Maven publication called "release".
release(MavenPublication) {
from components[ext.publishBuildVariant]
groupId = klaviyoGroupId
artifactId = 'messaging'
version = readXmlValue('src/main/res/values/strings.xml','klaviyo_sdk_version_override', project(":sdk:core"))
}
}
}
}
1 change: 1 addition & 0 deletions sdk/messaging/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest />
14 changes: 14 additions & 0 deletions sdk/messaging/src/main/assets/InAppFormsTemplate.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head data-sdk-name="SDK_NAME"
data-sdk-version="SDK_VERSION"
data-native-bridge-name="BRIDGE_NAME"
data-native-bridge-handshake='BRIDGE_HANDSHAKE'
>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Klaviyo In-App Form Template</title>
<script type="text/javascript" src="KLAVIYO_JS_URL"></script>
</head>
<body></body>
</html>
Loading