@bprotsyk/aso-core 2.1.112 → 2.1.114

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.
@@ -253,29 +253,122 @@ async function cloneTraffleCampaign(app, platform, addDefaultStreams) {
253
253
  // Для конкретної платформи
254
254
  const platformName = (0, app_1.getPlatformName)(platform);
255
255
  matchingCampaign = allCampaigns.filter((c) => {
256
- // Точна перевірка ID з межами слів
257
- const idPattern = new RegExp(`${app.id}\\b`);
258
- const hasId = idPattern.test(c.name);
259
- const hasBundle = c.name.includes(`[${app.bundle}]`);
256
+ const hasDomain = c.name.includes(app.domainParams.name);
257
+ const hasGroup = c.group == app.id.toString();
260
258
  // Перевіряємо наявність платформи в дужках в кінці назви
261
259
  const platformPattern = new RegExp(`\\(.*${platformName}.*\\)\\s*$`);
262
260
  const hasPlatform = platformPattern.test(c.name);
263
- return hasId && hasBundle && hasPlatform;
261
+ return hasGroup && hasDomain && hasPlatform;
264
262
  });
265
263
  }
266
264
  else {
267
265
  // Для General платформи
268
266
  matchingCampaign = allCampaigns.filter((c) => {
269
- // Точна перевірка ID з межами слів
270
- const idPattern = new RegExp(`${app.id}\\b`);
271
- const hasId = idPattern.test(c.name);
272
267
  const hasBundle = c.name.includes(`[${app.bundle}]`);
268
+ const hasDomain = c.name.includes(app.domainParams.name);
273
269
  // Перевіряємо відсутність платформи в дужках в кінці
274
270
  // Дозволяємо будь-які інші дужки (як для гео або опису)
275
271
  const noPlatformAtEnd = !/\(.*(?:iOS|Android|Desktop|Mobile).*\)\s*$/.test(c.name);
276
- return hasId && hasBundle && noPlatformAtEnd;
272
+ return hasBundle && hasDomain && noPlatformAtEnd;
277
273
  });
278
274
  }
