@redonvn/zalo-ads-sdk 0.2.19 → 0.2.25
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 +513 -3
- package/dist/index.d.ts +513 -3
- package/dist/index.js +365 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +348 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2048,7 +2048,24 @@ var VALID_AD_TYPES = {
|
|
|
2048
2048
|
COMMERCE: 28,
|
|
2049
2049
|
// Server trả về 28 (không phải 23)
|
|
2050
2050
|
ARTICLE: 3,
|
|
2051
|
-
DISPLAY: 21
|
|
2051
|
+
DISPLAY: 21,
|
|
2052
|
+
// Masthead Mobile (Format 1) & Masthead Desktop (Format 2)
|
|
2053
|
+
DISPLAY_HALFPAGE: 26,
|
|
2054
|
+
// Halfpage Mobile (Format 13) & Halfpage PC (Format 14)
|
|
2055
|
+
DISPLAY_MEDIUM_RECTANGLE: 23
|
|
2056
|
+
// Medium Rectangle 300x250 (Format 6)
|
|
2057
|
+
};
|
|
2058
|
+
var ZALO_DISPLAY_AD_FORMAT = {
|
|
2059
|
+
MASTHEAD_MOBILE: 1,
|
|
2060
|
+
// Kích thước 640x360, Os: [0, 1]
|
|
2061
|
+
MASTHEAD_DESKTOP: 2,
|
|
2062
|
+
// Kích thước 970x250, Os: [3]
|
|
2063
|
+
MEDIUM_RECTANGLE: 6,
|
|
2064
|
+
// Kích thước 300x250, Os: [0, 1]
|
|
2065
|
+
HALFPAGE_MOBILE: 13,
|
|
2066
|
+
// Kích thước 300x600, Os: [0, 1]
|
|
2067
|
+
HALFPAGE_PC: 14
|
|
2068
|
+
// Kích thước 300x600, Os: [3]
|
|
2052
2069
|
};
|
|
2053
2070
|
var ALLOWED_CTAS_PER_AD_TYPE = {
|
|
2054
2071
|
// Website (Type 5): 9 CTAs
|
|
@@ -2099,7 +2116,41 @@ var ALLOWED_CTAS_PER_AD_TYPE = {
|
|
|
2099
2116
|
ZaloAdsActionType.XEM_THEM
|
|
2100
2117
|
],
|
|
2101
2118
|
// OA (Type 2): Cố định Quan tâm OA (6)
|
|
2102
|
-
[VALID_AD_TYPES.OA]: [ZaloAdsActionType.QUAN_TAM_OA]
|
|
2119
|
+
[VALID_AD_TYPES.OA]: [ZaloAdsActionType.QUAN_TAM_OA],
|
|
2120
|
+
// Display (Type 21) & Display Halfpage (Type 26): Hỗ trợ các hành động cơ bản
|
|
2121
|
+
[VALID_AD_TYPES.DISPLAY]: [
|
|
2122
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
2123
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
2124
|
+
ZaloAdsActionType.THU_NGAY,
|
|
2125
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
2126
|
+
ZaloAdsActionType.XEM_THEM,
|
|
2127
|
+
ZaloAdsActionType.NGHE_NGAY,
|
|
2128
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
2129
|
+
ZaloAdsActionType.DANG_KY,
|
|
2130
|
+
ZaloAdsActionType.GOI_DIEN
|
|
2131
|
+
],
|
|
2132
|
+
[VALID_AD_TYPES.DISPLAY_HALFPAGE]: [
|
|
2133
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
2134
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
2135
|
+
ZaloAdsActionType.THU_NGAY,
|
|
2136
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
2137
|
+
ZaloAdsActionType.XEM_THEM,
|
|
2138
|
+
ZaloAdsActionType.NGHE_NGAY,
|
|
2139
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
2140
|
+
ZaloAdsActionType.DANG_KY,
|
|
2141
|
+
ZaloAdsActionType.GOI_DIEN
|
|
2142
|
+
],
|
|
2143
|
+
[VALID_AD_TYPES.DISPLAY_MEDIUM_RECTANGLE]: [
|
|
2144
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
2145
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
2146
|
+
ZaloAdsActionType.THU_NGAY,
|
|
2147
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
2148
|
+
ZaloAdsActionType.XEM_THEM,
|
|
2149
|
+
ZaloAdsActionType.NGHE_NGAY,
|
|
2150
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
2151
|
+
ZaloAdsActionType.DANG_KY,
|
|
2152
|
+
ZaloAdsActionType.GOI_DIEN
|
|
2153
|
+
]
|
|
2103
2154
|
};
|
|
2104
2155
|
function validateCreateCampaignPayload(payload, options = {}) {
|
|
2105
2156
|
const errors = [];
|
|
@@ -2117,11 +2168,18 @@ function validateCreateCampaignPayload(payload, options = {}) {
|
|
|
2117
2168
|
`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).`
|
|
2118
2169
|
);
|
|
2119
2170
|
}
|
|
2120
|
-
|
|
2171
|
+
const OA_REQUIRED_CAMPAIGN_TYPES = [
|
|
2172
|
+
VALID_CAMPAIGN_TYPES.FORM,
|
|
2173
|
+
VALID_CAMPAIGN_TYPES.MESSAGE,
|
|
2174
|
+
VALID_CAMPAIGN_TYPES.OA,
|
|
2175
|
+
VALID_CAMPAIGN_TYPES.COMMERCE,
|
|
2176
|
+
VALID_CAMPAIGN_TYPES.ARTICLE
|
|
2177
|
+
];
|
|
2178
|
+
if (payload.campaignType !== void 0 && OA_REQUIRED_CAMPAIGN_TYPES.includes(payload.campaignType)) {
|
|
2121
2179
|
if (!payload.pageId || payload.pageId <= 0) {
|
|
2122
|
-
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).");
|
|
2180
|
+
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, ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA).");
|
|
2123
2181
|
}
|
|
2124
|
-
} else {
|
|
2182
|
+
} else if (payload.campaignType === VALID_CAMPAIGN_TYPES.DISPLAY) {
|
|
2125
2183
|
if (payload.pageId !== -1 && payload.pageId !== 0 && !payload.pageId) {
|
|
2126
2184
|
warnings.push("Qu\u1EA3ng c\xE1o Display th\u01B0\u1EDDng s\u1EED d\u1EE5ng pageId = -1.");
|
|
2127
2185
|
}
|
|
@@ -2188,11 +2246,15 @@ function validateUpdateAdPayload(payload, options = {}) {
|
|
|
2188
2246
|
if (!adInfo) {
|
|
2189
2247
|
errors.push("Settings.AdInfo l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2190
2248
|
} else {
|
|
2249
|
+
const rawTypeNum = Number(payload.Type);
|
|
2250
|
+
const isDisplayAd = rawTypeNum === 21 || rawTypeNum === 23 || rawTypeNum === 26 || adInfo.AdFormat === 1 || adInfo.AdFormat === 2 || adInfo.AdFormat === 6 || adInfo.AdFormat === 13 || adInfo.AdFormat === 14;
|
|
2191
2251
|
if (!adInfo.Caption || !adInfo.Caption.trim()) {
|
|
2192
|
-
|
|
2252
|
+
if (!isDisplayAd) {
|
|
2253
|
+
errors.push("Settings.AdInfo.Caption l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2254
|
+
}
|
|
2193
2255
|
} else {
|
|
2194
2256
|
const captionLen = adInfo.Caption.trim().length;
|
|
2195
|
-
if (captionLen < 35) {
|
|
2257
|
+
if (!isDisplayAd && captionLen < 35) {
|
|
2196
2258
|
errors.push(`Settings.AdInfo.Caption qu\xE1 ng\u1EAFn (${captionLen}/35 k\xFD t\u1EF1 t\u1ED1i thi\u1EC3u).`);
|
|
2197
2259
|
} else if (captionLen > 90) {
|
|
2198
2260
|
errors.push(`Settings.AdInfo.Caption qu\xE1 d\xE0i (${captionLen}/90 k\xFD t\u1EF1 t\u1ED1i \u0111a).`);
|
|
@@ -2216,6 +2278,14 @@ function validateUpdateAdPayload(payload, options = {}) {
|
|
|
2216
2278
|
);
|
|
2217
2279
|
}
|
|
2218
2280
|
}
|
|
2281
|
+
if (isDisplayAd) {
|
|
2282
|
+
const targetUrl = typeof adInfo.TargetUrl === "object" ? adInfo.TargetUrl?.Url : adInfo.TargetUrl;
|
|
2283
|
+
if (!targetUrl || typeof targetUrl !== "string" || !targetUrl.trim()) {
|
|
2284
|
+
errors.push("Settings.AdInfo.TargetUrl l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Display.");
|
|
2285
|
+
} else if (!/^https?:\/\//i.test(targetUrl.trim())) {
|
|
2286
|
+
errors.push("Settings.AdInfo.TargetUrl ph\u1EA3i l\xE0 m\u1ED9t \u0111\u01B0\u1EDDng d\u1EABn h\u1EE3p l\u1EC7 (b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https://).");
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2219
2289
|
if (adInfo.Action !== void 0 && payload.Type) {
|
|
2220
2290
|
const allowedCtas = ALLOWED_CTAS_PER_AD_TYPE[payload.Type];
|
|
2221
2291
|
if (allowedCtas && !allowedCtas.includes(adInfo.Action)) {
|
|
@@ -2339,6 +2409,65 @@ function validateUpdateAdPayload(payload, options = {}) {
|
|
|
2339
2409
|
"Ng\xE2n s\xE1ch t\u1ED1i thi\u1EC3u cho Qu\u1EA3ng c\xE1o Tin nh\u1EAFn l\xE0 600,000 VN\u0110 (Price.Limit >= 600000). N\u1EBFu \u0111\u1EB7t d\u01B0\u1EDBi 600k m\xE1y ch\u1EE7 s\u1EBD t\u1EEB ch\u1ED1i."
|
|
2340
2410
|
);
|
|
2341
2411
|
}
|
|
2412
|
+
} else if (Number(payload.Type) === 21 || Number(payload.Type) === 23 || Number(payload.Type) === 26 || payload.Type === VALID_AD_TYPES.DISPLAY || payload.Type === VALID_AD_TYPES.DISPLAY_HALFPAGE || payload.Type === VALID_AD_TYPES.DISPLAY_MEDIUM_RECTANGLE) {
|
|
2413
|
+
const adFormat = payload.Settings?.AdInfo?.AdFormat;
|
|
2414
|
+
const typeNum = Number(payload.Type);
|
|
2415
|
+
const isHalfpage = typeNum === 26 || adFormat === 13 || adFormat === 14 || (payload.AdName || "").toLowerCase().includes("halfpage");
|
|
2416
|
+
const isMediumRectangle = typeNum === 23 || adFormat === 6 || (payload.AdName || "").toLowerCase().includes("medium rectangle") || (payload.AdName || "").toLowerCase().includes("300x250");
|
|
2417
|
+
const adNameLower = (payload.AdName || "").toLowerCase();
|
|
2418
|
+
const isWelcome = adNameLower.includes("welcome");
|
|
2419
|
+
const isMasthead = (adNameLower.includes("masthead") || typeNum === 21 || adFormat === 1 || adFormat === 2) && !isWelcome && !isMediumRectangle;
|
|
2420
|
+
if (price.Type !== 1 && price.Type !== 2) {
|
|
2421
|
+
errors.push(
|
|
2422
|
+
"\u0110\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Display, Price.Type ch\u1EC9 ch\u1EA5p nh\u1EADn 1 (CPM - L\u01B0\u1EE3t hi\u1EC3n th\u1ECB) ho\u1EB7c 2 (CPC - L\u01B0\u1EE3t nh\u1EA5n)."
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
if ((isHalfpage || isMasthead) && price.Type === 2) {
|
|
2426
|
+
errors.push(
|
|
2427
|
+
`Qu\u1EA3ng c\xE1o ${isHalfpage ? "Halfpage (Type 26 / AdFormat 13, 14)" : "Masthead (Type 21)"} ch\u1EC9 h\u1ED7 tr\u1EE3 t\xEDnh ti\u1EC1n theo l\u01B0\u1EE3t hi\u1EC3n th\u1ECB CPM (Price.Type = 1), kh\xF4ng h\u1ED7 tr\u1EE3 CPC.`
|
|
2428
|
+
);
|
|
2429
|
+
}
|
|
2430
|
+
if (price.Type === 1) {
|
|
2431
|
+
if (price.Bid !== void 0) {
|
|
2432
|
+
if (isWelcome && price.Bid < 3e4) {
|
|
2433
|
+
errors.push(
|
|
2434
|
+
`Gi\xE1 \u0111\u1EB7t m\u1ED7i 1,000 l\u01B0\u1EE3t hi\u1EC3n th\u1ECB (Price.Bid) cho Qu\u1EA3ng c\xE1o Welcome Mobile t\u1ED1i thi\u1EC3u l\xE0 30,000 VN\u0110. Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Bid}\u0111.`
|
|
2435
|
+
);
|
|
2436
|
+
} else if (isHalfpage && price.Bid < 16e3) {
|
|
2437
|
+
errors.push(
|
|
2438
|
+
`Gi\xE1 \u0111\u1EB7t m\u1ED7i 1,000 l\u01B0\u1EE3t hi\u1EC3n th\u1ECB (Price.Bid) cho Qu\u1EA3ng c\xE1o Halfpage t\u1ED1i thi\u1EC3u l\xE0 16,000 VN\u0110. Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Bid}\u0111.`
|
|
2439
|
+
);
|
|
2440
|
+
} else if (isMasthead && price.Bid < 13e3) {
|
|
2441
|
+
errors.push(
|
|
2442
|
+
`Gi\xE1 \u0111\u1EB7t m\u1ED7i 1,000 l\u01B0\u1EE3t hi\u1EC3n th\u1ECB (Price.Bid) cho Qu\u1EA3ng c\xE1o Masthead t\u1ED1i thi\u1EC3u l\xE0 13,000 VN\u0110. Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Bid}\u0111.`
|
|
2443
|
+
);
|
|
2444
|
+
} else if (isMediumRectangle && price.Bid < 8e3) {
|
|
2445
|
+
errors.push(
|
|
2446
|
+
`Gi\xE1 \u0111\u1EB7t m\u1ED7i 1,000 l\u01B0\u1EE3t hi\u1EC3n th\u1ECB (Price.Bid) cho Qu\u1EA3ng c\xE1o Medium Rectangle CPM t\u1ED1i thi\u1EC3u l\xE0 8,000 VN\u0110. Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Bid}\u0111.`
|
|
2447
|
+
);
|
|
2448
|
+
} else if (price.Bid < 8e3) {
|
|
2449
|
+
errors.push(
|
|
2450
|
+
`Gi\xE1 \u0111\u1EB7t m\u1ED7i 1,000 l\u01B0\u1EE3t hi\u1EC3n th\u1ECB (Price.Bid) cho Qu\u1EA3ng c\xE1o Display CPM t\u1ED1i thi\u1EC3u l\xE0 8,000 VN\u0110 (s\xE0n h\u1EC7 th\u1ED1ng). Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Bid}\u0111.`
|
|
2451
|
+
);
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
if (price.Limit !== void 0 && price.Limit > 0 && price.Limit < 50) {
|
|
2455
|
+
errors.push(
|
|
2456
|
+
"S\u1ED1 l\u01B0\u1EE3ng l\u01B0\u1EE3t hi\u1EC3n th\u1ECB t\u1ED1i thi\u1EC3u (Price.Limit) cho Qu\u1EA3ng c\xE1o Display CPM l\xE0 50 (t\u01B0\u01A1ng \u1EE9ng 50,000 l\u01B0\u1EE3t hi\u1EC3n th\u1ECB)."
|
|
2457
|
+
);
|
|
2458
|
+
}
|
|
2459
|
+
} else if (price.Type === 2) {
|
|
2460
|
+
if (price.Bid !== void 0 && price.Bid < 1800) {
|
|
2461
|
+
errors.push(
|
|
2462
|
+
`Gi\xE1 \u0111\u1EB7t m\u1ED7i l\u01B0\u1EE3t nh\u1EA5n (Price.Bid) cho Qu\u1EA3ng c\xE1o Display CPC t\u1ED1i thi\u1EC3u l\xE0 1,800 VN\u0110. Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Bid}\u0111.`
|
|
2463
|
+
);
|
|
2464
|
+
}
|
|
2465
|
+
if (price.Limit !== void 0 && price.Limit > 0 && price.Limit < 50) {
|
|
2466
|
+
errors.push(
|
|
2467
|
+
"S\u1ED1 l\u01B0\u1EE3ng l\u01B0\u1EE3t nh\u1EA5n t\u1ED1i thi\u1EC3u (Price.Limit) cho Qu\u1EA3ng c\xE1o Display CPC l\xE0 50 l\u01B0\u1EE3t nh\u1EA5n."
|
|
2468
|
+
);
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2342
2471
|
}
|
|
2343
2472
|
if (payload.Settings && payload.Settings.DeliveryType !== void 0) {
|
|
2344
2473
|
const deliveryType = payload.Settings.DeliveryType;
|
|
@@ -2355,6 +2484,21 @@ function validateUpdateAdPayload(payload, options = {}) {
|
|
|
2355
2484
|
}
|
|
2356
2485
|
const targeting = payload.Settings?.Targeting;
|
|
2357
2486
|
if (targeting) {
|
|
2487
|
+
if (targeting.Gender !== void 0 && targeting.Gender !== null) {
|
|
2488
|
+
if (![0, 1, 2].includes(Number(targeting.Gender))) {
|
|
2489
|
+
errors.push(`M\xE3 gi\u1EDBi t\xEDnh 'Gender' (${targeting.Gender}) kh\xF4ng h\u1EE3p l\u1EC7. H\u1EE3p l\u1EC7: 0 (T\u1EA5t c\u1EA3), 1 (Nam), 2 (N\u1EEF).`);
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
if (targeting.CustomAudienceId !== void 0 && targeting.CustomAudienceId !== null) {
|
|
2493
|
+
if (typeof targeting.CustomAudienceId !== "number" || targeting.CustomAudienceId < 0) {
|
|
2494
|
+
errors.push("CustomAudienceId ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn kh\xF4ng \xE2m (>= 0).");
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
if (targeting.ExcludedAudienceId !== void 0 && targeting.ExcludedAudienceId !== null) {
|
|
2498
|
+
if (typeof targeting.ExcludedAudienceId !== "number" || targeting.ExcludedAudienceId < 0) {
|
|
2499
|
+
errors.push("ExcludedAudienceId ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn kh\xF4ng \xE2m (>= 0).");
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2358
2502
|
const newAges = targeting.NewAgeRanges;
|
|
2359
2503
|
const oldAges = targeting.AgeRanges;
|
|
2360
2504
|
if (newAges && newAges.length > 0) {
|
|
@@ -2477,6 +2621,14 @@ function validateUpdateAdPayload(payload, options = {}) {
|
|
|
2477
2621
|
if (!payload.ZaloFeedId && !payload.articleId) {
|
|
2478
2622
|
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).");
|
|
2479
2623
|
}
|
|
2624
|
+
} else if (Number(payload.Type) === 21 || Number(payload.Type) === 23 || Number(payload.Type) === 26 || payload.Type === VALID_AD_TYPES.DISPLAY || payload.Type === VALID_AD_TYPES.DISPLAY_HALFPAGE || payload.Type === VALID_AD_TYPES.DISPLAY_MEDIUM_RECTANGLE) {
|
|
2625
|
+
const img = payload.Settings?.Image;
|
|
2626
|
+
const hasImage = img?.LandscapeCoverUrl || img?.BaseLandscapeCoverUrl || img?.PortraitCoverUrl || img?.SquareCoverUrl;
|
|
2627
|
+
if (!hasImage) {
|
|
2628
|
+
errors.push(
|
|
2629
|
+
"Qu\u1EA3ng c\xE1o Display b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 \xEDt nh\u1EA5t m\u1ED9t banner h\xECnh \u1EA3nh (Settings.Image.LandscapeCoverUrl ho\u1EB7c BaseLandscapeCoverUrl)."
|
|
2630
|
+
);
|
|
2631
|
+
}
|
|
2480
2632
|
}
|
|
2481
2633
|
return {
|
|
2482
2634
|
isValid: errors.length === 0,
|
|
@@ -2600,14 +2752,183 @@ function validateCropCoordinates(input) {
|
|
|
2600
2752
|
data: errors.length === 0 ? cleanData : void 0
|
|
2601
2753
|
};
|
|
2602
2754
|
}
|
|
2755
|
+
function validateCreateCommerceCampaign(payload, options = {}) {
|
|
2756
|
+
const errors = [];
|
|
2757
|
+
const warnings = [];
|
|
2758
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2759
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2760
|
+
} else if (payload.name.length > 255) {
|
|
2761
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2762
|
+
}
|
|
2763
|
+
if (!payload.pageId || payload.pageId <= 0) {
|
|
2764
|
+
errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Commerce (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
|
|
2765
|
+
}
|
|
2766
|
+
if (payload.productId === void 0 || payload.productId === null || payload.productId <= 0) {
|
|
2767
|
+
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).");
|
|
2768
|
+
}
|
|
2769
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
2770
|
+
}
|
|
2771
|
+
function validateCreateDisplayCampaign(payload, options = {}) {
|
|
2772
|
+
const errors = [];
|
|
2773
|
+
const warnings = [];
|
|
2774
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2775
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2776
|
+
} else if (payload.name.length > 255) {
|
|
2777
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2778
|
+
}
|
|
2779
|
+
if (payload.targetUrl && !/^https?:\/\/.+/i.test(payload.targetUrl)) {
|
|
2780
|
+
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://.");
|
|
2781
|
+
}
|
|
2782
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
2783
|
+
}
|
|
2784
|
+
function validateCreateWebsiteCampaign(payload, options = {}) {
|
|
2785
|
+
const errors = [];
|
|
2786
|
+
const warnings = [];
|
|
2787
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2788
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2789
|
+
} else if (payload.name.length > 255) {
|
|
2790
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2791
|
+
}
|
|
2792
|
+
if (!payload.targetUrl || typeof payload.targetUrl !== "string" || !payload.targetUrl.trim()) {
|
|
2793
|
+
errors.push("Li\xEAn k\u1EBFt website ('targetUrl') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Website.");
|
|
2794
|
+
} else if (!/^https?:\/\/.+/i.test(payload.targetUrl)) {
|
|
2795
|
+
errors.push("Li\xEAn k\u1EBFt website ('targetUrl') ph\u1EA3i l\xE0 \u0111\u01B0\u1EDDng link h\u1EE3p l\u1EC7 b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https://.");
|
|
2796
|
+
}
|
|
2797
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
2798
|
+
}
|
|
2799
|
+
function validateCreateFormCampaign(payload, options = {}) {
|
|
2800
|
+
const errors = [];
|
|
2801
|
+
const warnings = [];
|
|
2802
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2803
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2804
|
+
} else if (payload.name.length > 255) {
|
|
2805
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2806
|
+
}
|
|
2807
|
+
if (!payload.pageId || payload.pageId <= 0) {
|
|
2808
|
+
errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Form (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
|
|
2809
|
+
}
|
|
2810
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
2811
|
+
}
|
|
2812
|
+
function validateCreateMessageCampaign(payload, options = {}) {
|
|
2813
|
+
const errors = [];
|
|
2814
|
+
const warnings = [];
|
|
2815
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2816
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2817
|
+
} else if (payload.name.length > 255) {
|
|
2818
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2819
|
+
}
|
|
2820
|
+
if (!payload.pageId || payload.pageId <= 0) {
|
|
2821
|
+
errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Tin nh\u1EAFn (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
|
|
2822
|
+
}
|
|
2823
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
2824
|
+
}
|
|
2825
|
+
function validateCreateOfficialAccountCampaign(payload, options = {}) {
|
|
2826
|
+
const errors = [];
|
|
2827
|
+
const warnings = [];
|
|
2828
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2829
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2830
|
+
} else if (payload.name.length > 255) {
|
|
2831
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2832
|
+
}
|
|
2833
|
+
if (!payload.pageId || payload.pageId <= 0) {
|
|
2834
|
+
errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Zalo Official Account (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
|
|
2835
|
+
}
|
|
2836
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
2837
|
+
}
|
|
2838
|
+
function validateCreateArticleCampaign(payload, options = {}) {
|
|
2839
|
+
const errors = [];
|
|
2840
|
+
const warnings = [];
|
|
2841
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2842
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2843
|
+
} else if (payload.name.length > 255) {
|
|
2844
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2845
|
+
}
|
|
2846
|
+
if (!payload.pageId || payload.pageId <= 0) {
|
|
2847
|
+
errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o B\xE0i vi\u1EBFt (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
|
|
2848
|
+
}
|
|
2849
|
+
if (!payload.articleId || payload.articleId <= 0) {
|
|
2850
|
+
errors.push("B\xE0i vi\u1EBFt ('articleId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o B\xE0i vi\u1EBFt (ch\u1ECDn t\u1EEB Danh s\xE1ch b\xE0i vi\u1EBFt c\u1EE7a OA \u0111\xF3, l\u1EA5y qua getOwnedArticles).");
|
|
2851
|
+
}
|
|
2852
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
2853
|
+
}
|
|
2854
|
+
function validateCreateVideoCampaign(payload, options = {}) {
|
|
2855
|
+
const errors = [];
|
|
2856
|
+
const warnings = [];
|
|
2857
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2858
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2859
|
+
} else if (payload.name.length > 255) {
|
|
2860
|
+
errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2861
|
+
}
|
|
2862
|
+
if (!payload.targetUrl || typeof payload.targetUrl !== "string" || !payload.targetUrl.trim()) {
|
|
2863
|
+
errors.push("Li\xEAn k\u1EBFt Website ('targetUrl') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Video.");
|
|
2864
|
+
} else if (!/^https?:\/\/.+/i.test(payload.targetUrl)) {
|
|
2865
|
+
errors.push("Li\xEAn k\u1EBFt Website ('targetUrl') ph\u1EA3i l\xE0 \u0111\u01B0\u1EDDng link h\u1EE3p l\u1EC7 b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https://.");
|
|
2866
|
+
}
|
|
2867
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
2868
|
+
}
|
|
2869
|
+
function validateUpdateWebsiteAd(payload, options = {}) {
|
|
2870
|
+
return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.WEBSITE }, options);
|
|
2871
|
+
}
|
|
2872
|
+
function validateUpdateDisplayAd(payload, options = {}) {
|
|
2873
|
+
const adFormat = payload.Settings?.AdInfo?.AdFormat;
|
|
2874
|
+
const rawType = Number(payload.Type);
|
|
2875
|
+
const isHalfpage = rawType === 26 || adFormat === 13 || adFormat === 14;
|
|
2876
|
+
const isMediumRectangle = rawType === 23 || adFormat === 6;
|
|
2877
|
+
let effectiveType;
|
|
2878
|
+
if (isHalfpage) {
|
|
2879
|
+
effectiveType = VALID_AD_TYPES.DISPLAY_HALFPAGE;
|
|
2880
|
+
} else if (isMediumRectangle) {
|
|
2881
|
+
effectiveType = VALID_AD_TYPES.DISPLAY_MEDIUM_RECTANGLE;
|
|
2882
|
+
} else {
|
|
2883
|
+
effectiveType = payload.Type ?? VALID_AD_TYPES.DISPLAY;
|
|
2884
|
+
}
|
|
2885
|
+
return validateUpdateAdPayload({ ...payload, Type: effectiveType }, options);
|
|
2886
|
+
}
|
|
2887
|
+
function validateUpdateVideoAd(payload, options = {}) {
|
|
2888
|
+
return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.VIDEO }, options);
|
|
2889
|
+
}
|
|
2890
|
+
function validateUpdateCommerceAd(payload, options = {}) {
|
|
2891
|
+
return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.COMMERCE }, options);
|
|
2892
|
+
}
|
|
2893
|
+
function validateUpdateFormAd(payload, options = {}) {
|
|
2894
|
+
return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.FORM }, options);
|
|
2895
|
+
}
|
|
2896
|
+
function validateUpdateMessageAd(payload, options = {}) {
|
|
2897
|
+
return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.MESSAGE }, options);
|
|
2898
|
+
}
|
|
2899
|
+
function validateUpdateOfficialAccountAd(payload, options = {}) {
|
|
2900
|
+
return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.OA }, options);
|
|
2901
|
+
}
|
|
2902
|
+
function validateUpdateArticleAd(payload, options = {}) {
|
|
2903
|
+
return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.ARTICLE }, options);
|
|
2904
|
+
}
|
|
2603
2905
|
var ZaloCampaignsValidator = {
|
|
2906
|
+
// Generic
|
|
2604
2907
|
createCampaign: validateCreateCampaignPayload,
|
|
2605
2908
|
updateAd: validateUpdateAdPayload,
|
|
2606
2909
|
renameCampaign: validateRenameCampaignParams,
|
|
2607
2910
|
changeStatus: validateChangeCampaignStatusParams,
|
|
2608
2911
|
duplicateAd: validateDuplicateAdParams,
|
|
2609
2912
|
validateCropCoordinates,
|
|
2610
|
-
validateUploadCropAdImage: validateCropCoordinates
|
|
2913
|
+
validateUploadCropAdImage: validateCropCoordinates,
|
|
2914
|
+
// Specific Create Campaign
|
|
2915
|
+
createCommerceCampaign: validateCreateCommerceCampaign,
|
|
2916
|
+
createDisplayCampaign: validateCreateDisplayCampaign,
|
|
2917
|
+
createWebsiteCampaign: validateCreateWebsiteCampaign,
|
|
2918
|
+
createFormCampaign: validateCreateFormCampaign,
|
|
2919
|
+
createMessageCampaign: validateCreateMessageCampaign,
|
|
2920
|
+
createOfficialAccountCampaign: validateCreateOfficialAccountCampaign,
|
|
2921
|
+
createArticleCampaign: validateCreateArticleCampaign,
|
|
2922
|
+
createVideoCampaign: validateCreateVideoCampaign,
|
|
2923
|
+
// Specific Update Ad
|
|
2924
|
+
updateWebsiteAd: validateUpdateWebsiteAd,
|
|
2925
|
+
updateDisplayAd: validateUpdateDisplayAd,
|
|
2926
|
+
updateVideoAd: validateUpdateVideoAd,
|
|
2927
|
+
updateCommerceAd: validateUpdateCommerceAd,
|
|
2928
|
+
updateFormAd: validateUpdateFormAd,
|
|
2929
|
+
updateMessageAd: validateUpdateMessageAd,
|
|
2930
|
+
updateOfficialAccountAd: validateUpdateOfficialAccountAd,
|
|
2931
|
+
updateArticleAd: validateUpdateArticleAd
|
|
2611
2932
|
};
|
|
2612
2933
|
|
|
2613
2934
|
// src/services/campaigns.service.ts
|
|
@@ -5759,8 +6080,8 @@ function validateListFormLeadsRequest(input) {
|
|
|
5759
6080
|
const offset = typeof raw.offset === "number" && raw.offset >= 0 ? Math.floor(raw.offset) : 0;
|
|
5760
6081
|
const status = typeof raw.status === "string" && raw.status.trim() !== "" ? raw.status.trim() : "2,6,1,0,7,4,5,3";
|
|
5761
6082
|
const now = Math.floor(Date.now() / 1e3);
|
|
5762
|
-
const fromTime = typeof raw.fromTime === "number" && raw.fromTime >= 0 ? Math.floor(raw.fromTime) : now - 90 * 86400;
|
|
5763
|
-
const toTime = typeof raw.toTime === "number" && raw.toTime >= 0 ? Math.floor(raw.toTime) : now;
|
|
6083
|
+
const fromTime = typeof raw.fromTime === "number" && raw.fromTime >= 0 ? raw.fromTime >= 1e10 ? Math.floor(raw.fromTime / 1e3) : Math.floor(raw.fromTime) : now - 90 * 86400;
|
|
6084
|
+
const toTime = typeof raw.toTime === "number" && raw.toTime >= 0 ? raw.toTime >= 1e10 ? Math.floor(raw.toTime / 1e3) : Math.floor(raw.toTime) : now;
|
|
5764
6085
|
if (toTime < fromTime) {
|
|
5765
6086
|
errors.push("M\u1ED1c th\u1EDDi gian k\u1EBFt th\xFAc 'toTime' ph\u1EA3i l\u1EDBn h\u01A1n ho\u1EB7c b\u1EB1ng 'fromTime'.");
|
|
5766
6087
|
}
|
|
@@ -8707,6 +9028,7 @@ export {
|
|
|
8707
9028
|
VALID_AD_TYPES,
|
|
8708
9029
|
VALID_CAMPAIGN_TYPES,
|
|
8709
9030
|
VIETNAM_PHONE_REGEX,
|
|
9031
|
+
ZALO_DISPLAY_AD_FORMAT,
|
|
8710
9032
|
ZALO_NEW_REGION_PROVINCE_CODES,
|
|
8711
9033
|
ZALO_PROFILE_ADS_PROVINCES,
|
|
8712
9034
|
ZALO_PROFILE_ADS_SUB_CATEGORIES,
|
|
@@ -8781,18 +9103,26 @@ export {
|
|
|
8781
9103
|
sanitizeCanvasKeys,
|
|
8782
9104
|
validateChangeCampaignStatusParams,
|
|
8783
9105
|
validateCloneInstantPageRequest,
|
|
9106
|
+
validateCreateArticleCampaign,
|
|
8784
9107
|
validateCreateCampaignPayload,
|
|
9108
|
+
validateCreateCommerceCampaign,
|
|
8785
9109
|
validateCreateCustomAudienceRequest,
|
|
9110
|
+
validateCreateDisplayCampaign,
|
|
8786
9111
|
validateCreateFlowRequest,
|
|
9112
|
+
validateCreateFormCampaign,
|
|
8787
9113
|
validateCreateFormEventAudienceRequest,
|
|
8788
9114
|
validateCreateFormRequest,
|
|
8789
9115
|
validateCreateInstantPageRequest,
|
|
8790
9116
|
validateCreateLookalikeAudienceRequest,
|
|
9117
|
+
validateCreateMessageCampaign,
|
|
8791
9118
|
validateCreateMessageOaEventAudienceRequest,
|
|
8792
9119
|
validateCreateMessagePersonalEventAudienceRequest,
|
|
8793
9120
|
validateCreateOaPageRequest,
|
|
9121
|
+
validateCreateOfficialAccountCampaign,
|
|
8794
9122
|
validateCreatePhoneAudienceRequest,
|
|
8795
9123
|
validateCreateSavedAudienceRequest,
|
|
9124
|
+
validateCreateVideoCampaign,
|
|
9125
|
+
validateCreateWebsiteCampaign,
|
|
8796
9126
|
validateCropCoordinates,
|
|
8797
9127
|
validateDateRangeReportRequest,
|
|
8798
9128
|
validateDuplicateAdParams,
|
|
@@ -8815,10 +9145,18 @@ export {
|
|
|
8815
9145
|
validateSearchInstantPagesRequest,
|
|
8816
9146
|
validateToggleLeadNotificationRequest,
|
|
8817
9147
|
validateUpdateAdPayload,
|
|
9148
|
+
validateUpdateArticleAd,
|
|
9149
|
+
validateUpdateCommerceAd,
|
|
9150
|
+
validateUpdateDisplayAd,
|
|
8818
9151
|
validateUpdateFlowRequest,
|
|
9152
|
+
validateUpdateFormAd,
|
|
8819
9153
|
validateUpdateInstantPageRequest,
|
|
8820
9154
|
validateUpdateInstantPageSharesRequest,
|
|
8821
9155
|
validateUpdateLeadNotificationIntervalRequest,
|
|
9156
|
+
validateUpdateMessageAd,
|
|
9157
|
+
validateUpdateOfficialAccountAd,
|
|
9158
|
+
validateUpdateVideoAd,
|
|
9159
|
+
validateUpdateWebsiteAd,
|
|
8822
9160
|
validateUploadCustomAudiencePhoneListRequest,
|
|
8823
9161
|
validateUploadMediaRequest,
|
|
8824
9162
|
validateUpsertCustomReportRequest,
|