expo-tiktok-ads-events 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +87 -0
- package/README.md +92 -12
- package/android/build.gradle +9 -0
- package/android/src/main/AndroidManifest.xml +4 -1
- package/android/src/main/java/expo/modules/tiktokadsevents/ExpoTiktokAdsEventsModule.kt +141 -31
- package/package.json +1 -1
- package/android/src/main/java/expo/modules/tiktokadsevents/ExpoTiktokAdsEventsView.kt +0 -30
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
This is an Expo native module that wraps the TikTok Business SDK for both iOS and Android, enabling event tracking for TikTok advertising campaigns in React Native/Expo apps.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Build TypeScript
|
|
13
|
+
npm run build
|
|
14
|
+
|
|
15
|
+
# Clean build artifacts
|
|
16
|
+
npm run clean
|
|
17
|
+
|
|
18
|
+
# Lint code
|
|
19
|
+
npm run lint
|
|
20
|
+
|
|
21
|
+
# Run tests
|
|
22
|
+
npm run test
|
|
23
|
+
|
|
24
|
+
# Prepare for publishing
|
|
25
|
+
npm run prepare
|
|
26
|
+
|
|
27
|
+
# Open iOS project in Xcode
|
|
28
|
+
npm run open:ios
|
|
29
|
+
|
|
30
|
+
# Open Android project in Android Studio
|
|
31
|
+
npm run open:android
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Architecture
|
|
35
|
+
|
|
36
|
+
### Native Module Structure
|
|
37
|
+
|
|
38
|
+
The module exports a native module named `TiktokAdsEvents` (not `ExpoTiktokAdsEvents`). Both platforms must use this exact name.
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
src/
|
|
42
|
+
├── index.ts # Public exports
|
|
43
|
+
└── ExpoTiktokAdsEventsModule.ts # TypeScript interface and helpers
|
|
44
|
+
|
|
45
|
+
ios/
|
|
46
|
+
├── ExpoTiktokAdsEvents.podspec # CocoaPods spec (uses TikTokBusinessSDK)
|
|
47
|
+
└── ExpoTiktokAdsEventsModule.swift # iOS implementation
|
|
48
|
+
|
|
49
|
+
android/
|
|
50
|
+
├── build.gradle # Gradle config (uses JitPack SDK)
|
|
51
|
+
└── src/main/java/expo/modules/tiktokadsevents/
|
|
52
|
+
└── ExpoTiktokAdsEventsModule.kt # Android implementation
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Key Implementation Details
|
|
56
|
+
|
|
57
|
+
- **Module Name**: Must be `TiktokAdsEvents` in both `Name()` definitions
|
|
58
|
+
- **iOS SDK**: `TikTokBusinessSDK` via CocoaPods
|
|
59
|
+
- **Android SDK**: `com.github.tiktok:tiktok-business-android-sdk` via JitPack
|
|
60
|
+
- **Event Properties**: Passed as `List<Map<String, Any>>` (Android) or `[[String: Any]]` (iOS)
|
|
61
|
+
|
|
62
|
+
### TypeScript Interface
|
|
63
|
+
|
|
64
|
+
All native methods are async and must match this interface:
|
|
65
|
+
- `initializeSdk(accessToken, appId, tiktokAppId, debugModeEnabled)` → `Promise<boolean>`
|
|
66
|
+
- `trackTTEvent(name, properties?)` → `Promise<string>`
|
|
67
|
+
- `trackCustomEvent(eventName, eventID, properties?)` → `Promise<void>`
|
|
68
|
+
- `identify(externalId, externalUserName?, phoneNumber?, email?)` → `Promise<void>`
|
|
69
|
+
- `getAnonymousID()` → `Promise<string>`
|
|
70
|
+
- `getAccessToken()` → `Promise<string>`
|
|
71
|
+
- `getTestEventCode()` → `Promise<string>`
|
|
72
|
+
|
|
73
|
+
## Testing in Consumer Apps
|
|
74
|
+
|
|
75
|
+
After making changes, consumer apps need:
|
|
76
|
+
```bash
|
|
77
|
+
npx expo prebuild --clean
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For Android, ensure the app's `android/build.gradle` includes JitPack:
|
|
81
|
+
```groovy
|
|
82
|
+
allprojects {
|
|
83
|
+
repositories {
|
|
84
|
+
maven { url 'https://jitpack.io' }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
package/README.md
CHANGED
|
@@ -10,8 +10,60 @@ npm install expo-tiktok-ads-events
|
|
|
10
10
|
yarn add expo-tiktok-ads-events
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
### Peer Dependencies
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install expo-tracking-transparency
|
|
17
|
+
# or
|
|
18
|
+
yarn add expo-tracking-transparency
|
|
19
|
+
```
|
|
20
|
+
|
|
13
21
|
## Setup
|
|
14
22
|
|
|
23
|
+
### iOS Configuration
|
|
24
|
+
|
|
25
|
+
#### SKAdNetwork Configuration
|
|
26
|
+
|
|
27
|
+
Add the following to your `app.json` to enable proper attribution for TikTok Ads:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"expo": {
|
|
32
|
+
"ios": {
|
|
33
|
+
"infoPlist": {
|
|
34
|
+
"SKAdNetworkItems": [
|
|
35
|
+
{"SKAdNetworkIdentifier": "238da6jt44.skadnetwork"},
|
|
36
|
+
{"SKAdNetworkIdentifier": "22mmun2rn5.skadnetwork"},
|
|
37
|
+
// ... add all required SKAdNetwork IDs
|
|
38
|
+
// Full list available in the example app
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
> **Note:** The complete list of 150+ SKAdNetwork IDs is available in the [example app.json](./example/app.json). These IDs are required for proper attribution of TikTok Ads campaigns.
|
|
47
|
+
|
|
48
|
+
#### Tracking Permission
|
|
49
|
+
|
|
50
|
+
Add to your `app.json`:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"expo": {
|
|
55
|
+
"plugins": [
|
|
56
|
+
[
|
|
57
|
+
"expo-tracking-transparency",
|
|
58
|
+
{
|
|
59
|
+
"userTrackingPermission": "This identifier will be used to deliver personalized ads to you."
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
15
67
|
### Initialization
|
|
16
68
|
|
|
17
69
|
```typescript
|
|
@@ -24,11 +76,13 @@ const { status } = await requestTrackingPermissionsAsync();
|
|
|
24
76
|
// Initialize SDK
|
|
25
77
|
await TiktokAdsEvents.initializeSdk(
|
|
26
78
|
'YOUR_ACCESS_TOKEN', // TikTok Ads Manager access token
|
|
27
|
-
'YOUR_APP_ID', // App ID
|
|
79
|
+
'YOUR_APP_ID', // App ID
|
|
28
80
|
'YOUR_TIKTOK_APP_ID' // TikTok App ID
|
|
29
81
|
);
|
|
30
82
|
```
|
|
31
83
|
|
|
84
|
+
> **Important:** Get your credentials from [TikTok Ads Manager](https://ads.tiktok.com/)
|
|
85
|
+
|
|
32
86
|
## Usage
|
|
33
87
|
|
|
34
88
|
### Standard Events
|
|
@@ -198,15 +252,20 @@ export default function App() {
|
|
|
198
252
|
|
|
199
253
|
### Common Properties
|
|
200
254
|
|
|
201
|
-
- `currency` - Currency code (e.g., "USD", "EUR")
|
|
255
|
+
- `currency` - Currency code (e.g., "USD", "EUR", "BRL")
|
|
202
256
|
- `value` - Monetary value
|
|
203
|
-
- `content_type` - Content type
|
|
204
|
-
- `content_id` - Content ID
|
|
257
|
+
- `content_type` - Content type (e.g., "product", "subscription")
|
|
258
|
+
- `content_id` - Content ID or SKU
|
|
205
259
|
- `content_name` - Content name
|
|
260
|
+
- `content_category` - Content category
|
|
206
261
|
- `quantity` - Quantity
|
|
207
262
|
- `description` - Description
|
|
208
263
|
- `query` - Search query
|
|
209
|
-
- `status` - Status
|
|
264
|
+
- `status` - Status (e.g., "success", "failed")
|
|
265
|
+
- `level` - Level achieved (for gaming apps)
|
|
266
|
+
- `score` - Score value
|
|
267
|
+
- `success` - Success flag (boolean as string: "true"/"false")
|
|
268
|
+
- `payment_method` - Payment method used
|
|
210
269
|
|
|
211
270
|
### TypeScript Types
|
|
212
271
|
|
|
@@ -244,12 +303,16 @@ The SDK is automatically configured with:
|
|
|
244
303
|
- ✅ Retention tracking enabled
|
|
245
304
|
- ✅ SKAdNetwork enabled (iOS)
|
|
246
305
|
- ✅ Debug mode enabled (development)
|
|
306
|
+
- ✅ Install tracking enabled
|
|
307
|
+
- ✅ Auto tracking disabled (manual control)
|
|
247
308
|
|
|
248
|
-
##
|
|
309
|
+
## Requirements
|
|
249
310
|
|
|
250
311
|
- iOS 15.1+
|
|
251
312
|
- Android (in development)
|
|
252
313
|
- Expo SDK 54+
|
|
314
|
+
- TikTok Business SDK
|
|
315
|
+
- expo-tracking-transparency (for iOS 14+)
|
|
253
316
|
|
|
254
317
|
## Troubleshooting
|
|
255
318
|
|
|
@@ -259,6 +322,8 @@ The SDK is automatically configured with:
|
|
|
259
322
|
2. Confirm credentials are correct
|
|
260
323
|
3. Use test mode to validate events
|
|
261
324
|
4. Wait up to 24 hours for production events to appear
|
|
325
|
+
5. Ensure SKAdNetwork IDs are properly configured
|
|
326
|
+
6. Check that the app is running on a real device (not simulator)
|
|
262
327
|
|
|
263
328
|
### Empty Anonymous ID
|
|
264
329
|
|
|
@@ -267,23 +332,31 @@ Anonymous ID is generated after successful initialization. Make sure to call `in
|
|
|
267
332
|
### Initialization Error
|
|
268
333
|
|
|
269
334
|
Check:
|
|
270
|
-
- Valid access token
|
|
271
|
-
- Correct app IDs
|
|
335
|
+
- Valid access token from TikTok Ads Manager
|
|
336
|
+
- Correct app IDs (both App ID and TikTok App ID)
|
|
272
337
|
- Internet connection
|
|
338
|
+
- TikTok Business SDK is properly installed via CocoaPods
|
|
339
|
+
|
|
340
|
+
### SKAdNetwork Attribution Issues
|
|
341
|
+
|
|
342
|
+
- Ensure all required SKAdNetwork IDs are added to `app.json`
|
|
343
|
+
- Run `npx expo prebuild` after adding SKAdNetwork configuration
|
|
344
|
+
- Test on a real device (attribution doesn't work on simulator)
|
|
273
345
|
|
|
274
346
|
## API Reference
|
|
275
347
|
|
|
276
348
|
### Methods
|
|
277
349
|
|
|
278
|
-
#### `initializeSdk(accessToken, appId, tiktokAppId)`
|
|
350
|
+
#### `initializeSdk(accessToken, appId, tiktokAppId, debugMode?)`
|
|
279
351
|
Initialize the TikTok Business SDK.
|
|
280
352
|
|
|
281
353
|
**Parameters:**
|
|
282
354
|
- `accessToken` (string): TikTok Ads Manager access token
|
|
283
355
|
- `appId` (string): Your app ID
|
|
284
356
|
- `tiktokAppId` (string): TikTok app ID
|
|
357
|
+
- `debugMode` (boolean): Enable debug mode (optional, default: true in development)
|
|
285
358
|
|
|
286
|
-
**Returns:** Promise<string>
|
|
359
|
+
**Returns:** Promise<string> - "initialization successful" or error message
|
|
287
360
|
|
|
288
361
|
#### `trackTTEvent(eventName, properties?)`
|
|
289
362
|
Track a standard TikTok event.
|
|
@@ -342,9 +415,16 @@ Bruno Verçosa - [Pixel Logic Apps](https://github.com/Pixel-Logic-Apps)
|
|
|
342
415
|
|
|
343
416
|
Contributions are welcome! Please open an issue or submit a pull request.
|
|
344
417
|
|
|
345
|
-
##
|
|
418
|
+
## Resources
|
|
346
419
|
|
|
420
|
+
### Official Documentation
|
|
347
421
|
- [TikTok for Business](https://business.tiktok.com/)
|
|
348
422
|
- [TikTok Ads Manager](https://ads.tiktok.com/)
|
|
423
|
+
- [TikTok Events Manager](https://ads.tiktok.com/events_manager/)
|
|
349
424
|
- [TikTok Events API](https://business-api.tiktok.com/portal/docs)
|
|
350
|
-
- [
|
|
425
|
+
- [TikTok Business SDK iOS](https://github.com/tiktok/tiktok-business-ios-sdk)
|
|
426
|
+
|
|
427
|
+
### Related
|
|
428
|
+
- [Expo Modules Documentation](https://docs.expo.dev/modules/)
|
|
429
|
+
- [SKAdNetwork Documentation](https://developer.apple.com/documentation/storekit/skadnetwork)
|
|
430
|
+
- [App Tracking Transparency](https://developer.apple.com/documentation/apptrackingtransparency)
|
package/android/build.gradle
CHANGED
|
@@ -9,6 +9,11 @@ applyKotlinExpoModulesCorePlugin()
|
|
|
9
9
|
useCoreDependencies()
|
|
10
10
|
useExpoPublishing()
|
|
11
11
|
|
|
12
|
+
repositories {
|
|
13
|
+
maven { url 'https://jitpack.io' }
|
|
14
|
+
maven { url "https://artifact.bytedance.com/repository/pangle" }
|
|
15
|
+
}
|
|
16
|
+
|
|
12
17
|
// If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
|
|
13
18
|
// The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
|
|
14
19
|
// Most of the time, you may like to manage the Android SDK versions yourself.
|
|
@@ -41,3 +46,7 @@ android {
|
|
|
41
46
|
abortOnError false
|
|
42
47
|
}
|
|
43
48
|
}
|
|
49
|
+
|
|
50
|
+
dependencies {
|
|
51
|
+
implementation 'com.github.tiktok:tiktok-business-android-sdk:1.6.0'
|
|
52
|
+
}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
<manifest>
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
3
|
+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
4
|
+
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
|
|
2
5
|
</manifest>
|
|
@@ -1,50 +1,160 @@
|
|
|
1
1
|
package expo.modules.tiktokadsevents
|
|
2
2
|
|
|
3
|
+
import android.util.Log
|
|
3
4
|
import expo.modules.kotlin.modules.Module
|
|
4
5
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
|
-
import
|
|
6
|
+
import expo.modules.kotlin.Promise
|
|
7
|
+
import com.tiktok.TikTokBusinessSdk
|
|
8
|
+
import com.tiktok.TikTokBusinessSdk.TTConfig
|
|
9
|
+
import com.tiktok.TikTokBusinessSdk.LogLevel
|
|
10
|
+
import org.json.JSONObject
|
|
6
11
|
|
|
7
12
|
class ExpoTiktokAdsEventsModule : Module() {
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
|
|
13
|
+
|
|
14
|
+
// Store accessToken since Android SDK doesn't expose it like iOS
|
|
15
|
+
private var storedAccessToken: String = ""
|
|
16
|
+
|
|
17
|
+
private val standardEventMap = mapOf(
|
|
18
|
+
"achieve_level" to "AchieveLevel",
|
|
19
|
+
"add_payment_info" to "AddPaymentInfo",
|
|
20
|
+
"complete_tutorial" to "CompleteTutorial",
|
|
21
|
+
"create_group" to "CreateGroup",
|
|
22
|
+
"create_role" to "CreateRole",
|
|
23
|
+
"generate_lead" to "GenerateLead",
|
|
24
|
+
"in_app_ad_click" to "InAppADClick",
|
|
25
|
+
"in_app_ad_impr" to "InAppADImpr",
|
|
26
|
+
"install_app" to "InstallApp",
|
|
27
|
+
"join_group" to "JoinGroup",
|
|
28
|
+
"launch_app" to "LaunchAPP",
|
|
29
|
+
"loan_application" to "LoanApplication",
|
|
30
|
+
"loan_approval" to "LoanApproval",
|
|
31
|
+
"loan_disbursal" to "LoanDisbursal",
|
|
32
|
+
"login" to "Login",
|
|
33
|
+
"rate" to "Rate",
|
|
34
|
+
"registration" to "Registration",
|
|
35
|
+
"search" to "Search",
|
|
36
|
+
"spend_credits" to "SpendCredits",
|
|
37
|
+
"start_trial" to "StartTrial",
|
|
38
|
+
"subscribe" to "Subscribe",
|
|
39
|
+
"unlock_achievement" to "UnlockAchievement"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
private fun buildPropertiesJson(properties: List<Map<String, Any>>?): JSONObject? {
|
|
43
|
+
if (properties == null || properties.isEmpty()) return null
|
|
44
|
+
val json = JSONObject()
|
|
45
|
+
properties.forEach { prop ->
|
|
46
|
+
val key = prop["key"] as? String
|
|
47
|
+
val value = prop["value"]
|
|
48
|
+
if (key != null && value != null) {
|
|
49
|
+
json.put(key, value)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return json
|
|
53
|
+
}
|
|
54
|
+
|
|
11
55
|
override fun definition() = ModuleDefinition {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
56
|
+
Name("TiktokAdsEvents")
|
|
57
|
+
|
|
58
|
+
AsyncFunction("initializeSdk") { accessToken: String, appId: String, tiktokAppId: String, debugModeEnabled: Boolean, promise: Promise ->
|
|
59
|
+
try {
|
|
60
|
+
val context = appContext.reactContext ?: throw Exception("React context is null")
|
|
61
|
+
|
|
62
|
+
// Store accessToken for later retrieval
|
|
63
|
+
storedAccessToken = accessToken
|
|
64
|
+
|
|
65
|
+
val configBuilder = TTConfig(context)
|
|
66
|
+
.setAppId(appId)
|
|
67
|
+
.setTTAppId(tiktokAppId)
|
|
68
|
+
|
|
69
|
+
if (debugModeEnabled) {
|
|
70
|
+
configBuilder.setLogLevel(LogLevel.DEBUG)
|
|
71
|
+
configBuilder.openDebugMode()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
TikTokBusinessSdk.initializeSdk(configBuilder)
|
|
75
|
+
promise.resolve(true)
|
|
76
|
+
} catch (e: Exception) {
|
|
77
|
+
Log.e("TiktokAdsEvents", "Error initializing SDK: ${e.message}", e)
|
|
78
|
+
promise.reject("INIT_ERROR", e.message, e)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
AsyncFunction("getAnonymousID") { promise: Promise ->
|
|
83
|
+
try {
|
|
84
|
+
// Android SDK uses getSessionID() as equivalent to iOS anonymousID
|
|
85
|
+
val sessionId = TikTokBusinessSdk.getSessionID() ?: ""
|
|
86
|
+
promise.resolve(sessionId)
|
|
87
|
+
} catch (e: Exception) {
|
|
88
|
+
promise.reject("ERROR", e.message, e)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
16
91
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
92
|
+
AsyncFunction("getAccessToken") { promise: Promise ->
|
|
93
|
+
try {
|
|
94
|
+
// Return the stored accessToken from initialization
|
|
95
|
+
promise.resolve(storedAccessToken)
|
|
96
|
+
} catch (e: Exception) {
|
|
97
|
+
promise.reject("ERROR", e.message, e)
|
|
98
|
+
}
|
|
20
99
|
}
|
|
21
100
|
|
|
22
|
-
|
|
23
|
-
|
|
101
|
+
AsyncFunction("getTestEventCode") { promise: Promise ->
|
|
102
|
+
try {
|
|
103
|
+
val code = TikTokBusinessSdk.getTestEventCode() ?: ""
|
|
104
|
+
promise.resolve(code)
|
|
105
|
+
} catch (e: Exception) {
|
|
106
|
+
promise.reject("ERROR", e.message, e)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
24
109
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
110
|
+
AsyncFunction("trackCustomEvent") { eventName: String, eventID: String, properties: List<Map<String, Any>>?, promise: Promise ->
|
|
111
|
+
try {
|
|
112
|
+
val propsJson = buildPropertiesJson(properties)
|
|
113
|
+
if (propsJson != null) {
|
|
114
|
+
TikTokBusinessSdk.trackEvent(eventName, propsJson)
|
|
115
|
+
} else {
|
|
116
|
+
TikTokBusinessSdk.trackEvent(eventName)
|
|
117
|
+
}
|
|
118
|
+
TikTokBusinessSdk.flush()
|
|
119
|
+
promise.resolve(null)
|
|
120
|
+
} catch (e: Exception) {
|
|
121
|
+
Log.e("TiktokAdsEvents", "Error tracking custom event: ${e.message}", e)
|
|
122
|
+
promise.reject("TRACK_ERROR", e.message, e)
|
|
123
|
+
}
|
|
28
124
|
}
|
|
29
125
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
126
|
+
AsyncFunction("trackTTEvent") { eventKey: String, properties: List<Map<String, Any>>?, promise: Promise ->
|
|
127
|
+
try {
|
|
128
|
+
val resolved = standardEventMap[eventKey] ?: eventKey
|
|
129
|
+
val propsJson = buildPropertiesJson(properties)
|
|
130
|
+
|
|
131
|
+
if (propsJson != null) {
|
|
132
|
+
TikTokBusinessSdk.trackEvent(resolved, propsJson)
|
|
133
|
+
} else {
|
|
134
|
+
TikTokBusinessSdk.trackEvent(resolved)
|
|
135
|
+
}
|
|
136
|
+
TikTokBusinessSdk.flush()
|
|
137
|
+
|
|
138
|
+
promise.resolve(resolved)
|
|
139
|
+
} catch (e: Exception) {
|
|
140
|
+
Log.e("TiktokAdsEvents", "Error tracking event: ${e.message}", e)
|
|
141
|
+
promise.reject("TRACK_ERROR", e.message, e)
|
|
142
|
+
}
|
|
37
143
|
}
|
|
38
144
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
145
|
+
AsyncFunction("identify") { externalId: String, externalUserName: String?, phoneNumber: String?, email: String?, promise: Promise ->
|
|
146
|
+
try {
|
|
147
|
+
TikTokBusinessSdk.identify(
|
|
148
|
+
externalId,
|
|
149
|
+
externalUserName ?: "",
|
|
150
|
+
phoneNumber ?: "",
|
|
151
|
+
email ?: ""
|
|
152
|
+
)
|
|
153
|
+
promise.resolve(null)
|
|
154
|
+
} catch (e: Exception) {
|
|
155
|
+
Log.e("TiktokAdsEvents", "Error identifying user: ${e.message}", e)
|
|
156
|
+
promise.reject("IDENTIFY_ERROR", e.message, e)
|
|
45
157
|
}
|
|
46
|
-
// Defines an event that the view can send to JavaScript.
|
|
47
|
-
Events("onLoad")
|
|
48
158
|
}
|
|
49
159
|
}
|
|
50
160
|
}
|
package/package.json
CHANGED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
package expo.modules.tiktokadsevents
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.webkit.WebView
|
|
5
|
-
import android.webkit.WebViewClient
|
|
6
|
-
import expo.modules.kotlin.AppContext
|
|
7
|
-
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
8
|
-
import expo.modules.kotlin.views.ExpoView
|
|
9
|
-
|
|
10
|
-
class ExpoTiktokAdsEventsView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
|
|
11
|
-
// Creates and initializes an event dispatcher for the `onLoad` event.
|
|
12
|
-
// The name of the event is inferred from the value and needs to match the event name defined in the module.
|
|
13
|
-
private val onLoad by EventDispatcher()
|
|
14
|
-
|
|
15
|
-
// Defines a WebView that will be used as the root subview.
|
|
16
|
-
internal val webView = WebView(context).apply {
|
|
17
|
-
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
18
|
-
webViewClient = object : WebViewClient() {
|
|
19
|
-
override fun onPageFinished(view: WebView, url: String) {
|
|
20
|
-
// Sends an event to JavaScript. Triggers a callback defined on the view component in JavaScript.
|
|
21
|
-
onLoad(mapOf("url" to url))
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
init {
|
|
27
|
-
// Adds the WebView to the view hierarchy.
|
|
28
|
-
addView(webView)
|
|
29
|
-
}
|
|
30
|
-
}
|