react-native-moengage-personalize 1.0.0

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.
Files changed (32) hide show
  1. package/LICENSE.md +12 -0
  2. package/README.md +3 -0
  3. package/ReactNativeMoEngagePersonalize.podspec +30 -0
  4. package/android/build.gradle +69 -0
  5. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  6. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  7. package/android/gradlew +185 -0
  8. package/android/gradlew.bat +89 -0
  9. package/android/src/main/AndroidManifest.xml +1 -0
  10. package/android/src/main/java/com/moengage/react/personalize/MoEngagePersonalizeHandler.kt +104 -0
  11. package/android/src/main/java/com/moengage/react/personalize/MoengagePersonalizePackage.kt +50 -0
  12. package/android/src/newarch/java/com/moengage/react/personalize/MoEReactPersonalize.kt +54 -0
  13. package/android/src/oldarch/java/com/moengage/react/personalize/MoEReactPersonalize.kt +63 -0
  14. package/ios/MoEReactNativePersonalizeHandler.h +26 -0
  15. package/ios/MoEReactNativePersonalizeHandler.m +118 -0
  16. package/ios/MoEngagePersonalizeBridge.h +15 -0
  17. package/ios/MoEngagePersonalizeBridge.mm +46 -0
  18. package/package.json +52 -0
  19. package/src/NativeMoEngagePersonalize.ts +51 -0
  20. package/src/index.ts +164 -0
  21. package/src/internal/Constants.ts +16 -0
  22. package/src/internal/MoEngagePersonalizeHandler.ts +97 -0
  23. package/src/internal/utils/PayloadBuilder.ts +91 -0
  24. package/src/internal/utils/PayloadParser.ts +117 -0
  25. package/src/model/DataSource.ts +12 -0
  26. package/src/model/ExperienceCampaign.ts +47 -0
  27. package/src/model/ExperienceCampaignFailure.ts +28 -0
  28. package/src/model/ExperienceCampaignMeta.ts +34 -0
  29. package/src/model/ExperienceCampaignsMetadata.ts +29 -0
  30. package/src/model/ExperienceCampaignsResult.ts +30 -0
  31. package/src/model/ExperienceFailureReason.ts +36 -0
  32. package/src/model/ExperienceStatus.ts +14 -0
