@bprotsyk/aso-core 2.1.197 → 2.1.223

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/app/app.d.ts CHANGED
@@ -41,7 +41,11 @@ export declare enum IntegrationVersion {
41
41
  DIRECT = "direct",
42
42
  WEB_DIRECT = "web_direct",
43
43
  NONE = "none",
44
- POLICY = "policy"
44
+ POLICY = "policy",
45
+ OFFER_STUB = "offer_stub",
46
+ WEB = "web",
47
+ BANNER = "banner",
48
+ PWA = "pwa"
45
49
  }
46
50
  export declare enum EPlatform {
47
51
  GENERAL = "@",
@@ -108,19 +112,22 @@ export interface IUpsertAppRequest {
108
112
  enabled?: boolean;
109
113
  bundle?: string;
110
114
  name?: string;
111
- keitaroData?: any;
115
+ integrationType?: IntegrationType;
116
+ offerwallCampaign?: IAppKeitaroData | null;
117
+ directCampaign?: IAppKeitaroData | null;
112
118
  domainParams?: Partial<IDomainParams>;
119
+ policyPath?: string;
120
+ status?: AppStatus;
121
+ file?: any;
122
+ keitaroData?: any;
113
123
  bannerParams?: any;
114
124
  offersStubParams?: any;
115
125
  platforms?: {
116
126
  [key: string]: IPlatformParams;
117
127
  };
118
128
  ech?: any;
119
- policyPath?: string;
120
129
  appmetricaApiKey?: string;
121
130
  appmetricaAppId?: string | number;
122
- status?: AppStatus;
123
- file?: any;
124
131
  integrationVersion?: IntegrationVersion;
125
132
  geos?: string[];
126
133
  }
package/lib/app/app.js CHANGED
@@ -16,6 +16,10 @@ var IntegrationVersion;
16
16
  IntegrationVersion["WEB_DIRECT"] = "web_direct";
17
17
  IntegrationVersion["NONE"] = "none";
18
18
  IntegrationVersion["POLICY"] = "policy";
19
+ IntegrationVersion["OFFER_STUB"] = "offer_stub";
20
+ IntegrationVersion["WEB"] = "web";
21
+ IntegrationVersion["BANNER"] = "banner";
22
+ IntegrationVersion["PWA"] = "pwa";
19
23
  })(IntegrationVersion = exports.IntegrationVersion || (exports.IntegrationVersion = {}));
20
24
  // @deprecated - Platform enum (no longer used)
21
25
  var EPlatform;
@@ -1,7 +1,18 @@
1
1
  export interface IKeitaroOffer {
2
2
  id: number;
3
- campaign_id: number;
3
+ campaign_id?: number;
4
4
  name: string;
5
- url: string;
6
- country: string;
5
+ url?: string;
6
+ country?: string | string[];
7
+ group_id?: number;
8
+ action_type?: string;
9
+ action_payload?: string;
10
+ affiliate_network_id?: number;
11
+ payout_value?: number;
12
+ payout_currency?: string;
13
+ payout_type?: string;
14
+ state?: string;
15
+ offer_type?: string;
16
+ payout_auto?: boolean;
17
+ payout_upsell?: boolean;
7
18
  }
@@ -1,4 +1,5 @@
1
1
  import { IKeitaroStream } from "../../keitaro/keitaro-stream";
2
+ import { IOffer } from "../../offers/offer";
2
3
  import { IKeitaroCampaign } from "../../keitaro/keitaro-campaign";
3
4
  import { IKeitaroDomain } from "../../keitaro/keitaro-domain";
4
5
  import { IApp, IAppKeitaroData, IntegrationType } from "../../app/app";
@@ -15,6 +16,28 @@ declare function updateCampaign(id: number, payload: Partial<IKeitaroCampaign>):
15
16
  declare function createCampaign(campaignData: Partial<IKeitaroCampaign>): Promise<IKeitaroCampaign>;
