@bprotsyk/aso-core 2.1.121 → 2.1.123
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/lib/network/keitaro/traffle/traffle-keitaro-service.d.ts +2 -0
- package/lib/network/keitaro/traffle/traffle-keitaro-service.js +129 -2
- package/package.json +1 -1
- package/src/network/keitaro/traffle/traffle-keitaro-service.ts +141 -2
- package/test-keitaro-clo-geos.js +0 -93
- package/test-keitaro.js +0 -61
|
@@ -132,6 +132,7 @@ declare function TrafleKeitaroParameters(parameters: any): Promise<{
|
|
|
132
132
|
};
|
|
133
133
|
} | null>;
|
|
134
134
|
declare function cloneTraffleCampaign(app: IApp, platform: EPlatform, addDefaultStreams?: boolean): Promise<IKeitaroCampaign | any>;
|
|
135
|
+
export declare function updateStreamsForApp(app: IApp, platform: EPlatform): Promise<boolean>;
|
|
135
136
|
export declare const TraffleKeitaroService: {
|
|
136
137
|
addOffersToTraffleKeitaro: typeof addOffersToTraffleKeitaro;
|
|
137
138
|
getTraffleOffersGroups: typeof getTraffleOffersGroups;
|
|
@@ -142,5 +143,6 @@ export declare const TraffleKeitaroService: {
|
|
|
142
143
|
updateOfferLinkById: typeof updateOfferLinkById;
|
|
143
144
|
cloneTraffleCampaign: typeof cloneTraffleCampaign;
|
|
144
145
|
TrafleKeitaroParameters: typeof TrafleKeitaroParameters;
|
|
146
|
+
updateStreamsForApp: typeof updateStreamsForApp;
|
|
145
147
|
};
|
|
146
148
|
export {};
|
|
@@ -3,11 +3,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.TraffleKeitaroService = exports.ITraffleTrafficType = void 0;
|
|
6
|
+
exports.TraffleKeitaroService = exports.updateStreamsForApp = exports.ITraffleTrafficType = void 0;
|
|
7
7
|
const http_1 = __importDefault(require("./http"));
|
|
8
8
|
const app_1 = require("../../../app/app");
|
|
9
9
|
const openai_1 = require("../../../network/openai/openai");
|
|
10
10
|
const words_1 = require("../../../templates/words");
|
|
11
|
+
// Константи для функції updateStreamsForApp
|
|
12
|
+
const STREAM_NAMES = {
|
|
13
|
+
CLO: "CLO"
|
|
14
|
+
};
|
|
15
|
+
const FILTER_NAMES = {
|
|
16
|
+
COUNTRY: "country"
|
|
17
|
+
};
|
|
18
|
+
const FILTER_MODES = {
|
|
19
|
+
ACCEPT: "accept"
|
|
20
|
+
};
|
|
21
|
+
const STREAM_STATES = {
|
|
22
|
+
ACTIVE: "active",
|
|
23
|
+
DISABLED: "disabled"
|
|
24
|
+
};
|
|
11
25
|
async function getAllOffers() {
|
|
12
26
|
const { data: offers } = await http_1.default.get('offers');
|
|
13
27
|
return offers;
|
|
@@ -709,6 +723,119 @@ async function cloneTraffleCampaign(app, platform, addDefaultStreams) {
|
|
|
709
723
|
const updatedCampaign = await getCampaignById(newCampaign.id);
|
|
710
724
|
return updatedCampaign;
|
|
711
725
|
}
|
|
726
|
+
async function findCampaignForAppPlatform(app, platform) {
|
|
727
|
+
let allCampaigns = await getAllCampaigns();
|
|
728
|
+
let matchingCampaign = [];
|
|
729
|
+
if (platform && platform !== app_1.EPlatform.GENERAL) {
|
|
730
|
+
const platformName = (0, app_1.getPlatformName)(platform);
|
|
731
|
+
matchingCampaign = allCampaigns.filter((c) => {
|
|
732
|
+
const hasDomain = c.name.includes(app.domainParams.name);
|
|
733
|
+
const hasGroup = c.group == app.id.toString();
|
|
734
|
+
const platformPattern = new RegExp(`\\(.*${platformName}.*\\)\\s*$`);
|
|
735
|
+
const hasPlatform = platformPattern.test(c.name);
|
|
736
|
+
return hasGroup && hasDomain && hasPlatform;
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
matchingCampaign = allCampaigns.filter((c) => {
|
|
741
|
+
const hasBundle = c.name.includes(`[${app.bundle}]`);
|
|
742
|
+
const hasDomain = c.name.includes(app.domainParams.name);
|
|
743
|
+
const noPlatformAtEnd = !/\(.*(?:iOS|Android|Desktop|Mobile).*\)\s*$/.test(c.name);
|
|
744
|
+
return hasBundle && hasDomain && noPlatformAtEnd;
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
return matchingCampaign.length > 0 ? matchingCampaign[0] : null;
|
|
748
|
+
}
|
|
749
|
+
function arraysIntersect(a, b) {
|
|
750
|
+
if (!a || !b || a.length === 0 || b.length === 0)
|
|
751
|
+
return false;
|
|
752
|
+
const setA = new Set(a);
|
|
753
|
+
for (const item of b) {
|
|
754
|
+
if (setA.has(item))
|
|
755
|
+
return true;
|
|
756
|
+
}
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
async function updateStreamState(streamId, newState) {
|
|
760
|
+
console.log(`Updating stream ${streamId} to state: ${newState}`);
|
|
761
|
+
try {
|
|
762
|
+
await http_1.default.put(`streams/${streamId}`, { state: newState });
|
|
763
|
+
console.log(`Successfully updated stream ${streamId} to ${newState}`);
|
|
764
|
+
}
|
|
765
|
+
catch (error) {
|
|
766
|
+
console.error(`Failed to update stream ${streamId}:`, error.response?.data || error.message);
|
|
767
|
+
throw error;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
async function updateStreamsForApp(app, platform) {
|
|
771
|
+
try {
|
|
772
|
+
const platformData = app.platforms[platform];
|
|
773
|
+
if (!platformData) {
|
|
774
|
+
console.log(`No platform data for platform ${platform}`);
|
|
775
|
+
return false;
|
|
776
|
+
}
|
|
777
|
+
// Перевіряємо чи є directType і чи він трафлєвський
|
|
778
|
+
const directType = platformData.direct?.directType;
|
|
779
|
+
if (!directType || (directType !== app_1.EDirectType.TRAFFLE_KEITARO_OFFER && directType !== app_1.EDirectType.TRAFFLE_OFFER_DIRECT)) {
|
|
780
|
+
console.log(`Skipping stream update for platform ${platform}: directType is not traffle (${directType})`);
|
|
781
|
+
return false;
|
|
782
|
+
}
|
|
783
|
+
const campaign = await findCampaignForAppPlatform(app, platform);
|
|
784
|
+
if (!campaign) {
|
|
785
|
+
console.log(`No campaign found for app ${app.id} (${app.bundle}) and platform ${platform}`);
|
|
786
|
+
return false;
|
|
787
|
+
}
|
|
788
|
+
const streams = await getStreamsByCampaignId(campaign.id);
|
|
789
|
+
let changed = false;
|
|
790
|
+
if (!Array.isArray(streams) || streams.length === 0) {
|
|
791
|
+
console.log(`No streams found for campaign ${campaign.id}`);
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
console.log(`Found ${streams.length} streams for campaign ${campaign.id}:`);
|
|
795
|
+
streams.forEach((s) => {
|
|
796
|
+
console.log(`- Stream ${s.id}: "${s.name}" (state: ${s.state})`);
|
|
797
|
+
});
|
|
798
|
+
if (!platformData.enabled) {
|
|
799
|
+
for (const s of streams) {
|
|
800
|
+
const isClo = s.name === STREAM_NAMES.CLO;
|
|
801
|
+
const hasCountryFilter = Array.isArray(s.filters) && s.filters.some((f) => f?.name === FILTER_NAMES.COUNTRY);
|
|
802
|
+
if ((isClo || hasCountryFilter) && s.state !== STREAM_STATES.DISABLED) {
|
|
803
|
+
await updateStreamState(s.id, STREAM_STATES.DISABLED);
|
|
804
|
+
changed = true;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return changed;
|
|
808
|
+
}
|
|
809
|
+
// enabled: turn on CLO and geo streams that match platform geo. Leave others as-is.
|
|
810
|
+
const platformGeo = platformData.geo || [];
|
|
811
|
+
for (const s of streams) {
|
|
812
|
+
const isClo = s.name === STREAM_NAMES.CLO;
|
|
813
|
+
if (isClo && s.state !== STREAM_STATES.ACTIVE) {
|
|
814
|
+
await updateStreamState(s.id, STREAM_STATES.ACTIVE);
|
|
815
|
+
changed = true;
|
|
816
|
+
continue;
|
|
817
|
+
}
|
|
818
|
+
const countryFilter = Array.isArray(s.filters) ? s.filters.find((f) => f?.name === FILTER_NAMES.COUNTRY) : null;
|
|
819
|
+
if (!countryFilter)
|
|
820
|
+
continue;
|
|
821
|
+
// Heuristic: enable only geo streams whose payload intersects platform geo when mode is 'accept'.
|
|
822
|
+
const mode = countryFilter?.mode;
|
|
823
|
+
const payload = Array.isArray(countryFilter?.payload) ? countryFilter.payload : [];
|
|
824
|
+
if (mode === FILTER_MODES.ACCEPT && arraysIntersect(payload, platformGeo)) {
|
|
825
|
+
if (s.state !== STREAM_STATES.ACTIVE) {
|
|
826
|
+
await updateStreamState(s.id, STREAM_STATES.ACTIVE);
|
|
827
|
+
changed = true;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
return changed;
|
|
832
|
+
}
|
|
833
|
+
catch (error) {
|
|
834
|
+
console.error("Failed to update streams for app:", error);
|
|
835
|
+
return false;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
exports.updateStreamsForApp = updateStreamsForApp;
|
|
712
839
|
exports.TraffleKeitaroService = {
|
|
713
|
-
addOffersToTraffleKeitaro, getTraffleOffersGroups, getTraffleAffiliateNetworks, createGroup, deleteOfferById, getAllOffers, updateOfferLinkById, cloneTraffleCampaign, TrafleKeitaroParameters
|
|
840
|
+
addOffersToTraffleKeitaro, getTraffleOffersGroups, getTraffleAffiliateNetworks, createGroup, deleteOfferById, getAllOffers, updateOfferLinkById, cloneTraffleCampaign, TrafleKeitaroParameters, updateStreamsForApp
|
|
714
841
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import { IOffer } from "../../../offers/offer"
|
|
|
3
3
|
import keitaroApi from "./http"
|
|
4
4
|
import { IKeitaroCampaign } from "../../../keitaro/keitaro-campaign";
|
|
5
5
|
import { IKeitaroDomain } from "../../../keitaro/keitaro-domain";
|
|
6
|
-
import { EPlatform, getPlatformName, IApp } from "../../../app/app";
|
|
6
|
+
import { EPlatform, getPlatformName, IApp, EDirectType } from "../../../app/app";
|
|
7
7
|
import { TRAFFIC_SOURCE_ID_FLASH_AI, prepareOWCampaignParameters } from "../../../utils/keitaro-utils";
|
|
8
8
|
import { convertMillisToDate, getTimestampsForTodayAndYesterday } from "../../../utils/general";
|
|
9
9
|
import { IKeitaroOffer, IKeitaroOffersFilter } from "index";
|
|
@@ -13,6 +13,24 @@ import { off } from "process";
|
|
|
13
13
|
import { IKeitaroCampaignParameters } from "../../../keitaro/keitaro-campaign";
|
|
14
14
|
import { getRandomWord } from "../../../templates/words";
|
|
15
15
|
|
|
16
|
+
// Константи для функції updateStreamsForApp
|
|
17
|
+
const STREAM_NAMES = {
|
|
18
|
+
CLO: "CLO"
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
const FILTER_NAMES = {
|
|
22
|
+
COUNTRY: "country"
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
const FILTER_MODES = {
|
|
26
|
+
ACCEPT: "accept"
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
const STREAM_STATES = {
|
|
30
|
+
ACTIVE: "active",
|
|
31
|
+
DISABLED: "disabled"
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
16
34
|
async function getAllOffers(): Promise<IKeitaroOffer[]> {
|
|
17
35
|
const { data: offers } = await keitaroApi.get<IKeitaroOffer[]>('offers')
|
|
18
36
|
|
|
@@ -856,7 +874,128 @@ async function cloneTraffleCampaign(app: IApp, platform: EPlatform, addDefaultSt
|
|
|
856
874
|
return updatedCampaign;
|
|
857
875
|
}
|
|
858
876
|
|
|
877
|
+
async function findCampaignForAppPlatform(app: IApp, platform: EPlatform): Promise<IKeitaroCampaign | null> {
|
|
878
|
+
let allCampaigns = await getAllCampaigns();
|
|
879
|
+
let matchingCampaign: IKeitaroCampaign[] = [];
|
|
880
|
+
|
|
881
|
+
if (platform && platform !== EPlatform.GENERAL) {
|
|
882
|
+
const platformName = getPlatformName(platform);
|
|
883
|
+
matchingCampaign = allCampaigns.filter((c) => {
|
|
884
|
+
const hasDomain = c.name.includes(app.domainParams.name);
|
|
885
|
+
const hasGroup = c.group == app.id.toString();
|
|
886
|
+
const platformPattern = new RegExp(`\\(.*${platformName}.*\\)\\s*$`);
|
|
887
|
+
const hasPlatform = platformPattern.test(c.name);
|
|
888
|
+
return hasGroup && hasDomain && hasPlatform;
|
|
889
|
+
});
|
|
890
|
+
} else {
|
|
891
|
+
matchingCampaign = allCampaigns.filter((c) => {
|
|
892
|
+
const hasBundle = c.name.includes(`[${app.bundle}]`);
|
|
893
|
+
const hasDomain = c.name.includes(app.domainParams.name);
|
|
894
|
+
const noPlatformAtEnd = !/\(.*(?:iOS|Android|Desktop|Mobile).*\)\s*$/.test(c.name);
|
|
895
|
+
return hasBundle && hasDomain && noPlatformAtEnd;
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
return matchingCampaign.length > 0 ? matchingCampaign[0] : null;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
function arraysIntersect<T>(a: T[] | null | undefined, b: T[] | null | undefined): boolean {
|
|
903
|
+
if (!a || !b || a.length === 0 || b.length === 0) return false;
|
|
904
|
+
const setA = new Set(a);
|
|
905
|
+
for (const item of b) {
|
|
906
|
+
if (setA.has(item)) return true;
|
|
907
|
+
}
|
|
908
|
+
return false;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
async function updateStreamState(streamId: number, newState: string): Promise<void> {
|
|
912
|
+
console.log(`Updating stream ${streamId} to state: ${newState}`);
|
|
913
|
+
try {
|
|
914
|
+
await keitaroApi.put(`streams/${streamId}`, { state: newState });
|
|
915
|
+
console.log(`Successfully updated stream ${streamId} to ${newState}`);
|
|
916
|
+
} catch (error: any) {
|
|
917
|
+
console.error(`Failed to update stream ${streamId}:`, error.response?.data || error.message);
|
|
918
|
+
throw error;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
export async function updateStreamsForApp(app: IApp, platform: EPlatform): Promise<boolean> {
|
|
923
|
+
try {
|
|
924
|
+
const platformData = app.platforms[platform];
|
|
925
|
+
if (!platformData) {
|
|
926
|
+
console.log(`No platform data for platform ${platform}`);
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
// Перевіряємо чи є directType і чи він трафлєвський
|
|
931
|
+
const directType = platformData.direct?.directType;
|
|
932
|
+
if (!directType || (directType !== EDirectType.TRAFFLE_KEITARO_OFFER && directType !== EDirectType.TRAFFLE_OFFER_DIRECT)) {
|
|
933
|
+
console.log(`Skipping stream update for platform ${platform}: directType is not traffle (${directType})`);
|
|
934
|
+
return false;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
const campaign = await findCampaignForAppPlatform(app, platform);
|
|
938
|
+
if (!campaign) {
|
|
939
|
+
console.log(`No campaign found for app ${app.id} (${app.bundle}) and platform ${platform}`);
|
|
940
|
+
return false;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
const streams = await getStreamsByCampaignId(campaign.id);
|
|
944
|
+
let changed = false;
|
|
945
|
+
|
|
946
|
+
if (!Array.isArray(streams) || streams.length === 0) {
|
|
947
|
+
console.log(`No streams found for campaign ${campaign.id}`);
|
|
948
|
+
return false;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
console.log(`Found ${streams.length} streams for campaign ${campaign.id}:`);
|
|
952
|
+
streams.forEach((s: any) => {
|
|
953
|
+
console.log(`- Stream ${s.id}: "${s.name}" (state: ${s.state})`);
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
if (!platformData.enabled) {
|
|
957
|
+
for (const s of streams) {
|
|
958
|
+
const isClo = s.name === STREAM_NAMES.CLO;
|
|
959
|
+
const hasCountryFilter = Array.isArray(s.filters) && s.filters.some((f: any) => f?.name === FILTER_NAMES.COUNTRY);
|
|
960
|
+
if ((isClo || hasCountryFilter) && s.state !== STREAM_STATES.DISABLED) {
|
|
961
|
+
await updateStreamState((s as any).id, STREAM_STATES.DISABLED);
|
|
962
|
+
changed = true;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
return changed;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// enabled: turn on CLO and geo streams that match platform geo. Leave others as-is.
|
|
969
|
+
const platformGeo = platformData.geo || [];
|
|
970
|
+
for (const s of streams) {
|
|
971
|
+
const isClo = s.name === STREAM_NAMES.CLO;
|
|
972
|
+
if (isClo && s.state !== STREAM_STATES.ACTIVE) {
|
|
973
|
+
await updateStreamState((s as any).id, STREAM_STATES.ACTIVE);
|
|
974
|
+
changed = true;
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
const countryFilter = Array.isArray(s.filters) ? s.filters.find((f: any) => f?.name === FILTER_NAMES.COUNTRY) : null;
|
|
979
|
+
if (!countryFilter) continue;
|
|
980
|
+
|
|
981
|
+
// Heuristic: enable only geo streams whose payload intersects platform geo when mode is 'accept'.
|
|
982
|
+
const mode: string | undefined = countryFilter?.mode;
|
|
983
|
+
const payload: string[] = Array.isArray(countryFilter?.payload) ? countryFilter.payload : [];
|
|
984
|
+
if (mode === FILTER_MODES.ACCEPT && arraysIntersect(payload, platformGeo)) {
|
|
985
|
+
if (s.state !== STREAM_STATES.ACTIVE) {
|
|
986
|
+
await updateStreamState((s as any).id, STREAM_STATES.ACTIVE);
|
|
987
|
+
changed = true;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
return changed;
|
|
993
|
+
} catch (error) {
|
|
994
|
+
console.error("Failed to update streams for app:", error);
|
|
995
|
+
return false;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
859
998
|
|
|
860
999
|
export const TraffleKeitaroService = {
|
|
861
|
-
addOffersToTraffleKeitaro, getTraffleOffersGroups, getTraffleAffiliateNetworks, createGroup, deleteOfferById, getAllOffers, updateOfferLinkById, cloneTraffleCampaign, TrafleKeitaroParameters
|
|
1000
|
+
addOffersToTraffleKeitaro, getTraffleOffersGroups, getTraffleAffiliateNetworks, createGroup, deleteOfferById, getAllOffers, updateOfferLinkById, cloneTraffleCampaign, TrafleKeitaroParameters, updateStreamsForApp
|
|
862
1001
|
}
|
package/test-keitaro-clo-geos.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
const { KeitaroCLOGeosService } = require('./lib/keitaro/keitaro-clo-geos');
|
|
2
|
-
|
|
3
|
-
// Тестові дані додатків
|
|
4
|
-
const testApps = [
|
|
5
|
-
{
|
|
6
|
-
id: 9999,
|
|
7
|
-
bundle: "com.test.app2",
|
|
8
|
-
name: "Test App 2",
|
|
9
|
-
domainParams: {
|
|
10
|
-
name: "test.com"
|
|
11
|
-
},
|
|
12
|
-
platforms: {
|
|
13
|
-
'@': {
|
|
14
|
-
geo: ["US"],
|
|
15
|
-
enabled: true
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
id: 9998,
|
|
21
|
-
bundle: "com.test.app222",
|
|
22
|
-
name: "Test App 222",
|
|
23
|
-
domainParams: {
|
|
24
|
-
name: "test2.com"
|
|
25
|
-
},
|
|
26
|
-
platforms: {
|
|
27
|
-
'@': {
|
|
28
|
-
geo: ["UA"],
|
|
29
|
-
enabled: true
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
async function testGeoSync() {
|
|
36
|
-
try {
|
|
37
|
-
console.log('=== Тестування синхронізації гео Keitaro CLO ===\n');
|
|
38
|
-
|
|
39
|
-
// Тест 1: Отримання додатків, які потребують оновлення гео
|
|
40
|
-
console.log('1. Отримання додатків, які потребують оновлення гео...');
|
|
41
|
-
const appsNeedingUpdate = await KeitaroCLOGeosService.getAppsNeedingGeoUpdate(testApps);
|
|
42
|
-
console.log(`Результат: ${appsNeedingUpdate.length} додатків потребують оновлення\n`);
|
|
43
|
-
|
|
44
|
-
// Тест 2: Детальна синхронізація
|
|
45
|
-
console.log('2. Повна синхронізація гео...');
|
|
46
|
-
const syncSummary = await KeitaroCLOGeosService.syncKeitaroCLOGeosWithApps(testApps);
|
|
47
|
-
console.log('Результат синхронізації:');
|
|
48
|
-
console.log(`- Всього додатків: ${syncSummary.totalApps}`);
|
|
49
|
-
console.log(`- Потребують оновлення: ${syncSummary.appsNeedingUpdate}`);
|
|
50
|
-
console.log(`- Помилки: ${syncSummary.errors.length}\n`);
|
|
51
|
-
|
|
52
|
-
// Тест 3: Деталі для конкретного додатку (використовуємо наявний ID 9999)
|
|
53
|
-
console.log('3. Деталі синхронізації для додатку 9999...');
|
|
54
|
-
const appDetails = await KeitaroCLOGeosService.getAppGeoSyncDetails(9999, '@', testApps);
|
|
55
|
-
if (appDetails) {
|
|
56
|
-
// console.log('Деталі додатку:');
|
|
57
|
-
// console.log(`- App ID: ${appDetails.appId}`);
|
|
58
|
-
// console.log(`- Платформа: ${appDetails.platform}`);
|
|
59
|
-
// console.log(`- Keitaro гео: ${appDetails.keitaroGeos.join(', ')}`);
|
|
60
|
-
// console.log(`- App гео: ${appDetails.appGeos.join(', ')}`);
|
|
61
|
-
// console.log(`- Відсутні гео: ${appDetails.missingGeos.join(', ')}`);
|
|
62
|
-
// console.log(`- Потребує оновлення: ${appDetails.needsUpdate}\n`);
|
|
63
|
-
console.log(`appDetails: ${JSON.stringify(appDetails)}`);
|
|
64
|
-
} else {
|
|
65
|
-
console.log('Додаток не знайдено або помилка\n');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Виводимо всі оновлення
|
|
71
|
-
if (syncSummary.updates.length > 0) {
|
|
72
|
-
console.log('5. Список оновлень гео:');
|
|
73
|
-
syncSummary.updates.forEach((update, index) => {
|
|
74
|
-
console.log(`${index + 1}. Додаток ${update.appId} (${update.platform}):`);
|
|
75
|
-
console.log(` Нові гео: ${update.newGeos.join(', ')}`);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Виводимо помилки, якщо є
|
|
80
|
-
if (syncSummary.errors.length > 0) {
|
|
81
|
-
console.log('\n6. Помилки:');
|
|
82
|
-
syncSummary.errors.forEach((error, index) => {
|
|
83
|
-
console.log(`${index + 1}. ${error}`);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
} catch (error) {
|
|
88
|
-
console.error('Помилка тестування:', error);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Запускаємо тест
|
|
93
|
-
testGeoSync();
|
package/test-keitaro.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const { TraffleKeitaroService } = require('./lib/network/keitaro/traffle/traffle-keitaro-service');
|
|
2
|
-
const { EPlatform } = require('./lib/app/app');
|
|
3
|
-
|
|
4
|
-
async function testClone() {
|
|
5
|
-
try {
|
|
6
|
-
// Тестові дані для створення кампанії з trackingParams
|
|
7
|
-
const testApp = {
|
|
8
|
-
id: 9998,
|
|
9
|
-
bundle: "com.test.app222",
|
|
10
|
-
name: "Test App",
|
|
11
|
-
platforms: {
|
|
12
|
-
'@': {
|
|
13
|
-
geo: ["UA"],
|
|
14
|
-
appsflyerParams: {
|
|
15
|
-
apiToken: "test_token",
|
|
16
|
-
devKey: "test_dev_key"
|
|
17
|
-
},
|
|
18
|
-
direct: {
|
|
19
|
-
enabled: true,
|
|
20
|
-
keitaroData: {
|
|
21
|
-
trackingCampaignAlias: "test123",
|
|
22
|
-
trackingCampaignId: 9999,
|
|
23
|
-
trackingCampaignName: "[9998] Test App ET [com.test.app222] [Android] test2.com",
|
|
24
|
-
trackingDomainName: "test2.com",
|
|
25
|
-
campingToken: "test_token_123",
|
|
26
|
-
trackingParams: {
|
|
27
|
-
|
|
28
|
-
advertising_id: "old_advertising_id",
|
|
29
|
-
appsflyer_device_id: "old_device_id"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
domainParams: {
|
|
36
|
-
name: "test2.com"
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// Створюємо Traffle кампанію
|
|
41
|
-
const result = await TraffleKeitaroService.cloneTraffleCampaign(
|
|
42
|
-
testApp,
|
|
43
|
-
EPlatform.GENERAL,
|
|
44
|
-
true // addDefaultStreams
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
console.log('Cloned campaign:', result);
|
|
48
|
-
console.log(`domain`, result.domain.split('/')[2]);
|
|
49
|
-
|
|
50
|
-
// Показуємо оновлені trackingParams
|
|
51
|
-
console.log('Updated trackingParams:', testApp.platforms['@'].direct.keitaroData.trackingParams);
|
|
52
|
-
} catch (error) {
|
|
53
|
-
console.error('Error:', error);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
testClone();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|