275
+ // Якщо знайдена існуюча кампанія - повертаємо її без генерації параметрів
276
+ if (matchingCampaign.length > 0) {
277
+ const existingCampaign = matchingCampaign[0];
278
+ // Отримуємо потоки тільки якщо потрібно щось робити з ними
279
+ const originalStreams = await getStreamsByCampaignId(ORIGINAL_CLONE_CAMPAIGN_ID);
280
+ const existingStreams = await getStreamsByCampaignId(existingCampaign.id);
281
+ const updateOrCreateCLOStream = async (campaignId, existingStreams) => {
282
+ const cloTemplate = originalStreams.find(s => s.name === "CLO");
283
+ if (!cloTemplate)
284
+ return;
285
+ const cloStream = {
286
+ type: cloTemplate.type,
287
+ name: "CLO",
288
+ campaign_id: campaignId,
289
+ position: cloTemplate.position,
290
+ state: cloTemplate.state,
291
+ action_type: cloTemplate.action_type,
292
+ action_payload: cloTemplate.action_payload || "",
293
+ schema: cloTemplate.schema,
294
+ collect_clicks: cloTemplate.collect_clicks,
295
+ filter_or: cloTemplate.filter_or,
296
+ weight: cloTemplate.weight,
297
+ filters: [
298
+ {
299
+ name: "country",
300
+ mode: "reject",
301
+ payload: app.platforms[platform].geo || []
302
+ },
303
+ {
304
+ name: "bot",
305
+ mode: "accept",
306
+ payload: null
307
+ },
308
+ {
309
+ name: 'proxy',
310
+ mode: 'accept',
311
+ payload: null
312
+ }
313
+ ],
314
+ offers: []
315
+ };
316
+ if (existingStreams) {
317
+ console.log(`existingStreams`, existingStreams);
318
+ const existingCLO = existingStreams.find(s => s.name === "CLO");
319
+ if (existingCLO) {
320
+ await http_1.default.put(`streams/${existingCLO.id}`, cloStream);
321
+ return;
322
+ }
323
+ }
324
+ await http_1.default.post('streams', cloStream);
325
+ };
326
+ const createStreamWithoutIds = async (stream, campaignId) => {
327
+ // Створюємо базовий об'єкт потоку без ID
328
+ const newStream = {
329
+ type: stream.type,
330
+ name: stream.name,
331
+ campaign_id: campaignId,
332
+ position: stream.position,
333
+ state: stream.state,
334
+ action_type: stream.action_type,
335
+ action_payload: stream.action_payload || "",
336
+ schema: stream.schema,
337
+ collect_clicks: stream.collect_clicks,
338
+ filter_or: stream.filter_or,
339
+ weight: stream.weight,
340
+ filters: stream.filters.map(filter => ({
341
+ name: filter.name,
342
+ mode: filter.mode,
343
+ payload: filter.payload
344
+ })),
345
+ offers: stream.offers.map(offer => ({
346
+ offer_id: offer.offer_id,
347
+ state: offer.state,
348
+ share: offer.share
349
+ }))
350
+ };
351
+ // Створюємо новий потік
352
+ await http_1.default.post('streams', newStream);
353
+ };
354
+ // Завжди оновлюємо CLO потік
355
+ await updateOrCreateCLOStream(existingCampaign.id, existingStreams);
356
+ // Для інших потоків
357
+ if (addDefaultStreams) {
358
+ for (const stream of originalStreams) {
359
+ if (stream.name === "CLO")
360
+ continue; // Пропускаємо CLO
361
+ const existingStream = existingStreams.find(s => s.name === stream.name);
362
+ if (!existingStream) {
363
+ await createStreamWithoutIds(stream, existingCampaign.id);
364
+ }
365
+ }
366
+ }
367
+ console.log(existingCampaign);
368
+ return existingCampaign;
369
+ }
370
+ // Створення нової кампанії - тільки тепер генеруємо параметри
371
+ console.log("Creating new campaign, generating parameters...");
279
372
  const group = await createGroup(app.id.toString(), "campaigns");
280
373
  const originalCampaign = await getCampaignById(ORIGINAL_CLONE_CAMPAIGN_ID);
281
374
  const maxPosition = Math.max(...allCampaigns.map(c => c.position || 0));
@@ -286,6 +379,7 @@ async function cloneTraffleCampaign(app, platform, addDefaultStreams) {
286
379
  }
287
380
  const maxGroupId = Math.max(...allCampaigns.map(c => c.group_id || 0));
288
381
  const originalStreams = await getStreamsByCampaignId(ORIGINAL_CLONE_CAMPAIGN_ID);
382
+ // Параметри генеруються тільки для нових кампаній
289
383
  let parameters = await TrafleKeitaroParameters({ bundle: app.bundle, appsflyerDevKey: app.platforms[platform].appsflyerParams?.devKey, name: name, originalParameters: originalCampaign.parameters });
290
384
  const createStreamWithoutIds = async (stream, campaignId) => {
291
385
  // Створюємо базовий об'єкт потоку без ID
@@ -359,26 +453,6 @@ async function cloneTraffleCampaign(app, platform, addDefaultStreams) {
359
453
  }
360
454
  await http_1.default.post('streams', cloStream);
361
455
  };
362
- // Якщо знайдена існуюча кампанія
363
- if (matchingCampaign.length > 0) {
364
- const existingCampaign = matchingCampaign[0];
365
- const existingStreams = await getStreamsByCampaignId(existingCampaign.id);
366
- // Завжди оновлюємо CLO потік
367
- await updateOrCreateCLOStream(existingCampaign.id, existingStreams);
368
- // Для інших потоків
369
- if (addDefaultStreams) {
370
- for (const stream of originalStreams) {
371
- if (stream.name === "CLO")
372
- continue; // Пропускаємо CLO
373
- const existingStream = existingStreams.find(s => s.name === stream.name);
374
- if (!existingStream) {
375
- await createStreamWithoutIds(stream, existingCampaign.id);
376
- }
377
- }
378
- }
379
- console.log(existingCampaign);
380
- return existingCampaign;
381
- }
382
456
  // Створення нової кампанії
