@bprotsyk/aso-core 2.1.21 → 2.1.24
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/README.md +1 -1
- package/docs/assets/highlight.css +22 -22
- package/docs/assets/main.js +58 -58
- package/docs/assets/style.css +1279 -1279
- package/docs/enums/PanelUserAccessScope.html +126 -126
- package/docs/functions/ASO_v0.toDefault.html +80 -80
- package/docs/functions/ASO_v1.toDefault.html +80 -80
- package/docs/functions/ASO_v2.toDefault.html +78 -78
- package/docs/functions/ASO_v3.toDefault.html +77 -77
- package/docs/functions/ASO_v4.toDefault.html +75 -75
- package/docs/functions/ASO_v5.toDefault.html +76 -76
- package/docs/functions/ColoredText.html +92 -92
- package/docs/functions/ShapeDiv.html +109 -109
- package/docs/index.html +82 -82
- package/docs/interfaces/ASOConfigFetch.IUsageLogEntry.html +1413 -1413
- package/docs/interfaces/ASOConfigFetch.IUsageLogRequest.html +103 -103
- package/docs/interfaces/ASOConfigFetch.IUsageLogResponse.html +108 -108
- package/docs/interfaces/ASO_v0.IAuthorizationActionMapping.html +145 -145
- package/docs/interfaces/ASO_v0.IColoredSpan.html +89 -89
- package/docs/interfaces/ASO_v0.IColoredSpanMapping.html +89 -89
- package/docs/interfaces/ASO_v0.IColoredString.html +89 -89
- package/docs/interfaces/ASO_v0.IColoredStringMapping.html +89 -89
- package/docs/interfaces/ASO_v0.IConfig.html +556 -556
- package/docs/interfaces/ASO_v0.IConfigMapping.html +229 -229
- package/docs/interfaces/ASO_v0.ILocalization.html +516 -516
- package/docs/interfaces/ASO_v0.ILocalizationMap.html +77 -77
- package/docs/interfaces/ASO_v0.ILocalizationMapping.html +502 -502
- package/docs/interfaces/ASO_v0.IOfferResult.html +103 -103
- package/docs/interfaces/ASO_v0.IOfferResultEmoji.html +82 -82
- package/docs/interfaces/ASO_v0.IOfferResultMapping.html +117 -117
- package/docs/interfaces/ASO_v0.IOfferSectionMapping.html +108 -108
- package/docs/interfaces/ASO_v0.IOffersSection.html +96 -96
- package/docs/interfaces/ASO_v0.ISectionPalette.html +152 -152
- package/docs/interfaces/ASO_v0.ISectionPaletteMapping.html +152 -152
- package/docs/interfaces/ASO_v1.IAuthorizationActionMapping.html +145 -145
- package/docs/interfaces/ASO_v1.IColoredSpan.html +89 -89
- package/docs/interfaces/ASO_v1.IColoredSpanMapping.html +89 -89
- package/docs/interfaces/ASO_v1.IColoredString.html +89 -89
- package/docs/interfaces/ASO_v1.IColoredStringMapping.html +89 -89
- package/docs/interfaces/ASO_v1.IConfig.html +549 -549
- package/docs/interfaces/ASO_v1.IConfigMapping.html +229 -229
- package/docs/interfaces/ASO_v1.ILocalization.html +481 -481
- package/docs/interfaces/ASO_v1.ILocalizationMap.html +77 -77
- package/docs/interfaces/ASO_v1.ILocalizationMapping.html +481 -481
- package/docs/interfaces/ASO_v1.IOfferResult.html +103 -103
- package/docs/interfaces/ASO_v1.IOfferResultEmoji.html +82 -82
- package/docs/interfaces/ASO_v1.IOfferResultMapping.html +117 -117
- package/docs/interfaces/ASO_v1.IOfferSectionMapping.html +108 -108
- package/docs/interfaces/ASO_v1.IOffersSection.html +101 -101
- package/docs/interfaces/ASO_v1.ISectionPalette.html +152 -152
- package/docs/interfaces/ASO_v1.ISectionPaletteMapping.html +152 -152
- package/docs/interfaces/ASO_v2.IAuthorizationActionMapping.html +138 -138
- package/docs/interfaces/ASO_v2.IColoredSpanMapping.html +89 -89
- package/docs/interfaces/ASO_v2.IColoredString.html +89 -89
- package/docs/interfaces/ASO_v2.IColoredStringMapping.html +89 -89
- package/docs/interfaces/ASO_v2.IConfig.html +493 -493
- package/docs/interfaces/ASO_v2.IConfigMapping.html +201 -201
- package/docs/interfaces/ASO_v2.ILocalization.html +474 -474
- package/docs/interfaces/ASO_v2.ILocalizationMap.html +75 -75
- package/docs/interfaces/ASO_v2.ILocalizationMapping.html +362 -362
- package/docs/interfaces/ASO_v2.IOfferResult.html +110 -110
- package/docs/interfaces/ASO_v2.IOfferResultMapping.html +117 -117
- package/docs/interfaces/ASO_v2.IOfferSectionMapping.html +108 -108
- package/docs/interfaces/ASO_v2.IOffersSection.html +101 -101
- package/docs/interfaces/ASO_v2.ISectionPalette.html +152 -152
- package/docs/interfaces/ASO_v2.ISectionPaletteMapping.html +152 -152
- package/docs/interfaces/ASO_v3.IAuthorizationActionMapping.html +138 -138
- package/docs/interfaces/ASO_v3.IColoredSpanMapping.html +89 -89
- package/docs/interfaces/ASO_v3.IColoredString.html +89 -89
- package/docs/interfaces/ASO_v3.IColoredStringMapping.html +89 -89
- package/docs/interfaces/ASO_v3.IConfig.html +514 -514
- package/docs/interfaces/ASO_v3.IConfigMapping.html +208 -208
- package/docs/interfaces/ASO_v3.ILocalization.html +446 -446
- package/docs/interfaces/ASO_v3.ILocalizationMap.html +74 -74
- package/docs/interfaces/ASO_v3.ILocalizationMapping.html +341 -341
- package/docs/interfaces/ASO_v3.IOfferResultMapping.html +117 -117
- package/docs/interfaces/ASO_v3.IOfferSectionMapping.html +108 -108
- package/docs/interfaces/ASO_v3.IOffersSection.html +101 -101
- package/docs/interfaces/ASO_v3.ISectionPalette.html +152 -152
- package/docs/interfaces/ASO_v3.ISectionPaletteMapping.html +152 -152
- package/docs/interfaces/ASO_v4.IAuthorizationActionMapping.html +138 -138
- package/docs/interfaces/ASO_v4.IColoredSpanMapping.html +89 -89
- package/docs/interfaces/ASO_v4.IColoredString.html +89 -89
- package/docs/interfaces/ASO_v4.IColoredStringMapping.html +89 -89
- package/docs/interfaces/ASO_v4.IConfig.html +514 -514
- package/docs/interfaces/ASO_v4.IConfigMapping.html +131 -131
- package/docs/interfaces/ASO_v4.ILocalization.html +369 -369
- package/docs/interfaces/ASO_v4.ILocalizationMap.html +72 -72
- package/docs/interfaces/ASO_v4.ILocalizationMapping.html +257 -257
- package/docs/interfaces/ASO_v4.IOfferResultMapping.html +117 -117
- package/docs/interfaces/ASO_v4.IOfferSectionMapping.html +89 -89
- package/docs/interfaces/ASO_v4.LocalizedString.html +82 -82
- package/docs/interfaces/ASO_v5.IAuthorizationActionMapping.html +138 -138
- package/docs/interfaces/ASO_v5.IColoredSpan.html +89 -89
- package/docs/interfaces/ASO_v5.IColoredSpanMapping.html +89 -89
- package/docs/interfaces/ASO_v5.IColoredString.html +89 -89
- package/docs/interfaces/ASO_v5.IColoredStringMapping.html +89 -89
- package/docs/interfaces/ASO_v5.IConfig.html +542 -542
- package/docs/interfaces/ASO_v5.IConfigMapping.html +159 -159
- package/docs/interfaces/ASO_v5.ILocalization.html +411 -411
- package/docs/interfaces/ASO_v5.ILocalizationMap.html +73 -73
- package/docs/interfaces/ASO_v5.ILocalizationMapping.html +299 -299
- package/docs/interfaces/ASO_v5.IOfferResultMapping.html +117 -117
- package/docs/interfaces/ASO_v5.IOfferSectionMapping.html +89 -89
- package/docs/interfaces/ASO_v5.LocalizedString.html +82 -82
- package/docs/interfaces/IAsoConfigResponse.html +81 -81
- package/docs/interfaces/IAsoCustomizedOffer.html +116 -116
- package/docs/interfaces/IAsoDefaultConfig.html +443 -443
- package/docs/interfaces/IAsoOfferResponse.html +81 -81
- package/docs/interfaces/IAsoSection.html +88 -88
- package/docs/interfaces/IAsoSingleOffer.html +88 -88
- package/docs/interfaces/IAuthToken.html +102 -102
- package/docs/interfaces/IColoredTextProps.html +74 -74
- package/docs/interfaces/IFlashApp.html +144 -144
- package/docs/interfaces/IFlashAppListItem.html +88 -88
- package/docs/interfaces/IGradient.html +95 -95
- package/docs/interfaces/IOffer.html +137 -137
- package/docs/interfaces/IOfferWallAuthConfig.html +130 -130
- package/docs/interfaces/IOfferWallAuthLocalization.html +102 -102
- package/docs/interfaces/IOfferWallAuthSubmitRequest.html +74 -74
- package/docs/interfaces/IOfferWallAuthSubmitResponse.html +74 -74
- package/docs/interfaces/IOfferWallHomeDialogData.html +95 -95
- package/docs/interfaces/IOfferWallOffer.html +109 -109
- package/docs/interfaces/IOfferWallResponse.html +81 -81
- package/docs/interfaces/IOfferWallSection.html +88 -88
- package/docs/interfaces/IPanelUser.html +1405 -1405
- package/docs/interfaces/IPush.html +95 -95
- package/docs/interfaces/IShape.html +102 -102
- package/docs/interfaces/IStroke.html +81 -81
- package/docs/interfaces/IUpsertFlashAppRequest.html +214 -214
- package/docs/interfaces/IUpsertFlashAppResponse.html +81 -81
- package/docs/modules/ASOConfigFetch.html +63 -63
- package/docs/modules/ASO_v0.html +96 -96
- package/docs/modules/ASO_v1.html +96 -96
- package/docs/modules/ASO_v2.html +92 -92
- package/docs/modules/ASO_v3.html +90 -90
- package/docs/modules/ASO_v4.html +86 -86
- package/docs/modules/ASO_v5.html +88 -88
- package/docs/modules.html +133 -133
- package/docs/variables/FlashAppSchema.html +83 -83
- package/docs/variables/PanelUserSchema.html +83 -83
- package/lib/app/app-integration.d.ts +53 -53
- package/lib/app/app-integration.js +63 -63
- package/lib/app/app-list-item.d.ts +5 -5
- package/lib/app/app-list-item.js +2 -2
- package/lib/app/app-type.d.ts +4 -4
- package/lib/app/app-type.js +8 -8
- package/lib/app/app.d.ts +213 -206
- package/lib/app/app.js +184 -173
- package/lib/general/cloudflare-domain.d.ts +42 -42
- package/lib/general/cloudflare-domain.js +12 -12
- package/lib/general/domain.d.ts +108 -108
- package/lib/general/domain.js +61 -61
- package/lib/general/namecheap-domain.d.ts +85 -85
- package/lib/general/namecheap-domain.js +14 -14
- package/lib/general/push.d.ts +6 -6
- package/lib/general/push.js +2 -2
- package/lib/general/queue.d.ts +2 -2
- package/lib/general/queue.js +1 -1
- package/lib/general/shape.d.ts +18 -18
- package/lib/general/shape.js +36 -36
- package/lib/index.d.ts +26 -26
- package/lib/index.js +69 -69
- package/lib/keitaro/keitaro-campaign.d.ts +31 -31
- package/lib/keitaro/keitaro-campaign.js +5 -5
- package/lib/keitaro/keitaro-domain.d.ts +6 -6
- package/lib/keitaro/keitaro-domain.js +2 -2
- package/lib/keitaro/keitaro-offer.d.ts +7 -7
- package/lib/keitaro/keitaro-offer.js +2 -2
- package/lib/keitaro/keitaro-stream.d.ts +20 -20
- package/lib/keitaro/keitaro-stream.js +2 -2
- package/lib/network/keitaro/http.d.ts +2 -2
- package/lib/network/keitaro/http.js +12 -12
- package/lib/network/keitaro/keitaro-service.d.ts +50 -50
- package/lib/network/keitaro/keitaro-service.js +261 -261
- package/lib/offers/list.d.ts +37 -37
- package/lib/offers/list.js +12 -12
- package/lib/offers/offer.d.ts +91 -91
- package/lib/offers/offer.js +42 -42
- package/lib/offers/offerwall/offerwall-home-dialog-data.d.ts +6 -6
- package/lib/offers/offerwall/offerwall-home-dialog-data.js +2 -2
- package/lib/offers/offerwall/offerwall-offer.d.ts +12 -12
- package/lib/offers/offerwall/offerwall-offer.js +2 -2
- package/lib/offers/offerwall/offerwall-response.d.ts +6 -6
- package/lib/offers/offerwall/offerwall-response.js +2 -2
- package/lib/offers/offerwall/offerwall-section.d.ts +6 -6
- package/lib/offers/offerwall/offerwall-section.js +2 -2
- package/lib/offers/section.d.ts +47 -47
- package/lib/offers/section.js +20 -20
- package/lib/panel/auth.d.ts +9 -9
- package/lib/panel/auth.js +2 -2
- package/lib/panel/flash/upsert-flash-app-request.d.ts +31 -29
- package/lib/panel/flash/upsert-flash-app-request.js +2 -2
- package/lib/panel/user.d.ts +46 -46
- package/lib/panel/user.js +28 -28
- package/lib/templates/nginx-template.conf +35 -35
- package/lib/templates/nginx-template.d.ts +1 -1
- package/lib/templates/nginx-template.js +39 -39
- package/lib/templates/nginx-template.ts +35 -35
- package/lib/utils/general.d.ts +11 -11
- package/lib/utils/general.js +40 -40
- package/lib/utils/huawei/converter.d.ts +2 -2
- package/lib/utils/huawei/converter.js +53 -53
- package/lib/utils/keitaro-utils.d.ts +15 -15
- package/lib/utils/keitaro-utils.js +569 -569
- package/lib/utils/server-util.js +303 -303
- package/package.json +51 -51
- package/src/app/app-integration.ts +66 -66
- package/src/app/app-list-item.ts +4 -4
- package/src/app/app-type.ts +3 -3
- package/src/app/app.ts +346 -333
- package/src/general/cloudflare-domain.ts +44 -44
- package/src/general/domain.ts +105 -105
- package/src/general/namecheap-domain.ts +63 -63
- package/src/general/push.ts +5 -5
- package/src/general/queue.ts +4 -4
- package/src/general/shape.tsx +55 -55
- package/src/index.ts +32 -32
- package/src/keitaro/keitaro-campaign.ts +35 -35
- package/src/keitaro/keitaro-domain.ts +5 -5
- package/src/keitaro/keitaro-offer.ts +6 -6
- package/src/keitaro/keitaro-stream.ts +19 -19
- package/src/network/keitaro/http.ts +8 -8
- package/src/network/keitaro/keitaro-service.ts +323 -323
- package/src/offers/list.ts +19 -19
- package/src/offers/offer.ts +80 -80
- package/src/offers/offerwall/offerwall-home-dialog-data.ts +6 -6
- package/src/offers/offerwall/offerwall-offer.ts +12 -12
- package/src/offers/offerwall/offerwall-response.ts +7 -7
- package/src/offers/offerwall/offerwall-section.ts +7 -7
- package/src/offers/section.ts +29 -29
- package/src/panel/auth.ts +9 -9
- package/src/panel/flash/upsert-flash-app-request.ts +39 -37
- package/src/panel/user.ts +38 -38
- package/src/templates/nginx-template.ts +35 -35
- package/src/utils/data.csv +65 -65
- package/src/utils/general.ts +36 -36
- package/src/utils/huawei/converter.ts +55 -55
- package/src/utils/keitaro-utils.ts +661 -661
- package/src/utils/map-apps.json +4747 -4747
- package/src/utils/server-util.ts +368 -368
- package/src/utils/update-postbacks.js +27 -27
- package/tsconfig.json +20 -20
|
@@ -1,323 +1,323 @@
|
|
|
1
|
-
import { IKeitaroStream } from "../../keitaro/keitaro-stream";
|
|
2
|
-
import { IOffer } from "../../offers/offer"
|
|
3
|
-
import keitaroApi from "./http"
|
|
4
|
-
import { IKeitaroCampaign } from "../../keitaro/keitaro-campaign";
|
|
5
|
-
import { IKeitaroDomain } from "../../keitaro/keitaro-domain";
|
|
6
|
-
import { IApp } from "../../app/app";
|
|
7
|
-
import { TRAFFIC_SOURCE_ID_FLASH_AI, prepareOWCampaignParameters } from "../../utils/keitaro-utils";
|
|
8
|
-
import { convertMillisToDate, getTimestampsForTodayAndYesterday } from "../../utils/general";
|
|
9
|
-
import { IKeitaroOffer } from "index";
|
|
10
|
-
|
|
11
|
-
export interface IKeitaroOffersFilter {
|
|
12
|
-
keitaroId?: number,
|
|
13
|
-
name?: string,
|
|
14
|
-
caption?: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function getStreamsByCampaignId(campaignId: number): Promise<IKeitaroStream[]> {
|
|
18
|
-
const { data: streams } = await keitaroApi.get<IKeitaroStream[]>(`campaigns/${campaignId}/streams`);
|
|
19
|
-
|
|
20
|
-
return streams
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function getAllCampaigns(): Promise<IKeitaroCampaign[]> {
|
|
24
|
-
const { data: campaigns } = await keitaroApi.get<IKeitaroCampaign[]>('campaigns');
|
|
25
|
-
return campaigns
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function cloneStreams(originalCampaignId: number, streamPositionsToClone: number[], campaignRegExp: RegExp): Promise<void> {
|
|
29
|
-
// Get the original campaign's streams
|
|
30
|
-
const originalStreams = await getStreamsByCampaignId(originalCampaignId)
|
|
31
|
-
|
|
32
|
-
// Filter the original streams by the given stream positions to clone
|
|
33
|
-
const streamsToClone = originalStreams.filter(stream => streamPositionsToClone.includes(stream.position));
|
|
34
|
-
|
|
35
|
-
// Get a list of all campaigns
|
|
36
|
-
const allCampaigns = await getAllCampaigns()
|
|
37
|
-
|
|
38
|
-
// Filter the campaigns by the given RegExp
|
|
39
|
-
const matchingCampaigns = allCampaigns.filter(campaign => campaignRegExp.exec(campaign.name) && campaign.id != originalCampaignId);
|
|
40
|
-
// console.log(matchingCampaigns)
|
|
41
|
-
|
|
42
|
-
// For each matching campaign, clone the streams
|
|
43
|
-
for (const matchingCampaign of matchingCampaigns) {
|
|
44
|
-
for (const streamToClone of streamsToClone) {
|
|
45
|
-
await keitaroApi.post('streams', {
|
|
46
|
-
name: streamToClone.name,
|
|
47
|
-
campaign_id: matchingCampaign.id,
|
|
48
|
-
schema: streamToClone.schema,
|
|
49
|
-
type: streamToClone.type,
|
|
50
|
-
action_type: streamToClone.action_type,
|
|
51
|
-
weight: 100,
|
|
52
|
-
offers: streamToClone.offers.map((offer) => {
|
|
53
|
-
return {
|
|
54
|
-
offer_id: offer.offer_id,
|
|
55
|
-
share: 100
|
|
56
|
-
}
|
|
57
|
-
}),
|
|
58
|
-
filters: streamToClone.filters.map((filter) => {
|
|
59
|
-
return {
|
|
60
|
-
name: filter.name,
|
|
61
|
-
mode: filter.mode,
|
|
62
|
-
payload: filter.payload
|
|
63
|
-
}
|
|
64
|
-
}),
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function updateCampaign(id: number, payload: Partial<IKeitaroCampaign>) {
|
|
71
|
-
await keitaroApi.put(`campaigns/${id}`, payload)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async function createStreamForMatchingCampaigns(streamPartialPayload: any, offerId: string, campaignRegExp: RegExp, avoidGroup?: number) {
|
|
75
|
-
// Get a list of all campaigns
|
|
76
|
-
const allCampaigns = await getAllCampaigns()
|
|
77
|
-
|
|
78
|
-
// Filter the campaigns by the given RegExp
|
|
79
|
-
const matchingCampaigns = allCampaigns.filter(campaign => (avoidGroup ? campaign.group_id != avoidGroup : true) && campaignRegExp.exec(campaign.name));
|
|
80
|
-
// console.log(matchingCampaigns)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// For each matching campaign, clone the streams
|
|
84
|
-
for (const matchingCampaign of matchingCampaigns) {
|
|
85
|
-
let streams = await getStreamsByCampaignId(matchingCampaign.id)
|
|
86
|
-
|
|
87
|
-
let identicalStream = streams.find((stream) => stream.name.includes(offerId))
|
|
88
|
-
|
|
89
|
-
if (identicalStream) {
|
|
90
|
-
await keitaroApi.put(`streams/${identicalStream.id}`, {
|
|
91
|
-
campaign_id: matchingCampaign.id,
|
|
92
|
-
...streamPartialPayload
|
|
93
|
-
});
|
|
94
|
-
} else {
|
|
95
|
-
await keitaroApi.post('streams', {
|
|
96
|
-
campaign_id: matchingCampaign.id,
|
|
97
|
-
...streamPartialPayload
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async function getAllOffers(): Promise<IKeitaroOffer[]> {
|
|
104
|
-
const { data: offers } = await keitaroApi.get<IKeitaroOffer[]>('offers')
|
|
105
|
-
|
|
106
|
-
return offers
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
async function findKeitaroOffers(filter: IKeitaroOffersFilter): Promise<IKeitaroOffer[]> {
|
|
111
|
-
let offers = await getAllOffers()
|
|
112
|
-
|
|
113
|
-
if (filter.caption) offers = offers.filter((o) => o.name.includes(filter.caption!))
|
|
114
|
-
if (filter.keitaroId) offers = offers.filter((o) => o.id == filter.keitaroId!)
|
|
115
|
-
if (filter.name) offers = offers.filter((o) => o.name.includes(filter.name!))
|
|
116
|
-
|
|
117
|
-
return offers
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async function getOfferByKeitaroId(id: number): Promise<IKeitaroOffer> {
|
|
121
|
-
const { data: offer } = await keitaroApi.get<IKeitaroOffer>(`offers/${id}`)
|
|
122
|
-
|
|
123
|
-
return offer
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async function updateOffer(offer: any): Promise<IKeitaroOffer> {
|
|
127
|
-
const { data: o } = await keitaroApi.put<IKeitaroOffer>(`offers/${offer.id}`, offer)
|
|
128
|
-
|
|
129
|
-
return o
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function createStreamPartialPayload(keitaroOfferId: number, offerName: string, offerId: string, offerGeo: string) {
|
|
133
|
-
return {
|
|
134
|
-
name: `${offerName} ${offerGeo} (${offerId})`,
|
|
135
|
-
schema: "landings",
|
|
136
|
-
type: "regular",
|
|
137
|
-
action_type: "http",
|
|
138
|
-
weight: 100,
|
|
139
|
-
offers: [{
|
|
140
|
-
offer_id: keitaroOfferId,
|
|
141
|
-
share: 100,
|
|
142
|
-
state: "active"
|
|
143
|
-
}],
|
|
144
|
-
filters: [{
|
|
145
|
-
name: "sub_id_15",
|
|
146
|
-
mode: "accept",
|
|
147
|
-
payload: [offerId]
|
|
148
|
-
}],
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async function addOfferToKeitaro(offer: IOffer, affiliateId: number, link: string, avoidGroup?: number, groupId?: number) {
|
|
153
|
-
// TODO look if offer already exists by offer.name
|
|
154
|
-
let allOffers = await getAllOffers()
|
|
155
|
-
let identicalOffer = allOffers.find((o) => { return o.name.includes(offer.name) })
|
|
156
|
-
|
|
157
|
-
let keitaroOfferId
|
|
158
|
-
if (identicalOffer) {
|
|
159
|
-
keitaroOfferId = identicalOffer.id
|
|
160
|
-
} else {
|
|
161
|
-
let offerPayload = {
|
|
162
|
-
name: `${offer.caption} ${offer.geo} (${offer.name})`,
|
|
163
|
-
group_id: groupId || 1,
|
|
164
|
-
action_payload: link,
|
|
165
|
-
affiliate_network_id: affiliateId,
|
|
166
|
-
country: [offer.geo],
|
|
167
|
-
action_type: "http",
|
|
168
|
-
offer_type: "external",
|
|
169
|
-
payout_auto: true,
|
|
170
|
-
payout_upsell: true,
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const { data: keitaroOffer } = await keitaroApi.post(`offers`, offerPayload);
|
|
174
|
-
|
|
175
|
-
keitaroOfferId = keitaroOffer.id
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
let streamPartialPayload = createStreamPartialPayload(keitaroOfferId, offer.caption, offer.name, offer.geo)
|
|
179
|
-
|
|
180
|
-
await createStreamForMatchingCampaigns(streamPartialPayload, offer.name, /◈/, avoidGroup)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async function createCampaign(campaignData: Partial<IKeitaroCampaign>): Promise<IKeitaroCampaign> {
|
|
184
|
-
let { data: campaign } = await keitaroApi.post(`/campaigns`, campaignData)
|
|
185
|
-
|
|
186
|
-
return campaign
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async function getCampaignById(id: number): Promise<IKeitaroCampaign> {
|
|
190
|
-
const { data: campaign } = await keitaroApi.get(`/campaigns/${id}`);
|
|
191
|
-
return campaign
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export async function upsertStreamToCampaign(campaign: IKeitaroCampaign, stream: Partial<IKeitaroStream>) {
|
|
195
|
-
let streams = await getStreamsByCampaignId(campaign.id)
|
|
196
|
-
|
|
197
|
-
let identicalStream = streams.find((s) => stream.name == s.name)
|
|
198
|
-
|
|
199
|
-
if (identicalStream) {
|
|
200
|
-
console.log(`Found identical! Name: ${stream.name}`)
|
|
201
|
-
await keitaroApi.put(`streams/${identicalStream.id}`, {
|
|
202
|
-
campaign_id: campaign.id,
|
|
203
|
-
...stream
|
|
204
|
-
});
|
|
205
|
-
} else {
|
|
206
|
-
await keitaroApi.post('streams', {
|
|
207
|
-
campaign_id: campaign.id,
|
|
208
|
-
...stream
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
async function cloneOWCampaign(app: IApp): Promise<IKeitaroCampaign> {
|
|
214
|
-
let name = `#${app.id} [◈])`
|
|
215
|
-
|
|
216
|
-
let allCampaigns = await getAllCampaigns()
|
|
217
|
-
let matchingCampaign = allCampaigns.filter((c) => c.name.includes(`#${app.id} [◈]`))
|
|
218
|
-
if (matchingCampaign.length > 0) return matchingCampaign[0]
|
|
219
|
-
|
|
220
|
-
const { data: campaigns } = await keitaroApi.post(`/campaigns/2673/clone`);
|
|
221
|
-
|
|
222
|
-
if (campaigns.length == 0) throw Error("Campaign cloning falied")
|
|
223
|
-
|
|
224
|
-
let clonedCampaign: IKeitaroCampaign = campaigns[0]
|
|
225
|
-
|
|
226
|
-
let allDomains = await KeitaroService.getDomains(true)
|
|
227
|
-
if (!allDomains) {
|
|
228
|
-
throw Error(`Failed to get all domains list`)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const domain = allDomains[Math.floor(Math.random() * allDomains.length)];
|
|
232
|
-
|
|
233
|
-
let payload: Partial<IKeitaroCampaign> = {
|
|
234
|
-
name: name,
|
|
235
|
-
traffic_source_id: TRAFFIC_SOURCE_ID_FLASH_AI,
|
|
236
|
-
domain_id: domain.id,
|
|
237
|
-
parameters: prepareOWCampaignParameters(app)
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const { data: campaign } = await keitaroApi.put(`/campaigns/${clonedCampaign.id}`, payload)
|
|
241
|
-
|
|
242
|
-
return campaign
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
async function cloneDCampaign(app: IApp): Promise<IKeitaroCampaign> {
|
|
246
|
-
let name = `D #${app.id} (${app.bundle})`
|
|
247
|
-
|
|
248
|
-
let allCampaigns = await getAllCampaigns()
|
|
249
|
-
let matchingCampaign = allCampaigns.filter((c) => c.name.includes(`D #${app.id}`))
|
|
250
|
-
if (matchingCampaign.length > 0) return matchingCampaign[0]
|
|
251
|
-
|
|
252
|
-
const { data: campaigns } = await keitaroApi.post(`/campaigns/2693/clone`);
|
|
253
|
-
|
|
254
|
-
if (campaigns.length == 0) throw Error("Campaign cloning falied")
|
|
255
|
-
|
|
256
|
-
let clonedCampaign: IKeitaroCampaign = campaigns[0]
|
|
257
|
-
|
|
258
|
-
let allDomains = await KeitaroService.getDomains(true)
|
|
259
|
-
if (!allDomains) {
|
|
260
|
-
throw Error(`Failed to get all domains list`)
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
const domain = allDomains[Math.floor(Math.random() * allDomains.length)];
|
|
264
|
-
|
|
265
|
-
let payload: Partial<IKeitaroCampaign> = {
|
|
266
|
-
name: name,
|
|
267
|
-
traffic_source_id: TRAFFIC_SOURCE_ID_FLASH_AI,
|
|
268
|
-
domain_id: domain.id,
|
|
269
|
-
group_id: 93,
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const { data: campaign } = await keitaroApi.put(`/campaigns/${clonedCampaign.id}`, payload)
|
|
273
|
-
|
|
274
|
-
return campaign
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
async function changeCampaignsGroup(fromId: number, toId: number, exceptForCampaignIds: number[], onlyForCampaignIds?: number[]) {
|
|
278
|
-
let campaigns = await getAllCampaigns()
|
|
279
|
-
const matchingCampaigns = campaigns.filter(campaign => campaign.group_id == fromId
|
|
280
|
-
&& exceptForCampaignIds.length > 0 ? !exceptForCampaignIds.includes(campaign.id) : onlyForCampaignIds?.includes(campaign.id))
|
|
281
|
-
|
|
282
|
-
for (let campaign of matchingCampaigns) {
|
|
283
|
-
await updateCampaign(campaign.id, { group_id: toId })
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Domain
|
|
288
|
-
async function getDomains(onlyActive?: boolean): Promise<IKeitaroDomain[]> {
|
|
289
|
-
const { data: domains } = await keitaroApi.get<IKeitaroDomain[]>(`/domains`)
|
|
290
|
-
return onlyActive ? domains.filter((d) => d.network_status == "active") : domains
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
async function getProfitForTimeRange(from: number, to: number): Promise<number> {
|
|
294
|
-
let fromString = convertMillisToDate(from)
|
|
295
|
-
let toString = convertMillisToDate(to)
|
|
296
|
-
|
|
297
|
-
let { data: data } = await keitaroApi.post(`/report/build`, {
|
|
298
|
-
range: {
|
|
299
|
-
from: fromString,
|
|
300
|
-
to: toString,
|
|
301
|
-
timezone: 'Europe/Kyiv'
|
|
302
|
-
},
|
|
303
|
-
metrics: ['profit']
|
|
304
|
-
})
|
|
305
|
-
|
|
306
|
-
return data.rows[0].profit
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
async function getProfitForTodayAndYesterday(): Promise<any> {
|
|
310
|
-
let timestamps = getTimestampsForTodayAndYesterday()
|
|
311
|
-
let today = await KeitaroService.getProfitForTimeRange(timestamps.today.start, timestamps.today.end)
|
|
312
|
-
let yesterday = await KeitaroService.getProfitForTimeRange(timestamps.yesterday.start, timestamps.yesterday.end)
|
|
313
|
-
|
|
314
|
-
return {
|
|
315
|
-
today: today,
|
|
316
|
-
yesterday: yesterday
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
export const KeitaroService = {
|
|
321
|
-
getStreamsByCampaignId, updateCampaign, getAllCampaigns, getAllOffers, cloneStreams, addOfferToKeitaro, getOfferByKeitaroId, getDomains, createCampaign, getCampaignById, upsertStreamToCampaign, cloneOWCampaign,
|
|
322
|
-
updateOffer, changeCampaignsGroup, getProfitForTimeRange, getProfitForTodayAndYesterday, cloneDCampaign, findKeitaroOffers
|
|
323
|
-
}
|
|
1
|
+
import { IKeitaroStream } from "../../keitaro/keitaro-stream";
|
|
2
|
+
import { IOffer } from "../../offers/offer"
|
|
3
|
+
import keitaroApi from "./http"
|
|
4
|
+
import { IKeitaroCampaign } from "../../keitaro/keitaro-campaign";
|
|
5
|
+
import { IKeitaroDomain } from "../../keitaro/keitaro-domain";
|
|
6
|
+
import { IApp } from "../../app/app";
|
|
7
|
+
import { TRAFFIC_SOURCE_ID_FLASH_AI, prepareOWCampaignParameters } from "../../utils/keitaro-utils";
|
|
8
|
+
import { convertMillisToDate, getTimestampsForTodayAndYesterday } from "../../utils/general";
|
|
9
|
+
import { IKeitaroOffer } from "index";
|
|
10
|
+
|
|
11
|
+
export interface IKeitaroOffersFilter {
|
|
12
|
+
keitaroId?: number,
|
|
13
|
+
name?: string,
|
|
14
|
+
caption?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function getStreamsByCampaignId(campaignId: number): Promise<IKeitaroStream[]> {
|
|
18
|
+
const { data: streams } = await keitaroApi.get<IKeitaroStream[]>(`campaigns/${campaignId}/streams`);
|
|
19
|
+
|
|
20
|
+
return streams
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function getAllCampaigns(): Promise<IKeitaroCampaign[]> {
|
|
24
|
+
const { data: campaigns } = await keitaroApi.get<IKeitaroCampaign[]>('campaigns');
|
|
25
|
+
return campaigns
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function cloneStreams(originalCampaignId: number, streamPositionsToClone: number[], campaignRegExp: RegExp): Promise<void> {
|
|
29
|
+
// Get the original campaign's streams
|
|
30
|
+
const originalStreams = await getStreamsByCampaignId(originalCampaignId)
|
|
31
|
+
|
|
32
|
+
// Filter the original streams by the given stream positions to clone
|
|
33
|
+
const streamsToClone = originalStreams.filter(stream => streamPositionsToClone.includes(stream.position));
|
|
34
|
+
|
|
35
|
+
// Get a list of all campaigns
|
|
36
|
+
const allCampaigns = await getAllCampaigns()
|
|
37
|
+
|
|
38
|
+
// Filter the campaigns by the given RegExp
|
|
39
|
+
const matchingCampaigns = allCampaigns.filter(campaign => campaignRegExp.exec(campaign.name) && campaign.id != originalCampaignId);
|
|
40
|
+
// console.log(matchingCampaigns)
|
|
41
|
+
|
|
42
|
+
// For each matching campaign, clone the streams
|
|
43
|
+
for (const matchingCampaign of matchingCampaigns) {
|
|
44
|
+
for (const streamToClone of streamsToClone) {
|
|
45
|
+
await keitaroApi.post('streams', {
|
|
46
|
+
name: streamToClone.name,
|
|
47
|
+
campaign_id: matchingCampaign.id,
|
|
48
|
+
schema: streamToClone.schema,
|
|
49
|
+
type: streamToClone.type,
|
|
50
|
+
action_type: streamToClone.action_type,
|
|
51
|
+
weight: 100,
|
|
52
|
+
offers: streamToClone.offers.map((offer) => {
|
|
53
|
+
return {
|
|
54
|
+
offer_id: offer.offer_id,
|
|
55
|
+
share: 100
|
|
56
|
+
}
|
|
57
|
+
}),
|
|
58
|
+
filters: streamToClone.filters.map((filter) => {
|
|
59
|
+
return {
|
|
60
|
+
name: filter.name,
|
|
61
|
+
mode: filter.mode,
|
|
62
|
+
payload: filter.payload
|
|
63
|
+
}
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function updateCampaign(id: number, payload: Partial<IKeitaroCampaign>) {
|
|
71
|
+
await keitaroApi.put(`campaigns/${id}`, payload)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function createStreamForMatchingCampaigns(streamPartialPayload: any, offerId: string, campaignRegExp: RegExp, avoidGroup?: number) {
|
|
75
|
+
// Get a list of all campaigns
|
|
76
|
+
const allCampaigns = await getAllCampaigns()
|
|
77
|
+
|
|
78
|
+
// Filter the campaigns by the given RegExp
|
|
79
|
+
const matchingCampaigns = allCampaigns.filter(campaign => (avoidGroup ? campaign.group_id != avoidGroup : true) && campaignRegExp.exec(campaign.name));
|
|
80
|
+
// console.log(matchingCampaigns)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
// For each matching campaign, clone the streams
|
|
84
|
+
for (const matchingCampaign of matchingCampaigns) {
|
|
85
|
+
let streams = await getStreamsByCampaignId(matchingCampaign.id)
|
|
86
|
+
|
|
87
|
+
let identicalStream = streams.find((stream) => stream.name.includes(offerId))
|
|
88
|
+
|
|
89
|
+
if (identicalStream) {
|
|
90
|
+
await keitaroApi.put(`streams/${identicalStream.id}`, {
|
|
91
|
+
campaign_id: matchingCampaign.id,
|
|
92
|
+
...streamPartialPayload
|
|
93
|
+
});
|
|
94
|
+
} else {
|
|
95
|
+
await keitaroApi.post('streams', {
|
|
96
|
+
campaign_id: matchingCampaign.id,
|
|
97
|
+
...streamPartialPayload
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function getAllOffers(): Promise<IKeitaroOffer[]> {
|
|
104
|
+
const { data: offers } = await keitaroApi.get<IKeitaroOffer[]>('offers')
|
|
105
|
+
|
|
106
|
+
return offers
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
async function findKeitaroOffers(filter: IKeitaroOffersFilter): Promise<IKeitaroOffer[]> {
|
|
111
|
+
let offers = await getAllOffers()
|
|
112
|
+
|
|
113
|
+
if (filter.caption) offers = offers.filter((o) => o.name.includes(filter.caption!))
|
|
114
|
+
if (filter.keitaroId) offers = offers.filter((o) => o.id == filter.keitaroId!)
|
|
115
|
+
if (filter.name) offers = offers.filter((o) => o.name.includes(filter.name!))
|
|
116
|
+
|
|
117
|
+
return offers
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function getOfferByKeitaroId(id: number): Promise<IKeitaroOffer> {
|
|
121
|
+
const { data: offer } = await keitaroApi.get<IKeitaroOffer>(`offers/${id}`)
|
|
122
|
+
|
|
123
|
+
return offer
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function updateOffer(offer: any): Promise<IKeitaroOffer> {
|
|
127
|
+
const { data: o } = await keitaroApi.put<IKeitaroOffer>(`offers/${offer.id}`, offer)
|
|
128
|
+
|
|
129
|
+
return o
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function createStreamPartialPayload(keitaroOfferId: number, offerName: string, offerId: string, offerGeo: string) {
|
|
133
|
+
return {
|
|
134
|
+
name: `${offerName} ${offerGeo} (${offerId})`,
|
|
135
|
+
schema: "landings",
|
|
136
|
+
type: "regular",
|
|
137
|
+
action_type: "http",
|
|
138
|
+
weight: 100,
|
|
139
|
+
offers: [{
|
|
140
|
+
offer_id: keitaroOfferId,
|
|
141
|
+
share: 100,
|
|
142
|
+
state: "active"
|
|
143
|
+
}],
|
|
144
|
+
filters: [{
|
|
145
|
+
name: "sub_id_15",
|
|
146
|
+
mode: "accept",
|
|
147
|
+
payload: [offerId]
|
|
148
|
+
}],
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function addOfferToKeitaro(offer: IOffer, affiliateId: number, link: string, avoidGroup?: number, groupId?: number) {
|
|
153
|
+
// TODO look if offer already exists by offer.name
|
|
154
|
+
let allOffers = await getAllOffers()
|
|
155
|
+
let identicalOffer = allOffers.find((o) => { return o.name.includes(offer.name) })
|
|
156
|
+
|
|
157
|
+
let keitaroOfferId
|
|
158
|
+
if (identicalOffer) {
|
|
159
|
+
keitaroOfferId = identicalOffer.id
|
|
160
|
+
} else {
|
|
161
|
+
let offerPayload = {
|
|
162
|
+
name: `${offer.caption} ${offer.geo} (${offer.name})`,
|
|
163
|
+
group_id: groupId || 1,
|
|
164
|
+
action_payload: link,
|
|
165
|
+
affiliate_network_id: affiliateId,
|
|
166
|
+
country: [offer.geo],
|
|
167
|
+
action_type: "http",
|
|
168
|
+
offer_type: "external",
|
|
169
|
+
payout_auto: true,
|
|
170
|
+
payout_upsell: true,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const { data: keitaroOffer } = await keitaroApi.post(`offers`, offerPayload);
|
|
174
|
+
|
|
175
|
+
keitaroOfferId = keitaroOffer.id
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
let streamPartialPayload = createStreamPartialPayload(keitaroOfferId, offer.caption, offer.name, offer.geo)
|
|
179
|
+
|
|
180
|
+
await createStreamForMatchingCampaigns(streamPartialPayload, offer.name, /◈/, avoidGroup)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function createCampaign(campaignData: Partial<IKeitaroCampaign>): Promise<IKeitaroCampaign> {
|
|
184
|
+
let { data: campaign } = await keitaroApi.post(`/campaigns`, campaignData)
|
|
185
|
+
|
|
186
|
+
return campaign
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function getCampaignById(id: number): Promise<IKeitaroCampaign> {
|
|
190
|
+
const { data: campaign } = await keitaroApi.get(`/campaigns/${id}`);
|
|
191
|
+
return campaign
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export async function upsertStreamToCampaign(campaign: IKeitaroCampaign, stream: Partial<IKeitaroStream>) {
|
|
195
|
+
let streams = await getStreamsByCampaignId(campaign.id)
|
|
196
|
+
|
|
197
|
+
let identicalStream = streams.find((s) => stream.name == s.name)
|
|
198
|
+
|
|
199
|
+
if (identicalStream) {
|
|
200
|
+
console.log(`Found identical! Name: ${stream.name}`)
|
|
201
|
+
await keitaroApi.put(`streams/${identicalStream.id}`, {
|
|
202
|
+
campaign_id: campaign.id,
|
|
203
|
+
...stream
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
await keitaroApi.post('streams', {
|
|
207
|
+
campaign_id: campaign.id,
|
|
208
|
+
...stream
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function cloneOWCampaign(app: IApp): Promise<IKeitaroCampaign> {
|
|
214
|
+
let name = `#${app.id} [◈])`
|
|
215
|
+
|
|
216
|
+
let allCampaigns = await getAllCampaigns()
|
|
217
|
+
let matchingCampaign = allCampaigns.filter((c) => c.name.includes(`#${app.id} [◈]`))
|
|
218
|
+
if (matchingCampaign.length > 0) return matchingCampaign[0]
|
|
219
|
+
|
|
220
|
+
const { data: campaigns } = await keitaroApi.post(`/campaigns/2673/clone`);
|
|
221
|
+
|
|
222
|
+
if (campaigns.length == 0) throw Error("Campaign cloning falied")
|
|
223
|
+
|
|
224
|
+
let clonedCampaign: IKeitaroCampaign = campaigns[0]
|
|
225
|
+
|
|
226
|
+
let allDomains = await KeitaroService.getDomains(true)
|
|
227
|
+
if (!allDomains) {
|
|
228
|
+
throw Error(`Failed to get all domains list`)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const domain = allDomains[Math.floor(Math.random() * allDomains.length)];
|
|
232
|
+
|
|
233
|
+
let payload: Partial<IKeitaroCampaign> = {
|
|
234
|
+
name: name,
|
|
235
|
+
traffic_source_id: TRAFFIC_SOURCE_ID_FLASH_AI,
|
|
236
|
+
domain_id: domain.id,
|
|
237
|
+
parameters: prepareOWCampaignParameters(app)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const { data: campaign } = await keitaroApi.put(`/campaigns/${clonedCampaign.id}`, payload)
|
|
241
|
+
|
|
242
|
+
return campaign
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async function cloneDCampaign(app: IApp): Promise<IKeitaroCampaign> {
|
|
246
|
+
let name = `D #${app.id} (${app.bundle})`
|
|
247
|
+
|
|
248
|
+
let allCampaigns = await getAllCampaigns()
|
|
249
|
+
let matchingCampaign = allCampaigns.filter((c) => c.name.includes(`D #${app.id}`))
|
|
250
|
+
if (matchingCampaign.length > 0) return matchingCampaign[0]
|
|
251
|
+
|
|
252
|
+
const { data: campaigns } = await keitaroApi.post(`/campaigns/2693/clone`);
|
|
253
|
+
|
|
254
|
+
if (campaigns.length == 0) throw Error("Campaign cloning falied")
|
|
255
|
+
|
|
256
|
+
let clonedCampaign: IKeitaroCampaign = campaigns[0]
|
|
257
|
+
|
|
258
|
+
let allDomains = await KeitaroService.getDomains(true)
|
|
259
|
+
if (!allDomains) {
|
|
260
|
+
throw Error(`Failed to get all domains list`)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const domain = allDomains[Math.floor(Math.random() * allDomains.length)];
|
|
264
|
+
|
|
265
|
+
let payload: Partial<IKeitaroCampaign> = {
|
|
266
|
+
name: name,
|
|
267
|
+
traffic_source_id: TRAFFIC_SOURCE_ID_FLASH_AI,
|
|
268
|
+
domain_id: domain.id,
|
|
269
|
+
group_id: 93,
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const { data: campaign } = await keitaroApi.put(`/campaigns/${clonedCampaign.id}`, payload)
|
|
273
|
+
|
|
274
|
+
return campaign
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async function changeCampaignsGroup(fromId: number, toId: number, exceptForCampaignIds: number[], onlyForCampaignIds?: number[]) {
|
|
278
|
+
let campaigns = await getAllCampaigns()
|
|
279
|
+
const matchingCampaigns = campaigns.filter(campaign => campaign.group_id == fromId
|
|
280
|
+
&& exceptForCampaignIds.length > 0 ? !exceptForCampaignIds.includes(campaign.id) : onlyForCampaignIds?.includes(campaign.id))
|
|
281
|
+
|
|
282
|
+
for (let campaign of matchingCampaigns) {
|
|
283
|
+
await updateCampaign(campaign.id, { group_id: toId })
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Domain
|
|
288
|
+
async function getDomains(onlyActive?: boolean): Promise<IKeitaroDomain[]> {
|
|
289
|
+
const { data: domains } = await keitaroApi.get<IKeitaroDomain[]>(`/domains`)
|
|
290
|
+
return onlyActive ? domains.filter((d) => d.network_status == "active") : domains
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async function getProfitForTimeRange(from: number, to: number): Promise<number> {
|
|
294
|
+
let fromString = convertMillisToDate(from)
|
|
295
|
+
let toString = convertMillisToDate(to)
|
|
296
|
+
|
|
297
|
+
let { data: data } = await keitaroApi.post(`/report/build`, {
|
|
298
|
+
range: {
|
|
299
|
+
from: fromString,
|
|
300
|
+
to: toString,
|
|
301
|
+
timezone: 'Europe/Kyiv'
|
|
302
|
+
},
|
|
303
|
+
metrics: ['profit']
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
return data.rows[0].profit
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async function getProfitForTodayAndYesterday(): Promise<any> {
|
|
310
|
+
let timestamps = getTimestampsForTodayAndYesterday()
|
|
311
|
+
let today = await KeitaroService.getProfitForTimeRange(timestamps.today.start, timestamps.today.end)
|
|
312
|
+
let yesterday = await KeitaroService.getProfitForTimeRange(timestamps.yesterday.start, timestamps.yesterday.end)
|
|
313
|
+
|
|
314
|
+
return {
|
|
315
|
+
today: today,
|
|
316
|
+
yesterday: yesterday
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export const KeitaroService = {
|
|
321
|
+
getStreamsByCampaignId, updateCampaign, getAllCampaigns, getAllOffers, cloneStreams, addOfferToKeitaro, getOfferByKeitaroId, getDomains, createCampaign, getCampaignById, upsertStreamToCampaign, cloneOWCampaign,
|
|
322
|
+
updateOffer, changeCampaignsGroup, getProfitForTimeRange, getProfitForTodayAndYesterday, cloneDCampaign, findKeitaroOffers
|
|
323
|
+
}
|