gomarketme-react-native 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.
- package/.editorconfig +15 -0
- package/.gitattributes +3 -0
- package/.github/actions/setup/action.yml +27 -0
- package/.github/workflows/ci.yml +157 -0
- package/.nvmrc +1 -0
- package/.watchmanconfig +1 -0
- package/.yarn/releases/yarn-4.3.1-git.20240705.hash-35167b2.cjs +894 -0
- package/.yarnrc.yml +5 -0
- package/README.md +8 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +460 -0
- package/lefthook.yml +35 -0
- package/package.json +34 -0
- package/src/index.tsx +234 -0
- package/tsconfig.json +19 -0
package/src/index.tsx
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { Platform, Dimensions, PixelRatio } from 'react-native';
|
|
2
|
+
import DeviceInfo from 'react-native-device-info';
|
|
3
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
4
|
+
import InAppPurchase, { Purchase, Product, ProductPurchase } from 'react-native-iap';
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
|
|
7
|
+
class GoMarketMe {
|
|
8
|
+
private static instance: GoMarketMe;
|
|
9
|
+
private sdkInitializedKey = 'GOMARKETME_SDK_INITIALIZED';
|
|
10
|
+
private affiliateCampaignCode = '';
|
|
11
|
+
private deviceId = '';
|
|
12
|
+
private sdkInitializationUrl = 'https://api.gomarketme.net/v1/sdk-initialization';
|
|
13
|
+
private systemInfoUrl = 'https://api.gomarketme.net/v1/mobile/system-info';
|
|
14
|
+
private eventUrl = 'https://api.gomarketme.net/v1/event';
|
|
15
|
+
|
|
16
|
+
private constructor() {}
|
|
17
|
+
|
|
18
|
+
public static getInstance(): GoMarketMe {
|
|
19
|
+
if (!GoMarketMe.instance) {
|
|
20
|
+
GoMarketMe.instance = new GoMarketMe();
|
|
21
|
+
}
|
|
22
|
+
return GoMarketMe.instance;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public async initialize(apiKey: string): Promise<void> {
|
|
26
|
+
try {
|
|
27
|
+
const isSDKInitialized = await this.isSDKInitialized();
|
|
28
|
+
if (!isSDKInitialized) {
|
|
29
|
+
await this.postSDKInitialization(apiKey);
|
|
30
|
+
}
|
|
31
|
+
const systemInfo = await this.getSystemInfo();
|
|
32
|
+
await this.postSystemInfo(systemInfo, apiKey);
|
|
33
|
+
await this.addListener(apiKey);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
console.error('Error initializing GoMarketMe:', e);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private async addListener(apiKey: string): Promise<void> {
|
|
40
|
+
InAppPurchase.purchaseUpdatedListener(async (purchase: Purchase) => {
|
|
41
|
+
if (this.affiliateCampaignCode) {
|
|
42
|
+
const productIds = await this.fetchPurchases([purchase], apiKey);
|
|
43
|
+
await this.fetchPurchaseProducts(productIds, apiKey);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private async getSystemInfo(): Promise<any> {
|
|
49
|
+
const deviceData = Platform.select({
|
|
50
|
+
ios: await this.readIosDeviceInfo(),
|
|
51
|
+
android: await this.readAndroidDeviceInfo(),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const windowData = {
|
|
55
|
+
devicePixelRatio: PixelRatio.get(),
|
|
56
|
+
width: Dimensions.get('window').width,
|
|
57
|
+
height: Dimensions.get('window').height,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
device_info: deviceData,
|
|
62
|
+
window_info: windowData,
|
|
63
|
+
time_zone_code: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
64
|
+
language_code: DeviceInfo.getDeviceId(),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private async postSDKInitialization(apiKey: string): Promise<void> {
|
|
69
|
+
try {
|
|
70
|
+
const response = await axios.post(this.sdkInitializationUrl, {}, {
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
'x-api-key': apiKey,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
if (response.status === 200) {
|
|
77
|
+
await this.markSDKAsInitialized();
|
|
78
|
+
} else {
|
|
79
|
+
console.error('Failed to mark SDK as Initialized. Status code:', response.status);
|
|
80
|
+
}
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.error('Error sending SDK information to server:', e);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private async postSystemInfo(systemInfo: any, apiKey: string): Promise<void> {
|
|
87
|
+
try {
|
|
88
|
+
const response = await axios.post(this.systemInfoUrl, systemInfo, {
|
|
89
|
+
headers: {
|
|
90
|
+
'Content-Type': 'application/json',
|
|
91
|
+
'x-api-key': apiKey,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
if (response.status === 200) {
|
|
95
|
+
const responseData = response.data;
|
|
96
|
+
if (responseData.affiliate_campaign_code) {
|
|
97
|
+
this.affiliateCampaignCode = responseData.affiliate_campaign_code;
|
|
98
|
+
}
|
|
99
|
+
if (responseData.device_id) {
|
|
100
|
+
this.deviceId = responseData.device_id;
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
console.error('Failed to send system info. Status code:', response.status);
|
|
104
|
+
}
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.error('Error sending system info to server:', e);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private async readAndroidDeviceInfo(): Promise<any> {
|
|
111
|
+
return {
|
|
112
|
+
deviceId: await DeviceInfo.getDeviceId(),
|
|
113
|
+
systemName: await DeviceInfo.getSystemName(),
|
|
114
|
+
systemVersion: await DeviceInfo.getSystemVersion(),
|
|
115
|
+
brand: await DeviceInfo.getBrand(),
|
|
116
|
+
model: await DeviceInfo.getModel(),
|
|
117
|
+
manufacturer: await DeviceInfo.getManufacturer(),
|
|
118
|
+
isEmulator: await DeviceInfo.isEmulator(),
|
|
119
|
+
uniqueId: await DeviceInfo.getUniqueId(),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private async readIosDeviceInfo(): Promise<any> {
|
|
124
|
+
return {
|
|
125
|
+
deviceId: await DeviceInfo.getDeviceId(),
|
|
126
|
+
systemName: await DeviceInfo.getSystemName(),
|
|
127
|
+
systemVersion: await DeviceInfo.getSystemVersion(),
|
|
128
|
+
brand: await DeviceInfo.getBrand(),
|
|
129
|
+
model: await DeviceInfo.getModel(),
|
|
130
|
+
manufacturer: await DeviceInfo.getManufacturer(),
|
|
131
|
+
isEmulator: await DeviceInfo.isEmulator(),
|
|
132
|
+
uniqueId: await DeviceInfo.getUniqueId(),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private async fetchPurchases(purchaseDetailsList: Purchase[], apiKey: string): Promise<string[]> {
|
|
137
|
+
const productIds: string[] = [];
|
|
138
|
+
for (const purchase of purchaseDetailsList) {
|
|
139
|
+
if (purchase.transactionReceipt) {
|
|
140
|
+
await this.sendEventToServer(JSON.stringify(this.serializePurchaseDetails(purchase)), 'purchase', apiKey);
|
|
141
|
+
if (purchase.productId && !productIds.includes(purchase.productId)) {
|
|
142
|
+
productIds.push(purchase.productId);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return productIds;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private async fetchPurchaseProducts(productIds: string[], apiKey: string): Promise<void> {
|
|
150
|
+
try {
|
|
151
|
+
const products = await InAppPurchase.getProducts(productIds);
|
|
152
|
+
if (products.length > 0) {
|
|
153
|
+
for (const product of products) {
|
|
154
|
+
await this.sendEventToServer(JSON.stringify(this.serializeProductDetails(product)), 'product', apiKey);
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
await this.sendEventToServer(JSON.stringify({ notFoundIDs: productIds.join(',') }), 'product', apiKey);
|
|
158
|
+
}
|
|
159
|
+
} catch (e) {
|
|
160
|
+
console.error('Error fetching products:', e);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private async sendEventToServer(body: string, eventType: string, apiKey: string): Promise<void> {
|
|
165
|
+
try {
|
|
166
|
+
const response = await axios.post(this.eventUrl, body, {
|
|
167
|
+
headers: {
|
|
168
|
+
'Content-Type': 'application/json',
|
|
169
|
+
'x-affiliate-campaign-code': this.affiliateCampaignCode,
|
|
170
|
+
'x-device-id': this.deviceId,
|
|
171
|
+
'x-event-type': eventType,
|
|
172
|
+
'x-product-type': Platform.OS,
|
|
173
|
+
'x-source-name': Platform.OS === 'android' ? 'google_play' : 'app_store',
|
|
174
|
+
'x-api-key': apiKey,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
if (response.status === 200) {
|
|
178
|
+
console.log(`${eventType} sent successfully`);
|
|
179
|
+
} else {
|
|
180
|
+
console.error(`Failed to send ${eventType}. Status code:`, response.status);
|
|
181
|
+
}
|
|
182
|
+
} catch (e) {
|
|
183
|
+
console.error(`Error sending ${eventType} to server:`, e);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private serializePurchaseDetails(purchase: Purchase): any {
|
|
188
|
+
return {
|
|
189
|
+
productID: purchase.productId,
|
|
190
|
+
purchaseID: purchase.transactionId || '',
|
|
191
|
+
transactionDate: purchase.transactionDate || '',
|
|
192
|
+
status: Platform.select({
|
|
193
|
+
ios: (purchase as any).transactionStateIOS, // Removed non-existent properties
|
|
194
|
+
android: (purchase as any).purchaseStateAndroid,
|
|
195
|
+
}),
|
|
196
|
+
verificationData: {
|
|
197
|
+
localVerificationData: purchase.transactionReceipt,
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private serializeProductDetails(product: Product): any {
|
|
203
|
+
return {
|
|
204
|
+
productID: product.productId,
|
|
205
|
+
productTitle: product.title,
|
|
206
|
+
productDescription: product.description,
|
|
207
|
+
productPrice: product.price,
|
|
208
|
+
productRawPrice: product.price,
|
|
209
|
+
productCurrencyCode: product.currency,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private async markSDKAsInitialized(): Promise<boolean> {
|
|
214
|
+
try {
|
|
215
|
+
await AsyncStorage.setItem(this.sdkInitializedKey, 'true');
|
|
216
|
+
return true;
|
|
217
|
+
} catch (e) {
|
|
218
|
+
console.error('Failed to save SDK initialization:', e);
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private async isSDKInitialized(): Promise<boolean> {
|
|
224
|
+
try {
|
|
225
|
+
const value = await AsyncStorage.getItem(this.sdkInitializedKey);
|
|
226
|
+
return value === 'true';
|
|
227
|
+
} catch (e) {
|
|
228
|
+
console.error('Failed to load SDK initialization:', e);
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export default GoMarketMe.getInstance();
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES5",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["es6", "dom"],
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"jsx": "react",
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"moduleResolution": "node",
|
|
14
|
+
"outDir": "./dist",
|
|
15
|
+
"rootDir": "./src"
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
18
|
+
"exclude": ["node_modules", "dist", "**/__tests__/*"]
|
|
19
|
+
}
|