383
457
  let alias = generateAlias();
384
458
  console.log(group);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bprotsyk/aso-core",
3
- "version": "2.1.112",
3
+ "version": "2.1.114",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "scripts": {
@@ -337,33 +337,137 @@ async function cloneTraffleCampaign(app: IApp, platform: EPlatform, addDefaultSt
337
337
  // Для конкретної платформи
338
338
  const platformName = getPlatformName(platform);
339
339
  matchingCampaign = allCampaigns.filter((c) => {
340
- // Точна перевірка ID з межами слів
341
- const idPattern = new RegExp(`${app.id}\\b`);
342
- const hasId = idPattern.test(c.name);
343
- const hasBundle = c.name.includes(`[${app.bundle}]`);
340
+
341
+ const hasDomain = c.name.includes(app.domainParams.name);
342
+ const hasGroup = c.group == app.id.toString()
344
343
 
345
344
  // Перевіряємо наявність платформи в дужках в кінці назви
346
345
  const platformPattern = new RegExp(`\\(.*${platformName}.*\\)\\s*$`);
347
346
  const hasPlatform = platformPattern.test(c.name);
348
- return hasId && hasBundle && hasPlatform;
347
+ return hasGroup && hasDomain && hasPlatform;
349
348
  });
350
349
  } else {
351
350
  // Для General платформи
352
351
  matchingCampaign = allCampaigns.filter((c) => {
353
- // Точна перевірка ID з межами слів
354
- const idPattern = new RegExp(`${app.id}\\b`);
355
- const hasId = idPattern.test(c.name);
356
352
  const hasBundle = c.name.includes(`[${app.bundle}]`);
353
+ const hasDomain = c.name.includes(app.domainParams.name);
357
354
 
358
355
  // Перевіряємо відсутність платформи в дужках в кінці
359
356
  // Дозволяємо будь-які інші дужки (як для гео або опису)
360
357
  const noPlatformAtEnd = !/\(.*(?:iOS|Android|Desktop|Mobile).*\)\s*$/.test(c.name);
361
- return hasId && hasBundle && noPlatformAtEnd;
358
+ return hasBundle && hasDomain && noPlatformAtEnd;
362
359
  });
363
360
  }
364
361
 
362
+ // Якщо знайдена існуюча кампанія - повертаємо її без генерації параметрів
363
+ if (matchingCampaign.length > 0) {
364
+ const existingCampaign = matchingCampaign[0];
365
+
366
+ // Отримуємо потоки тільки якщо потрібно щось робити з ними
367
+ const originalStreams = await getStreamsByCampaignId(ORIGINAL_CLONE_CAMPAIGN_ID);
368
+ const existingStreams = await getStreamsByCampaignId(existingCampaign.id);
369
+
370
+ const updateOrCreateCLOStream = async (campaignId: number, existingStreams?: IKeitaroStream[]) => {
371
+ const cloTemplate = originalStreams.find(s => s.name === "CLO");
372
+ if (!cloTemplate) return;
373
+
374
+ const cloStream = {
375
+ type: cloTemplate.type,
376
+ name: "CLO",
377
+ campaign_id: campaignId,
378
+ position: cloTemplate.position,
379
+ state: cloTemplate.state,
380
+ action_type: cloTemplate.action_type,
381
+ action_payload: cloTemplate.action_payload || "",
382
+ schema: cloTemplate.schema,
383
+ collect_clicks: cloTemplate.collect_clicks,
384
+ filter_or: cloTemplate.filter_or,
385
+ weight: cloTemplate.weight,
386
+ filters: [
387
+ {
388
+ name: "country",
389
+ mode: "reject",
390
+ payload: app.platforms[platform].geo || []
391
+ },
392
+ {
393
+ name: "bot",
394
+ mode: "accept",
395
+ payload: null
396
+ },
397
+ {
398
+ name: 'proxy',
399
+ mode: 'accept',
400
+ payload: null
401
+ }
402
+
403
+ ],
404
+ offers: []
405
+ };
365
406
 
407
+ if (existingStreams) {
408
+ console.log(`existingStreams`,existingStreams)
409
+ const existingCLO = existingStreams.find(s => s.name === "CLO");
410
+ if (existingCLO) {
411
+ await keitaroApi.put(`streams/${existingCLO.id}`, cloStream);
412
+ return;
413
+ }
414
+ }
415
+
416
+ await keitaroApi.post('streams', cloStream);
417
+ };
366
418
 
419
+ const createStreamWithoutIds = async (stream: IKeitaroStream, campaignId: number) => {
420
+ // Створюємо базовий об'єкт потоку без ID
421
+ const newStream = {
422
+ type: stream.type,
423
+ name: stream.name,
424
+ campaign_id: campaignId,
425
+ position: stream.position,
426
+ state: stream.state,
427
+ action_type: stream.action_type,
428
+ action_payload: stream.action_payload || "",
429
+ schema: stream.schema,
430
+ collect_clicks: stream.collect_clicks,
431
+ filter_or: stream.filter_or,
432
+ weight: stream.weight,
433
+ filters: stream.filters.map(filter => ({
434
+ name: filter.name,
435
+ mode: filter.mode,
436
+ payload: filter.payload
437
+ })),
438
+ offers: stream.offers.map(offer => ({
439
+ offer_id: offer.offer_id,
440
+ state: offer.state,
441
+ share: offer.share
442
+ }))
443
+ };
444
+
445
+ // Створюємо новий потік
446
+ await keitaroApi.post('streams', newStream);
447
+ };
448
+
449
+ // Завжди оновлюємо CLO потік
450
+ await updateOrCreateCLOStream(existingCampaign.id, existingStreams);
451
+
452
+ // Для інших потоків
453
+ if (addDefaultStreams) {
454
+ for (const stream of originalStreams) {
455
+ if (stream.name === "CLO") continue; // Пропускаємо CLO
456
+
457
+ const existingStream = existingStreams.find(s => s.name === stream.name);
458
+ if (!existingStream) {
459
+ await createStreamWithoutIds(stream, existingCampaign.id);
460
+ }
461
+ }
462
+ }
463
+
464
+ console.log(existingCampaign)
465
+ return existingCampaign;
466
+ }
467
+
468
+ // Створення нової кампанії - тільки тепер генеруємо параметри
469
+ console.log("Creating new campaign, generating parameters...");
470
+
367
471
  const group = await createGroup(app.id.toString(), "campaigns")
368
472
 
369
473
  const originalCampaign: IKeitaroCampaign = await getCampaignById(ORIGINAL_CLONE_CAMPAIGN_ID);
@@ -376,11 +480,10 @@ async function cloneTraffleCampaign(app: IApp, platform: EPlatform, addDefaultSt
376
480
  throw Error(`Failed to get all domains list`);
377
481
  }
378
482
 
379
-
380
483
  const maxGroupId = Math.max(...allCampaigns.map(c => c.group_id || 0));
381
484
  const originalStreams = await getStreamsByCampaignId(ORIGINAL_CLONE_CAMPAIGN_ID);
382
485
 
383
-
486
+ // Параметри генеруються тільки для нових кампаній
384
487
  let parameters = await TrafleKeitaroParameters({bundle: app.bundle, appsflyerDevKey: app.platforms[platform].appsflyerParams?.devKey, name: name, originalParameters: originalCampaign.parameters})
385
488
 
386
489
  const createStreamWithoutIds = async (stream: IKeitaroStream, campaignId: number) => {
@@ -461,37 +564,9 @@ async function cloneTraffleCampaign(app: IApp, platform: EPlatform, addDefaultSt
461
564
  await keitaroApi.post('streams', cloStream);
462
565
  };
463
566
 
464
- // Якщо знайдена існуюча кампанія
465
- if (matchingCampaign.length > 0) {
466
- const existingCampaign = matchingCampaign[0];
467
- const existingStreams = await getStreamsByCampaignId(existingCampaign.id);
468
-
469
- // Завжди оновлюємо CLO потік
470
- await updateOrCreateCLOStream(existingCampaign.id, existingStreams);
471
-
472
- // Для інших потоків
473
- if (addDefaultStreams) {
474
- for (const stream of originalStreams) {
475
- if (stream.name === "CLO") continue; // Пропускаємо CLO
476
-
477
- const existingStream = existingStreams.find(s => s.name === stream.name);
478
- if (!existingStream) {
479
- await createStreamWithoutIds(stream, existingCampaign.id);
480
- }
481
- }
482
- }
483
-
484
- console.log(existingCampaign)
485
- return existingCampaign;
486
- }
487
-
488
-
489
-
490
567
  // Створення нової кампанії
491
568
  let alias = generateAlias();
492
569
 
493
-
494
-
495
570
  console.log(group)
496
571
 
497
572
  let payload: Partial<IKeitaroCampaign> = {
package/test-keitaro.js CHANGED
@@ -1,49 +1,43 @@
1
1
  const { TraffleKeitaroService } = require('./lib/network/keitaro/traffle/traffle-keitaro-service');
2
2
  const { EPlatform } = require('./lib/app/app');
3
3
 
4
- // async function testClone() {
5
- // try {
6
- // // Тестові дані для створення кампанії
7
- // const testApp = {
8
- // id: 901,
9
- // bundle: "com.test.app",
10
- // name: "Test App",
11
- // platforms: {
12
- // '@': {
13
- // geo: ["UA", "RU", "US"],
14
- // appsflyerParams: {
15
- // apiToken: "test_token"
16
- // }
17
- // }
18
- // },
19
- // domainParams: {
20
- // name: "test.com"
21
- // }
22
- // };
23
-
24
- // // Створюємо Traffle кампанію
25
- // const result = await TraffleKeitaroService.cloneTraffleCampaign(
26
- // testApp,
27
- // EPlatform.GENERAL,
28
- // true // addDefaultStreams
29
- // );
4
+ async function testClone() {
5
+ try {
6
+ // Тестові дані для створення кампанії
7
+ const testApp = {
8
+ id: 901,
9
+ bundle: "com.test.app",
10
+ name: "Test App",
11
+ platforms: {
12
+ '@': {
13
+ geo: ["UA", "RU", "US"],
14
+ appsflyerParams: {
15
+ apiToken: "test_token",
16
+ devKey: "test_dev_key"
17
+ }
18
+ }
19
+ },
20
+ domainParams: {
21
+ name: "test.com"
22
+ }
23
+ };
24
+
25
+ // Створюємо Traffle кампанію
26
+ const result = await TraffleKeitaroService.cloneTraffleCampaign(
27
+ testApp,
28
+ EPlatform.GENERAL,
29
+ true // addDefaultStreams
30
+ );
30
31
 
31
- // console.log('Cloned campaign:', result);
32
- // console.log(`domain`, result.domain.split('/')[2])
33
- // } catch (error) {
34
- // console.error('Error:', error);
35
- // }
36
- // }
37
-
38
- // testClone();
39
-
32
+ console.log('Cloned campaign:', result);
33
+ console.log(`domain`, result.domain.split('/')[2])
34
+ } catch (error) {
35
+ console.error('Error:', error);
36
+ }
37
+ }
40
38
 
39
+ testClone();
41
40
 
42
41
 
43
- async function testC() {
44
42
 
45
- const createGroup = await TraffleKeitaroService.createGroup("727", "campaigns")
46
- console.log(`createGroup`, createGroup)
47
- }
48
43
 
49
- testC()