16
17
  declare function getDomains(onlyActive?: boolean): Promise<IKeitaroDomain[]>;
17
18
  declare function getAllOffers(): Promise<IKeitaroOffer[]>;
19
+ /**
20
+ * Create offer in Keitaro from our IOffer
21
+ * @param offer - Our internal IOffer object
22
+ * @returns Keitaro offer with ID
23
+ */
24
+ declare function createOfferInKeitaro(offer: IOffer): Promise<IKeitaroOffer>;
25
+ declare function createStream(campaignId: number, streamData: Partial<IKeitaroStream>): Promise<IKeitaroStream>;
26
+ /**
27
+ * Get all offerwall campaigns (campaigns with [◈] prefix in group 106)
28
+ */
29
+ declare function getOfferwallCampaigns(): Promise<IKeitaroCampaign[]>;
30
+ /**
31
+ * Add our IOffer to Keitaro and distribute to all offerwall campaigns
32
+ * @param offer - Our internal IOffer object
33
+ * @returns Result with Keitaro offer ID and distribution stats
34
+ */
35
+ declare function addOfferToKeitaro(offer: IOffer): Promise<{
36
+ keitaroOfferId: number;
37
+ success: number;
38
+ failed: number;
39
+ campaigns: string[];
40
+ }>;
18
41
  declare function generateAlias(): string;
19
42
  /**
20
43
  * Clone a campaign for an app based on integration type
@@ -33,9 +56,13 @@ export declare const KeitaroService: {
33
56
  createCampaign: typeof createCampaign;
34
57
  updateCampaign: typeof updateCampaign;
35
58
  cloneCampaignForApp: typeof cloneCampaignForApp;
59
+ getOfferwallCampaigns: typeof getOfferwallCampaigns;
36
60
  getStreamsByCampaignId: typeof getStreamsByCampaignId;
61
+ createStream: typeof createStream;
37
62
  getDomains: typeof getDomains;
38
63
  getAllOffers: typeof getAllOffers;
64
+ createOfferInKeitaro: typeof createOfferInKeitaro;
65
+ addOfferToKeitaro: typeof addOfferToKeitaro;
39
66
  generateAlias: typeof generateAlias;
40
67
  campaignToKeitaroData: typeof campaignToKeitaroData;
41
68
  };
@@ -39,6 +39,97 @@ async function getAllOffers() {
39
39
  const { data: offers } = await http_1.default.get('offers');
40
40
  return offers;
41
41
  }
42
+ /**
43
+ * Create offer in Keitaro from our IOffer
44
+ * @param offer - Our internal IOffer object
45
+ * @returns Keitaro offer with ID
46
+ */
47
+ async function createOfferInKeitaro(offer) {
48
+ const payload = {
49
+ name: `${offer.caption} ${offer.geo} (${offer.name})`,
50
+ group_id: DEFAULT_OFFERS_GROUP_ID,
51
+ action_type: 'http',
52
+ action_payload: offer.link,
53
+ affiliate_network_id: 0,
54
+ payout_value: 0,
55
+ payout_currency: 'USD',
56
+ payout_type: 'CPA',
57
+ state: offer.hidden ? 'disabled' : 'active',
58
+ country: [offer.geo],
59
+ offer_type: 'external',
60
+ payout_auto: true,
61
+ payout_upsell: true,
62
+ };
63
+ const { data: keitaroOffer } = await http_1.default.post('offers', payload);
64
+ return keitaroOffer;
65
+ }
66
+ // Stream operations
67
+ async function createStream(campaignId, streamData) {
68
+ const { data: stream } = await http_1.default.post('streams', {
69
+ ...streamData,
70
+ campaign_id: campaignId
71
+ });
72
+ return stream;
73
+ }
74
+ /**
75
+ * Get all offerwall campaigns (campaigns with [◈] prefix in group 106)
76
+ */
77
+ async function getOfferwallCampaigns() {
78
+ const allCampaigns = await getAllCampaigns();
79
+ // Offerwall campaigns have [◈] in their name and are in group 106
80
+ return allCampaigns.filter(c => c.name.includes('[◈]') && c.group_id === DEFAULT_CAMPAIGNS_GROUP_ID);
81
+ }
82
+ /**
83
+ * Add our IOffer to Keitaro and distribute to all offerwall campaigns
84
+ * @param offer - Our internal IOffer object
85
+ * @returns Result with Keitaro offer ID and distribution stats
86
+ */
87
+ async function addOfferToKeitaro(offer) {
88
+ // First, create the offer in Keitaro
89
+ const keitaroOffer = await createOfferInKeitaro(offer);
90
+ console.log(`Created Keitaro offer #${keitaroOffer.id}: ${keitaroOffer.name}`);
91
+ // Then distribute to all offerwall campaigns
92
+ const offerwallCampaigns = await getOfferwallCampaigns();
93
+ let success = 0;
94
+ let failed = 0;
95
+ const campaignNames = [];
96
+ for (const campaign of offerwallCampaigns) {
97
+ try {
98
+ // Check if stream with this offer already exists
99
+ const existingStreams = await getStreamsByCampaignId(campaign.id);
100
+ const streamExists = existingStreams.some(stream => stream.offers?.some(o => o.offer_id === keitaroOffer.id));
101
+ if (streamExists) {
102
+ console.log(`Stream with offer ${keitaroOffer.id} already exists in campaign ${campaign.name}`);
103
+ continue;
104
+ }
105
+ // Create a new stream with the offer
106
+ await createStream(campaign.id, {
107
+ name: `${offer.geo} - ${offer.caption} (${offer.name})`,
108
+ type: 'regular',
109
+ action_type: 'http',
110
+ weight: 100,
111
+ state: offer.hidden ? 'disabled' : 'active',
112
+ offers: [{
113
+ offer_id: keitaroOffer.id,
114
+ share: 100,
115
+ state: 'active'
116
+ }],
117
+ filters: [{
118
+ name: 'country',
119
+ mode: 'accept',
120
+ payload: [offer.geo]
121
+ }]
122
+ });
123
+ success++;
124
+ campaignNames.push(campaign.name);
125
+ }
126
+ catch (error) {
127
+ console.error(`Failed to add offer to campaign ${campaign.name}:`, error);
128
+ failed++;
129
+ }
130
+ }
131
+ return { keitaroOfferId: keitaroOffer.id, success, failed, campaigns: campaignNames };
132
+ }
42
133
  // Generate random alias for campaigns
