@inngageregistry/inngage-react 3.3.1 → 4.0.0-alpha.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inngageregistry/inngage-react",
3
- "version": "3.3.1",
3
+ "version": "4.0.0-alpha.2",
4
4
  "description": "Inngage Plugin for React Native applications for marketing campaign optimization using Push Notification.",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.d.ts",
package/src/Inngage.ts CHANGED
@@ -3,62 +3,62 @@ import DeviceInfo from "react-native-device-info";
3
3
  import * as RNLocalize from "react-native-localize";
4
4
  import AsyncStorage from '@react-native-async-storage/async-storage';
5
5
 
6
- import { addUserDataRequest, eventRequest, formatDate, subscriptionRequestAdapter } from "./utils";
7
- import notificationsListener, { notificationsListenerProps } from "./notificationsListener";
8
- import { subscriptionApi, eventsApi, addUserDataApi } from "./services/inngage";
6
+ import { formatDate } from "./utils";
7
+ import { InngageNotificationMessage } from "./firebase/notifications_listener";
9
8
  import { InngageProperties } from './models/inngage_properties';
10
9
 
11
10
  import RNPermissions, { NotificationOption, RESULTS } from 'react-native-permissions';
12
11
 
12
+ import ApiService from './services/api_service';
13
+
14
+ import {
15
+ SUBSCRIBE_REQUEST,
16
+ EVENT_REQUEST,
17
+ USER_DATA_REQUEST,
18
+ } from './models/requests';
19
+
20
+ const API_LEVEL_33 = 33;
21
+
13
22
  // --- Get Firebase Access ------/