@@ -0,0 +1,63 @@
1
+ /*
2
+ * Copyright (c) 2026 MoEngage, Inc.
3
+ * All rights reserved.
4
+ * Use of source code or binaries contained within MoEngage's SDKs is permitted only to enable use of the MoEngage platform by customers of MoEngage. The Licensee may not:
5
+ * - permit any third party to use the Software;
6
+ * - modify or translate the Software except as otherwise permitted;
7
+ * - reverse engineer, decompile, or disassemble the Software;
8
+ * - copy the Software, except as expressly provided above; or
9
+ * - remove or obscure any proprietary rights notices or labels on the Software.
10
+ * - Licensee may not transfer the Software or any rights under this Agreement without the Licensor's prior written consent.
11
+ * - MoEngage owns the Software and all intellectual property rights embodied therein, including copyrights and valuable trade secrets embodied in the Software. The Licensee shall not alter or remove this copyright notice.
12
+ *
13
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE USER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ */
15
+
16
+ package com.moengage.react.personalize
17
+
18
+ import com.facebook.react.bridge.Promise
19
+ import com.facebook.react.bridge.ReactApplicationContext
20
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
21
+ import com.facebook.react.bridge.ReactMethod
22
+
23
+ /**
24
+ * Bridge to communicate with personalize plugin JS code in old arch.
25
+ */
26
+ class MoEReactPersonalize(
27
+ reactContext: ReactApplicationContext
28
+ ) : ReactContextBaseJavaModule(reactContext) {
29
+
30
+ private val bridgeHandler = MoEngagePersonalizeHandler(reactContext.applicationContext)
31
+
32
+ override fun getName() = bridgeHandler.getName()
33
+
34
+ @ReactMethod
35
+ fun fetchExperiencesMeta(payload: String, promise: Promise) {
36
+ bridgeHandler.fetchExperiencesMeta(payload, promise)
37
+ }
38
+
39
+ @ReactMethod
40
+ fun fetchExperiences(payload: String, promise: Promise) {
41
+ bridgeHandler.fetchExperiences(payload, promise)
42
+ }
43
+
44
+ @ReactMethod
45
+ fun experiencesShown(payload: String) {
46
+ bridgeHandler.trackExperienceShown(payload)
47
+ }
48
+
49
+ @ReactMethod
50
+ fun experienceClicked(payload: String) {
51
+ bridgeHandler.trackExperienceClicked(payload)
52
+ }
53
+
54
+ @ReactMethod
55
+ fun offeringsShown(payload: String) {
56
+ bridgeHandler.trackOfferingShown(payload)
57
+ }
58
+
59
+ @ReactMethod
60
+ fun offeringClicked(payload: String) {
61
+ bridgeHandler.trackOfferingClicked(payload)
62
+ }
63
+ }
@@ -0,0 +1,26 @@
1
+ //
2
+ // MoEReactNativePersonalizeHandler.h
3
+ // ReactNativeMoEngagePersonalize
4
+ //
5
+
6
+ #import <Foundation/Foundation.h>
7
+ #import <UIKit/UIKit.h>
8
+ #import <React/RCTBridgeModule.h>
9
+
10
+ @interface MoEReactNativePersonalizeHandler : NSObject
11
+
12
+ +(instancetype)sharedInstance;
13
+
14
+ // Fetch APIs
15
+ -(void)fetchExperiencesMeta:(NSString *)payload resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
16
+ -(void)fetchExperiences:(NSString *)payload resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
17
+
18
+ // Experience Tracking
19
+ -(void)experiencesShown:(NSString *)payload;
20
+ -(void)experienceClicked:(NSString *)payload;
21
+
22
+ // Offering Tracking
23
+ -(void)offeringsShown:(NSString *)payload;
24
+ -(void)offeringClicked:(NSString *)payload;
25
+
26
+ @end
@@ -0,0 +1,118 @@
1
+ //
2
+ // MoEReactNativePersonalizeHandler.m
3
+ // ReactNativeMoEngagePersonalize
4
+ //
5
+
6
+ #import <Foundation/Foundation.h>
7
+ #import "MoEReactNativePersonalizeHandler.h"
8
+ #import "ReactNativeMoEngage/MoEngageReactUtils.h"
9
+
10
+ @import MoEngagePluginPersonalize;
11
+
12
+ static NSString * const kLogTag = @"[MoEngageReactPersonalize]";
13
+
14
+ @implementation MoEReactNativePersonalizeHandler : NSObject
15
+
16
+ +(instancetype)sharedInstance {
17
+ static dispatch_once_t onceToken;
18
+ static MoEReactNativePersonalizeHandler *instance;
19
+ dispatch_once(&onceToken, ^{
20
+ instance = [[MoEReactNativePersonalizeHandler alloc] init];
21
+ });
22
+ return instance;
23
+ }
24
+
25
+ #pragma mark - Helpers
26
+
27
+ /// Serializes the bridge response and resolves/rejects the JS promise. If the
28
+ /// response carries an `error` key (per the contract), the promise is rejected
29
+ /// with the stringified payload. JSON serialization failures reject with PARSE_ERROR.
30
+ -(void)resolveResponse:(NSDictionary *)response
31
+ resolver:(RCTPromiseResolveBlock)resolve
32
+ rejecter:(RCTPromiseRejectBlock)reject
33
+ method:(NSString *)method {
34
+ NSError *err;
35
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:response options:0 error:&err];
36
+ if (jsonData) {
37
+ NSString *strPayload = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
38
+ if (response[@"error"] != nil) {
39
+ NSLog(@"%@ %@: rejecting with PERSONALIZE_ERROR — %@", kLogTag, method, response[@"error"]);
40
+ reject(@"PERSONALIZE_ERROR", strPayload, nil);
41
+ } else {
42
+ resolve(strPayload);
43
+ }
44
+ } else {
45
+ NSLog(@"%@ %@: failed to serialize response — %@", kLogTag, method, err);
46
+ reject(@"PARSE_ERROR", @"Failed to serialize response", err);
47
+ }
48
+ }
49
+
50
+ /// Logs and parses the incoming JS payload string into an NSDictionary. Returns
51
+ /// nil (and logs) on parse failure so callers can short-circuit safely.
52
+ -(NSDictionary *)parsePayload:(NSString *)payload method:(NSString *)method {
53
+ NSDictionary *jsonPayload = [MoEngageReactUtils getJSONRepresentation:payload];
54
+ if (jsonPayload == nil) {
55
+ NSLog(@"%@ %@: failed to parse payload — input: %@", kLogTag, method, payload);
56
+ }
57
+ return jsonPayload;
58
+ }
59
+
60
+ #pragma mark - Fetch APIs
61
+
62
+ -(void)fetchExperiencesMeta:(NSString *)payload resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
63
+ NSLog(@"%@ fetchExperiencesMeta", kLogTag);
64
+ NSDictionary *jsonPayload = [self parsePayload:payload method:@"fetchExperiencesMeta"];
65
+ if (jsonPayload == nil) {
66
+ reject(@"PARSE_ERROR", @"Failed to parse incoming payload", nil);
67
+ return;
68
+ }
69
+ [[MoEngagePluginPersonalizeBridge sharedInstance] fetchExperiencesMeta:jsonPayload completionHandler:^(NSDictionary<NSString *,id> * _Nonnull response) {
70
+ [self resolveResponse:response resolver:resolve rejecter:reject method:@"fetchExperiencesMeta"];
71
+ }];
72
+ }
73
+
74
+ -(void)fetchExperiences:(NSString *)payload resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
75
+ NSLog(@"%@ fetchExperiences", kLogTag);
76
+ NSDictionary *jsonPayload = [self parsePayload:payload method:@"fetchExperiences"];
77
+ if (jsonPayload == nil) {
78
+ reject(@"PARSE_ERROR", @"Failed to parse incoming payload", nil);
79
+ return;
80
+ }
81
+ [[MoEngagePluginPersonalizeBridge sharedInstance] fetchExperiences:jsonPayload completionHandler:^(NSDictionary<NSString *,id> * _Nonnull response) {
82
+ [self resolveResponse:response resolver:resolve rejecter:reject method:@"fetchExperiences"];
83
+ }];
84
+ }
85
+
86
+ #pragma mark - Experience Tracking
87
+
88
+ -(void)experiencesShown:(NSString *)payload {
89
+ NSLog(@"%@ experiencesShown", kLogTag);
90
+ NSDictionary *jsonPayload = [self parsePayload:payload method:@"experiencesShown"];
91
+ if (jsonPayload == nil) return;
92
+ [[MoEngagePluginPersonalizeBridge sharedInstance] experiencesShown:jsonPayload];
93
+ }
94
+
95
+ -(void)experienceClicked:(NSString *)payload {
96
+ NSLog(@"%@ experienceClicked", kLogTag);
97
+ NSDictionary *jsonPayload = [self parsePayload:payload method:@"experienceClicked"];
98
+ if (jsonPayload == nil) return;
99
+ [[MoEngagePluginPersonalizeBridge sharedInstance] experienceClicked:jsonPayload];
100
+ }
101
+
102
+ #pragma mark - Offering Tracking
103
+
104
+ -(void)offeringsShown:(NSString *)payload {
105
+ NSLog(@"%@ offeringsShown", kLogTag);
106
+ NSDictionary *jsonPayload = [self parsePayload:payload method:@"offeringsShown"];
107
+ if (jsonPayload == nil) return;
108
+ [[MoEngagePluginPersonalizeBridge sharedInstance] offeringsShown:jsonPayload];
109
+ }
110
+
111
+ -(void)offeringClicked:(NSString *)payload {
112
+ NSLog(@"%@ offeringClicked", kLogTag);
113
+ NSDictionary *jsonPayload = [self parsePayload:payload method:@"offeringClicked"];
114
+ if (jsonPayload == nil) return;
115
+ [[MoEngagePluginPersonalizeBridge sharedInstance] offeringClicked:jsonPayload];
116
+ }
117
+
118
+ @end
@@ -0,0 +1,15 @@
1
+ // MoEngagePersonalizeBridge.h
2
+
3
+ #import <React/RCTBridgeModule.h>
4
+
5
+ #ifdef RCT_NEW_ARCH_ENABLED
6
+ #import <NativeMoEngagePersonalizeSpec/NativeMoEngagePersonalizeSpec.h>
7
+ #endif
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+ @interface MoEngagePersonalizeBridge : NSObject <NativeMoEngagePersonalizeSpec>
11
+ @end
12
+ #else
13
+ @interface MoEngagePersonalizeBridge : NSObject <RCTBridgeModule>
14
+ @end
15
+ #endif
@@ -0,0 +1,46 @@
1
+ // MoEngagePersonalizeBridge.mm
2
+
3
+ #import "MoEngagePersonalizeBridge.h"
4
+ #import "MoEReactNativePersonalizeHandler.h"
5
+
6
+ @implementation MoEngagePersonalizeBridge
7
+
8
+ RCT_EXPORT_MODULE()
9
+
10
+ #pragma mark - Fetch APIs
11
+
12
+ RCT_EXPORT_METHOD(fetchExperiencesMeta:(NSString *)payload resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
13
+ [[MoEReactNativePersonalizeHandler sharedInstance] fetchExperiencesMeta:payload resolve:resolve reject:reject];
14
+ }
15
+
16
+ RCT_EXPORT_METHOD(fetchExperiences:(NSString *)payload resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
17
+ [[MoEReactNativePersonalizeHandler sharedInstance] fetchExperiences:payload resolve:resolve reject:reject];
18
+ }
19
+
20
+ #pragma mark - Experience Tracking
21
+
22
+ RCT_EXPORT_METHOD(experiencesShown:(NSString *)payload) {
23
+ [[MoEReactNativePersonalizeHandler sharedInstance] experiencesShown:payload];
24
+ }
25
+
26
+ RCT_EXPORT_METHOD(experienceClicked:(NSString *)payload) {
27
+ [[MoEReactNativePersonalizeHandler sharedInstance] experienceClicked:payload];
28
+ }
29
+
30
+ #pragma mark - Offering Tracking
31
+
32
+ RCT_EXPORT_METHOD(offeringsShown:(NSString *)payload) {
33
+ [[MoEReactNativePersonalizeHandler sharedInstance] offeringsShown:payload];
34
+ }
35
+
36
+ RCT_EXPORT_METHOD(offeringClicked:(NSString *)payload) {
37
+ [[MoEReactNativePersonalizeHandler sharedInstance] offeringClicked:payload];
38
+ }
39
+
40
+ #ifdef RCT_NEW_ARCH_ENABLED
41
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
42
+ return std::make_shared<facebook::react::NativeMoEngagePersonalizeSpecJSI>(params);
43
+ }
44
+ #endif
45
+
46
+ @end
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "react-native-moengage-personalize",
3
+ "version": "1.0.0",
4
+ "description": "Personalize Module for the MoEngage Platform",
5
+ "main": "src/index.ts",
6
+ "files": [
7
+ "android",
8
+ "ios",
9
+ "src",
10
+ "package.json",
11
+ "ReactNativeMoEngagePersonalize.podspec",
12
+ "README.md",
13
+ "!**/__tests__",
14
+ "!**/__mocks__"
15
+ ],
16
+ "scripts": {
17
+ "test": "jest",
18
+ "build": "echo \"Not required\" && exit 0"
19
+ },
20
+ "keywords": [
21
+ "react-native",
22
+ "ios",
23
+ "android",
24
+ "moengage"
25
+ ],
26
+ "repository": "https://github.com/moengage/React-Native",
27
+ "author": {
28
+ "name": "MoEngage",
29
+ "email": "mobiledevs@moengage.com"
30
+ },
31
+ "publishConfig": {
32
+ "registry": "https://registry.npmjs.org/"
33
+ },
34
+ "peerDependencies": {
35
+ "react-native-moengage": "^12.0.0"
36
+ },
37
+ "license": "SEE LICENSE IN LICENSE.md",
38
+ "devDependencies": {
39
+ "@types/jest": "^29.5.0",
40
+ "react-native": "0.73.0",
41
+ "ts-jest": "^29.1.0",
42
+ "typescript": "^4.3.0"
43
+ },
44
+ "codegenConfig": {
45
+ "name": "NativeMoEngagePersonalizeSpec",
46
+ "type": "modules",
47
+ "jsSrcsDir": "src",
48
+ "android": {
49
+ "javaPackageName": "com.moengage.react.personalize"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,51 @@
1
+ import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport';
2
+ import { TurboModuleRegistry } from 'react-native';
3
+
4
+ export interface Spec extends TurboModule {
5
+ /**
6
+ * Fetches experience campaign metadata filtered by status.
7
+ *
8
+ * @param payload Stringified JSON payload.
9
+ * @returns {Promise<string>} A promise that contains experience metadata.
10
+ */
11
+ fetchExperiencesMeta(payload: string): Promise<string>;
12
+
13
+ /**
14
+ * Fetches experience campaigns for the given keys and optional attributes.
15
+ *
16
+ * @param payload Stringified JSON payload.
17
+ * @returns {Promise<string>} A promise that contains experiences and failures.
18
+ */
19
+ fetchExperiences(payload: string): Promise<string>;
20
+
21
+ /**
22
+ * Tracks impression events for one or more experience campaigns.
23
+ *
24
+ * @param payload Stringified JSON payload.
25
+ */
26
+ experiencesShown(payload: string): void;
27
+
28
+ /**
29
+ * Tracks a click event for a single experience campaign.
30
+ *
31
+ * @param payload Stringified JSON payload.
32
+ */
33
+ experienceClicked(payload: string): void;
34
+
35
+ /**
36
+ * Tracks impression events for one or more offerings.
37
+ *
38
+ * @param payload Stringified JSON payload.
39
+ */
40
+ offeringsShown(payload: string): void;
41
+
42
+ /**
43
+ * Tracks a click event for a single offering within an experience campaign.
44
+ *
45
+ * @param payload Stringified JSON payload.
46
+ */
47
+ offeringClicked(payload: string): void;
48
+ }
49
+
50
+ const MoEngagePersonalizeBridge = TurboModuleRegistry.getEnforcing<Spec>('MoEngagePersonalizeBridge');
51
+ export default MoEngagePersonalizeBridge;
package/src/index.ts ADDED
@@ -0,0 +1,164 @@
1
+ import ExperienceCampaign from "./model/ExperienceCampaign";
2
+ import ExperienceCampaignFailure from "./model/ExperienceCampaignFailure";
3
+ import ExperienceCampaignMeta from "./model/ExperienceCampaignMeta";
4
+ import ExperienceCampaignsMetadata from "./model/ExperienceCampaignsMetadata";
5
+ import ExperienceCampaignsResult from "./model/ExperienceCampaignsResult";
6
+ import { DataSource } from "./model/DataSource";
7
+ import { ExperienceStatus } from "./model/ExperienceStatus";
8
+ import { ExperienceFailureReason } from "./model/ExperienceFailureReason";
9
+ import MoEngagePersonalizeHandler from "./internal/MoEngagePersonalizeHandler";
10
+ import { MoEngageLogger } from "react-native-moengage";
11
+ import { MODULE_TAG } from "./internal/Constants";
12
+
13
+ /**
14
+ * Public API for the MoEngage Personalize Experience module. Each instance is
15
+ * scoped to a single MoEngage workspace (app id) — multiple workspaces should
16
+ * each instantiate their own.
17
+ *
18
+ * @author MoEngage
19
+ * @since 1.0.0
20
+ */
21
+ class ReactMoEngagePersonalize {
22
+
23
+ private readonly TAG = `${MODULE_TAG}ReactMoEngagePersonalize`;
24
+
25
+ private handler: MoEngagePersonalizeHandler;
26
+
27
+ /**
28
+ * Construct a personalize instance for the given workspace.
29
+ *
30
+ * @param appId The MoEngage workspace identifier.
31
+ * @since 1.0.0
32
+ */
33
+ constructor(appId: string) {
34
+ MoEngageLogger.debug(`${this.TAG} constructor() : appId=${appId}`);
35
+ this.handler = new MoEngagePersonalizeHandler(appId);
36
+ }
37
+
38
+ /**
39
+ * Fetches experience campaign metadata filtered by status.
40
+ *
41
+ * @param statuses Array of {@link ExperienceStatus} to filter by.
42
+ * @returns Promise resolving to {@link ExperienceCampaignsMetadata}.
43
+ * @throws Rejects on SDK-level failures (SDK not initialized, network error, etc.).
44
+ * @since 1.0.0
45
+ */
46
+ fetchExperiencesMeta(statuses: ExperienceStatus[]): Promise<ExperienceCampaignsMetadata> {
47
+ MoEngageLogger.verbose(`${this.TAG} fetchExperiencesMeta() : `);
48
+ return this.handler.fetchExperiencesMeta(statuses);
49
+ }
50
+
51
+ /**
52
+ * Fetches a single experience campaign for the given key.
53
+ *
54
+ * @param experienceKey The experience key to fetch.
55
+ * @param attributes Optional key-value attributes for personalization.
56
+ * @returns Promise resolving to {@link ExperienceCampaignsResult}.
57
+ * @throws Rejects on SDK-level failures.
58
+ * @since 1.0.0
59
+ */
60
+ fetchExperience(
61
+ experienceKey: string,
62
+ attributes: Record<string, string> = {}
63
+ ): Promise<ExperienceCampaignsResult> {
64
+ MoEngageLogger.verbose(`${this.TAG} fetchExperience() : `);
65
+ return this.fetchExperiences([experienceKey], attributes);
66
+ }
67
+
68
+ /**
69
+ * Fetches experience campaigns for the given keys and optional attributes.
70
+ *
71
+ * @param experienceKeys Array of experience keys to fetch.
72
+ * @param attributes Optional key-value attributes for personalization.
73
+ * @returns Promise resolving to {@link ExperienceCampaignsResult}.
74
+ * @throws Rejects on SDK-level failures.
75
+ * @since 1.0.0
76
+ */
77
+ fetchExperiences(
78
+ experienceKeys: string[],
79
+ attributes: Record<string, string> = {}
80
+ ): Promise<ExperienceCampaignsResult> {
81
+ MoEngageLogger.verbose(`${this.TAG} fetchExperiences() : `);
82
+ return this.handler.fetchExperiences(experienceKeys, attributes);
83
+ }
84
+
85
+ /**
86
+ * Tracks impression events for one or more experience campaigns.
87
+ *
88
+ * @param campaigns Array of {@link ExperienceCampaign} that were shown.
89
+ * @since 1.0.0
90
+ */
91
+ experiencesShown(campaigns: ExperienceCampaign[]): void {
92
+ MoEngageLogger.verbose(`${this.TAG} experiencesShown() : `);
93
+ this.handler.experiencesShown(campaigns);
94
+ }
95
+
96
+ /**
97
+ * Tracks an impression event for a single experience campaign.
98
+ *
99
+ * @param campaign The {@link ExperienceCampaign} that was shown.
100
+ * @since 1.0.0
101
+ */
102
+ experienceShown(campaign: ExperienceCampaign): void {
103
+ MoEngageLogger.verbose(`${this.TAG} experienceShown() : `);
104
+ this.experiencesShown([campaign]);
105
+ }
106
+
107
+ /**
108
+ * Tracks a click event for a single experience campaign.
109
+ *
110
+ * @param campaign The {@link ExperienceCampaign} that was clicked.
111
+ * @since 1.0.0
112
+ */
113
+ experienceClicked(campaign: ExperienceCampaign): void {
114
+ MoEngageLogger.verbose(`${this.TAG} experienceClicked() : `);
115
+ this.handler.experienceClicked(campaign);
116
+ }
117
+
118
+ /**
119
+ * Tracks impression events for one or more offerings.
120
+ *
121
+ * @param offeringPayloads Array of full offering payload dictionaries.
122
+ * @since 1.0.0
123
+ */
124
+ offeringsShown(offeringPayloads: Record<string, any>[]): void {
125
+ MoEngageLogger.verbose(`${this.TAG} offeringsShown() : `);
126
+ this.handler.offeringsShown(offeringPayloads);
127
+ }
128
+
129
+ /**
130
+ * Tracks an impression event for a single offering.
131
+ *
132
+ * @param offeringPayload The full offering payload dictionary that was shown.
133
+ * @since 1.0.0
134
+ */
135
+ offeringShown(offeringPayload: Record<string, any>): void {
136
+ MoEngageLogger.verbose(`${this.TAG} offeringShown() : `);
137
+ this.offeringsShown([offeringPayload]);
138
+ }
139
+
140
+ /**
141
+ * Tracks a click event for a single offering within an experience campaign.
142
+ *
143
+ * @param campaign The {@link ExperienceCampaign} containing the offering.
144
+ * @param offeringPayload The full offering payload dictionary that was clicked.
145
+ * @since 1.0.0
146
+ */
147
+ offeringClicked(campaign: ExperienceCampaign, offeringPayload: Record<string, any>): void {
148
+ MoEngageLogger.verbose(`${this.TAG} offeringClicked() : `);
149
+ this.handler.offeringClicked(campaign, offeringPayload);
150
+ }
151
+ }
152
+
153
+ export {
154
+ ExperienceCampaign,
155
+ ExperienceCampaignFailure,
156
+ ExperienceCampaignMeta,
157
+ ExperienceCampaignsMetadata,
158
+ ExperienceCampaignsResult,
159
+ DataSource,
160
+ ExperienceStatus,
161
+ ExperienceFailureReason,
162
+ };
163
+
164
+ export default ReactMoEngagePersonalize;
@@ -0,0 +1,16 @@
1
+ export const MODULE_TAG = "MoEngageReactPersonalize_"
2
+
3
+ export const keyData = 'data'
4
+
5
+ export const keyStatus = 'status'
6
+
7
+ export const keyExperiences = 'experiences'
8
+ export const keyExperienceKey = 'experienceKey'
9
+ export const keyExperienceName = 'experienceName'
10
+ export const keyPayload = 'payload'
11
+ export const keyExperienceContext = 'experienceContext'
12
+ export const keySource = 'source'
13
+
14
+ export const keyFailures = 'failures'
15
+ export const keyReason = 'reason'
16
+ export const keyExperienceKeys = 'experienceKeys'
@@ -0,0 +1,97 @@
1
+ import MoEngagePersonalizeBridge from "../NativeMoEngagePersonalize";
2
+ import ExperienceCampaign from "../model/ExperienceCampaign";
3
+ import ExperienceCampaignsMetadata from "../model/ExperienceCampaignsMetadata";
4
+ import ExperienceCampaignsResult from "../model/ExperienceCampaignsResult";
5
+ import { ExperienceStatus } from "../model/ExperienceStatus";
6
+ import { MoEngageLogger } from "react-native-moengage";
7
+ import { MODULE_TAG } from "./Constants";
8
+ import * as PayloadBuilder from "./utils/PayloadBuilder";
9
+ import * as Parser from "./utils/PayloadParser";
10
+
11
+ /**
12
+ * Helper class that translates Public Personalize APIs into native bridge calls.
13
+ *
14
+ * @author MoEngage
15
+ * @since 1.0.0
16
+ */
17
+ export default class MoEngagePersonalizeHandler {
18
+
19
+ private TAG = `${MODULE_TAG}MoEngagePersonalizeHandler`;
20
+
21
+ private appId: string;
22
+
23
+ constructor(appId: string) {
24
+ this.appId = appId;
25
+ MoEngageLogger.debug(`${this.TAG} constructor() : initialised for appId=${appId}`);
26
+ }
27
+
28
+ async fetchExperiencesMeta(statuses: ExperienceStatus[]): Promise<ExperienceCampaignsMetadata> {
29
+ try {
30
+ const payload = PayloadBuilder.buildFetchExperiencesMetaPayload(this.appId, statuses);
31
+ MoEngageLogger.verbose(`${this.TAG} fetchExperiencesMeta() : ${payload}`);
32
+ const response = await MoEngagePersonalizeBridge.fetchExperiencesMeta(payload);
33
+ return Parser.parseExperiencesMetadata(response);
34
+ } catch (error) {
35
+ MoEngageLogger.error(`${this.TAG} fetchExperiencesMeta() : `, error);
36
+ throw error;
37
+ }
38
+ }
39
+
40
+ async fetchExperiences(
41
+ experienceKeys: string[],
42
+ attributes: Record<string, string>
43
+ ): Promise<ExperienceCampaignsResult> {
44
+ try {
45
+ const payload = PayloadBuilder.buildFetchExperiencesPayload(this.appId, experienceKeys, attributes);
46
+ MoEngageLogger.verbose(`${this.TAG} fetchExperiences() : ${payload}`);
47
+ const response = await MoEngagePersonalizeBridge.fetchExperiences(payload);
48
+ return Parser.parseExperiencesResult(response);
49
+ } catch (error) {
50
+ MoEngageLogger.error(`${this.TAG} fetchExperiences() : `, error);
51
+ throw error;
52
+ }
53
+ }
54
+
55
+ experiencesShown(campaigns: ExperienceCampaign[]): void {
56
+ try {
57
+ const payload = PayloadBuilder.buildExperiencesShownPayload(this.appId, campaigns);
58
+ MoEngageLogger.verbose(`${this.TAG} experiencesShown() : ${payload}`);
59
+ MoEngagePersonalizeBridge.experiencesShown(payload);
60
+ } catch (error) {
61
+ MoEngageLogger.error(`${this.TAG} experiencesShown() : `, error);
62
+ }
63
+ }
64
+
65
+ experienceClicked(campaign: ExperienceCampaign): void {
66
+ try {
67
+ const payload = PayloadBuilder.buildExperienceClickedPayload(this.appId, campaign);
68
+ MoEngageLogger.verbose(`${this.TAG} experienceClicked() : ${payload}`);
69
+ MoEngagePersonalizeBridge.experienceClicked(payload);
70
+ } catch (error) {
71
+ MoEngageLogger.error(`${this.TAG} experienceClicked() : `, error);
72
+ }
73
+ }
74
+
75
+ offeringsShown(offeringPayloads: Record<string, any>[]): void {
76
+ try {
77
+ const payload = PayloadBuilder.buildOfferingsShownPayload(this.appId, offeringPayloads);
78
+ MoEngageLogger.verbose(`${this.TAG} offeringsShown() : ${payload}`);
79
+ MoEngagePersonalizeBridge.offeringsShown(payload);
80
+ } catch (error) {
81
+ MoEngageLogger.error(`${this.TAG} offeringsShown() : `, error);
82
+ }
83
+ }
84
+
85
+ offeringClicked(
86
+ campaign: ExperienceCampaign,
87
+ offeringPayload: Record<string, any>
88
+ ): void {
89
+ try {
90
+ const payload = PayloadBuilder.buildOfferingClickedPayload(this.appId, campaign, offeringPayload);
91
+ MoEngageLogger.verbose(`${this.TAG} offeringClicked() : ${payload}`);
92
+ MoEngagePersonalizeBridge.offeringClicked(payload);
93
+ } catch (error) {
94
+ MoEngageLogger.error(`${this.TAG} offeringClicked() : `, error);
95
+ }
96
+ }
97
+ }