diff --git a/CHANGELOG.md b/CHANGELOG.md index 844f8e6d..dc4fa619 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,25 @@ Change Log ========== +Version 4.2.0 *(June 10 2026)* +------------------------------------------- +**What's new** +* **[Android Platform]** + * Supports [CleverTap Android SDK v8.3.0](https://github.com/CleverTap/clevertap-android-sdk/blob/master/docs/CTCORECHANGELOG.md#version-830-june-2026). + * App Inbox Cross-Device Sync — inbox state (read, deleted) syncs across a user's devices automatically. The built-in App Inbox view also gains a pull-to-refresh gesture, throttled to once every 5 minutes. + * Native Display Element Click — finer-grained click analytics for individual elements within a Display Unit. + +* **[iOS Platform]** + * Supports [CleverTap iOS SDK v7.7.1](https://github.com/CleverTap/clevertap-ios-sdk/blob/master/CHANGELOG.md#version-771-june-04-2026). + * App Inbox Cross-Device Sync — inbox state (read, deleted) syncs across a user's devices automatically. The built-in App Inbox view also gains a pull-to-refresh gesture, throttled to once every 5 minutes. + * Native Display Element Click — finer-grained click analytics for individual elements within a Display Unit. + * Silent-in-foreground push — notifications with `wzrk_sif:true` in the payload are delivered silently to the tray when the app is in the foreground, handled automatically by the SDK. + +**API changes** +* **[Android and iOS Platform]** + * Adds `fetchInbox(callback?)` — triggers an on-demand App Inbox refresh from the server. The optional callback receives `true` on success or `false` if the fetch was throttled, disabled, or failed. + * Adds `pushDisplayUnitElementClickedEventForID(unitID, additionalProperties)` — records a `Notification Clicked` event for a specific element within a Display Unit, merging caller-supplied attribution fields with cached `wzrk_*` data from the unit. + Version 4.1.0 *(April 30 2026)* ------------------------------------------- **What's new** diff --git a/Example/android/app/src/main/assets/custom/templates.json b/Example/android/app/src/main/assets/custom/templates.json new file mode 100644 index 00000000..2229e8c7 --- /dev/null +++ b/Example/android/app/src/main/assets/custom/templates.json @@ -0,0 +1,68 @@ +{ + "Example template": { + "type": "template", + "arguments": { + "bool": { + "type": "boolean", + "value": false + }, + "string": { + "type": "string", + "value": "Default" + }, + "map": { + "type": "object", + "value": { + "int": { + "type": "number", + "value": 0 + }, + "string": { + "type": "string", + "value": "Default" + } + } + }, + "action": { + "type": "action" + }, + "file": { + "type": "file" + } + } + }, + "Example function": { + "type": "function", + "isVisual": false, + "arguments": { + "double": { + "type": "number", + "value": 99.98 + }, + "string": { + "type": "string", + "value": "Default" + }, + "file": { + "type": "file" + } + } + }, + "Example visual function": { + "type": "function", + "isVisual": true, + "arguments": { + "color": { + "type": "string", + "value": "transparent" + }, + "enabled": { + "type": "boolean", + "value": false + }, + "image": { + "type": "file" + } + } + } +} diff --git a/Example/ios/.xcode.env b/Example/ios/.xcode.env new file mode 100644 index 00000000..772b339b --- /dev/null +++ b/Example/ios/.xcode.env @@ -0,0 +1 @@ +export NODE_BINARY=$(command -v node) diff --git a/Example/ios/Example.xcodeproj/project.pbxproj b/Example/ios/Example.xcodeproj/project.pbxproj index 48562268..e1171487 100644 --- a/Example/ios/Example.xcodeproj/project.pbxproj +++ b/Example/ios/Example.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ 48BF79852AB076F20091FF16 /* NotificationContentSwift.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 48BF79792AB076F10091FF16 /* NotificationContentSwift.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 685D0A42F74FC38D84284799 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 9A4C3DD3EBC1242A62F0E22B /* PrivacyInfo.xcprivacy */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + AEBABB8DDA82439084117624 /* templates.json in Resources */ = {isa = PBXBuildFile; fileRef = 0E42C5B8A6C5431FB0AB24EF /* templates.json */; }; C28EE22363709BEF624F9F1E /* libPods-NotificationContentSwift.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C33252DD165317E32A556B4 /* libPods-NotificationContentSwift.a */; }; FFDFBBA910887882FBEAC7E1 /* libPods-NotificationContent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DEC195091200DD33134801AA /* libPods-NotificationContent.a */; }; /* End PBXBuildFile section */ @@ -82,6 +83,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0E42C5B8A6C5431FB0AB24EF /* templates.json */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = templates.json; path = ../assets/templates.json; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Example/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = Example/AppDelegate.mm; sourceTree = ""; }; @@ -281,6 +283,7 @@ 83CBBA001A601CBA00E9B192 /* Products */, 2D16E6871FA4F8E400B85C8A /* Frameworks */, 7168044AA71FBFBA4A3B8E24 /* Pods */, + FB0CA6791B3E4590ABE326A8 /* Resources */, ); indentWidth = 2; sourceTree = ""; @@ -299,6 +302,15 @@ name = Products; sourceTree = ""; }; + FB0CA6791B3E4590ABE326A8 /* Resources */ = { + isa = PBXGroup; + children = ( + 0E42C5B8A6C5431FB0AB24EF /* templates.json */, + ); + name = Resources; + path = ""; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -461,6 +473,7 @@ 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 685D0A42F74FC38D84284799 /* PrivacyInfo.xcprivacy in Resources */, + AEBABB8DDA82439084117624 /* templates.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1295,7 +1308,10 @@ ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; @@ -1363,7 +1379,10 @@ "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; diff --git a/Example/ios/Example/Info.plist b/Example/ios/Example/Info.plist index f91f7d33..6d90d0e9 100644 --- a/Example/ios/Example/Info.plist +++ b/Example/ios/Example/Info.plist @@ -42,7 +42,7 @@ NSLocationWhenInUseUsageDescription - + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities diff --git a/Example/ios/Example/PrivacyInfo.xcprivacy b/Example/ios/Example/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..bad32761 --- /dev/null +++ b/Example/ios/Example/PrivacyInfo.xcprivacy @@ -0,0 +1,37 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 35F9.1 + + + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/Example/ios/Podfile b/Example/ios/Podfile index 23b33797..7e11d7af 100644 --- a/Example/ios/Podfile +++ b/Example/ios/Podfile @@ -45,23 +45,28 @@ target 'Example' do aggregate_target.user_project.save end end + pod "SDWebImage", :modular_headers => true end target 'NotificationService' do pod_clevertap_ios_sdk pod "CTNotificationService", :modular_headers => true + pod "SDWebImage", :modular_headers => true end target 'NotificationContent' do pod "CTNotificationContent" + pod "SDWebImage", :modular_headers => true end # Added these target for sample code only in Swift target 'NotificationServiceSwift' do pod_clevertap_ios_sdk pod "CTNotificationService", :modular_headers => true + pod "SDWebImage", :modular_headers => true end target 'NotificationContentSwift' do pod "CTNotificationContent" + pod "SDWebImage", :modular_headers => true end diff --git a/Example/package-lock.json b/Example/package-lock.json index 3d4fb608..64701dec 100644 --- a/Example/package-lock.json +++ b/Example/package-lock.json @@ -19,7 +19,7 @@ "react-native-drawer": "^2.5.1", "react-native-gesture-handler": "^1.10.3", "react-native-pager-view": "^5.1.2", - "react-native-reanimated": "^3.15.0", + "react-native-reanimated": "^3.4.0", "react-native-safe-area-context": "^3.2.0", "react-native-screens": "3.31.1", "react-native-svg-transformer": "^1.3.0", @@ -49,8 +49,8 @@ } }, "..": { - "version": "3.2.0", - "extraneous": true, + "name": "clevertap-react-native", + "version": "4.2.0", "license": "MIT", "devDependencies": { "eslint": "^4.18.2", @@ -70,6 +70,7 @@ }, ".yalc/clevertap-react-native": { "version": "3.3.0", + "extraneous": true, "license": "MIT", "peerDependencies": { "react-native": ">=0.65.0" @@ -174,6 +175,7 @@ }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", @@ -434,6 +436,7 @@ }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { "version": "7.25.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8", @@ -448,6 +451,7 @@ }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { "version": "7.25.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8" @@ -461,6 +465,7 @@ }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.25.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8" @@ -474,6 +479,7 @@ }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -489,6 +495,7 @@ }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "version": "7.25.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8", @@ -635,6 +642,7 @@ }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -666,6 +674,7 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" @@ -676,6 +685,7 @@ }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -712,6 +722,7 @@ }, "node_modules/@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" @@ -735,6 +746,7 @@ }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -748,6 +760,7 @@ }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -761,6 +774,7 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -771,6 +785,7 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -867,6 +882,7 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -893,6 +909,7 @@ }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", @@ -920,6 +937,7 @@ }, "node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.25.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8", @@ -951,6 +969,7 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -991,6 +1010,7 @@ }, "node_modules/@babel/plugin-transform-class-static-block": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.24.7", @@ -1051,6 +1071,7 @@ }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.24.7", @@ -1065,6 +1086,7 @@ }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -1078,6 +1100,7 @@ }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { "version": "7.25.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.0", @@ -1092,6 +1115,7 @@ }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1106,6 +1130,7 @@ }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", @@ -1120,6 +1145,7 @@ }, "node_modules/@babel/plugin-transform-export-namespace-from": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1148,6 +1174,7 @@ }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1177,6 +1204,7 @@ }, "node_modules/@babel/plugin-transform-json-strings": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1204,6 +1232,7 @@ }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1218,6 +1247,7 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -1231,6 +1261,7 @@ }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.24.7", @@ -1260,6 +1291,7 @@ }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.25.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.25.0", @@ -1276,6 +1308,7 @@ }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.24.7", @@ -1304,6 +1337,7 @@ }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -1331,6 +1365,7 @@ }, "node_modules/@babel/plugin-transform-numeric-separator": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1345,6 +1380,7 @@ }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.24.7", @@ -1361,6 +1397,7 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1375,6 +1412,7 @@ }, "node_modules/@babel/plugin-transform-optional-catch-binding": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1447,6 +1485,7 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -1516,6 +1555,7 @@ }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7", @@ -1530,6 +1570,7 @@ }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -1614,6 +1655,7 @@ }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.24.8", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8" @@ -1644,6 +1686,7 @@ }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -1657,6 +1700,7 @@ }, "node_modules/@babel/plugin-transform-unicode-property-regex": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.24.7", @@ -1685,6 +1729,7 @@ }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.24.7", @@ -1699,6 +1744,7 @@ }, "node_modules/@babel/preset-env": { "version": "7.25.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.25.2", @@ -1809,6 +1855,7 @@ }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -4548,12 +4595,12 @@ }, "node_modules/@types/prop-types": { "version": "15.7.12", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@types/react": { "version": "18.3.3", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -5628,7 +5675,7 @@ "license": "MIT" }, "node_modules/clevertap-react-native": { - "resolved": ".yalc/clevertap-react-native", + "resolved": "..", "link": true }, "node_modules/cli-cursor": { @@ -6013,18 +6060,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css-tree": { - "version": "1.1.3", - "license": "MIT", - "peer": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/css-what": { "version": "6.1.0", "license": "BSD-2-Clause", @@ -6064,7 +6099,7 @@ }, "node_modules/csstype": { "version": "3.1.3", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/data-view-buffer": { @@ -7242,6 +7277,7 @@ }, "node_modules/esutils": { "version": "2.0.3", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -10598,11 +10634,6 @@ "version": "1.2.5", "license": "Apache-2.0" }, - "node_modules/mdn-data": { - "version": "2.0.14", - "license": "CC0-1.0", - "peer": true - }, "node_modules/memoize-one": { "version": "5.2.1", "license": "MIT" @@ -12020,20 +12051,6 @@ "react-native": "*" } }, - "node_modules/react-native-svg": { - "version": "15.5.0", - "license": "MIT", - "peer": true, - "dependencies": { - "css-select": "^5.1.0", - "css-tree": "^1.1.3", - "warn-once": "0.1.1" - }, - "peerDependencies": { - "react": "*", - "react-native": "*" - } - }, "node_modules/react-native-svg-transformer": { "version": "1.5.0", "license": "MIT", @@ -12307,6 +12324,7 @@ }, "node_modules/regenerator-transform": { "version": "0.15.2", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" @@ -13410,7 +13428,7 @@ }, "node_modules/typescript": { "version": "5.0.4", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/android/build.gradle b/android/build.gradle index 1d4067a6..8d7b409c 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -35,8 +35,8 @@ android { defaultConfig { minSdkVersion 23 targetSdkVersion 36 - versionCode 410 - versionName "4.1.0" + versionCode 420 + versionName "4.2.0" buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()) } @@ -54,7 +54,7 @@ android { } dependencies { - api 'com.clevertap.android:clevertap-android-sdk:8.1.0' + api 'com.clevertap.android:clevertap-android-sdk:8.3.0' implementation 'com.android.installreferrer:installreferrer:2.2' //compile 'com.android.support:appcompat-v7:28.0.0' implementation 'com.facebook.react:react-native:+' diff --git a/android/src/main/java/com/clevertap/react/CleverTapModuleImpl.java b/android/src/main/java/com/clevertap/react/CleverTapModuleImpl.java index 1768c966..8cfe2e43 100644 --- a/android/src/main/java/com/clevertap/react/CleverTapModuleImpl.java +++ b/android/src/main/java/com/clevertap/react/CleverTapModuleImpl.java @@ -25,6 +25,7 @@ import com.clevertap.android.sdk.events.EventDetail; import com.clevertap.android.sdk.featureFlags.CTFeatureFlagsController; import com.clevertap.android.sdk.inapp.CTLocalInApp; +import com.clevertap.android.sdk.FetchInboxCallback; import com.clevertap.android.sdk.inapp.callbacks.FetchInAppsCallback; import com.clevertap.android.sdk.inapp.customtemplates.CustomTemplateContext; import com.clevertap.android.sdk.inbox.CTInboxMessage; @@ -661,6 +662,19 @@ public void pushInboxNotificationViewedEventForId(String messageId) { } } + public void fetchInbox(@Nullable Callback callback) { + CleverTapAPI cleverTap = getCleverTapAPI(); + if (cleverTap == null) { + Log.e(TAG, ErrorMessages.CLEVERTAP_NOT_INITIALIZED); + return; + } + if (callback != null) { + cleverTap.fetchInbox((FetchInboxCallback) success -> callback.invoke(null, success)); + } else { + cleverTap.fetchInbox(); + } + } + public void showInbox(ReadableMap styleConfig) { CTInboxStyleConfig inboxStyleConfig = styleConfigFromReadableMap(styleConfig); CleverTapAPI cleverTap = getCleverTapAPI(); @@ -876,6 +890,16 @@ public void pushDisplayUnitClickedEventForID(String unitID) { } } + public void pushDisplayUnitElementClickedEventForID(String unitID, ReadableMap additionalProperties) { + CleverTapAPI cleverTap = getCleverTapAPI(); + if (cleverTap == null) { + Log.e(TAG, ErrorMessages.CLEVERTAP_NOT_INITIALIZED); + return; + } + HashMap props = eventPropsFromReadableMap(additionalProperties, Object.class); + cleverTap.pushDisplayUnitElementClickedEventForID(unitID, props); + } + public void pushDisplayUnitViewedEventForID(String unitID) { CleverTapAPI cleverTap = getCleverTapAPI(); if (cleverTap != null) { diff --git a/android/src/newarch/CleverTapModule.kt b/android/src/newarch/CleverTapModule.kt index d9521112..3b3d08bb 100644 --- a/android/src/newarch/CleverTapModule.kt +++ b/android/src/newarch/CleverTapModule.kt @@ -253,6 +253,10 @@ class CleverTapModule(reactContext: ReactApplicationContext?) : cleverTapModuleImpl.pushInboxNotificationViewedEventForId(messageId) } + override fun fetchInbox(callback: Callback?) { + cleverTapModuleImpl.fetchInbox(callback) + } + override fun showInbox(styleConfig: ReadableMap?) { cleverTapModuleImpl.showInbox(styleConfig) } @@ -325,6 +329,10 @@ class CleverTapModule(reactContext: ReactApplicationContext?) : cleverTapModuleImpl.pushDisplayUnitClickedEventForID(unitID) } + override fun pushDisplayUnitElementClickedEventForID(unitID: String?, additionalProperties: ReadableMap?) { + cleverTapModuleImpl.pushDisplayUnitElementClickedEventForID(unitID, additionalProperties) + } + override fun pushDisplayUnitViewedEventForID(unitID: String?) { cleverTapModuleImpl.pushDisplayUnitViewedEventForID(unitID) } diff --git a/android/src/oldarch/CleverTapModule.kt b/android/src/oldarch/CleverTapModule.kt index 1afb7165..1bcb13d7 100644 --- a/android/src/oldarch/CleverTapModule.kt +++ b/android/src/oldarch/CleverTapModule.kt @@ -292,6 +292,11 @@ class CleverTapModule(reactContext: ReactApplicationContext?) : cleverTapModuleImpl.pushInboxNotificationViewedEventForId(messageId) } + @ReactMethod + fun fetchInbox(callback: Callback?) { + cleverTapModuleImpl.fetchInbox(callback) + } + @ReactMethod fun showInbox(styleConfig: ReadableMap?) { cleverTapModuleImpl.showInbox(styleConfig) @@ -382,6 +387,11 @@ class CleverTapModule(reactContext: ReactApplicationContext?) : cleverTapModuleImpl.pushDisplayUnitClickedEventForID(unitID) } + @ReactMethod + fun pushDisplayUnitElementClickedEventForID(unitID: String?, additionalProperties: ReadableMap?) { + cleverTapModuleImpl.pushDisplayUnitElementClickedEventForID(unitID, additionalProperties) + } + @ReactMethod fun pushDisplayUnitViewedEventForID(unitID: String?) { cleverTapModuleImpl.pushDisplayUnitViewedEventForID(unitID) diff --git a/clevertap-react-native.podspec b/clevertap-react-native.podspec index a978f2a8..0a57b38d 100644 --- a/clevertap-react-native.podspec +++ b/clevertap-react-native.podspec @@ -24,7 +24,7 @@ Pod::Spec.new do |s| s.dependency 'React-Core' end - s.dependency 'CleverTap-iOS-SDK', '7.6.0' + s.dependency 'CleverTap-iOS-SDK', '7.7.1' if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then s.pod_target_xcconfig = { diff --git a/docs/install.md b/docs/install.md index 9e1cb3e1..9e755348 100644 --- a/docs/install.md +++ b/docs/install.md @@ -86,7 +86,7 @@ dependencies { //clevertap - implementation 'com.clevertap.android:clevertap-android-sdk:8.1.0' + implementation 'com.clevertap.android:clevertap-android-sdk:8.3.0' // other libs diff --git a/docs/usage.md b/docs/usage.md index 372f3439..7ac8406b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -180,6 +180,21 @@ CleverTap.addListener(CleverTap.CleverTapInboxMessageButtonTapped, (event) => {/ CleverTap.dismissInbox(); ``` +#### Fetch Inbox Messages + +*Available from CleverTap React Native SDK v4.2.0.* + +Requests a fresh fetch of App Inbox messages from the server. Calls are throttled to once every 5 minutes; calls within the throttle window silently return without hitting the network. The optional callback receives `true` when messages were successfully fetched and applied to the local cache, or `false` when the fetch was throttled, disabled for the session, or failed due to a network or server error. + +```javascript +CleverTap.fetchInbox((err, success) => { + console.log('Inbox fetch result:', success, err); +}); + +// Fire-and-forget (no callback): +CleverTap.fetchInbox(); +``` + ### Mark read all inbox messages by array of messageIds ```javascript CleverTap.markReadInboxMessagesForIDs(['1', '2', '3']); @@ -343,6 +358,20 @@ CleverTap.getAllDisplayUnits((err, res) => { }); ``` +#### Push Display Unit Element Clicked Event + +*Available from CleverTap React Native SDK v4.2.0.* + +Records a `Notification Clicked` event for a specific interactive element within a Display Unit. Pass the unit's ID and a properties object that includes `wzrk_element_id` (from the element's action metadata) along with any other `wzrk_*` attribution fields. The SDK merges these caller-supplied properties with cached attribution data from the unit before sending the event. + +```javascript +CleverTap.pushDisplayUnitElementClickedEventForID('unit-001', { + wzrk_element_id: 'btn-cta', + wzrk_cta: 'Shop Now', + wzrk_pos: 1 +}); +``` + ----------- ## Product Config diff --git a/ios/CleverTapReact/CleverTapReact.mm b/ios/CleverTapReact/CleverTapReact.mm index 38db39d6..688ca330 100644 --- a/ios/CleverTapReact/CleverTapReact.mm +++ b/ios/CleverTapReact/CleverTapReact.mm @@ -704,6 +704,17 @@ - (NSMutableDictionary *)getVariableValues { [[self cleverTapInstance] dismissAppInbox]; } +RCT_EXPORT_METHOD(fetchInbox:(RCTResponseSenderBlock)callback) { + RCTLogInfo(@"[CleverTap fetchInbox]"); + if (callback == NULL) { + [[self cleverTapInstance] fetchInboxWithCallback:nil]; + } else { + [[self cleverTapInstance] fetchInboxWithCallback:^(BOOL success) { + callback(@[[NSNull null], @(success)]); + }]; + } +} + RCT_EXPORT_METHOD(initializeInbox) { RCTLogInfo(@"[CleverTap Inbox Initialize]"); [[self cleverTapInstance] initializeInboxWithCallback:^(BOOL success) { @@ -856,6 +867,11 @@ - (void)messageDidSelect:(CleverTapInboxMessage *_Nonnull)message atIndex:(int)i [[self cleverTapInstance] recordDisplayUnitClickedEventForID:unitId]; } +RCT_EXPORT_METHOD(pushDisplayUnitElementClickedEventForID:(NSString*)unitId additionalProperties:(NSDictionary*)additionalProperties) { + RCTLogInfo(@"[CleverTap pushDisplayUnitElementClickedEventForID]"); + [[self cleverTapInstance] recordDisplayUnitElementClickedEventForID:unitId additionalProperties:additionalProperties]; +} + # pragma mark - Feature Flag diff --git a/package.json b/package.json index 957e4acd..2ff20286 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clevertap-react-native", - "version": "4.1.0", + "version": "4.2.0", "description": "CleverTap React Native SDK.", "main": "src/index.js", "types": "src/index.d.ts", diff --git a/src/NativeCleverTapModule.ts b/src/NativeCleverTapModule.ts index 3de7ec83..9c4f299e 100644 --- a/src/NativeCleverTapModule.ts +++ b/src/NativeCleverTapModule.ts @@ -177,6 +177,8 @@ export interface Spec extends TurboModule { ): void; pushDisplayUnitViewedEventForID(unitId: string): void; pushDisplayUnitClickedEventForID(unitId: string): void; + pushDisplayUnitElementClickedEventForID(unitId: string, additionalProperties: Object | null): void; + fetchInbox(callback: ((error: Object, result: boolean) => void) | null): void; getFeatureFlag( flag: string, withdefaultValue: boolean, diff --git a/src/index.d.ts b/src/index.d.ts index 75aa3cc1..0cbcab8c 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -588,6 +588,13 @@ export function isPushPermissionGranted(callback: CallbackString): void; */ export function pushInboxNotificationViewedEventForId(messageId: string): void; + /** + * Requests a fresh fetch of App Inbox messages from the server. + * Calls are throttled to once every 5 minutes. + * @param callback optional; called with (null, true) on success or (null, false) on failure/throttle + */ + export function fetchInbox(callback?: Callback): void; + /**************************** * Native Display Methods ****************************/ @@ -612,6 +619,13 @@ export function isPushPermissionGranted(callback: CallbackString): void; */ export function pushDisplayUnitClickedEventForID(unitID: string): void; + /** + * Records a Notification Clicked event for a specific element within a Display Unit. + * @param unitID the Display Unit id + * @param additionalProperties per-click context including wzrk_element_id and other wzrk_* attribution fields + */ + export function pushDisplayUnitElementClickedEventForID(unitID: string, additionalProperties: Record): void; + /******************* * Product Configs ******************/ diff --git a/src/index.js b/src/index.js index d915b754..4c34ca4c 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,7 @@ const EventEmitter = Platform.select({ * @param {int} libVersion - The updated library version. If current version is 1.1.0 then pass as 10100 */ const libName = 'React-Native'; -const libVersion = 40100; +const libVersion = 40200; CleverTapReact.setLibrary(libName,libVersion); function defaultCallback(method, err, res) { @@ -767,6 +767,15 @@ var CleverTap = { CleverTapReact.pushInboxNotificationViewedEventForId(messageId); }, + /** + * Requests a fresh fetch of App Inbox messages from the server. + * Calls are throttled to once every 5 minutes; a call within the throttle window silently returns. + * @param {function(err, res)} callback - optional; invoked with (null, true) on success or (null, false) on failure/throttle. + */ + fetchInbox: function (callback) { + callWithCallback('fetchInbox', null, callback); + }, + /** * Get all display units * @param {function(err, res)} callback that returns a list of json string representation of CleverTapDisplayUnit @@ -800,6 +809,15 @@ var CleverTap = { CleverTapReact.pushDisplayUnitClickedEventForID(unitID); }, + /** + * Records a Notification Clicked event for a specific element within a Display Unit. + * @param {string} unitID - the Display Unit id + * @param {object} additionalProperties - per-click context, including wzrk_element_id and other wzrk_* fields from the action metadata + */ + pushDisplayUnitElementClickedEventForID: function (unitID, additionalProperties) { + CleverTapReact.pushDisplayUnitElementClickedEventForID(unitID, additionalProperties); + }, + /** * @deprecated - Since version 1.1.0 and will be removed in the future versions of this SDK.