@appmetrica/react-native-analytics 3.0.0 → 3.1.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/android/build.gradle +1 -1
- package/android/src/main/java/io/appmetrica/analytics/reactnative/AppMetricaModule.java +10 -0
- package/android/src/main/java/io/appmetrica/analytics/reactnative/UserProfileSerializer.java +257 -0
- package/android/src/main/java/io/appmetrica/analytics/reactnative/Utils.java +9 -0
- package/appmetrica-react-native-analytics.podspec +1 -1
- package/ios/AMARNAppMetrica.m +6 -0
- package/ios/AMARNAppMetricaUtils.h +2 -0
- package/ios/AMARNAppMetricaUtils.m +8 -0
- package/ios/AMARNUserProfileSerializer.h +6 -0
- package/ios/AMARNUserProfileSerializer.m +182 -0
- package/lib/commonjs/ecommerce.js +10 -9
- package/lib/commonjs/ecommerce.js.map +1 -1
- package/lib/commonjs/index.js +17 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/userProfile.js +283 -0
- package/lib/commonjs/userProfile.js.map +1 -0
- package/lib/commonjs/utils.js +72 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/ecommerce.js +10 -9
- package/lib/module/ecommerce.js.map +1 -1
- package/lib/module/index.js +6 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/userProfile.js +267 -0
- package/lib/module/userProfile.js.map +1 -0
- package/lib/module/utils.js +61 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/src/ecommerce.d.ts +3 -3
- package/lib/typescript/src/ecommerce.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +5 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/revenue.d.ts +1 -1
- package/lib/typescript/src/revenue.d.ts.map +1 -1
- package/lib/typescript/src/userProfile.d.ts +84 -0
- package/lib/typescript/src/userProfile.d.ts.map +1 -0
- package/lib/typescript/src/utils.d.ts +9 -0
- package/lib/typescript/src/utils.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/ecommerce.ts +20 -12
- package/src/index.ts +10 -2
- package/src/revenue.ts +1 -1
- package/src/userProfile.ts +362 -0
- package/src/utils.ts +71 -0
package/src/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Linking, NativeModules, Platform } from 'react-native';
|
|
2
2
|
import type { ECommerceEvent } from './ecommerce';
|
|
3
3
|
import type { AdRevenue, Revenue } from './revenue';
|
|
4
|
+
import type { UserProfile } from './userProfile';
|
|
5
|
+
import { normalizeAdRevenue } from './utils';
|
|
4
6
|
|
|
5
7
|
const LINKING_ERROR =
|
|
6
8
|
`The package '@appmetrica/react-native-analytics' doesn't seem to be linked. Make sure: \n\n` +
|
|
@@ -51,6 +53,7 @@ export type AppMetricaConfig = {
|
|
|
51
53
|
activationAsSessionStart?: boolean; // iOS only
|
|
52
54
|
sessionsAutoTracking?: boolean; // iOS only
|
|
53
55
|
appOpenTrackingEnabled?: boolean;
|
|
56
|
+
userProfileID?: string;
|
|
54
57
|
};
|
|
55
58
|
|
|
56
59
|
export type PreloadInfo = {
|
|
@@ -87,6 +90,7 @@ export const UUID_KEY = 'appmetrica_uuid';
|
|
|
87
90
|
|
|
88
91
|
export * from './ecommerce';
|
|
89
92
|
export * from './revenue';
|
|
93
|
+
export * from './userProfile';
|
|
90
94
|
|
|
91
95
|
export default class AppMetrica {
|
|
92
96
|
static activate(config: AppMetricaConfig) {
|
|
@@ -116,7 +120,7 @@ export default class AppMetrica {
|
|
|
116
120
|
AppMetricaNative.reportAppOpen(deeplink);
|
|
117
121
|
}
|
|
118
122
|
|
|
119
|
-
static reportError(identifier: string, message: string, _reason
|
|
123
|
+
static reportError(identifier: string, message: string, _reason?: Object) {
|
|
120
124
|
AppMetricaNative.reportError(identifier, message);
|
|
121
125
|
}
|
|
122
126
|
|
|
@@ -164,6 +168,10 @@ export default class AppMetrica {
|
|
|
164
168
|
}
|
|
165
169
|
|
|
166
170
|
static reportAdRevenue(adRevenue: AdRevenue) {
|
|
167
|
-
AppMetricaNative.reportAdRevenue(adRevenue);
|
|
171
|
+
AppMetricaNative.reportAdRevenue(normalizeAdRevenue(adRevenue));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
static reportUserProfile(userProfile: UserProfile) {
|
|
175
|
+
AppMetricaNative.reportUserProfile(userProfile)
|
|
168
176
|
}
|
|
169
177
|
}
|
package/src/revenue.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type Receipt = {
|
|
|
16
16
|
export type AdRevenue = {
|
|
17
17
|
price: number | string;
|
|
18
18
|
currency: string;
|
|
19
|
-
payload?: Map<string, string>;
|
|
19
|
+
payload?: Map<string, string> | Record<string, string>;
|
|
20
20
|
adNetwork?: string;
|
|
21
21
|
adPlacementID?: string;
|
|
22
22
|
adPlacementName?: string;
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
export class UserProfile {
|
|
2
|
+
private attributes: Array<UserProfileUpdate>;
|
|
3
|
+
|
|
4
|
+
constructor() {
|
|
5
|
+
this.attributes = [];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
apply(attribute: UserProfileUpdate): UserProfile {
|
|
9
|
+
this.attributes.push(attribute);
|
|
10
|
+
|
|
11
|
+
return this;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type UserProfileUpdateType =
|
|
16
|
+
| 'BirthDateWithAge'
|
|
17
|
+
| 'BirthDateWithYear'
|
|
18
|
+
| 'BirthDateWithMonth'
|
|
19
|
+
| 'BirthDateWithDay'
|
|
20
|
+
| 'BirthDateValueReset'
|
|
21
|
+
| 'BooleanValue'
|
|
22
|
+
| 'BooleanValueReset'
|
|
23
|
+
| 'Counter'
|
|
24
|
+
| 'GenderValue'
|
|
25
|
+
| 'GenderValueReset'
|
|
26
|
+
| 'NameValue'
|
|
27
|
+
| 'NameValueReset'
|
|
28
|
+
| 'NotificationsEnabledValue'
|
|
29
|
+
| 'NotificationsEnabledValueReset'
|
|
30
|
+
| 'NumberValue'
|
|
31
|
+
| 'NumberValueReset'
|
|
32
|
+
| 'StringValue'
|
|
33
|
+
| 'StringValueReset';
|
|
34
|
+
|
|
35
|
+
export interface UserProfileUpdate {
|
|
36
|
+
type: UserProfileUpdateType;
|
|
37
|
+
key?: string;
|
|
38
|
+
value?: any;
|
|
39
|
+
ifUndefined?: boolean;
|
|
40
|
+
age?: number;
|
|
41
|
+
year?: number;
|
|
42
|
+
month?: number;
|
|
43
|
+
day?: number;
|
|
44
|
+
delta?: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type UserProfileGender = 'male' | 'female' | 'other';
|
|
48
|
+
|
|
49
|
+
export class Attributes {
|
|
50
|
+
static birthDate() {
|
|
51
|
+
return new BirthDateAttribute();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static customBoolean(key: string) {
|
|
55
|
+
return new BooleanAttribute(key);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static customCounter(key: string) {
|
|
59
|
+
return new CounterAttribute(key);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static customNumber(key: string) {
|
|
63
|
+
return new NumberAttribute(key);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static customString(key: string) {
|
|
67
|
+
return new StringAttribute(key);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static gender() {
|
|
71
|
+
return new GenderAttribute();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static userName() {
|
|
75
|
+
return new NameAttribute();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static notificationsEnabled() {
|
|
79
|
+
return new NotificationsEnabledAttribute();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class BirthDateAttribute {
|
|
84
|
+
withAge(age: number): UserProfileUpdate {
|
|
85
|
+
return {
|
|
86
|
+
type: 'BirthDateWithAge',
|
|
87
|
+
age: age,
|
|
88
|
+
ifUndefined: false,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
withAgeIfUndefined(age: number): UserProfileUpdate {
|
|
93
|
+
return {
|
|
94
|
+
type: 'BirthDateWithAge',
|
|
95
|
+
age: age,
|
|
96
|
+
ifUndefined: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
withYear(year: number): UserProfileUpdate {
|
|
101
|
+
return {
|
|
102
|
+
type: 'BirthDateWithYear',
|
|
103
|
+
year: year,
|
|
104
|
+
ifUndefined: false,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
withYearIfUndefined(year: number): UserProfileUpdate {
|
|
109
|
+
return {
|
|
110
|
+
type: 'BirthDateWithYear',
|
|
111
|
+
year: year,
|
|
112
|
+
ifUndefined: true,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
withMonth(year: number, month: number): UserProfileUpdate {
|
|
117
|
+
return {
|
|
118
|
+
type: 'BirthDateWithMonth',
|
|
119
|
+
year: year,
|
|
120
|
+
month: month,
|
|
121
|
+
ifUndefined: false,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
withMonthIfUndefined(year: number, month: number): UserProfileUpdate {
|
|
126
|
+
return {
|
|
127
|
+
type: 'BirthDateWithMonth',
|
|
128
|
+
year: year,
|
|
129
|
+
month: month,
|
|
130
|
+
ifUndefined: true,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
withDay(year: number, month: number, day: number): UserProfileUpdate {
|
|
135
|
+
return {
|
|
136
|
+
type: 'BirthDateWithDay',
|
|
137
|
+
year: year,
|
|
138
|
+
month: month,
|
|
139
|
+
day: day,
|
|
140
|
+
ifUndefined: false,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
withDayIfUndefined(
|
|
145
|
+
year: number,
|
|
146
|
+
month: number,
|
|
147
|
+
day: number
|
|
148
|
+
): UserProfileUpdate {
|
|
149
|
+
return {
|
|
150
|
+
type: 'BirthDateWithDay',
|
|
151
|
+
year: year,
|
|
152
|
+
month: month,
|
|
153
|
+
day: day,
|
|
154
|
+
ifUndefined: true,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
withDate(date: Date): UserProfileUpdate {
|
|
159
|
+
return this.withDay(date.getFullYear(), date.getMonth(), date.getDate());
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
withDateIfUndefined(date: Date): UserProfileUpdate {
|
|
163
|
+
return this.withDayIfUndefined(
|
|
164
|
+
date.getFullYear(),
|
|
165
|
+
date.getMonth(),
|
|
166
|
+
date.getDate()
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
withValueReset(): UserProfileUpdate {
|
|
171
|
+
return {
|
|
172
|
+
type: 'BirthDateValueReset',
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export class BooleanAttribute {
|
|
178
|
+
private readonly key: string;
|
|
179
|
+
|
|
180
|
+
constructor(key: string) {
|
|
181
|
+
this.key = key;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
withValue(value: boolean): UserProfileUpdate {
|
|
185
|
+
return {
|
|
186
|
+
type: 'BooleanValue',
|
|
187
|
+
key: this.key,
|
|
188
|
+
value: value,
|
|
189
|
+
ifUndefined: false,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
withValueIfUndefined(value: boolean): UserProfileUpdate {
|
|
194
|
+
return {
|
|
195
|
+
type: 'BooleanValue',
|
|
196
|
+
key: this.key,
|
|
197
|
+
value: value,
|
|
198
|
+
ifUndefined: true,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
withValueReset(): UserProfileUpdate {
|
|
203
|
+
return {
|
|
204
|
+
type: 'BooleanValueReset',
|
|
205
|
+
key: this.key,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export class CounterAttribute {
|
|
211
|
+
private readonly key: string;
|
|
212
|
+
|
|
213
|
+
constructor(key: string) {
|
|
214
|
+
this.key = key;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
withDelta(delta: number): UserProfileUpdate {
|
|
218
|
+
return {
|
|
219
|
+
type: 'Counter',
|
|
220
|
+
key: this.key,
|
|
221
|
+
delta: delta,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export class GenderAttribute {
|
|
227
|
+
withValue(gender: UserProfileGender): UserProfileUpdate {
|
|
228
|
+
return {
|
|
229
|
+
type: 'GenderValue',
|
|
230
|
+
value: gender,
|
|
231
|
+
ifUndefined: false,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
withValueIfUndefined(gender: UserProfileGender): UserProfileUpdate {
|
|
236
|
+
return {
|
|
237
|
+
type: 'GenderValue',
|
|
238
|
+
value: gender,
|
|
239
|
+
ifUndefined: true,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
withValueReset(): UserProfileUpdate {
|
|
244
|
+
return {
|
|
245
|
+
type: 'GenderValueReset',
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export class NameAttribute {
|
|
251
|
+
withValue(value: string): UserProfileUpdate {
|
|
252
|
+
return {
|
|
253
|
+
type: 'NameValue',
|
|
254
|
+
value: value,
|
|
255
|
+
ifUndefined: false,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
withValueIfUndefined(value: string): UserProfileUpdate {
|
|
260
|
+
return {
|
|
261
|
+
type: 'NameValue',
|
|
262
|
+
value: value,
|
|
263
|
+
ifUndefined: true,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
withValueReset(): UserProfileUpdate {
|
|
268
|
+
return {
|
|
269
|
+
type: 'NameValueReset',
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export class NotificationsEnabledAttribute {
|
|
275
|
+
withValue(value: boolean): UserProfileUpdate {
|
|
276
|
+
return {
|
|
277
|
+
type: 'NotificationsEnabledValue',
|
|
278
|
+
value: value,
|
|
279
|
+
ifUndefined: false,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
withValueIfUndefined(value: boolean): UserProfileUpdate {
|
|
284
|
+
return {
|
|
285
|
+
type: 'NotificationsEnabledValue',
|
|
286
|
+
value: value,
|
|
287
|
+
ifUndefined: true,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
withValueReset(): UserProfileUpdate {
|
|
292
|
+
return {
|
|
293
|
+
type: 'NotificationsEnabledValueReset',
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export class NumberAttribute {
|
|
299
|
+
private readonly key: string;
|
|
300
|
+
|
|
301
|
+
constructor(key: string) {
|
|
302
|
+
this.key = key;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
withValue(value: number): UserProfileUpdate {
|
|
306
|
+
return {
|
|
307
|
+
type: 'NumberValue',
|
|
308
|
+
key: this.key,
|
|
309
|
+
value: value,
|
|
310
|
+
ifUndefined: false,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
withValueIfUndefined(value: number): UserProfileUpdate {
|
|
315
|
+
return {
|
|
316
|
+
type: 'NumberValue',
|
|
317
|
+
key: this.key,
|
|
318
|
+
value: value,
|
|
319
|
+
ifUndefined: true,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
withValueReset(): UserProfileUpdate {
|
|
324
|
+
return {
|
|
325
|
+
type: 'NumberValueReset',
|
|
326
|
+
key: this.key,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export class StringAttribute {
|
|
332
|
+
private readonly key: string;
|
|
333
|
+
|
|
334
|
+
constructor(key: string) {
|
|
335
|
+
this.key = key;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
withValue(value: string): UserProfileUpdate {
|
|
339
|
+
return {
|
|
340
|
+
type: 'StringValue',
|
|
341
|
+
key: this.key,
|
|
342
|
+
value: value,
|
|
343
|
+
ifUndefined: false,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
withValueIfUndefined(value: string): UserProfileUpdate {
|
|
348
|
+
return {
|
|
349
|
+
type: 'StringValue',
|
|
350
|
+
key: this.key,
|
|
351
|
+
value: value,
|
|
352
|
+
ifUndefined: true,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
withValueReset(): UserProfileUpdate {
|
|
357
|
+
return {
|
|
358
|
+
type: 'StringValueReset',
|
|
359
|
+
key: this.key,
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ECommerceCartItem,
|
|
3
|
+
ECommerceOrder,
|
|
4
|
+
ECommerceProduct,
|
|
5
|
+
ECommerceReferrer,
|
|
6
|
+
ECommerceScreen,
|
|
7
|
+
} from './ecommerce';
|
|
8
|
+
import type { AdRevenue } from './revenue';
|
|
9
|
+
|
|
10
|
+
function convertMap(
|
|
11
|
+
map?: Map<string, string>
|
|
12
|
+
): Record<string, string> | undefined {
|
|
13
|
+
return map !== undefined ? Object.fromEntries(map) : undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function normalizeECommerceOrder(order: ECommerceOrder): ECommerceOrder {
|
|
17
|
+
const newOrder = { ...order } as ECommerceOrder;
|
|
18
|
+
if (order.payload instanceof Map) {
|
|
19
|
+
newOrder.payload = convertMap(order.payload);
|
|
20
|
+
}
|
|
21
|
+
newOrder.products = order.products.map(normalizeECommerceCartItem)
|
|
22
|
+
return newOrder;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function normalizeECommerceCartItem(
|
|
26
|
+
item: ECommerceCartItem
|
|
27
|
+
): ECommerceCartItem {
|
|
28
|
+
const newItem = { ...item } as ECommerceCartItem;
|
|
29
|
+
newItem.product = normalizeECommerceProduct(item.product);
|
|
30
|
+
newItem.referrer = normalizeECommerceReferrer(item.referrer);
|
|
31
|
+
return newItem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function normalizeECommerceProduct(
|
|
35
|
+
product: ECommerceProduct
|
|
36
|
+
): ECommerceProduct {
|
|
37
|
+
const newProduct = { ...product } as ECommerceProduct;
|
|
38
|
+
if (product.payload instanceof Map) {
|
|
39
|
+
newProduct.payload = convertMap(product.payload);
|
|
40
|
+
}
|
|
41
|
+
return newProduct;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function normalizeECommerceReferrer(
|
|
45
|
+
referrer?: ECommerceReferrer
|
|
46
|
+
): ECommerceReferrer | undefined {
|
|
47
|
+
if (referrer === undefined) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
const newReferrer = { ...referrer } as ECommerceReferrer;
|
|
51
|
+
if (referrer.screen != undefined) {
|
|
52
|
+
newReferrer.screen = normalizeECommerceScreen(referrer.screen);
|
|
53
|
+
}
|
|
54
|
+
return newReferrer;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function normalizeECommerceScreen(screen: ECommerceScreen): ECommerceScreen {
|
|
58
|
+
const newScreen = { ...screen } as ECommerceScreen;
|
|
59
|
+
if (screen.payload instanceof Map) {
|
|
60
|
+
newScreen.payload = convertMap(screen.payload);
|
|
61
|
+
}
|
|
62
|
+
return newScreen;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function normalizeAdRevenue(adRevenue: AdRevenue): AdRevenue {
|
|
66
|
+
const newAdRevenue = { ...adRevenue } as AdRevenue;
|
|
67
|
+
if (adRevenue.payload instanceof Map) {
|
|
68
|
+
newAdRevenue.payload = convertMap(adRevenue.payload);
|
|
69
|
+
}
|
|
70
|
+
return newAdRevenue;
|
|
71
|
+
}
|