@bprotsyk/aso-core 1.2.68 → 1.2.70

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.
@@ -0,0 +1,495 @@
1
+ import { IKeitaroStream } from "../keitaro/keitaro-stream"
2
+ import { FlashAppPlugStatus, IFlashApp, PlugType, } from "../flash/flash-app"
3
+ import { FlashAppType } from "../flash/flash-app-type"
4
+ import { IKeitaroCampaign, IKeitaroCampaignParameters } from "../keitaro/keitaro-campaign"
5
+ import { IKeitaroDomain } from "../keitaro/keitaro-domain"
6
+ import { KeitaroService } from "../network/keitaro/keitaro-service"
7
+ import sleep from 'sleep-promise';
8
+ const fs = require("fs")
9
+ import * as util from 'util';
10
+ import { PasteMap, TrackingMap } from "utils/app-gathering-utils"
11
+ import axios from "axios"
12
+ const readFile = util.promisify(fs.readFile);
13
+
14
+ const FLASH_REDIRECT_GROUP_ID = 82
15
+ export const TRAFFIC_SOURCE_ID_FLASH_AI = 22
16
+ const UNIQUENESS_METHOD = "ip_ua"
17
+ const MAX_COOKIES_TTL = 8760
18
+ const TYPE_POSITION = "position"
19
+ const STATE_ACTIVE = "active"
20
+ const COST_TYPE_CPC = "CPC"
21
+ const COST_VALUE = 0
22
+ const COST_CURRENCY_USD = "USD"
23
+
24
+ // clear campaigns from unused / wrong streams
25
+
26
+ let sampleApp: IFlashApp = {
27
+ id: 96,
28
+ bundle: "com.dynastyof.desert",
29
+ name: "Room of Fortuna",
30
+ plugId: "https://pastebin.com/raw/AR2u7dSD",
31
+ plugType: PlugType.PASTEBIN,
32
+ plugContent: "",
33
+ plugStatus: FlashAppPlugStatus.DISABLED,
34
+ plugAccountId: 1,
35
+ reservePlugId: "none",
36
+ reservePlugType: PlugType.OTHER,
37
+ reservePlugContent: "",
38
+ reservePlugStatus: FlashAppPlugStatus.DISABLED,
39
+ reservePlugAccountId: 1,
40
+ type: FlashAppType.GAMBLING,
41
+ developerEmail: "bolly.dreams@yahoo.com",
42
+ developerName: "Serhii Bolsky",
43
+ developerOrganization: "S.I.B FOP",
44
+ onesignalAppId: "e66658af-91c3-44bc-8123-ec64b1969cbd",
45
+ onesignalRestApiKey: "MDk2NjZlNTMtMzBhYi00MjEzLTg0ZGItOWVmZWZhMTczMzI0",
46
+
47
+ generationOptions: {
48
+ splashActivityClassName: "SplashActivity",
49
+ mainActivityClassName: "YourActivity",
50
+ linkName: "likn",
51
+ savedName: "isOk",
52
+ paranoidSeed: 228143750
53
+ },
54
+ geos: "RU,UA,KZ,ES,BR,PT,CL,MX",
55
+ keitaroData: {
56
+ redirectCampaignId: 0,
57
+ redirectCampaignName: "",
58
+ redirectDomainId: 0,
59
+ redirectDomainName: "",
60
+ trackingCampaignId: 0,
61
+ trackingCampaignName: "",
62
+ trackingDomainId: 0,
63
+ trackingDomainName: "",
64
+ clickIdParameterName: "p",
65
+ offerIdParameterName: "i",
66
+ }
67
+ } as IFlashApp
68
+
69
+ export let addGeosToAllRedirectCampaigns = async (geosToAdd: string) => {
70
+ let allCampaigns = await KeitaroService.getAllCampaigns()
71
+
72
+
73
+ let regexp = new RegExp(`^F #`)
74
+ const matchingCampaigns = allCampaigns.filter(campaign => regexp.exec(campaign.name));
75
+ for (let campaign of matchingCampaigns) {
76
+ console.log(campaign.name)
77
+ console.log("––––––––––––––––––––––––")
78
+ let streams = await KeitaroService.getStreamsByCampaignId(campaign.id)
79
+ let botStream = streams[0]
80
+ botStream.name = "Bot Protection"
81
+ let owStream = streams.find(s => s.name == "OW")
82
+
83
+ for (let stream of [owStream, botStream]) {
84
+ if (!stream) continue
85
+ console.log({
86
+ name: stream.name,
87
+ })
88
+ let geos = stream?.filters[0]?.payload
89
+ if (!geos) continue
90
+ geosToAdd.split(" ").forEach((geo: string) => {
91
+ let streamForGeo = streams.find((s) => s.name == geo)
92
+ if (streamForGeo && stream && stream.type != "forced") return
93
+ if (!geos.includes(geo)) geos.push(geo)
94
+ });
95
+
96
+ stream.filters[0].payload = geos
97
+
98
+ await KeitaroService.upsertStreamToCampaign(campaign, stream)
99
+ await sleep(2000)
100
+ }
101
+ console.log("––––––––––––––––––––––––")
102
+ }
103
+ }
104
+
105
+ export let removeGeosFromAllRedirectCampaigns = async (geoToRemove: string) => {
106
+ let allCampaigns = await KeitaroService.getAllCampaigns()
107
+
108
+
109
+ let regexp = new RegExp(`^F #`)
110
+ const matchingCampaigns = allCampaigns.filter(campaign => regexp.exec(campaign.name));
111
+ for (let campaign of matchingCampaigns) {
112
+ console.log(campaign.name)
113
+ console.log("––––––––––––––––––––––––")
114
+ let streams = await KeitaroService.getStreamsByCampaignId(campaign.id)
115
+ let botStream = streams[0]
116
+ botStream.name = "Bot Protection"
117
+ let owStream = streams.find(s => s.name == "OW")
118
+
119
+ for (let stream of [owStream, botStream]) {
120
+ if (!stream) continue
121
+ let geos: string[] = stream?.filters[0]?.payload
122
+
123
+ if (!geos) continue
124
+ let index = geos.findIndex(geo => geo == geoToRemove)
125
+ geos.splice(index, 1)
126
+ let newGeos = stream.filters[0].payload = geos
127
+ console.log({
128
+ name: stream.name,
129
+ geos: geos,
130
+ geosToRemove: geoToRemove,
131
+ newGeos: newGeos
132
+ })
133
+
134
+ await KeitaroService.upsertStreamToCampaign(campaign, stream)
135
+ await sleep(1200)
136
+ }
137
+ console.log("––––––––––––––––––––––––")
138
+ }
139
+ }
140
+
141
+ export let createOrFindFlashRedirectCampaign = async (app: IFlashApp): Promise<IKeitaroCampaign> => {
142
+ if (app.keitaroData.redirectCampaignId != 0) {
143
+ let campaign = await KeitaroService.getCampaignById(app.keitaroData.redirectCampaignId)
144
+ return campaign
145
+ }
146
+
147
+ // Checking for already existing campaign
148
+ let allCampaigns = await KeitaroService.getAllCampaigns()
149
+ let regexp = new RegExp(`^F #${app.id}`)
150
+ const matchingCampaigns = allCampaigns.filter(campaign => regexp.exec(campaign.name));
151
+
152
+ if (matchingCampaigns.length != 0) {
153
+ let campaign = matchingCampaigns[0]
154
+ app.keitaroData.redirectCampaignId = campaign.id
155
+
156
+ console.log("Already exists!")
157
+ // await app.save()
158
+ return campaign
159
+ }
160
+
161
+ // Select domain for a campaign
162
+ let allDomains = await KeitaroService.getDomains(true)
163
+ if (!allDomains) {
164
+ throw Error(`Failed to get all domains list`)
165
+ }
166
+
167
+ const domain = allDomains[Math.floor(Math.random() * allDomains.length)];
168
+
169
+ // Okay, now we have everything, let's create name for our campaign
170
+ const name = `F #${app.id} (${app.bundle})`
171
+
172
+ // And generate alias
173
+ const alias = Array.from({ length: 8 }, () => Math.floor(Math.random() * 36).toString(36)).join('');
174
+
175
+ // Here go the parameters for our campaign
176
+ let parameters = prepareRedirectCampaignParameters(app.id)
177
+
178
+ // Now let create a campaign object
179
+ let campaignData = prepareCampaignObject(name, alias, domain, parameters)
180
+
181
+ // And POST it to Keitaro!
182
+
183
+ let createdCampaign = await KeitaroService.createCampaign(campaignData)
184
+
185
+ console.log(`Done! Campaign data:`)
186
+ console.log(createdCampaign)
187
+
188
+ return createdCampaign
189
+ }
190
+
191
+ let prepareCampaignObject = (name: string, alias: string, domain: IKeitaroDomain, parameters: IKeitaroCampaignParameters): Partial<IKeitaroCampaign> => {
192
+ return {
193
+ name: name,
194
+ alias: alias,
195
+ type: TYPE_POSITION,
196
+ uniqueness_method: UNIQUENESS_METHOD,
197
+ cookies_ttl: MAX_COOKIES_TTL,
198
+ state: STATE_ACTIVE,
199
+ cost_type: COST_TYPE_CPC,
200
+ cost_value: COST_VALUE,
201
+ cost_currency: COST_CURRENCY_USD,
202
+ group_id: FLASH_REDIRECT_GROUP_ID,
203
+ traffic_source_id: TRAFFIC_SOURCE_ID_FLASH_AI,
204
+ domain_id: domain.id,
205
+ parameters: parameters,
206
+ uniqueness_use_cookies: true,
207
+ traffic_loss: 0
208
+ }
209
+ }
210
+
211
+ let prepareRedirectCampaignParameters = (appId: number): IKeitaroCampaignParameters => {
212
+ return {
213
+ "keyword": {
214
+ "name": "keyword",
215
+ "placeholder": "",
216
+ "alias": ""
217
+ },
218
+ "cost": {
219
+ "name": "cost",
220
+ "placeholder": "",
221
+ "alias": ""
222
+ },
223
+ "currency": {
224
+ "name": "currency",
225
+ "placeholder": "",
226
+ "alias": ""
227
+ },
228
+ "external_id": {
229
+ "name": "external_id",
230
+ "placeholder": "",
231
+ "alias": ""
232
+ },
233
+ "creative_id": {
234
+ "name": "creative_id",
235
+ "placeholder": "",
236
+ "alias": ""
237
+ },
238
+ "ad_campaign_id": {
239
+ "name": "ad_campaign_id",
240
+ "placeholder": "",
241
+ "alias": ""
242
+ },
243
+ "source": {
244
+ "name": "source",
245
+ "placeholder": "",
246
+ "alias": ""
247
+ },
248
+ sub_id_1: {
249
+ name: "appId",
250
+ placeholder: `${appId}`,
251
+ alias: ""
252
+ }
253
+ }
254
+ }
255
+
256
+ export let prepareOWCampaignParameters = (app: IFlashApp): IKeitaroCampaignParameters => {
257
+ return {
258
+ "keyword": {
259
+ "name": "keyword",
260
+ "placeholder": "",
261
+ "alias": ""
262
+ },
263
+ "cost": {
264
+ "name": "cost",
265
+ "placeholder": "",
266
+ "alias": ""
267
+ },
268
+ "currency": {
269
+ "name": "currency",
270
+ "placeholder": "",
271
+ "alias": ""
272
+ },
273
+ "external_id": {
274
+ "name": "external_id",
275
+ "placeholder": "",
276
+ "alias": ""
277
+ },
278
+ "creative_id": {
279
+ "name": "creative_id",
280
+ "placeholder": "",
281
+ "alias": ""
282
+ },
283
+ "ad_campaign_id": {
284
+ "name": "ad_campaign_id",
285
+ "placeholder": "",
286
+ "alias": ""
287
+ },
288
+ "source": {
289
+ "name": "source",
290
+ "placeholder": "",
291
+ "alias": ""
292
+ },
293
+ sub_id_8: {
294
+ "name": app.keitaroData.clickIdParameterName,
295
+ "placeholder": "{click_id}",
296
+ "alias": "click_id"
297
+ },
298
+ sub_id_15: {
299
+ "name": app.keitaroData.offerIdParameterName,
300
+ "placeholder": "{offer_custom_id}",
301
+ "alias": "offer_custom_id"
302
+ }
303
+ }
304
+ }
305
+
306
+ function createBPStreamPartialPayload(app: IFlashApp): Partial<IKeitaroStream> {
307
+ return {
308
+ name: `Bot Protection`,
309
+ type: "forced",
310
+ action_type: "http",
311
+ action_payload: "https://tomain.com",
312
+ schema: "redirect",
313
+ filter_or: true,
314
+ collect_clicks: true,
315
+ weight: 0,
316
+ filters: [{
317
+ name: "country",
318
+ mode: "reject",
319
+ payload: app.geos.split(",")
320
+ }, {
321
+ name: "bot",
322
+ mode: "accept",
323
+ payload: null,
324
+ }],
325
+ }
326
+ }
327
+
328
+ export function createOWStreamPartialPayload(app: IFlashApp): Partial<IKeitaroStream> {
329
+ return {
330
+ name: `OW`,
331
+ type: "regular",
332
+ action_type: "http",
333
+ action_payload: "https://bprtsk-controlpanel.com/ow?appId={appId}&clickId={uid}&countryCode={country}",
334
+ schema: "redirect",
335
+ filter_or: false,
336
+ collect_clicks: true,
337
+ weight: 100,
338
+ filters: [{
339
+ name: "country",
340
+ mode: "accept",
341
+ payload: app.geos.split(",")
342
+ }],
343
+ }
344
+ }
345
+
346
+ export async function createFlashCampaigns(app: IFlashApp) {
347
+ // Upserting Flash Redirect campaign
348
+ let redirectCampaign = await createOrFindFlashRedirectCampaign(app)
349
+ console.log(`Redirect campaign name:`)
350
+ console.log(`${redirectCampaign.domain}${redirectCampaign.alias}?uid=`)
351
+
352
+ // Upserting necessary streams
353
+ let botProtectionStream = createBPStreamPartialPayload(app)
354
+ let owStream = createOWStreamPartialPayload(app)
355
+
356
+ for (let stream of [botProtectionStream, owStream]) {
357
+ await KeitaroService.upsertStreamToCampaign(redirectCampaign, stream)
358
+ }
359
+
360
+ // TODO random domain for OW
361
+
362
+ // Upserting OW campaign
363
+ let owCampaign = await KeitaroService.cloneOWCampaign(app)
364
+ console.log("Done! OW campaign link:")
365
+ console.log(`${owCampaign.domain}${owCampaign.alias}?${app.keitaroData.clickIdParameterName}={click_id}&${app.keitaroData.offerIdParameterName}={offer_custom_id}`)
366
+ }
367
+
368
+ // TODO separate files for offers, campaigns etc.
369
+
370
+ let removeBrokenDomain = async () => {
371
+
372
+ let regexp = new RegExp(`^FA #`)
373
+ let campaigns = (await KeitaroService.getAllCampaigns()).filter(campaign => regexp.exec(campaign.name) && campaign.domain == "https://slottibolt.com/");
374
+ for (let campaign of campaigns) {
375
+ console.log(campaign.name)
376
+ }
377
+ }
378
+
379
+ let changeSourceForFA = async () => {
380
+ let regexp = new RegExp(`^FA #`)
381
+ let campaigns = (await KeitaroService.getAllCampaigns()).filter(campaign => regexp.exec(campaign.name));
382
+ for (let campaign of campaigns) {
383
+ console.log(campaign.name)
384
+ await KeitaroService.updateCampaign(campaign.id, {
385
+ traffic_source_id: 22
386
+ })
387
+ }
388
+ }
389
+
390
+ let gatherInfoForFlashApps = async () => {
391
+ console.log(__dirname)
392
+ const pasteMap: PasteMap = JSON.parse(await readFile('/Users/bprtsk/Documents/Work/ASO/AI Control Panel /AI Panel Core/src/utils/map-paste.json', 'utf8'));
393
+ const trackingMap: TrackingMap = JSON.parse(await readFile('/Users/bprtsk/Documents/Work/ASO/AI Control Panel /AI Panel Core/src/utils/map-tracking.json', 'utf8'));
394
+ const flashApps: { [key: string]: IFlashApp | undefined } = JSON.parse(await readFile('/Users/bprtsk/Documents/Work/ASO/AI Control Panel /AI Panel Core/src/utils/map-apps.json', 'utf8'));
395
+
396
+ let allCampaigns = await KeitaroService.getAllCampaigns()
397
+ let owCampaigns = allCampaigns.filter(c => new RegExp(`^FA #`).exec(c.name)).reduce((acc, obj) => ({ ...acc, [new RegExp(/#(.*) \(/g).exec(obj.name)?.[1] || obj.name]: obj }), {});
398
+ let redirectCampaigns = allCampaigns.filter(c => new RegExp(`^F #`).exec(c.name)).reduce((acc, obj) => ({ ...acc, [new RegExp(/#(.*) \(/g).exec(obj.name)?.[1] || obj.name]: obj }), {});
399
+
400
+ let result = []
401
+ for (let [id, paste] of Object.entries(pasteMap)) {
402
+ console.log(`- #${id}`)
403
+ let ow = owCampaigns[id as keyof object] as IKeitaroCampaign | undefined
404
+ let redirect = redirectCampaigns[id as keyof object] as IKeitaroCampaign | undefined
405
+ let tracking = trackingMap[id as keyof object]
406
+ let app = flashApps[id as keyof object]
407
+
408
+ if (!app) {
409
+ console.log(`! No app for ${id}`)
410
+ continue
411
+ }
412
+
413
+ if (paste.status == FlashAppPlugStatus.ENABLED) {
414
+ if (!ow) console.log(`#${id}: no OW`)
415
+
416
+ if (!redirect) console.log(`No redirect for #${id}`)
417
+ else if (!paste.content.includes(redirect.domain)) console.log(`#${id}: Redirect domain (${redirect.domain}) differs from paste domain (${paste.content})`)
418
+ else if (!paste.content.includes(redirect.alias)) console.log(`#${id}: Redirect campaign alias (${redirect.alias}) differs from paste id (${paste.content})`)
419
+ }
420
+
421
+ let appId
422
+ for (let parameter of Object.values(redirect?.parameters || {})) {
423
+ if (parameter.name == "appId") {
424
+ appId = parameter.placeholder
425
+ }
426
+ }
427
+ if (!appId && ow) console.log(`No app id for #${id}`)
428
+ else if (appId != id && ow) console.log(`Wrong app id (${appId}) for #${id}`)
429
+
430
+ let owDomain = ow?.domain?.split("/")[2]
431
+ let owDomainId = ow?.domain_id
432
+ let owCampaignId = ow?.id
433
+ let owCampaignName = ow?.name
434
+ let redirectDomain = redirect?.domain?.split("/")[2]
435
+ let redirectDomainId = redirect?.domain_id
436
+ let redirectCampaignId = redirect?.id
437
+ let redirectCampaignName = redirect?.name
438
+
439
+ let clickIdParameterName = ow?.parameters?.sub_id_8?.name
440
+ let offerIdParameterName = ow?.parameters?.sub_id_15?.name
441
+ if (!clickIdParameterName && app && ow) console.log(`No click id parameter for #${id}`)
442
+ if (!offerIdParameterName && app && ow) console.log(`No offer id parameter for #${id}`)
443
+
444
+ let trackingLink = tracking?.trackingUrl
445
+
446
+ app.plugStatus = paste.status
447
+ app.plugContent = paste.content
448
+ app.plugType = PlugType.PASTEBIN
449
+ app.plugId = paste.paste_id
450
+ app.plugAccountId = parseInt(paste.accountId)
451
+
452
+ app.keitaroData.redirectDomainName = redirectDomain || "none"
453
+ app.keitaroData.redirectDomainId = redirectDomainId || 0
454
+ app.keitaroData.redirectCampaignId = redirectCampaignId || 0
455
+ app.keitaroData.redirectCampaignName = redirectCampaignName || "none"
456
+ app.keitaroData.trackingDomainId = owDomainId || 0
457
+ app.keitaroData.trackingDomainName = owDomain || "none"
458
+ app.keitaroData.trackingCampaignId = owCampaignId || 0
459
+ app.keitaroData.trackingCampaignName = owCampaignName || "none"
460
+
461
+ if (clickIdParameterName) app.keitaroData.clickIdParameterName = clickIdParameterName
462
+ if (offerIdParameterName) app.keitaroData.offerIdParameterName = offerIdParameterName
463
+
464
+ if (trackingLink) app.trackingUrl = trackingLink
465
+
466
+ if (!owCampaignName?.includes(app.bundle) && ow) {
467
+ console.log(`OW: bundle differs (${app.bundle} in DB and ${owCampaignName})`)
468
+ }
469
+
470
+ if (!redirectCampaignName?.includes(app.bundle) && redirect) {
471
+ console.log(`Redirect: bundle differs (${app.bundle} in DB and ${redirectCampaignName})`)
472
+ }
473
+
474
+ result.push(app)
475
+
476
+ console.log("--------------------")
477
+ }
478
+
479
+ await axios.post(`https://aipanel-secondary.com/flash/batch-update`, result, {
480
+ headers: {
481
+ "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjg3Mjc2NjA0LCJleHAiOjE2ODc4ODE0MDR9.XesrnNGmWlK-yBBMs5TeKvTe07A8Sud7B4MyfZAOMag"
482
+ }
483
+ })
484
+
485
+ // console.log(result)
486
+ }
487
+
488
+ // removeBrokenDomain()
489
+
490
+ // createFlashCampaigns(sampleApp)
491
+ // changeSourceForFA()
492
+ // addGeosToAllRedirectCampaigns("BE")
493
+ // removeGeosFromAllRedirectCampaigns("BE`")
494
+
495
+ gatherInfoForFlashApps()