43
134
  function generateAlias() {
44
135
  const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
@@ -152,12 +243,16 @@ exports.KeitaroService = {
152
243
  createCampaign,
153
244
  updateCampaign,
154
245
  cloneCampaignForApp,
246
+ getOfferwallCampaigns,
155
247
  // Stream operations
156
248
  getStreamsByCampaignId,
249
+ createStream,
157
250
  // Domain operations
158
251
  getDomains,
159
252
  // Offer operations
160
253
  getAllOffers,
254
+ createOfferInKeitaro,
255
+ addOfferToKeitaro,
161
256
  // Utilities
162
257
  generateAlias,
163
258
  campaignToKeitaroData,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bprotsyk/aso-core",
3
- "version": "2.1.197",
3
+ "version": "2.1.223",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "scripts": {
package/src/app/app.ts CHANGED
@@ -21,7 +21,11 @@ export enum IntegrationVersion {
21
21
  DIRECT = "direct",
22
22
  WEB_DIRECT = "web_direct",
23
23
  NONE = "none",
24
- POLICY = "policy"
24
+ POLICY = "policy",
25
+ OFFER_STUB = "offer_stub",
26
+ WEB = "web",
27
+ BANNER = "banner",
28
+ PWA = "pwa"
25
29
  }
26
30
 
27
31
  // @deprecated - Platform enum (no longer used)
@@ -78,23 +82,33 @@ export enum AlternativeOnBackPressed { DEFAULT = "default" }
78
82
  export enum AlternativeSourceType { DEFAULT = "default" }
79
83
  export enum AlternativeStorageType { DEFAULT = "default" }
80
84
 
81
- // @deprecated - Upsert request interface
85
+ // Upsert request interface
82
86
  export interface IUpsertAppRequest {
83
87
  id: number
84
88
  enabled?: boolean
85
89
  bundle?: string
86
90
  name?: string
87
- keitaroData?: any
91
+
92
+ // Integration type - offerwall or direct
93
+ integrationType?: IntegrationType
94
+
95
+ // Keitaro campaigns
96
+ offerwallCampaign?: IAppKeitaroData | null
97
+ directCampaign?: IAppKeitaroData | null
98
+
88
99
  domainParams?: Partial<IDomainParams>
100
+ policyPath?: string
101
+ status?: AppStatus
102
+ file?: any
103
+
104
+ // @deprecated fields
105
+ keitaroData?: any
89
106
  bannerParams?: any
90
107
  offersStubParams?: any
91
108
  platforms?: { [key: string]: IPlatformParams }
92
109
  ech?: any
93
- policyPath?: string
94
110
  appmetricaApiKey?: string
95
111
  appmetricaAppId?: string | number
96
- status?: AppStatus
97
- file?: any
98
112
  integrationVersion?: IntegrationVersion
99
113
  geos?: string[]
100
114
  }
@@ -1,7 +1,18 @@
1
1
  export interface IKeitaroOffer {
2
2
  id: number;
3
- campaign_id: number;
3
+ campaign_id?: number;
4
4
  name: string;
5
- url: string;
6
- country: string
5
+ url?: string;
6
+ country?: string | string[];
7
+ group_id?: number;
8
+ action_type?: string;
9
+ action_payload?: string;
10
+ affiliate_network_id?: number;
11
+ payout_value?: number;
12
+ payout_currency?: string;
13
+ payout_type?: string;
14
+ state?: string;
15
+ offer_type?: string;
16
+ payout_auto?: boolean;
17
+ payout_upsell?: boolean;
7
18
  }
@@ -1,5 +1,5 @@
1
1
  import { IKeitaroStream } from "../../keitaro/keitaro-stream";
2
- import { IOffer } from "../../offers/offer"
2
+ 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";
@@ -59,6 +59,115 @@ async function getAllOffers(): Promise<IKeitaroOffer[]> {
59
59
  return offers
60
60
  }
61
61
 
62
+ /**
63
+ * Create offer in Keitaro from our IOffer
64
+ * @param offer - Our internal IOffer object
65
+ * @returns Keitaro offer with ID
66
+ */
67
+ async function createOfferInKeitaro(offer: IOffer): Promise<IKeitaroOffer> {
68
+ const payload = {
69
+ name: `${offer.caption} ${offer.geo} (${offer.name})`,
70
+ group_id: DEFAULT_OFFERS_GROUP_ID,
71
+ action_type: 'http',
72
+ action_payload: offer.link,
73
+ affiliate_network_id: 0, // Can be set if we have partner mapping
74
+ payout_value: 0,
75
+ payout_currency: 'USD',
76
+ payout_type: 'CPA',
77
+ state: offer.hidden ? 'disabled' : 'active',
78
+ country: [offer.geo],
79
+ offer_type: 'external',
80
+ payout_auto: true,
81
+ payout_upsell: true,
82
+ };
83
+ const { data: keitaroOffer } = await keitaroApi.post<IKeitaroOffer>('offers', payload);
84
+ return keitaroOffer;
85
+ }
86
+
87
+ // Stream operations
88
+ async function createStream(campaignId: number, streamData: Partial<IKeitaroStream>): Promise<IKeitaroStream> {
89
+ const { data: stream } = await keitaroApi.post<IKeitaroStream>('streams', {
90
+ ...streamData,
91
+ campaign_id: campaignId
92
+ });
93
+ return stream;
94
+ }
95
+
96
+ /**
97
+ * Get all offerwall campaigns (campaigns with [◈] prefix in group 106)
98
+ */
99
+ async function getOfferwallCampaigns(): Promise<IKeitaroCampaign[]> {
100
+ const allCampaigns = await getAllCampaigns();
101
+ // Offerwall campaigns have [◈] in their name and are in group 106
102
+ return allCampaigns.filter(c =>
103
+ c.name.includes('[◈]') && c.group_id === DEFAULT_CAMPAIGNS_GROUP_ID
104
+ );
105
+ }
106
+
107
+ /**
108
+ * Add our IOffer to Keitaro and distribute to all offerwall campaigns
109
+ * @param offer - Our internal IOffer object
110
+ * @returns Result with Keitaro offer ID and distribution stats
111
+ */
112
+ async function addOfferToKeitaro(offer: IOffer): Promise<{
113
+ keitaroOfferId: number;
114
+ success: number;
115
+ failed: number;
116
+ campaigns: string[]
117
+ }> {
118
+ // First, create the offer in Keitaro
119
+ const keitaroOffer = await createOfferInKeitaro(offer);
120
+ console.log(`Created Keitaro offer #${keitaroOffer.id}: ${keitaroOffer.name}`);
121
+
122
+ // Then distribute to all offerwall campaigns
123
+ const offerwallCampaigns = await getOfferwallCampaigns();
124
+ let success = 0;
125
+ let failed = 0;
126
+ const campaignNames: string[] = [];
127
+
128
+ for (const campaign of offerwallCampaigns) {
129
+ try {
130
+ // Check if stream with this offer already exists
131
+ const existingStreams = await getStreamsByCampaignId(campaign.id);
132
+ const streamExists = existingStreams.some(stream =>
133
+ stream.offers?.some(o => o.offer_id === keitaroOffer.id)
134
+ );
135
+
136
+ if (streamExists) {
137
+ console.log(`Stream with offer ${keitaroOffer.id} already exists in campaign ${campaign.name}`);
138
+ continue;
139
+ }
140
+
141
+ // Create a new stream with the offer
142
+ await createStream(campaign.id, {
143
+ name: `${offer.geo} - ${offer.caption} (${offer.name})`,
144
+ type: 'regular',
145
+ action_type: 'http',
146
+ weight: 100,
147
+ state: offer.hidden ? 'disabled' : 'active',
148
+ offers: [{
149
+ offer_id: keitaroOffer.id,
150
+ share: 100,
151
+ state: 'active'
152
+ }],
153
+ filters: [{
154
+ name: 'country',
155
+ mode: 'accept',
156
+ payload: [offer.geo]
157
+ }]
158
+ });
159
+
160
+ success++;
161
+ campaignNames.push(campaign.name);
162
+ } catch (error) {
163
+ console.error(`Failed to add offer to campaign ${campaign.name}:`, error);
164
+ failed++;
165
+ }
166
+ }
167
+
168
+ return { keitaroOfferId: keitaroOffer.id, success, failed, campaigns: campaignNames };
169
+ }
170
+
62
171
  // Generate random alias for campaigns
63
172
  function generateAlias(): string {
64
173
  const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
@@ -191,15 +300,19 @@ export const KeitaroService = {
191
300
  createCampaign,
192
301
  updateCampaign,
193
302
  cloneCampaignForApp,
303
+ getOfferwallCampaigns,
194
304
 
195
305
  // Stream operations
196
306
  getStreamsByCampaignId,
307
+ createStream,
197
308
 
198
309
  // Domain operations
199
310
  getDomains,
200
311
 
201
312
  // Offer operations
202
313
  getAllOffers,
314
+ createOfferInKeitaro,
315
+ addOfferToKeitaro,
203
316
 
204
317
  // Utilities
205
318
  generateAlias,