14
- const getFirebaseAccess = async (): Promise<string | null> => {
15
- try {
16
- return await handleNotificationsPermission();
17
- } catch (error) {
18
- console.error('Erro no getFirebaseAccess: ', error);
19
- throw error;
20
- }
23
+ const getFirebaseAccess = async () => {
24
+ return await handleNotificationsPermission();
21
25
  };
22
26
 
23
27
  const handleNotificationsPermission = async () => {
24
- try {
25
- const options: NotificationOption[] = ['alert', 'badge', 'sound'];
26
- const apiLevel = await DeviceInfo.getApiLevel();
27
- const isPermissionGranted =
28
- apiLevel >= 33
29
- ? ((await RNPermissions.requestNotifications(options)).status) === RESULTS.GRANTED
30
- : (await firebase.messaging().requestPermission()) ===
31
- firebase.messaging.AuthorizationStatus.AUTHORIZED ||
32
- firebase.messaging.AuthorizationStatus.PROVISIONAL;
33
-
34
- return isPermissionGranted ? await getFirebaseToken() : null;
35
- } catch (error) {
36
- console.error(error);
37
- throw error;
28
+ const options: NotificationOption[] = ['alert', 'badge', 'sound'];
29
+ const apiLevel = await DeviceInfo.getApiLevel();
30
+
31
+ const permissionGranted =
32
+ apiLevel >= API_LEVEL_33
33
+ ? (await RNPermissions.requestNotifications(options)).status === RESULTS.GRANTED
34
+ : (await firebase.messaging().requestPermission()) ===
35
+ firebase.messaging.AuthorizationStatus.AUTHORIZED ||
36
+ firebase.messaging.AuthorizationStatus.PROVISIONAL;
37
+
38
+ if (permissionGranted) {
39
+ return await getFirebaseToken();
38
40
  }
41
+
42
+ throw new Error('Notification permission not granted');
39
43
  };
40
44
 
41
- const getFirebaseToken = async (): Promise<string | null> => {
42
- try {
43
- let fcmToken = await AsyncStorage.getItem('fcmToken');
45
+ const getFirebaseToken = async () => {
46
+ let fcmToken = await AsyncStorage.getItem('fcmToken');
44
47
 
45
- if (!fcmToken) {
46
- if (!firebase.messaging().isDeviceRegisteredForRemoteMessages) {
47
- await firebase.messaging().registerDeviceForRemoteMessages?.();
48
- }
48
+ if (!fcmToken) {
49
+ if (!firebase.messaging().isDeviceRegisteredForRemoteMessages) {
50
+ await firebase.messaging().registerDeviceForRemoteMessages?.();
51
+ }
49
52
 
50
- const newFcmToken = await firebase.messaging().getToken?.();
53
+ const newFcmToken = await firebase.messaging().getToken?.();
51
54
 
52
- if (newFcmToken) {
53
- await AsyncStorage.setItem('fcmToken', newFcmToken);
54
- return newFcmToken;
55
- }
55
+ if (newFcmToken) {
56
+ await AsyncStorage.setItem('fcmToken', newFcmToken);
57
+ return newFcmToken;
56
58
  }
57
- return fcmToken || null;
58
- } catch (error) {
59
- console.error(error);
60
- throw error;
61
59
  }
60
+
61
+ return fcmToken || null;
62
62
  };
63
63
 
64
64
  interface SubscriptionProps {
@@ -83,126 +83,121 @@ interface SendEventProps {
83
83
  eventValues?: any
84
84
  }
85
85
 
86
- const Inngage = {
87
- // ------------ Register Notification Listener ------------//
88
- RegisterNotificationListener: async (props: notificationsListenerProps) => {
86
+ class Inngage {
87
+ private static instance: Inngage;
88
+ private apiService: ApiService;
89
+
90
+ constructor() {
91
+ this.apiService = new ApiService();
92
+ }
93
+
94
+ static getInstance(): Inngage {
95
+ if (!Inngage.instance) {
96
+ Inngage.instance = new Inngage();
97
+ }
98
+
99
+ return Inngage.instance;
100
+ }
101
+
102
+ static async notificationListener(firebaseListenCallback?: any) {
89
103
  try {
90
- await notificationsListener({ ...props });
104
+ InngageNotificationMessage(firebaseListenCallback)
91
105
  } catch (e) {
92
- console.error(e);
93
- return { subscribed: false };
106
+ console.log(e)
94
107
  }
95
- },
108
+ }
96
109
 
97
- Subscribe: async ({
110
+ static async subscribe({
98
111
  appToken,
99
- dev,
100
112
  friendlyIdentifier,
101
113
  customFields,
102
- customData,
103
114
  phoneNumber,
104
115
  email,
105
- }: SubscriptionProps) => {
116
+ }: SubscriptionProps) {
117
+ const inngage = Inngage.getInstance();
118
+
106
119
  InngageProperties.appToken = appToken;
107
120
  InngageProperties.identifier = friendlyIdentifier!;
108
121
 
109
- try {
110
- const respToken = await getFirebaseAccess()
111
-
112
- const locales = RNLocalize.getLocales();
113
-
114
- const os_locale = locales ? locales[0].countryCode : ''
115
- const os_language = locales && locales.length ? locales[0].languageCode : ''
116
- const device_manufacturer = await DeviceInfo.getManufacturer();
117
- const installTime = await DeviceInfo.getFirstInstallTime();
118
- const lastUpdateTime = await DeviceInfo.getLastUpdateTime();
119
- const uuid = await DeviceInfo.getUniqueId();
120
- const app_installed_in = formatDate(installTime);
121
- const app_updated_in = formatDate(lastUpdateTime);
122
-
123
- const rawRequest = {
124
- registerSubscriberRequest: {
125
- app_token: appToken,
126
- identifier: friendlyIdentifier,
127
- registration: respToken,
128
- platform: DeviceInfo.getSystemName(),
129
- sdk: DeviceInfo.getBuildNumber(),
130
- device_model: DeviceInfo.getModel(),
131
- device_manufacturer,
132
- os_locale,
133
- os_language,
134
- os_version: DeviceInfo.getReadableVersion(),
135
- app_version: DeviceInfo.getBuildNumber(),
136
- app_installed_in,
137
- app_updated_in,
138
- uuid,
139
- phone_Number: phoneNumber,
140
- email: email,
141
- }
142
- };
143
-
144
- const request = subscriptionRequestAdapter(rawRequest, customData, customFields)
145
- const subscribe = await subscriptionApi(request, dev);
146
- return subscribe;
147
- } catch (e) {
148
- console.error(e);
149
- return { subscribed: false };
122
+ const respToken = await getFirebaseAccess();
123
+
124
+ const { countryCode: osLocale, languageCode: osLanguage } = RNLocalize.getLocales()[0] || {};
125
+ const deviceManufacturer = await DeviceInfo.getManufacturer();
126
+ const installTime = await DeviceInfo.getFirstInstallTime();
127
+ const lastUpdateTime = await DeviceInfo.getLastUpdateTime();
128
+ const uuid = await DeviceInfo.getUniqueId();
129
+ const appInstalledIn = formatDate(installTime);
130
+ const appUpdatedIn = formatDate(lastUpdateTime);
131
+
132
+ const subscription = {
133
+ registerSubscriberRequest: {
134
+ app_token: appToken,
135
+ identifier: friendlyIdentifier,
136
+ registration: respToken,
137
+ platform: DeviceInfo.getSystemName(),
138
+ sdk: DeviceInfo.getBuildNumber(),
139
+ deviceModel: DeviceInfo.getModel(),
140
+ deviceManufacturer,
141
+ osLocale,
142
+ osLanguage,
143
+ os_version: DeviceInfo.getReadableVersion(),
144
+ app_version: DeviceInfo.getBuildNumber(),
145
+ appInstalledIn,
146
+ appUpdatedIn,
147
+ uuid,
148
+ phone_Number: phoneNumber,
149
+ email: email,
150
+ customFields: customFields,
151
+ }
150
152
  }
151
- },
152
153
 
153
- SendEvent: async ({
154
- appToken,
154
+ return inngage.apiService.subscribe(subscription);
155
+ }
156
+
157
+ static async sendEvent({
155
158
  eventName,
156
- identifier,
157
- registration,
158
159
  conversionEvent,
159
160
  conversionValue,
160
161
  conversionNotId,
161
162
  eventValues,
162
- }: SendEventProps) => {
163
+ }: SendEventProps) {
164
+ const inngage = Inngage.getInstance();
165
+
166
+ const registration = await getFirebaseAccess();
163
167
 
164
- const rawRequest = {
168
+ const request = {
165
169
  newEventRequest: {
166
- app_token: appToken,
167
- identifier: identifier,
168
- registration: registration,
169
- event_name: eventName,
170
- conversion_event: conversionEvent ?? false,
171
- conversion_value: conversionValue ?? 0,
172
- conversion_notid: conversionNotId ?? '',
173
- event_values: eventValues ?? {}
174
- }
170
+ appToken: InngageProperties.appToken,
171
+ identifier: InngageProperties.identifier,
172
+ registration,
173
+ eventName,
174
+ conversionEvent: !!conversionEvent,
175
+ conversionValue,
176
+ conversionNotId,
177
+ eventValues,
178
+ },
175
179
  };
176
180
 
177
- const request = eventRequest(rawRequest)
178
- try {
179
- return await eventsApi(request);
180
- } catch (e) {
181
- console.error(e)
182
- return { subscribed: false };
183
- }
184
- },
181
+ return inngage.apiService.sendEvent(request);
182
+ }
183
+
184
+ static async addUserData(customFields: any): Promise<any> {
185
+ const inngage = Inngage.getInstance();
185
186
 
186
- async addUserData(customFields: any): Promise<any> {
187
- const rawRequest = {
187
+ const request = {
188
188
  fieldsRequest: {
189
- app_token: InngageProperties.appToken,
189
+ appToken: InngageProperties.appToken,
190
190
  identifier: InngageProperties.identifier,
191
- custom_field: customFields ?? {}
192
- }
191
+ customField: customFields,
192
+ },
193
193
  };
194
194
 
195
- const request = addUserDataRequest(rawRequest);
196
- try {
197
- return await addUserDataApi(request);
198
- } catch (e) {
199
- console.error(e);
200
- }
201
- },
195
+ return inngage.apiService.addUserData(request);
196
+ }
202
197
 
203
- setDebugMode(value: boolean) {
204
- InngageProperties.debugMode = value
198
+ static setDebugMode(value: boolean) {
199
+ InngageProperties.debugMode = value;
205
200
  }
206
201
  }
207
202
 
208
- export default Inngage;
203
+ export default Inngage;
package/src/api/api.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { fetchClient } from './handler'
2
+
3
+ const apiEndpoints = {
4
+ subscription: '/subscription/',
5
+ notification: '/notification/',
6
+ events: '/events/newEvent/',
7
+ addUserData: '/subscription/addCustomField',
8
+ };
9
+
10
+ const makeApiCall = (method: string, request: any, endpoint: string) => {
11
+ return fetchClient(method, request, endpoint);
12
+ };
13
+
14
+ export const subscriptionApi = (request: any) => {
15
+ return makeApiCall('POST', request, apiEndpoints.subscription);
16
+ };
17
+
18
+ export const notificationApi = (request: any) => {
19
+ return makeApiCall('POST', request, apiEndpoints.notification);
20
+ };
21
+
22
+ export const eventsApi = (request: any) => {
23
+ return makeApiCall('POST', request, apiEndpoints.events);
24
+ };
25
+
26
+ export const addUserDataApi = (request: any) => {
27
+ return makeApiCall('POST', request, apiEndpoints.addUserData);
28
+ };
@@ -30,12 +30,24 @@ const requestConfigFactory = (method, request) => {
30
30
  return objToSend
31
31
  }
32
32
 
33
- export const fetchClient = (method, requestBody, path, isDev = false): Promise<Response> => {
34
- return new Promise((resolve) => {
35
- const url = String(baseUrlHook[isDev as any]).concat(path)
36
- const request = requestConfigFactory(method, requestBody)
37
- fetch(url, request)
38
- .then(resolve)
39
- .catch(err => console.error('Fetch Error', err))
40
- })
41
- }
33
+ export const fetchClient = async (
34
+ method: string,
35
+ requestBody: any,
36
+ path: string,
37
+ isDev = false
38
+ ): Promise<Response> => {
39
+ try {
40
+ const url: URL = new URL(`${baseUrlHook[isDev as any]}${path}`);
41
+ const request: RequestInit = requestConfigFactory(method, requestBody);
42
+ const response: Response = await fetch(url, request);
43
+
44
+ if (!response.ok) {
45
+ throw new Error(`Network response was not ok (${response.status})`);
46
+ }
47
+
48
+ return response;
49
+ } catch (error: any) {
50
+ console.error('Fetch Error:', error.message);
51
+ throw error;
52
+ }
53
+ };
@@ -0,0 +1,102 @@
1
+ import * as React from "react";
2
+ import {
3
+ View,
4
+ Text,
5
+ TouchableOpacity,
6
+ ImageBackground,
7
+ } from "react-native";
8
+
9
+ import AsyncStorage from "@react-native-async-storage/async-storage";
10
+
11
+ import { buildStyles } from "./styles";
12
+ import { Modal } from "../components/modal";
13
+
14
+ interface InAppData {
15
+ inapp_message: boolean
16
+ title: string
17
+ body: string
18
+ title_font_color: string
19
+ body_font_color: string
20
+ background_color: string
21
+ btn_left_txt_color: string
22
+ btn_left_bg_color: string
23
+ btn_right_txt_color: string
24
+ btn_right_bg_color: string
25
+ background_image: string
26
+ btn_left_text: string
27
+ btn_left_action_type: string
28
+ btn_left_action_link: string
29
+ btn_right_text: string
30
+ btn_right_action_type: string
31
+ btn_right_action_link: string
32
+ rick_content: string
33
+ inpression: string
34
+ bg_img_action_type: string
35
+ bg_img_action_link: string
36
+ dot_color: string
37
+ }
38
+
39
+ export function InAppContainer(): JSX.Element {
40
+ const [data, setData] = React.useState<InAppData>();
41
+ const [visible, setVisible] = React.useState(false);
42
+
43
+ React.useEffect(() => {
44
+ const fetchAdditionalData = async () => {
45
+ try {
46
+ const data = await AsyncStorage.getItem('inapp');
47
+ if (data) {
48
+ const parsedData = JSON.parse(data);
49
+
50
+ setVisible(true);
51
+ setData(parsedData);
52
+ }
53
+ } catch (error) {
54
+ console.error('Error retrieving additionalData from AsyncStorage:', error);
55
+ }
56
+ };
57
+
58
+ fetchAdditionalData();
59
+ }, []);
60
+
61
+ const styles = buildStyles(data);
62
+
63
+ const handleDismissInApp = async () => {
64
+ await AsyncStorage.removeItem('inapp');
65
+ setVisible(false);
66
+ }
67
+
68
+ if (data != null)
69
+ console.log('data in app', data)
70
+
71
+ return (
72
+ <Modal
73
+ renderToHardwareTextureAndroid={true}
74
+ transparent={true}
75
+ visible={visible}>
76
+ <ImageBackground style={styles.content} source={{ uri: data?.background_image }}>
77
+ <TouchableOpacity style={styles.closeButton} onPress={handleDismissInApp}>
78
+ <Text>X</Text>
79
+ </TouchableOpacity>
80
+ <View style={styles.messageData}>
81
+ <Text style={styles.title}>{data?.title}</Text>
82
+ <Text style={styles.body}>{data?.body}</Text>
83
+ </View>
84
+ <View style={styles.footer}>
85
+ <TouchableOpacity
86
+ style={styles.buttonLeft}>
87
+ <Text style={styles.textButton}>{data?.btn_left_text}</Text>
88
+ </TouchableOpacity>
89
+ <TouchableOpacity
90
+ style={styles.buttonRight}>
91
+ <Text style={styles.textButton}>{data?.btn_right_text}</Text>
92
+ </TouchableOpacity>
93
+ </View>
94
+ </ImageBackground>
95
+ </Modal>
96
+ )
97
+ }
98
+
99
+
100
+
101
+
102
+