@redonvn/zalo-ads-sdk 0.2.7 → 0.2.13
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/dist/index.d.mts +238 -15
- package/dist/index.d.ts +238 -15
- package/dist/index.js +590 -114
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +577 -114
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30,21 +30,28 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ALLOWED_CTAS_PER_AD_TYPE: () => ALLOWED_CTAS_PER_AD_TYPE,
|
|
33
34
|
ALL_ZALO_ADS_DOMAINS: () => ALL_ZALO_ADS_DOMAINS,
|
|
34
35
|
MemoryZaloSessionStore: () => MemoryZaloSessionStore,
|
|
35
36
|
RedisZaloSessionStore: () => RedisZaloSessionStore,
|
|
36
37
|
TieredZaloSessionStore: () => TieredZaloSessionStore,
|
|
38
|
+
VALID_AD_TYPES: () => VALID_AD_TYPES,
|
|
39
|
+
VALID_CAMPAIGN_TYPES: () => VALID_CAMPAIGN_TYPES,
|
|
37
40
|
ZaloAccountService: () => ZaloAccountService,
|
|
38
41
|
ZaloAdsAccountPool: () => ZaloAdsIntegrationManager,
|
|
42
|
+
ZaloAdsActionType: () => ZaloAdsActionType,
|
|
43
|
+
ZaloAdsAgeRangeId: () => ZaloAdsAgeRangeId,
|
|
39
44
|
ZaloAdsCreateFlowRequest: () => ZaloAdsCreateFlowRequest,
|
|
40
45
|
ZaloAdsCreateFlowResponse: () => ZaloAdsCreateFlowResponse,
|
|
41
46
|
ZaloAdsCreatePostCampaignRequest: () => ZaloAdsCreatePostCampaignRequest,
|
|
42
47
|
ZaloAdsCreatePostCampaignResponse: () => ZaloAdsCreatePostCampaignResponse,
|
|
48
|
+
ZaloAdsDeliveryType: () => ZaloAdsDeliveryType,
|
|
43
49
|
ZaloAdsFlowButtonDto: () => ZaloAdsFlowButtonDto,
|
|
44
50
|
ZaloAdsFlowChildMessageDto: () => ZaloAdsFlowChildMessageDto,
|
|
45
51
|
ZaloAdsFlowMessageDto: () => ZaloAdsFlowMessageDto,
|
|
46
52
|
ZaloAdsIntegrationManager: () => ZaloAdsIntegrationManager,
|
|
47
53
|
ZaloAdsMessageAdUpdateDataDto: () => ZaloAdsMessageAdUpdateDataDto,
|
|
54
|
+
ZaloAdsOsId: () => ZaloAdsOsId,
|
|
48
55
|
ZaloAdsSdk: () => ZaloAdsSdk,
|
|
49
56
|
ZaloAdsService: () => ZaloAdsService,
|
|
50
57
|
ZaloAdsUpdateMessageAdRequest: () => ZaloAdsUpdateMessageAdRequest,
|
|
@@ -56,6 +63,7 @@ __export(index_exports, {
|
|
|
56
63
|
ZaloAuthManager: () => ZaloAuthManager,
|
|
57
64
|
ZaloAutomatedRulesService: () => ZaloAutomatedRulesService,
|
|
58
65
|
ZaloCampaignsService: () => ZaloCampaignsService,
|
|
66
|
+
ZaloCampaignsValidator: () => ZaloCampaignsValidator,
|
|
59
67
|
ZaloChatWidgetService: () => ZaloChatWidgetService,
|
|
60
68
|
ZaloConversionsService: () => ZaloConversionsService,
|
|
61
69
|
ZaloFlowsService: () => ZaloFlowsService,
|
|
@@ -78,7 +86,9 @@ __export(index_exports, {
|
|
|
78
86
|
defaultSharedMemorySessionStore: () => defaultSharedMemorySessionStore,
|
|
79
87
|
deriveAccountKeyFromZpsid: () => deriveAccountKeyFromZpsid,
|
|
80
88
|
parseZaloCookieInput: () => parseZaloCookieInput,
|
|
89
|
+
validateChangeCampaignStatusParams: () => validateChangeCampaignStatusParams,
|
|
81
90
|
validateCloneInstantPageRequest: () => validateCloneInstantPageRequest,
|
|
91
|
+
validateCreateCampaignPayload: () => validateCreateCampaignPayload,
|
|
82
92
|
validateCreateFlowRequest: () => validateCreateFlowRequest,
|
|
83
93
|
validateCreateFormEventAudienceRequest: () => validateCreateFormEventAudienceRequest,
|
|
84
94
|
validateCreateFormRequest: () => validateCreateFormRequest,
|
|
@@ -87,6 +97,7 @@ __export(index_exports, {
|
|
|
87
97
|
validateCreateMessagePersonalEventAudienceRequest: () => validateCreateMessagePersonalEventAudienceRequest,
|
|
88
98
|
validateCreatePhoneAudienceRequest: () => validateCreatePhoneAudienceRequest,
|
|
89
99
|
validateCreateSavedAudienceRequest: () => validateCreateSavedAudienceRequest,
|
|
100
|
+
validateDuplicateAdParams: () => validateDuplicateAdParams,
|
|
90
101
|
validateEstimateAudienceRequest: () => validateEstimateAudienceRequest,
|
|
91
102
|
validateGetInstantPageDetailRequest: () => validateGetInstantPageDetailRequest,
|
|
92
103
|
validateGetInstantPageSharedUserRequest: () => validateGetInstantPageSharedUserRequest,
|
|
@@ -100,7 +111,9 @@ __export(index_exports, {
|
|
|
100
111
|
validateListInstantPageUsersRequest: () => validateListInstantPageUsersRequest,
|
|
101
112
|
validateListMiniPageTemplatesRequest: () => validateListMiniPageTemplatesRequest,
|
|
102
113
|
validateListOfficialAccountsRequest: () => validateListOfficialAccountsRequest,
|
|
114
|
+
validateRenameCampaignParams: () => validateRenameCampaignParams,
|
|
103
115
|
validateSearchInstantPagesRequest: () => validateSearchInstantPagesRequest,
|
|
116
|
+
validateUpdateAdPayload: () => validateUpdateAdPayload,
|
|
104
117
|
validateUpdateFlowRequest: () => validateUpdateFlowRequest,
|
|
105
118
|
validateUpdateInstantPageRequest: () => validateUpdateInstantPageRequest,
|
|
106
119
|
validateUpsertInstantPageFormRequest: () => validateUpsertInstantPageFormRequest
|
|
@@ -727,7 +740,10 @@ var ZaloAuthManager = class {
|
|
|
727
740
|
let adsProfile;
|
|
728
741
|
let formProfile;
|
|
729
742
|
if (domain === "ads.zalo.me") {
|
|
730
|
-
|
|
743
|
+
const explicitPlaySession = this.extraCookies?.PLAY_SESSION || cookies["PLAY_SESSION"];
|
|
744
|
+
if (!explicitPlaySession) {
|
|
745
|
+
await this.followOAuthRedirects("https://ads.zalo.me/api/login", cookies, true);
|
|
746
|
+
}
|
|
731
747
|
const whoamiRes = await this.fetchImpl("https://ads.zalo.me/api/whoami", {
|
|
732
748
|
method: "GET",
|
|
733
749
|
headers: {
|
|
@@ -737,12 +753,17 @@ var ZaloAuthManager = class {
|
|
|
737
753
|
}
|
|
738
754
|
});
|
|
739
755
|
this.mergeSetCookies(whoamiRes, cookies);
|
|
756
|
+
if (explicitPlaySession) {
|
|
757
|
+
cookies["PLAY_SESSION"] = explicitPlaySession;
|
|
758
|
+
}
|
|
740
759
|
const whoamiJson = await whoamiRes.json().catch(() => null);
|
|
741
760
|
if (whoamiJson?.data) {
|
|
742
761
|
adsProfile = whoamiJson.data;
|
|
743
762
|
if (adsProfile.id) {
|
|
744
763
|
cookies["ads_user_id"] = String(adsProfile.id);
|
|
745
764
|
}
|
|
765
|
+
} else if (this.extraCookies?.ads_user_id) {
|
|
766
|
+
cookies["ads_user_id"] = this.extraCookies.ads_user_id;
|
|
746
767
|
}
|
|
747
768
|
} else if (domain === "page.ads.zalo.me") {
|
|
748
769
|
await this.followOAuthRedirects("https://page.ads.zalo.me/api/login", cookies, false);
|
|
@@ -1147,6 +1168,469 @@ async function resolveCookies(auth, context) {
|
|
|
1147
1168
|
return { ...auth?.cookies ?? {}, ...await auth?.getCookies?.(context) ?? {} };
|
|
1148
1169
|
}
|
|
1149
1170
|
|
|
1171
|
+
// src/dtos/ads.dto.ts
|
|
1172
|
+
var ZaloAdsFlowChildMessageDto = class {
|
|
1173
|
+
/** Mẫu Zalo đã xác minh dùng 8 cho tin nhắn văn bản trong nhánh. */
|
|
1174
|
+
type;
|
|
1175
|
+
/** Nội dung phản hồi trong nhánh. */
|
|
1176
|
+
text;
|
|
1177
|
+
};
|
|
1178
|
+
var ZaloAdsFlowButtonDto = class {
|
|
1179
|
+
/** 3 = Gửi tin nhắn vào nhánh hội thoại; 10 = Mở website; 12 = Thực hiện cuộc gọi. */
|
|
1180
|
+
type;
|
|
1181
|
+
/** Nhãn nút hiển thị cho người dùng. */
|
|
1182
|
+
text;
|
|
1183
|
+
/** URL website; bắt buộc với type 10. */
|
|
1184
|
+
url;
|
|
1185
|
+
/** Cờ của nút website; dùng true với type 10. */
|
|
1186
|
+
editable;
|
|
1187
|
+
/** Số hotline, bắt buộc khi type là 12. */
|
|
1188
|
+
phone;
|
|
1189
|
+
/** Nhánh tin nhắn, bắt buộc khi type là 3. Với type 10 hoặc 12, để null hoặc bỏ qua. */
|
|
1190
|
+
messages;
|
|
1191
|
+
};
|
|
1192
|
+
var ZaloAdsFlowMessageDto = class {
|
|
1193
|
+
/** 1 = Tin nhắn văn bản; 2 = Tin nhắn kèm hình ảnh. */
|
|
1194
|
+
type;
|
|
1195
|
+
/** Nội dung tin nhắn, tối đa 1961 ký tự. Hỗ trợ biến: {{user_name}}, {{page_name}}, {{user_gender}}, {{user_id}}, {{page_id}}, {{date}}, {{datetime}}. */
|
|
1196
|
+
text;
|
|
1197
|
+
/** URL media hoặc null với tin nhắn văn bản thuần. Bắt buộc và không được null khi type = 2. */
|
|
1198
|
+
url;
|
|
1199
|
+
/** Các nút đi kèm tin nhắn. */
|
|
1200
|
+
buttons;
|
|
1201
|
+
};
|
|
1202
|
+
var ZaloAdsCreateFlowRequest = class {
|
|
1203
|
+
/** ID Official Account sở hữu kịch bản. */
|
|
1204
|
+
oaId;
|
|
1205
|
+
/** Luôn null khi tạo kịch bản mới. */
|
|
1206
|
+
id;
|
|
1207
|
+
/** Tên kịch bản, tối đa 33 ký tự theo giao diện Zalo Ads. */
|
|
1208
|
+
name;
|
|
1209
|
+
/** Các tin nhắn được gửi theo thứ tự trong kịch bản. */
|
|
1210
|
+
messages;
|
|
1211
|
+
};
|
|
1212
|
+
var ZaloAdsCreateFlowResponse = class {
|
|
1213
|
+
/** 0 khi tạo thành công; 1 khi lỗi (ví dụ: đã tới hạn mức 20 kịch bản). */
|
|
1214
|
+
code;
|
|
1215
|
+
/** Thông báo lỗi từ Zalo Ads khi code khác 0. */
|
|
1216
|
+
msg;
|
|
1217
|
+
/** ID kịch bản mới, truyền vào data.ZaloFlowId khi cập nhật quảng cáo Tin nhắn. */
|
|
1218
|
+
data;
|
|
1219
|
+
};
|
|
1220
|
+
var ZaloAdsActionType = {
|
|
1221
|
+
DAT_NGAY: 1,
|
|
1222
|
+
MUA_NGAY: 2,
|
|
1223
|
+
THU_NGAY: 3,
|
|
1224
|
+
TAI_NGAY: 4,
|
|
1225
|
+
XEM_THEM: 5,
|
|
1226
|
+
QUAN_TAM_OA: 6,
|
|
1227
|
+
NGHE_NGAY: 7,
|
|
1228
|
+
CHOI_NGAY: 8,
|
|
1229
|
+
DANG_KY: 9,
|
|
1230
|
+
GOI_DIEN: 10
|
|
1231
|
+
};
|
|
1232
|
+
var ZaloAdsAgeRangeId = {
|
|
1233
|
+
UNDER_18: 10282,
|
|
1234
|
+
FROM_18_TO_24: 10283,
|
|
1235
|
+
FROM_25_TO_34: 10284,
|
|
1236
|
+
FROM_35_TO_44: 10285,
|
|
1237
|
+
FROM_45_TO_54: 10286,
|
|
1238
|
+
FROM_55_TO_64: 10287,
|
|
1239
|
+
OVER_64: 10288
|
|
1240
|
+
};
|
|
1241
|
+
var ZaloAdsOsId = {
|
|
1242
|
+
ANDROID: 0,
|
|
1243
|
+
IOS: 1,
|
|
1244
|
+
PC: 3
|
|
1245
|
+
};
|
|
1246
|
+
var ZaloAdsDeliveryType = {
|
|
1247
|
+
STANDARD: 1,
|
|
1248
|
+
ACCELERATED: 2
|
|
1249
|
+
};
|
|
1250
|
+
var ZaloAdsUpdateVideoAdRequest = class {
|
|
1251
|
+
data;
|
|
1252
|
+
est;
|
|
1253
|
+
isBoostAd;
|
|
1254
|
+
stt;
|
|
1255
|
+
};
|
|
1256
|
+
var ZaloAdsUpdateVideoAdResponse = class {
|
|
1257
|
+
code;
|
|
1258
|
+
msg;
|
|
1259
|
+
data;
|
|
1260
|
+
};
|
|
1261
|
+
var ZaloAdsCreatePostCampaignRequest = class {
|
|
1262
|
+
/** Cấu hình chiến dịch Bài viết (object hoặc chuỗi JSON). */
|
|
1263
|
+
data;
|
|
1264
|
+
};
|
|
1265
|
+
var ZaloAdsCreatePostCampaignResponse = class {
|
|
1266
|
+
code;
|
|
1267
|
+
/** Chuỗi ID quảng cáo mới trong response Zalo Ads. */
|
|
1268
|
+
msg;
|
|
1269
|
+
data;
|
|
1270
|
+
};
|
|
1271
|
+
var ZaloAdsMessageAdUpdateDataDto = class {
|
|
1272
|
+
AdId;
|
|
1273
|
+
CampaignId;
|
|
1274
|
+
MemberId;
|
|
1275
|
+
/** Phiên bản lạc quan lấy từ bản quảng cáo hiện tại. */
|
|
1276
|
+
RowVersion;
|
|
1277
|
+
AdName;
|
|
1278
|
+
/** 20 (hoặc 19) là quảng cáo Tin nhắn. */
|
|
1279
|
+
Type;
|
|
1280
|
+
Settings;
|
|
1281
|
+
Status;
|
|
1282
|
+
StartDate;
|
|
1283
|
+
EndDate;
|
|
1284
|
+
/** ID kịch bản, lấy từ createFlow hoặc listFlowsByOfficialAccount. */
|
|
1285
|
+
ZaloFlowId;
|
|
1286
|
+
ZaloPageId;
|
|
1287
|
+
ZaloFormId;
|
|
1288
|
+
ConversionId;
|
|
1289
|
+
Report;
|
|
1290
|
+
};
|
|
1291
|
+
var ZaloAdsUpdateMessageAdRequest = class {
|
|
1292
|
+
/** Payload quảng cáo đầy đủ (object hoặc chuỗi JSON); service tự tuần tự hóa thành field form data. */
|
|
1293
|
+
data;
|
|
1294
|
+
/** Tham số UI phụ trợ; capture Zalo Ads có giá trị literal "undefined". */
|
|
1295
|
+
est;
|
|
1296
|
+
/** 0 là quảng cáo thông thường, 1 là boost ad. */
|
|
1297
|
+
isBoostAd;
|
|
1298
|
+
/** Trạng thái thao tác của giao diện; mẫu đã ghi nhận 0. */
|
|
1299
|
+
stt;
|
|
1300
|
+
};
|
|
1301
|
+
var ZaloAdsUpdateMessageAdResponse = class {
|
|
1302
|
+
msg;
|
|
1303
|
+
code;
|
|
1304
|
+
data;
|
|
1305
|
+
};
|
|
1306
|
+
|
|
1307
|
+
// src/validators/campaigns.validator.ts
|
|
1308
|
+
var VALID_CAMPAIGN_TYPES = {
|
|
1309
|
+
WEBSITE: 6,
|
|
1310
|
+
FORM: 17,
|
|
1311
|
+
MESSAGE: 18,
|
|
1312
|
+
OA: 3,
|
|
1313
|
+
VIDEO: 14,
|
|
1314
|
+
COMMERCE: 22,
|
|
1315
|
+
ARTICLE: 4,
|
|
1316
|
+
DISPLAY: 20
|
|
1317
|
+
};
|
|
1318
|
+
var VALID_AD_TYPES = {
|
|
1319
|
+
WEBSITE: 5,
|
|
1320
|
+
FORM: 18,
|
|
1321
|
+
MESSAGE: 30,
|
|
1322
|
+
OA: 2,
|
|
1323
|
+
VIDEO: 11,
|
|
1324
|
+
COMMERCE: 28,
|
|
1325
|
+
// Server trả về 28 (không phải 23)
|
|
1326
|
+
ARTICLE: 3,
|
|
1327
|
+
DISPLAY: 21
|
|
1328
|
+
};
|
|
1329
|
+
var ALLOWED_CTAS_PER_AD_TYPE = {
|
|
1330
|
+
// Website (Type 5): 9 CTAs
|
|
1331
|
+
[VALID_AD_TYPES.WEBSITE]: [
|
|
1332
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
1333
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
1334
|
+
ZaloAdsActionType.THU_NGAY,
|
|
1335
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
1336
|
+
ZaloAdsActionType.XEM_THEM,
|
|
1337
|
+
ZaloAdsActionType.NGHE_NGAY,
|
|
1338
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
1339
|
+
ZaloAdsActionType.DANG_KY,
|
|
1340
|
+
ZaloAdsActionType.GOI_DIEN
|
|
1341
|
+
],
|
|
1342
|
+
// Video (Type 11): 8 CTAs
|
|
1343
|
+
[VALID_AD_TYPES.VIDEO]: [
|
|
1344
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
1345
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
1346
|
+
ZaloAdsActionType.THU_NGAY,
|
|
1347
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
1348
|
+
ZaloAdsActionType.XEM_THEM,
|
|
1349
|
+
ZaloAdsActionType.NGHE_NGAY,
|
|
1350
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
1351
|
+
ZaloAdsActionType.DANG_KY
|
|
1352
|
+
],
|
|
1353
|
+
// Article (Type 3): 7 CTAs
|
|
1354
|
+
[VALID_AD_TYPES.ARTICLE]: [
|
|
1355
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
1356
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
1357
|
+
ZaloAdsActionType.THU_NGAY,
|
|
1358
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
1359
|
+
ZaloAdsActionType.XEM_THEM,
|
|
1360
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
1361
|
+
ZaloAdsActionType.DANG_KY
|
|
1362
|
+
],
|
|
1363
|
+
// Form (Type 18): 5 CTAs
|
|
1364
|
+
[VALID_AD_TYPES.FORM]: [
|
|
1365
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
1366
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
1367
|
+
ZaloAdsActionType.THU_NGAY,
|
|
1368
|
+
ZaloAdsActionType.XEM_THEM,
|
|
1369
|
+
ZaloAdsActionType.DANG_KY
|
|
1370
|
+
],
|
|
1371
|
+
// Commerce (Type 28): 3 CTAs
|
|
1372
|
+
[VALID_AD_TYPES.COMMERCE]: [
|
|
1373
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
1374
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
1375
|
+
ZaloAdsActionType.XEM_THEM
|
|
1376
|
+
],
|
|
1377
|
+
// OA (Type 2): Cố định Quan tâm OA (6)
|
|
1378
|
+
[VALID_AD_TYPES.OA]: [ZaloAdsActionType.QUAN_TAM_OA]
|
|
1379
|
+
};
|
|
1380
|
+
function validateCreateCampaignPayload(payload, options = {}) {
|
|
1381
|
+
const errors = [];
|
|
1382
|
+
const warnings = [];
|
|
1383
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
1384
|
+
errors.push("name l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
1385
|
+
} else if (payload.name.length > 255) {
|
|
1386
|
+
errors.push("name kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
1387
|
+
}
|
|
1388
|
+
const validTypes = Object.values(VALID_CAMPAIGN_TYPES);
|
|
1389
|
+
if (payload.campaignType === void 0 || payload.campaignType === null) {
|
|
1390
|
+
errors.push("campaignType l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1391
|
+
} else if (!validTypes.includes(payload.campaignType)) {
|
|
1392
|
+
errors.push(
|
|
1393
|
+
`campaignType: ${payload.campaignType} kh\xF4ng h\u1EE3p l\u1EC7. C\xE1c lo\u1EA1i h\u1ED7 tr\u1EE3: 6 (Website), 17 (Form), 18 (Message), 3 (OA), 14 (Video), 22 (Commerce), 4 (Article), 20 (Display).`
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
if (payload.campaignType !== VALID_CAMPAIGN_TYPES.DISPLAY) {
|
|
1397
|
+
if (!payload.pageId || payload.pageId <= 0) {
|
|
1398
|
+
errors.push("pageId c\u1EE7a Official Account l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi lo\u1EA1i chi\u1EBFn d\u1ECBch n\xE0y (ph\u1EA3i > 0).");
|
|
1399
|
+
}
|
|
1400
|
+
} else {
|
|
1401
|
+
if (payload.pageId !== -1 && payload.pageId !== 0 && !payload.pageId) {
|
|
1402
|
+
warnings.push("Qu\u1EA3ng c\xE1o Display th\u01B0\u1EDDng s\u1EED d\u1EE5ng pageId = -1.");
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
switch (payload.campaignType) {
|
|
1406
|
+
case VALID_CAMPAIGN_TYPES.WEBSITE:
|
|
1407
|
+
if (!payload.targetUrl || typeof payload.targetUrl !== "string" || !payload.targetUrl.trim()) {
|
|
1408
|
+
errors.push("targetUrl l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Website.");
|
|
1409
|
+
} else if (!/^https?:\/\/.+/i.test(payload.targetUrl)) {
|
|
1410
|
+
errors.push("targetUrl ph\u1EA3i l\xE0 m\u1ED9t \u0111\u01B0\u1EDDng link h\u1EE3p l\u1EC7 b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https://.");
|
|
1411
|
+
}
|
|
1412
|
+
break;
|
|
1413
|
+
case VALID_CAMPAIGN_TYPES.ARTICLE:
|
|
1414
|
+
if (!payload.articleId || payload.articleId <= 0) {
|
|
1415
|
+
errors.push("articleId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o B\xE0i Vi\u1EBFt (ph\u1EA3i > 0, l\u1EA5y t\u1EEB getOwnedArticles).");
|
|
1416
|
+
}
|
|
1417
|
+
break;
|
|
1418
|
+
case VALID_CAMPAIGN_TYPES.COMMERCE:
|
|
1419
|
+
if (payload.productId === void 0 || payload.productId === null) {
|
|
1420
|
+
warnings.push("Qu\u1EA3ng c\xE1o Commerce n\xEAn ch\u1EC9 \u0111\u1ECBnh productId (ho\u1EB7c -1/0 khi d\xF9ng Instant Page s\u1EA3n ph\u1EA9m).");
|
|
1421
|
+
}
|
|
1422
|
+
break;
|
|
1423
|
+
case VALID_CAMPAIGN_TYPES.FORM:
|
|
1424
|
+
case VALID_CAMPAIGN_TYPES.MESSAGE:
|
|
1425
|
+
break;
|
|
1426
|
+
}
|
|
1427
|
+
if (payload.budgetType !== void 0 && payload.budgetlimit !== void 0) {
|
|
1428
|
+
if (payload.budgetType === 2) {
|
|
1429
|
+
if (payload.budgetlimit > 0 && payload.budgetlimit < 6e5) {
|
|
1430
|
+
errors.push("Ng\xE2n s\xE1ch cho To\xE0n l\u1ECBch ch\u1EA1y t\u1ED1i thi\u1EC3u l\xE0 600,000 VN\u0110.");
|
|
1431
|
+
}
|
|
1432
|
+
} else if (payload.budgetType === 1) {
|
|
1433
|
+
if (payload.budgetlimit > 0 && payload.budgetlimit < 50) {
|
|
1434
|
+
warnings.push("S\u1ED1 l\u01B0\u1EE3ng t\u01B0\u01A1ng t\xE1c m\u1ED7i ng\xE0y t\u1ED1i thi\u1EC3u \u0111\u01B0\u1EE3c khuy\u1EBFn ngh\u1ECB t\u1EEB 50 l\u01B0\u1EE3t.");
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
if (payload.campaignId && payload.campaignId > 0) {
|
|
1439
|
+
if (payload.adId !== 0) {
|
|
1440
|
+
warnings.push("Khi th\xEAm Ad m\u1EDBi v\xE0o chi\u1EBFn d\u1ECBch hi\u1EC7n c\xF3 (Multi-Ad), adId n\xEAn \u0111\u1EC3 b\u1EB1ng 0.");
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
return {
|
|
1444
|
+
isValid: errors.length === 0,
|
|
1445
|
+
errors,
|
|
1446
|
+
warnings
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
function validateUpdateAdPayload(payload, options = {}) {
|
|
1450
|
+
const errors = [];
|
|
1451
|
+
const warnings = [];
|
|
1452
|
+
if (!payload.AdId || payload.AdId <= 0) {
|
|
1453
|
+
errors.push("AdId l\xE0 b\u1EAFt bu\u1ED9c (ph\u1EA3i > 0).");
|
|
1454
|
+
}
|
|
1455
|
+
if (!payload.CampaignId || payload.CampaignId <= 0) {
|
|
1456
|
+
errors.push("CampaignId l\xE0 b\u1EAFt bu\u1ED9c (ph\u1EA3i > 0).");
|
|
1457
|
+
}
|
|
1458
|
+
if (!payload.AdName || !payload.AdName.trim()) {
|
|
1459
|
+
errors.push("AdName l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
1460
|
+
} else if (payload.AdName.length > 255) {
|
|
1461
|
+
errors.push(`AdName qu\xE1 d\xE0i (${payload.AdName.length}/255 k\xFD t\u1EF1).`);
|
|
1462
|
+
}
|
|
1463
|
+
const adInfo = payload.Settings?.AdInfo;
|
|
1464
|
+
if (!adInfo) {
|
|
1465
|
+
errors.push("Settings.AdInfo l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1466
|
+
} else {
|
|
1467
|
+
if (!adInfo.Caption || !adInfo.Caption.trim()) {
|
|
1468
|
+
errors.push("Settings.AdInfo.Caption l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1469
|
+
} else {
|
|
1470
|
+
const captionLen = adInfo.Caption.trim().length;
|
|
1471
|
+
if (captionLen < 35) {
|
|
1472
|
+
errors.push(`Settings.AdInfo.Caption qu\xE1 ng\u1EAFn (${captionLen}/35 k\xFD t\u1EF1 t\u1ED1i thi\u1EC3u).`);
|
|
1473
|
+
} else if (captionLen > 90) {
|
|
1474
|
+
errors.push(`Settings.AdInfo.Caption qu\xE1 d\xE0i (${captionLen}/90 k\xFD t\u1EF1 t\u1ED1i \u0111a).`);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
if (adInfo.MoreInfo && adInfo.MoreInfo.trim()) {
|
|
1478
|
+
const moreInfoLen = adInfo.MoreInfo.trim().length;
|
|
1479
|
+
if (moreInfoLen < 90) {
|
|
1480
|
+
warnings.push(`Ch\xFA th\xEDch m\u1EDF r\u1ED9ng n\xEAn \u0111\u1EA1t t\u1ED1i thi\u1EC3u 90 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${moreInfoLen}).`);
|
|
1481
|
+
} else if (moreInfoLen > 2e3) {
|
|
1482
|
+
errors.push(`Ch\xFA th\xEDch m\u1EDF r\u1ED9ng v\u01B0\u1EE3t qu\xE1 gi\u1EDBi h\u1EA1n t\u1ED1i \u0111a 2000 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${moreInfoLen}).`);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
if (adInfo.Action !== void 0 && payload.Type) {
|
|
1486
|
+
const allowedCtas = ALLOWED_CTAS_PER_AD_TYPE[payload.Type];
|
|
1487
|
+
if (allowedCtas && !allowedCtas.includes(adInfo.Action)) {
|
|
1488
|
+
warnings.push(
|
|
1489
|
+
`M\xE3 h\xE0nh \u0111\u1ED9ng Action: ${adInfo.Action} c\xF3 th\u1EC3 kh\xF4ng n\u1EB1m trong danh m\u1EE5c n\xFAt CTA h\u1ED7 tr\u1EE3 cho Ad Type ${payload.Type}.`
|
|
1490
|
+
);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
const price = payload.Settings?.Price;
|
|
1495
|
+
if (!price) {
|
|
1496
|
+
errors.push("Settings.Price l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1497
|
+
} else {
|
|
1498
|
+
if (payload.Type === VALID_AD_TYPES.WEBSITE) {
|
|
1499
|
+
if (price.Type !== 1) {
|
|
1500
|
+
errors.push(
|
|
1501
|
+
"\u0110\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Website (Type 5), Price.Type b\u1EAFt bu\u1ED9c ph\u1EA3i b\u1EB1ng 1 (CPC). N\u1EBFu truy\u1EC1n 2 s\u1EBD b\u1ECB m\xE1y ch\u1EE7 l\u1ED7i."
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
if (price.LimitType === 1) {
|
|
1505
|
+
errors.push(
|
|
1506
|
+
"Qu\u1EA3ng c\xE1o Website kh\xF4ng h\u1ED7 tr\u1EE3 LimitType: 1 (t\u1ED5ng ng\xE2n s\xE1ch). B\u1EAFt bu\u1ED9c ph\u1EA3i d\xF9ng LimitType: 0 (ng\xE2n s\xE1ch ng\xE0y)."
|
|
1507
|
+
);
|
|
1508
|
+
}
|
|
1509
|
+
} else if (payload.Type === VALID_AD_TYPES.COMMERCE || payload.Type === VALID_AD_TYPES.OA || payload.Type === VALID_AD_TYPES.ARTICLE || payload.Type === VALID_AD_TYPES.VIDEO || payload.Type === VALID_AD_TYPES.FORM || payload.Type === VALID_AD_TYPES.MESSAGE) {
|
|
1510
|
+
if (price.Type !== 2) {
|
|
1511
|
+
errors.push(
|
|
1512
|
+
`\u0110\u1ED1i v\u1EDBi Ad Type ${payload.Type}, Price.Type b\u1EAFt bu\u1ED9c ph\u1EA3i b\u1EB1ng 2. N\u1EBFu truy\u1EC1n 1, Zalo Ads s\u1EBD b\xE1o l\u1ED7i code 14 (\u0110\u1EB7t gi\xE1 theo L\u01B0\u1EE3t hi\u1EC3n th\u1ECB kh\xF4ng h\u1ED7 tr\u1EE3).`
|
|
1513
|
+
);
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
if (price.Limit !== void 0 && price.Limit > 0 && price.Limit < 50) {
|
|
1517
|
+
warnings.push("S\u1ED1 l\u01B0\u1EE3ng l\u01B0\u1EE3t t\u01B0\u01A1ng t\xE1c \u0111\u1EB7t m\u1ED7i ng\xE0y t\u1ED1i thi\u1EC3u l\xE0 50 l\u01B0\u1EE3t.");
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
const targeting = payload.Settings?.Targeting;
|
|
1521
|
+
if (targeting) {
|
|
1522
|
+
if (targeting.AgeRanges && targeting.AgeRanges.length > 0) {
|
|
1523
|
+
const validAges = Object.values(ZaloAdsAgeRangeId);
|
|
1524
|
+
const invalidAges = targeting.AgeRanges.filter((a) => !validAges.includes(a));
|
|
1525
|
+
if (invalidAges.length > 0) {
|
|
1526
|
+
errors.push(`M\xE3 kho\u1EA3ng tu\u1ED5i kh\xF4ng h\u1EE3p l\u1EC7: ${invalidAges.join(", ")}. H\u1EE3p l\u1EC7: ${validAges.join(", ")}.`);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
if (targeting.OsTypes && targeting.OsTypes.length > 0) {
|
|
1530
|
+
const validOs = Object.values(ZaloAdsOsId);
|
|
1531
|
+
const invalidOs = targeting.OsTypes.filter((os) => !validOs.includes(os));
|
|
1532
|
+
if (invalidOs.length > 0) {
|
|
1533
|
+
errors.push(`M\xE3 h\u1EC7 \u0111i\u1EC1u h\xE0nh kh\xF4ng h\u1EE3p l\u1EC7: ${invalidOs.join(", ")}. H\u1EE3p l\u1EC7: 0 (Android), 1 (iOS), 3 (PC).`);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
const deliveryType = payload.Settings?.DeliveryType;
|
|
1537
|
+
if (deliveryType !== void 0 && deliveryType !== 1 && deliveryType !== 2) {
|
|
1538
|
+
warnings.push("DeliveryType n\xEAn l\xE0 1 (Ti\xEAu chu\u1EA9n) ho\u1EB7c 2 (T\u0103ng t\u1ED1c).");
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
if (payload.Type === VALID_AD_TYPES.FORM) {
|
|
1542
|
+
if (!payload.ZaloFormId || !payload.ZaloFormId.trim()) {
|
|
1543
|
+
errors.push("ZaloFormId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Form (Ad Type 18).");
|
|
1544
|
+
}
|
|
1545
|
+
} else if (payload.Type === VALID_AD_TYPES.MESSAGE) {
|
|
1546
|
+
if (!payload.Settings?.Image?.LogoUrl) {
|
|
1547
|
+
errors.push("Settings.Image.LogoUrl l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Tin Nh\u1EAFn (Ad Type 30).");
|
|
1548
|
+
}
|
|
1549
|
+
if (!payload.ZaloFlowId && !payload.MiniPageId) {
|
|
1550
|
+
warnings.push("Qu\u1EA3ng c\xE1o Tin Nh\u1EAFn n\xEAn g\u1EAFn ZaloFlowId ho\u1EB7c MiniPageId (Template 4 k\u1ECBch b\u1EA3n tin nh\u1EAFn).");
|
|
1551
|
+
}
|
|
1552
|
+
} else if (payload.Type === VALID_AD_TYPES.COMMERCE) {
|
|
1553
|
+
if (!payload.MiniPageId || payload.MiniPageId <= 0) {
|
|
1554
|
+
errors.push("MiniPageId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Commerce (Ad Type 28, Template 1/2/3).");
|
|
1555
|
+
}
|
|
1556
|
+
} else if (payload.Type === VALID_AD_TYPES.VIDEO) {
|
|
1557
|
+
if (!payload.ZaloVideoId && !payload.Settings?.Image?.VideoUrl) {
|
|
1558
|
+
errors.push("ZaloVideoId ho\u1EB7c Settings.Image.VideoUrl l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Video (Ad Type 11).");
|
|
1559
|
+
}
|
|
1560
|
+
if (payload.Settings?.Image?.VideoUrl && !payload.Settings.Image.VideoUrl.includes("zascdn.me")) {
|
|
1561
|
+
warnings.push("VideoUrl n\xEAn l\xE0 \u0111\u01B0\u1EDDng d\u1EABn CDN ch\xEDnh th\u1EE9c c\u1EE7a Zalo Ads (*.zascdn.me).");
|
|
1562
|
+
}
|
|
1563
|
+
} else if (payload.Type === VALID_AD_TYPES.ARTICLE) {
|
|
1564
|
+
if (!payload.ZaloFeedId && !payload.articleId) {
|
|
1565
|
+
errors.push("ZaloFeedId ho\u1EB7c articleId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o B\xE0i Vi\u1EBFt (Ad Type 3).");
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
return {
|
|
1569
|
+
isValid: errors.length === 0,
|
|
1570
|
+
errors,
|
|
1571
|
+
warnings
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
function validateRenameCampaignParams(params) {
|
|
1575
|
+
const errors = [];
|
|
1576
|
+
const warnings = [];
|
|
1577
|
+
const id = params.campid || params.campaignId;
|
|
1578
|
+
const name = params.newname || params.newName || params.name;
|
|
1579
|
+
if (!id || id <= 0) {
|
|
1580
|
+
errors.push("ID chi\u1EBFn d\u1ECBch (campid/campaignId) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i > 0.");
|
|
1581
|
+
}
|
|
1582
|
+
if (!name || !name.trim()) {
|
|
1583
|
+
errors.push("T\xEAn m\u1EDBi c\u1EE7a chi\u1EBFn d\u1ECBch (newname/name) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
1584
|
+
} else if (name.length > 255) {
|
|
1585
|
+
errors.push(`T\xEAn chi\u1EBFn d\u1ECBch qu\xE1 d\xE0i (${name.length}/255 k\xFD t\u1EF1).`);
|
|
1586
|
+
}
|
|
1587
|
+
return {
|
|
1588
|
+
isValid: errors.length === 0,
|
|
1589
|
+
errors,
|
|
1590
|
+
warnings
|
|
1591
|
+
};
|
|
1592
|
+
}
|
|
1593
|
+
function validateChangeCampaignStatusParams(params) {
|
|
1594
|
+
const errors = [];
|
|
1595
|
+
const warnings = [];
|
|
1596
|
+
if (!params.campaignId || params.campaignId <= 0) {
|
|
1597
|
+
errors.push("campaignId l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i > 0.");
|
|
1598
|
+
}
|
|
1599
|
+
if (![1, 2, -2].includes(params.status)) {
|
|
1600
|
+
errors.push(`status: ${params.status} kh\xF4ng h\u1EE3p l\u1EC7. C\xE1c tr\u1EA1ng th\xE1i h\u1EE3p l\u1EC7: 1 (B\u1EADt), 2 (T\u1EA1m d\u1EEBng), -2 (X\xF3a).`);
|
|
1601
|
+
}
|
|
1602
|
+
if (params.status === 2 && params.isDraft) {
|
|
1603
|
+
warnings.push(
|
|
1604
|
+
"Chi\u1EBFn d\u1ECBch nh\xE1p ch\u01B0a c\xF3 qu\u1EA3ng c\xE1o ho\u1EA1t \u0111\u1ED9ng khi g\u1ECDi status: 2 (T\u1EA1m d\u1EEBng) s\u1EBD b\u1ECB m\xE1y ch\u1EE7 n\xE9m l\u1ED7i HTTP 500 Internal Server Error. \u0110\u1EC3 d\u1ECDn d\u1EB9p h\xE3y d\xF9ng status: -2 (X\xF3a)."
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1607
|
+
return {
|
|
1608
|
+
isValid: errors.length === 0,
|
|
1609
|
+
errors,
|
|
1610
|
+
warnings
|
|
1611
|
+
};
|
|
1612
|
+
}
|
|
1613
|
+
function validateDuplicateAdParams(params) {
|
|
1614
|
+
const errors = [];
|
|
1615
|
+
const warnings = [];
|
|
1616
|
+
const id = params.adid || params.adId;
|
|
1617
|
+
if (!id || id <= 0) {
|
|
1618
|
+
errors.push("ID m\u1EABu qu\u1EA3ng c\xE1o g\u1ED1c c\u1EA7n nh\xE2n b\u1EA3n (adid/adId) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i > 0.");
|
|
1619
|
+
}
|
|
1620
|
+
return {
|
|
1621
|
+
isValid: errors.length === 0,
|
|
1622
|
+
errors,
|
|
1623
|
+
warnings
|
|
1624
|
+
};
|
|
1625
|
+
}
|
|
1626
|
+
var ZaloCampaignsValidator = {
|
|
1627
|
+
createCampaign: validateCreateCampaignPayload,
|
|
1628
|
+
updateAd: validateUpdateAdPayload,
|
|
1629
|
+
renameCampaign: validateRenameCampaignParams,
|
|
1630
|
+
changeStatus: validateChangeCampaignStatusParams,
|
|
1631
|
+
duplicateAd: validateDuplicateAdParams
|
|
1632
|
+
};
|
|
1633
|
+
|
|
1150
1634
|
// src/services/campaigns.service.ts
|
|
1151
1635
|
var OP_ZaloAdsUpdateVideoAd = {
|
|
1152
1636
|
operationId: "ZaloAds_updateVideoAd",
|
|
@@ -1267,7 +1751,9 @@ var OP_ZaloAdsGetAdById = {
|
|
|
1267
1751
|
"binaryFields": [],
|
|
1268
1752
|
"pathFields": [],
|
|
1269
1753
|
"queryFields": [
|
|
1270
|
-
"adId"
|
|
1754
|
+
"adId",
|
|
1755
|
+
"v",
|
|
1756
|
+
"newWard"
|
|
1271
1757
|
],
|
|
1272
1758
|
"headerFields": [],
|
|
1273
1759
|
"cookieFields": [],
|
|
@@ -1339,7 +1825,9 @@ var OP_ZaloAdsGetZaapiGetadsfromcampaignid = {
|
|
|
1339
1825
|
"pathFields": [],
|
|
1340
1826
|
"queryFields": [
|
|
1341
1827
|
"campaignId",
|
|
1342
|
-
"campId"
|
|
1828
|
+
"campId",
|
|
1829
|
+
"dataType",
|
|
1830
|
+
"v"
|
|
1343
1831
|
],
|
|
1344
1832
|
"headerFields": [],
|
|
1345
1833
|
"cookieFields": [],
|
|
@@ -1640,6 +2128,18 @@ var OP_ZaloAdsDeleteCampaign = {
|
|
|
1640
2128
|
"status"
|
|
1641
2129
|
]
|
|
1642
2130
|
};
|
|
2131
|
+
var OP_ZaloAdsDuplicateAd = {
|
|
2132
|
+
operationId: "zalo_ads_duplicate_ad",
|
|
2133
|
+
method: "POST",
|
|
2134
|
+
endpoint: "/zaapi/DuplicateAd",
|
|
2135
|
+
baseUrl: "https://ads.zalo.me",
|
|
2136
|
+
binaryFields: [],
|
|
2137
|
+
pathFields: [],
|
|
2138
|
+
queryFields: [],
|
|
2139
|
+
headerFields: [],
|
|
2140
|
+
cookieFields: [],
|
|
2141
|
+
bodyFields: ["adid"]
|
|
2142
|
+
};
|
|
1643
2143
|
var OP_ZaloAdsCreateSpellCheckV3Job = {
|
|
1644
2144
|
operationId: "zalo_ads_create_spell_check_v3_job",
|
|
1645
2145
|
method: "POST",
|
|
@@ -1668,6 +2168,8 @@ var ZaloCampaignsService = class {
|
|
|
1668
2168
|
constructor(client) {
|
|
1669
2169
|
this.client = client;
|
|
1670
2170
|
}
|
|
2171
|
+
validator = ZaloCampaignsValidator;
|
|
2172
|
+
static validator = ZaloCampaignsValidator;
|
|
1671
2173
|
updateVideoAd(request, options) {
|
|
1672
2174
|
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateVideoAd, this.client.toTransportInput(OP_ZaloAdsUpdateVideoAd, request), options);
|
|
1673
2175
|
}
|
|
@@ -1724,10 +2226,19 @@ var ZaloCampaignsService = class {
|
|
|
1724
2226
|
return this.createPostCampaign(request, options);
|
|
1725
2227
|
}
|
|
1726
2228
|
getAdById(request = {}, options) {
|
|
1727
|
-
|
|
2229
|
+
const normalized = {
|
|
2230
|
+
adId: request.adId,
|
|
2231
|
+
v: request.v ?? 2,
|
|
2232
|
+
newWard: request.newWard ?? true
|
|
2233
|
+
};
|
|
2234
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetAdById, this.client.toTransportInput(OP_ZaloAdsGetAdById, normalized), options);
|
|
1728
2235
|
}
|
|
1729
2236
|
getAdChangeLog(request, options) {
|
|
1730
|
-
|
|
2237
|
+
const normalized = {
|
|
2238
|
+
adId: request.adId,
|
|
2239
|
+
type: request.type ?? 1
|
|
2240
|
+
};
|
|
2241
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetAdChangeLog, this.client.toTransportInput(OP_ZaloAdsGetAdChangeLog, normalized), options);
|
|
1731
2242
|
}
|
|
1732
2243
|
getApiPlaceGetalldistricts(request = {}, options) {
|
|
1733
2244
|
return this.client.requestWithoutBody(OP_ZaloAdsGetApiPlaceGetalldistricts, this.client.toTransportInput(OP_ZaloAdsGetApiPlaceGetalldistricts, request), options);
|
|
@@ -1739,7 +2250,16 @@ var ZaloCampaignsService = class {
|
|
|
1739
2250
|
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiCheckcamphasmanyads, this.client.toTransportInput(OP_ZaloAdsGetZaapiCheckcamphasmanyads, request), options);
|
|
1740
2251
|
}
|
|
1741
2252
|
getZaapiGetadsfromcampaignid(request = {}, options) {
|
|
1742
|
-
|
|
2253
|
+
const normalized = {
|
|
2254
|
+
campaignId: request.campaignId ?? request.campId,
|
|
2255
|
+
dataType: request.dataType ?? 1,
|
|
2256
|
+
v: request.v ?? 2
|
|
2257
|
+
};
|
|
2258
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetadsfromcampaignid, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetadsfromcampaignid, normalized), options);
|
|
2259
|
+
}
|
|
2260
|
+
/** Alias lấy danh sách quảng cáo của chiến dịch kèm metadata extend và extra.appliedRuleInfo */
|
|
2261
|
+
getAdsFromCampaignId(request = {}, options) {
|
|
2262
|
+
return this.getZaapiGetadsfromcampaignid(request, options);
|
|
1743
2263
|
}
|
|
1744
2264
|
getZaapiGetallpages(request = {}, options) {
|
|
1745
2265
|
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetallpages, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetallpages, request), options);
|
|
@@ -1769,7 +2289,11 @@ var ZaloCampaignsService = class {
|
|
|
1769
2289
|
return this.client.requestWithoutBody(OP_ZaloAdsPostZaapiDeletead, this.client.toTransportInput(OP_ZaloAdsPostZaapiDeletead, request), options);
|
|
1770
2290
|
}
|
|
1771
2291
|
renameCampaign(request, options) {
|
|
1772
|
-
|
|
2292
|
+
const normalized = {
|
|
2293
|
+
campid: request.campid ?? request.campaignId,
|
|
2294
|
+
newname: request.newname ?? request.campaignName ?? request.name
|
|
2295
|
+
};
|
|
2296
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsRenameCampaign, this.client.toTransportInput(OP_ZaloAdsRenameCampaign, normalized), options);
|
|
1773
2297
|
}
|
|
1774
2298
|
updateEcommerceAd(request, options) {
|
|
1775
2299
|
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateEcommerceAd, this.client.toTransportInput(OP_ZaloAdsUpdateEcommerceAd, request), options);
|
|
@@ -1855,6 +2379,20 @@ var ZaloCampaignsService = class {
|
|
|
1855
2379
|
}
|
|
1856
2380
|
throw new Error(`[SpellCheckV3] Qu\xE1 th\u1EDDi gian ch\u1EDD (${timeoutMs}ms) cho t\xE1c v\u1EE5 ki\u1EC3m tra ch\xEDnh t\u1EA3 jobId: ${jobId}`);
|
|
1857
2381
|
}
|
|
2382
|
+
/**
|
|
2383
|
+
* Nhân bản (sao chép / duplicate) một mẫu quảng cáo đã tồn tại trên Zalo Ads (POST /zaapi/DuplicateAd).
|
|
2384
|
+
* Giúp tạo nhanh một bản sao Ad mới trong cùng chiến dịch để thực hiện A/B testing.
|
|
2385
|
+
*/
|
|
2386
|
+
duplicateAd(request, options) {
|
|
2387
|
+
const payload = {
|
|
2388
|
+
adid: request.adid ?? request.adId
|
|
2389
|
+
};
|
|
2390
|
+
return this.client.requestFormUrlEncoded(
|
|
2391
|
+
OP_ZaloAdsDuplicateAd,
|
|
2392
|
+
this.client.toTransportInput(OP_ZaloAdsDuplicateAd, payload),
|
|
2393
|
+
options
|
|
2394
|
+
);
|
|
2395
|
+
}
|
|
1858
2396
|
};
|
|
1859
2397
|
|
|
1860
2398
|
// src/services/account.service.ts
|
|
@@ -2756,6 +3294,25 @@ var OP_ZaloAdsUpsertCustomReport = {
|
|
|
2756
3294
|
"isDefault"
|
|
2757
3295
|
]
|
|
2758
3296
|
};
|
|
3297
|
+
var OP_ZaloAdsDownloadReport = {
|
|
3298
|
+
operationId: "zalo_ads_download_report",
|
|
3299
|
+
method: "POST",
|
|
3300
|
+
endpoint: "/api/collect",
|
|
3301
|
+
baseUrl: "https://ads.zalo.me",
|
|
3302
|
+
binaryFields: [],
|
|
3303
|
+
pathFields: [],
|
|
3304
|
+
queryFields: [],
|
|
3305
|
+
headerFields: [],
|
|
3306
|
+
cookieFields: [],
|
|
3307
|
+
bodyFields: [
|
|
3308
|
+
"t",
|
|
3309
|
+
"adIds",
|
|
3310
|
+
"status",
|
|
3311
|
+
"dateFilter",
|
|
3312
|
+
"reportKind",
|
|
3313
|
+
"et"
|
|
3314
|
+
]
|
|
3315
|
+
};
|
|
2759
3316
|
var ZaloReportsService = class {
|
|
2760
3317
|
constructor(client) {
|
|
2761
3318
|
this.client = client;
|
|
@@ -2818,6 +3375,18 @@ var ZaloReportsService = class {
|
|
|
2818
3375
|
getCampaignReportLegacy(...args) {
|
|
2819
3376
|
return this.getZaapiCampaignReportcampaign(...args);
|
|
2820
3377
|
}
|
|
3378
|
+
/** Xuất và tải trực tiếp tệp tin Excel (.xlsx / Blob) báo cáo hiệu quả quảng cáo (POST /api/collect) */
|
|
3379
|
+
downloadReport(request, options) {
|
|
3380
|
+
const payload = {
|
|
3381
|
+
t: request.t ?? "cd.download.report",
|
|
3382
|
+
status: request.status ?? 2,
|
|
3383
|
+
dateFilter: request.dateFilter ?? 0,
|
|
3384
|
+
reportKind: request.reportKind ?? 100001,
|
|
3385
|
+
et: request.et ?? Math.floor(Date.now() / 1e3),
|
|
3386
|
+
adIds: request.adIds
|
|
3387
|
+
};
|
|
3388
|
+
return this.client.requestJson(OP_ZaloAdsDownloadReport, this.client.toTransportInput(OP_ZaloAdsDownloadReport, payload), options);
|
|
3389
|
+
}
|
|
2821
3390
|
};
|
|
2822
3391
|
|
|
2823
3392
|
// src/services/conversions.service.ts
|
|
@@ -5076,7 +5645,7 @@ function validateUpdateInstantPageRequest(input) {
|
|
|
5076
5645
|
if (obj.status !== void 0 && obj.status !== null) {
|
|
5077
5646
|
const st = Number(obj.status);
|
|
5078
5647
|
if (![0, 1, 2, 3].includes(st)) {
|
|
5079
|
-
errors.push("Tr\u01B0\u1EDDng 'status' ph\u1EA3i l\xE0 m\u1ED9t trong c\xE1c m\xE3: 0 (B\u1EA3n sao m\u1EDBi), 1 (
|
|
5648
|
+
errors.push("Tr\u01B0\u1EDDng 'status' ph\u1EA3i l\xE0 m\u1ED9t trong c\xE1c m\xE3: 0 (B\u1EA3n sao m\u1EDBi t\u1EA1o ch\u01B0a l\u01B0u), 1 (\u0110ang ho\u1EA1t \u0111\u1ED9ng / \u0110\xE3 xu\u1EA5t b\u1EA3n), 3 (\u0110\xE3 k\u1EBFt th\xFAc / L\u01B0u tr\u1EEF).");
|
|
5080
5649
|
} else {
|
|
5081
5650
|
data.status = st;
|
|
5082
5651
|
}
|
|
@@ -5984,112 +6553,6 @@ var ZaloAdsIntegrationManager = class {
|
|
|
5984
6553
|
}
|
|
5985
6554
|
};
|
|
5986
6555
|
|
|
5987
|
-
// src/dtos/ads.dto.ts
|
|
5988
|
-
var ZaloAdsFlowChildMessageDto = class {
|
|
5989
|
-
/** Mẫu Zalo đã xác minh dùng 8 cho tin nhắn văn bản trong nhánh. */
|
|
5990
|
-
type;
|
|
5991
|
-
/** Nội dung phản hồi trong nhánh. */
|
|
5992
|
-
text;
|
|
5993
|
-
};
|
|
5994
|
-
var ZaloAdsFlowButtonDto = class {
|
|
5995
|
-
/** 3 = Gửi tin nhắn vào nhánh hội thoại; 10 = Mở website; 12 = Thực hiện cuộc gọi. */
|
|
5996
|
-
type;
|
|
5997
|
-
/** Nhãn nút hiển thị cho người dùng. */
|
|
5998
|
-
text;
|
|
5999
|
-
/** URL website; bắt buộc với type 10. */
|
|
6000
|
-
url;
|
|
6001
|
-
/** Cờ của nút website; dùng true với type 10. */
|
|
6002
|
-
editable;
|
|
6003
|
-
/** Số hotline, bắt buộc khi type là 12. */
|
|
6004
|
-
phone;
|
|
6005
|
-
/** Nhánh tin nhắn, bắt buộc khi type là 3. Với type 10 hoặc 12, để null hoặc bỏ qua. */
|
|
6006
|
-
messages;
|
|
6007
|
-
};
|
|
6008
|
-
var ZaloAdsFlowMessageDto = class {
|
|
6009
|
-
/** 1 = Tin nhắn văn bản; 2 = Tin nhắn kèm hình ảnh. */
|
|
6010
|
-
type;
|
|
6011
|
-
/** Nội dung tin nhắn, tối đa 1961 ký tự. Hỗ trợ biến: {{user_name}}, {{page_name}}, {{user_gender}}, {{user_id}}, {{page_id}}, {{date}}, {{datetime}}. */
|
|
6012
|
-
text;
|
|
6013
|
-
/** URL media hoặc null với tin nhắn văn bản thuần. Bắt buộc và không được null khi type = 2. */
|
|
6014
|
-
url;
|
|
6015
|
-
/** Các nút đi kèm tin nhắn. */
|
|
6016
|
-
buttons;
|
|
6017
|
-
};
|
|
6018
|
-
var ZaloAdsCreateFlowRequest = class {
|
|
6019
|
-
/** ID Official Account sở hữu kịch bản. */
|
|
6020
|
-
oaId;
|
|
6021
|
-
/** Luôn null khi tạo kịch bản mới. */
|
|
6022
|
-
id;
|
|
6023
|
-
/** Tên kịch bản, tối đa 33 ký tự theo giao diện Zalo Ads. */
|
|
6024
|
-
name;
|
|
6025
|
-
/** Các tin nhắn được gửi theo thứ tự trong kịch bản. */
|
|
6026
|
-
messages;
|
|
6027
|
-
};
|
|
6028
|
-
var ZaloAdsCreateFlowResponse = class {
|
|
6029
|
-
/** 0 khi tạo thành công; 1 khi lỗi (ví dụ: đã tới hạn mức 20 kịch bản). */
|
|
6030
|
-
code;
|
|
6031
|
-
/** Thông báo lỗi từ Zalo Ads khi code khác 0. */
|
|
6032
|
-
msg;
|
|
6033
|
-
/** ID kịch bản mới, truyền vào data.ZaloFlowId khi cập nhật quảng cáo Tin nhắn. */
|
|
6034
|
-
data;
|
|
6035
|
-
};
|
|
6036
|
-
var ZaloAdsUpdateVideoAdRequest = class {
|
|
6037
|
-
data;
|
|
6038
|
-
est;
|
|
6039
|
-
isBoostAd;
|
|
6040
|
-
stt;
|
|
6041
|
-
};
|
|
6042
|
-
var ZaloAdsUpdateVideoAdResponse = class {
|
|
6043
|
-
code;
|
|
6044
|
-
msg;
|
|
6045
|
-
data;
|
|
6046
|
-
};
|
|
6047
|
-
var ZaloAdsCreatePostCampaignRequest = class {
|
|
6048
|
-
/** Cấu hình chiến dịch Bài viết (object hoặc chuỗi JSON). */
|
|
6049
|
-
data;
|
|
6050
|
-
};
|
|
6051
|
-
var ZaloAdsCreatePostCampaignResponse = class {
|
|
6052
|
-
code;
|
|
6053
|
-
/** Chuỗi ID quảng cáo mới trong response Zalo Ads. */
|
|
6054
|
-
msg;
|
|
6055
|
-
data;
|
|
6056
|
-
};
|
|
6057
|
-
var ZaloAdsMessageAdUpdateDataDto = class {
|
|
6058
|
-
AdId;
|
|
6059
|
-
CampaignId;
|
|
6060
|
-
MemberId;
|
|
6061
|
-
/** Phiên bản lạc quan lấy từ bản quảng cáo hiện tại. */
|
|
6062
|
-
RowVersion;
|
|
6063
|
-
AdName;
|
|
6064
|
-
/** 20 (hoặc 19) là quảng cáo Tin nhắn. */
|
|
6065
|
-
Type;
|
|
6066
|
-
Settings;
|
|
6067
|
-
Status;
|
|
6068
|
-
StartDate;
|
|
6069
|
-
EndDate;
|
|
6070
|
-
/** ID kịch bản, lấy từ createFlow hoặc listFlowsByOfficialAccount. */
|
|
6071
|
-
ZaloFlowId;
|
|
6072
|
-
ZaloPageId;
|
|
6073
|
-
ZaloFormId;
|
|
6074
|
-
ConversionId;
|
|
6075
|
-
Report;
|
|
6076
|
-
};
|
|
6077
|
-
var ZaloAdsUpdateMessageAdRequest = class {
|
|
6078
|
-
/** Payload quảng cáo đầy đủ (object hoặc chuỗi JSON); service tự tuần tự hóa thành field form data. */
|
|
6079
|
-
data;
|
|
6080
|
-
/** Tham số UI phụ trợ; capture Zalo Ads có giá trị literal "undefined". */
|
|
6081
|
-
est;
|
|
6082
|
-
/** 0 là quảng cáo thông thường, 1 là boost ad. */
|
|
6083
|
-
isBoostAd;
|
|
6084
|
-
/** Trạng thái thao tác của giao diện; mẫu đã ghi nhận 0. */
|
|
6085
|
-
stt;
|
|
6086
|
-
};
|
|
6087
|
-
var ZaloAdsUpdateMessageAdResponse = class {
|
|
6088
|
-
msg;
|
|
6089
|
-
code;
|
|
6090
|
-
data;
|
|
6091
|
-
};
|
|
6092
|
-
|
|
6093
6556
|
// src/dtos/instant-pages.dto.ts
|
|
6094
6557
|
var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
6095
6558
|
ZaloInstantPageBlockType2[ZaloInstantPageBlockType2["CAROUSEL_SLIDER"] = 1] = "CAROUSEL_SLIDER";
|
|
@@ -6114,21 +6577,28 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
6114
6577
|
})(ZaloInstantPageBlockType || {});
|
|
6115
6578
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6116
6579
|
0 && (module.exports = {
|
|
6580
|
+
ALLOWED_CTAS_PER_AD_TYPE,
|
|
6117
6581
|
ALL_ZALO_ADS_DOMAINS,
|
|
6118
6582
|
MemoryZaloSessionStore,
|
|
6119
6583
|
RedisZaloSessionStore,
|
|
6120
6584
|
TieredZaloSessionStore,
|
|
6585
|
+
VALID_AD_TYPES,
|
|
6586
|
+
VALID_CAMPAIGN_TYPES,
|
|
6121
6587
|
ZaloAccountService,
|
|
6122
6588
|
ZaloAdsAccountPool,
|
|
6589
|
+
ZaloAdsActionType,
|
|
6590
|
+
ZaloAdsAgeRangeId,
|
|
6123
6591
|
ZaloAdsCreateFlowRequest,
|
|
6124
6592
|
ZaloAdsCreateFlowResponse,
|
|
6125
6593
|
ZaloAdsCreatePostCampaignRequest,
|
|
6126
6594
|
ZaloAdsCreatePostCampaignResponse,
|
|
6595
|
+
ZaloAdsDeliveryType,
|
|
6127
6596
|
ZaloAdsFlowButtonDto,
|
|
6128
6597
|
ZaloAdsFlowChildMessageDto,
|
|
6129
6598
|
ZaloAdsFlowMessageDto,
|
|
6130
6599
|
ZaloAdsIntegrationManager,
|
|
6131
6600
|
ZaloAdsMessageAdUpdateDataDto,
|
|
6601
|
+
ZaloAdsOsId,
|
|
6132
6602
|
ZaloAdsSdk,
|
|
6133
6603
|
ZaloAdsService,
|
|
6134
6604
|
ZaloAdsUpdateMessageAdRequest,
|
|
@@ -6140,6 +6610,7 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
6140
6610
|
ZaloAuthManager,
|
|
6141
6611
|
ZaloAutomatedRulesService,
|
|
6142
6612
|
ZaloCampaignsService,
|
|
6613
|
+
ZaloCampaignsValidator,
|
|
6143
6614
|
ZaloChatWidgetService,
|
|
6144
6615
|
ZaloConversionsService,
|
|
6145
6616
|
ZaloFlowsService,
|
|
@@ -6161,7 +6632,9 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
6161
6632
|
defaultSharedMemorySessionStore,
|
|
6162
6633
|
deriveAccountKeyFromZpsid,
|
|
6163
6634
|
parseZaloCookieInput,
|
|
6635
|
+
validateChangeCampaignStatusParams,
|
|
6164
6636
|
validateCloneInstantPageRequest,
|
|
6637
|
+
validateCreateCampaignPayload,
|
|
6165
6638
|
validateCreateFlowRequest,
|
|
6166
6639
|
validateCreateFormEventAudienceRequest,
|
|
6167
6640
|
validateCreateFormRequest,
|
|
@@ -6170,6 +6643,7 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
6170
6643
|
validateCreateMessagePersonalEventAudienceRequest,
|
|
6171
6644
|
validateCreatePhoneAudienceRequest,
|
|
6172
6645
|
validateCreateSavedAudienceRequest,
|
|
6646
|
+
validateDuplicateAdParams,
|
|
6173
6647
|
validateEstimateAudienceRequest,
|
|
6174
6648
|
validateGetInstantPageDetailRequest,
|
|
6175
6649
|
validateGetInstantPageSharedUserRequest,
|
|
@@ -6183,7 +6657,9 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
6183
6657
|
validateListInstantPageUsersRequest,
|
|
6184
6658
|
validateListMiniPageTemplatesRequest,
|
|
6185
6659
|
validateListOfficialAccountsRequest,
|
|
6660
|
+
validateRenameCampaignParams,
|
|
6186
6661
|
validateSearchInstantPagesRequest,
|
|
6662
|
+
validateUpdateAdPayload,
|
|
6187
6663
|
validateUpdateFlowRequest,
|
|
6188
6664
|
validateUpdateInstantPageRequest,
|
|
6189
6665
|
validateUpsertInstantPageFormRequest
|