@redonvn/zalo-ads-sdk 0.2.4 → 0.2.7
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 +392 -56
- package/dist/index.d.ts +392 -56
- package/dist/index.js +1095 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1079 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1531,6 +1531,30 @@ var OP_ZaloAdsDeleteCampaign = {
|
|
|
1531
1531
|
"status"
|
|
1532
1532
|
]
|
|
1533
1533
|
};
|
|
1534
|
+
var OP_ZaloAdsCreateSpellCheckV3Job = {
|
|
1535
|
+
operationId: "zalo_ads_create_spell_check_v3_job",
|
|
1536
|
+
method: "POST",
|
|
1537
|
+
endpoint: "/api/spell-check/v3",
|
|
1538
|
+
baseUrl: "https://ads.zalo.me",
|
|
1539
|
+
binaryFields: [],
|
|
1540
|
+
pathFields: [],
|
|
1541
|
+
queryFields: [],
|
|
1542
|
+
headerFields: [],
|
|
1543
|
+
cookieFields: [],
|
|
1544
|
+
bodyFields: ["title", "caption"]
|
|
1545
|
+
};
|
|
1546
|
+
var OP_ZaloAdsGetSpellCheckV3Job = {
|
|
1547
|
+
operationId: "zalo_ads_get_spell_check_v3_job",
|
|
1548
|
+
method: "GET",
|
|
1549
|
+
endpoint: "/api/spell-check/v3/{jobId}",
|
|
1550
|
+
baseUrl: "https://ads.zalo.me",
|
|
1551
|
+
binaryFields: [],
|
|
1552
|
+
pathFields: ["jobId"],
|
|
1553
|
+
queryFields: [],
|
|
1554
|
+
headerFields: [],
|
|
1555
|
+
cookieFields: [],
|
|
1556
|
+
bodyFields: []
|
|
1557
|
+
};
|
|
1534
1558
|
var ZaloCampaignsService = class {
|
|
1535
1559
|
constructor(client) {
|
|
1536
1560
|
this.client = client;
|
|
@@ -1680,6 +1704,48 @@ var ZaloCampaignsService = class {
|
|
|
1680
1704
|
getSpellCheckV2(...args) {
|
|
1681
1705
|
return this.getApiSpellCheckV2(...args);
|
|
1682
1706
|
}
|
|
1707
|
+
/**
|
|
1708
|
+
* Khởi tạo tác vụ kiểm tra chính tả và vi phạm quy chuẩn quảng cáo AI V3 (POST /api/spell-check/v3).
|
|
1709
|
+
*/
|
|
1710
|
+
createSpellCheckV3Job(request, options) {
|
|
1711
|
+
return this.client.requestJson(
|
|
1712
|
+
OP_ZaloAdsCreateSpellCheckV3Job,
|
|
1713
|
+
this.client.toTransportInput(OP_ZaloAdsCreateSpellCheckV3Job, request),
|
|
1714
|
+
options
|
|
1715
|
+
);
|
|
1716
|
+
}
|
|
1717
|
+
/**
|
|
1718
|
+
* Lấy kết quả kiểm tra chính tả AI V3 theo jobId (GET /api/spell-check/v3/{jobId}).
|
|
1719
|
+
*/
|
|
1720
|
+
getSpellCheckV3Job(request, options) {
|
|
1721
|
+
return this.client.requestWithoutBody(
|
|
1722
|
+
OP_ZaloAdsGetSpellCheckV3Job,
|
|
1723
|
+
this.client.toTransportInput(OP_ZaloAdsGetSpellCheckV3Job, request),
|
|
1724
|
+
options
|
|
1725
|
+
);
|
|
1726
|
+
}
|
|
1727
|
+
/**
|
|
1728
|
+
* Helper kiểm tra chính tả AI V3 trọn gói: Gửi kiểm tra và tự động polling cho đến khi hoàn thành (hoặc timeout).
|
|
1729
|
+
* @param request Tiêu đề (title) và chú thích (caption) cần kiểm tra.
|
|
1730
|
+
* @param pollIntervalMs Chu kỳ polling kiểm tra trạng thái (mặc định: 600ms).
|
|
1731
|
+
* @param timeoutMs Thời gian chờ tối đa (mặc định: 15.000ms = 15 giây).
|
|
1732
|
+
*/
|
|
1733
|
+
async checkSpellV3AndWait(request, pollIntervalMs = 600, timeoutMs = 15e3, options) {
|
|
1734
|
+
const jobRes = await this.createSpellCheckV3Job(request, options);
|
|
1735
|
+
const jobId = jobRes?.data?.jobId;
|
|
1736
|
+
if (!jobId) {
|
|
1737
|
+
throw new Error(`[SpellCheckV3] Kh\xF4ng nh\u1EADn \u0111\u01B0\u1EE3c jobId t\u1EEB Zalo Ads (code: ${jobRes?.code})`);
|
|
1738
|
+
}
|
|
1739
|
+
const startTime = Date.now();
|
|
1740
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
1741
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
1742
|
+
const res = await this.getSpellCheckV3Job({ jobId }, options);
|
|
1743
|
+
if (res?.data?.status === "COMPLETED") {
|
|
1744
|
+
return res;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
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}`);
|
|
1748
|
+
}
|
|
1683
1749
|
};
|
|
1684
1750
|
|
|
1685
1751
|
// src/services/account.service.ts
|
|
@@ -1834,6 +1900,365 @@ var ZaloAccountService = class {
|
|
|
1834
1900
|
}
|
|
1835
1901
|
};
|
|
1836
1902
|
|
|
1903
|
+
// src/validators/audiences.validator.ts
|
|
1904
|
+
function validateCreateSavedAudienceRequest(input) {
|
|
1905
|
+
const errors = [];
|
|
1906
|
+
if (!input || typeof input !== "object") {
|
|
1907
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1908
|
+
}
|
|
1909
|
+
const raw = input;
|
|
1910
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
1911
|
+
if (!name) {
|
|
1912
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1913
|
+
} else if (name.length < 2 || name.length > 255) {
|
|
1914
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
1915
|
+
}
|
|
1916
|
+
let targetingObj;
|
|
1917
|
+
if (typeof raw.targeting === "string") {
|
|
1918
|
+
try {
|
|
1919
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
1920
|
+
} catch {
|
|
1921
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
1922
|
+
targetingObj = {};
|
|
1923
|
+
}
|
|
1924
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
1925
|
+
targetingObj = raw.targeting;
|
|
1926
|
+
} else {
|
|
1927
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c (chu\u1ED7i JSON ho\u1EB7c Object c\u1EA5u h\xECnh targeting).");
|
|
1928
|
+
targetingObj = {};
|
|
1929
|
+
}
|
|
1930
|
+
const gender = typeof targetingObj.Gender === "number" ? targetingObj.Gender : 0;
|
|
1931
|
+
if (![0, 1, 2].includes(gender)) {
|
|
1932
|
+
errors.push("Tr\u01B0\u1EDDng 'Gender' ph\u1EA3i l\xE0 0 (T\u1EA5t c\u1EA3), 1 (Nam), ho\u1EB7c 2 (N\u1EEF).");
|
|
1933
|
+
}
|
|
1934
|
+
const VALID_AGE_RANGES = [10282, 10283, 10284, 10285, 10286, 10287, 10288];
|
|
1935
|
+
const newAgeRanges = Array.isArray(targetingObj.NewAgeRanges) && targetingObj.NewAgeRanges.length > 0 ? targetingObj.NewAgeRanges.map(Number) : VALID_AGE_RANGES;
|
|
1936
|
+
for (const age of newAgeRanges) {
|
|
1937
|
+
if (!VALID_AGE_RANGES.includes(age)) {
|
|
1938
|
+
errors.push(`M\xE3 \u0111\u1ED9 tu\u1ED5i '${age}' kh\xF4ng h\u1EE3p l\u1EC7. C\xE1c m\xE3 cho ph\xE9p: ${VALID_AGE_RANGES.join(", ")}.`);
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
const VALID_OS = [0, 1, 2, 3];
|
|
1942
|
+
const os = Array.isArray(targetingObj.Os) && targetingObj.Os.length > 0 ? targetingObj.Os.map(Number) : [0, 1, 3];
|
|
1943
|
+
for (const o of os) {
|
|
1944
|
+
if (!VALID_OS.includes(o)) {
|
|
1945
|
+
errors.push(`M\xE3 h\u1EC7 \u0111i\u1EC1u h\xE0nh '${o}' kh\xF4ng h\u1EE3p l\u1EC7 (0: Android, 1: iOS, 2: Windows Phone, 3: PC).`);
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
let location = targetingObj.Location;
|
|
1949
|
+
if (!location || typeof location !== "object") {
|
|
1950
|
+
location = {
|
|
1951
|
+
Addresses: [],
|
|
1952
|
+
Cities: [],
|
|
1953
|
+
WardTargeting: { Includes: [], Excludes: [] }
|
|
1954
|
+
};
|
|
1955
|
+
} else {
|
|
1956
|
+
location = {
|
|
1957
|
+
Addresses: Array.isArray(location.Addresses) ? location.Addresses : [],
|
|
1958
|
+
Cities: Array.isArray(location.Cities) ? location.Cities : [],
|
|
1959
|
+
WardTargeting: location.WardTargeting && typeof location.WardTargeting === "object" ? location.WardTargeting : { Includes: [], Excludes: [] }
|
|
1960
|
+
};
|
|
1961
|
+
if (location.WardTargeting.Includes && !Array.isArray(location.WardTargeting.Includes)) {
|
|
1962
|
+
errors.push("Tr\u01B0\u1EDDng 'Location.WardTargeting.Includes' ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng khu v\u1EF1c.");
|
|
1963
|
+
} else if (Array.isArray(location.WardTargeting.Includes)) {
|
|
1964
|
+
for (const inc of location.WardTargeting.Includes) {
|
|
1965
|
+
if (![1, 2, 3].includes(Number(inc.Id))) {
|
|
1966
|
+
errors.push(`M\xE3 v\xF9ng mi\u1EC1n Id='${inc.Id}' kh\xF4ng h\u1EE3p l\u1EC7 (1: Mi\u1EC1n B\u1EAFc, 2: Mi\u1EC1n Trung, 3: Mi\u1EC1n Nam).`);
|
|
1967
|
+
}
|
|
1968
|
+
if (inc.Provinces && !Array.isArray(inc.Provinces)) {
|
|
1969
|
+
errors.push(`Tr\u01B0\u1EDDng 'Provinces' trong v\xF9ng mi\u1EC1n Id=${inc.Id} ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng t\u1EC9nh/th\xE0nh.`);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
const finalTargeting = {
|
|
1975
|
+
...targetingObj,
|
|
1976
|
+
CustomAudienceId: 0,
|
|
1977
|
+
Gender: gender,
|
|
1978
|
+
NewAgeRanges: newAgeRanges,
|
|
1979
|
+
Os: os,
|
|
1980
|
+
Location: location
|
|
1981
|
+
};
|
|
1982
|
+
return {
|
|
1983
|
+
isValid: errors.length === 0,
|
|
1984
|
+
errors,
|
|
1985
|
+
data: errors.length === 0 ? {
|
|
1986
|
+
name,
|
|
1987
|
+
caType: 1,
|
|
1988
|
+
targeting: JSON.stringify(finalTargeting)
|
|
1989
|
+
} : void 0
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
function validateCreatePhoneAudienceRequest(input) {
|
|
1993
|
+
const errors = [];
|
|
1994
|
+
if (!input || typeof input !== "object") {
|
|
1995
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1996
|
+
}
|
|
1997
|
+
const raw = input;
|
|
1998
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
1999
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2000
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2001
|
+
}
|
|
2002
|
+
let targetingObj = {};
|
|
2003
|
+
if (typeof raw.targeting === "string") {
|
|
2004
|
+
try {
|
|
2005
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2006
|
+
} catch {
|
|
2007
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2008
|
+
}
|
|
2009
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2010
|
+
targetingObj = raw.targeting;
|
|
2011
|
+
} else {
|
|
2012
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2013
|
+
}
|
|
2014
|
+
const path = typeof targetingObj.Path === "string" ? targetingObj.Path.trim() : "";
|
|
2015
|
+
if (!path) {
|
|
2016
|
+
errors.push("Tr\u01B0\u1EDDng 'Path' (URL file .txt sau khi upload) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2017
|
+
}
|
|
2018
|
+
const total = typeof targetingObj.Total === "number" ? targetingObj.Total : 0;
|
|
2019
|
+
if (total <= 0) {
|
|
2020
|
+
errors.push("Tr\u01B0\u1EDDng 'Total' (s\u1ED1 l\u01B0\u1EE3ng S\u0110T trong file) ph\u1EA3i l\u1EDBn h\u01A1n 0.");
|
|
2021
|
+
}
|
|
2022
|
+
return {
|
|
2023
|
+
isValid: errors.length === 0,
|
|
2024
|
+
errors,
|
|
2025
|
+
data: errors.length === 0 ? {
|
|
2026
|
+
name,
|
|
2027
|
+
caType: 3,
|
|
2028
|
+
targeting: JSON.stringify({
|
|
2029
|
+
Name: String(targetingObj.Name || "phones.txt"),
|
|
2030
|
+
Path: path,
|
|
2031
|
+
Total: total,
|
|
2032
|
+
ZaloId: Number(targetingObj.ZaloId || 0),
|
|
2033
|
+
OriginAudience: 0
|
|
2034
|
+
})
|
|
2035
|
+
} : void 0
|
|
2036
|
+
};
|
|
2037
|
+
}
|
|
2038
|
+
function validateCreateLookalikeAudienceRequest(input) {
|
|
2039
|
+
const errors = [];
|
|
2040
|
+
if (!input || typeof input !== "object") {
|
|
2041
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2042
|
+
}
|
|
2043
|
+
const raw = input;
|
|
2044
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2045
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2046
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2047
|
+
}
|
|
2048
|
+
let targetingObj = {};
|
|
2049
|
+
if (typeof raw.targeting === "string") {
|
|
2050
|
+
try {
|
|
2051
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2052
|
+
} catch {
|
|
2053
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2054
|
+
}
|
|
2055
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2056
|
+
targetingObj = raw.targeting;
|
|
2057
|
+
} else {
|
|
2058
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2059
|
+
}
|
|
2060
|
+
const originAudience = Number(targetingObj.OriginAudience);
|
|
2061
|
+
if (!originAudience || originAudience <= 0) {
|
|
2062
|
+
errors.push("Tr\u01B0\u1EDDng 'OriginAudience' (ID nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng S\u0110T g\u1ED1c) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2063
|
+
}
|
|
2064
|
+
const total = Number(targetingObj.Total);
|
|
2065
|
+
if (![1e6, 15e5, 2e6].includes(total)) {
|
|
2066
|
+
errors.push("Tr\u01B0\u1EDDng 'Total' c\u1EE7a Lookalike ch\u1EC9 ch\u1EA5p nh\u1EADn c\xE1c m\u1ED1c: 1.000.000, 1.500.000 ho\u1EB7c 2.000.000.");
|
|
2067
|
+
}
|
|
2068
|
+
return {
|
|
2069
|
+
isValid: errors.length === 0,
|
|
2070
|
+
errors,
|
|
2071
|
+
data: errors.length === 0 ? {
|
|
2072
|
+
name,
|
|
2073
|
+
caType: 6,
|
|
2074
|
+
targeting: JSON.stringify({
|
|
2075
|
+
OriginAudience: originAudience,
|
|
2076
|
+
Total: total,
|
|
2077
|
+
Name: String(targetingObj.Name || "Lookalike Audience"),
|
|
2078
|
+
Path: String(targetingObj.Path || "")
|
|
2079
|
+
})
|
|
2080
|
+
} : void 0
|
|
2081
|
+
};
|
|
2082
|
+
}
|
|
2083
|
+
function validateCreateFormEventAudienceRequest(input) {
|
|
2084
|
+
const errors = [];
|
|
2085
|
+
if (!input || typeof input !== "object") {
|
|
2086
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2087
|
+
}
|
|
2088
|
+
const raw = input;
|
|
2089
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2090
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2091
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2092
|
+
}
|
|
2093
|
+
let targetingObj = {};
|
|
2094
|
+
if (typeof raw.targeting === "string") {
|
|
2095
|
+
try {
|
|
2096
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2097
|
+
} catch {
|
|
2098
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2099
|
+
}
|
|
2100
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2101
|
+
targetingObj = raw.targeting;
|
|
2102
|
+
}
|
|
2103
|
+
const eventType = Number(targetingObj.EventType);
|
|
2104
|
+
if (![1, 2, 3, 4].includes(eventType)) {
|
|
2105
|
+
errors.push("Tr\u01B0\u1EDDng 'EventType' ph\u1EA3i l\xE0 1 (\u0110\xE3 xem ch\u01B0a g\u1EEDi), 2 (\u0110\xE3 xem & g\u1EEDi), 3 (\u0110\xE3 xem), ho\u1EB7c 4 (M\u1EDF chat t\u1EEB Form).");
|
|
2106
|
+
}
|
|
2107
|
+
const oaId = typeof targetingObj.OaId === "string" ? targetingObj.OaId.trim() : String(targetingObj.OaId || "");
|
|
2108
|
+
if (!oaId) {
|
|
2109
|
+
errors.push("Tr\u01B0\u1EDDng 'OaId' (d\u1EA1ng chu\u1ED7i c\u1EE7a pageId ho\u1EB7c noisedId) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2110
|
+
}
|
|
2111
|
+
const numDays = Number(targetingObj.NumDays);
|
|
2112
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
2113
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
2114
|
+
}
|
|
2115
|
+
const formIds = Array.isArray(targetingObj.FormIds) ? targetingObj.FormIds : [];
|
|
2116
|
+
if (formIds.length === 0) {
|
|
2117
|
+
errors.push("Tr\u01B0\u1EDDng 'FormIds' ph\u1EA3i ch\u1EE9a \xEDt nh\u1EA5t 1 ID Form.");
|
|
2118
|
+
}
|
|
2119
|
+
return {
|
|
2120
|
+
isValid: errors.length === 0,
|
|
2121
|
+
errors,
|
|
2122
|
+
data: errors.length === 0 ? {
|
|
2123
|
+
name,
|
|
2124
|
+
caType: 12,
|
|
2125
|
+
targeting: JSON.stringify({
|
|
2126
|
+
EventType: eventType,
|
|
2127
|
+
OaId: oaId,
|
|
2128
|
+
NumDays: numDays,
|
|
2129
|
+
FormIds: formIds
|
|
2130
|
+
})
|
|
2131
|
+
} : void 0
|
|
2132
|
+
};
|
|
2133
|
+
}
|
|
2134
|
+
function validateCreateMessageOaEventAudienceRequest(input) {
|
|
2135
|
+
const errors = [];
|
|
2136
|
+
if (!input || typeof input !== "object") {
|
|
2137
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2138
|
+
}
|
|
2139
|
+
const raw = input;
|
|
2140
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2141
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2142
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2143
|
+
}
|
|
2144
|
+
let targetingObj = {};
|
|
2145
|
+
if (typeof raw.targeting === "string") {
|
|
2146
|
+
try {
|
|
2147
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2148
|
+
} catch {
|
|
2149
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2150
|
+
}
|
|
2151
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2152
|
+
targetingObj = raw.targeting;
|
|
2153
|
+
}
|
|
2154
|
+
const eventId = Number(targetingObj.EventId ?? targetingObj.EventType ?? 1);
|
|
2155
|
+
const oaId = typeof targetingObj.OaId === "string" ? targetingObj.OaId.trim() : String(targetingObj.OaId || "");
|
|
2156
|
+
if (!oaId) {
|
|
2157
|
+
errors.push("Tr\u01B0\u1EDDng 'OaId' (chu\u1ED7i pageId ho\u1EB7c noisedId c\u1EE7a OA) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2158
|
+
}
|
|
2159
|
+
const numDays = Number(targetingObj.NumDays);
|
|
2160
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
2161
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
2162
|
+
}
|
|
2163
|
+
return {
|
|
2164
|
+
isValid: errors.length === 0,
|
|
2165
|
+
errors,
|
|
2166
|
+
data: errors.length === 0 ? {
|
|
2167
|
+
name,
|
|
2168
|
+
caType: 11,
|
|
2169
|
+
targeting: JSON.stringify({
|
|
2170
|
+
EventId: eventId,
|
|
2171
|
+
OaId: oaId,
|
|
2172
|
+
NumDays: numDays
|
|
2173
|
+
})
|
|
2174
|
+
} : void 0
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
function validateCreateMessagePersonalEventAudienceRequest(input) {
|
|
2178
|
+
const errors = [];
|
|
2179
|
+
if (!input || typeof input !== "object") {
|
|
2180
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2181
|
+
}
|
|
2182
|
+
const raw = input;
|
|
2183
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2184
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2185
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2186
|
+
}
|
|
2187
|
+
let targetingObj = {};
|
|
2188
|
+
if (typeof raw.targeting === "string") {
|
|
2189
|
+
try {
|
|
2190
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2191
|
+
} catch {
|
|
2192
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2193
|
+
}
|
|
2194
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2195
|
+
targetingObj = raw.targeting;
|
|
2196
|
+
}
|
|
2197
|
+
const eventId = Number(targetingObj.EventId ?? targetingObj.EventType ?? 1);
|
|
2198
|
+
if (![1, 2, 3].includes(eventId)) {
|
|
2199
|
+
errors.push("Tr\u01B0\u1EDDng 'EventId' ph\u1EA3i l\xE0 1 (\u0110\xE3 li\xEAn h\u1EC7), 2 (\u0110\xE3 xem kh\xF4ng li\xEAn h\u1EC7), ho\u1EB7c 3 (Xem carousel kh\xF4ng li\xEAn h\u1EC7).");
|
|
2200
|
+
}
|
|
2201
|
+
const numDays = Number(targetingObj.NumDays);
|
|
2202
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
2203
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
2204
|
+
}
|
|
2205
|
+
const pageIds = Array.isArray(targetingObj.PageIds) ? targetingObj.PageIds.map(String) : [];
|
|
2206
|
+
if (pageIds.length === 0) {
|
|
2207
|
+
errors.push("Tr\u01B0\u1EDDng 'PageIds' ph\u1EA3i ch\u1EE9a \xEDt nh\u1EA5t 1 ID trang c\xE1 nh\xE2n.");
|
|
2208
|
+
}
|
|
2209
|
+
return {
|
|
2210
|
+
isValid: errors.length === 0,
|
|
2211
|
+
errors,
|
|
2212
|
+
data: errors.length === 0 ? {
|
|
2213
|
+
name,
|
|
2214
|
+
caType: 14,
|
|
2215
|
+
targeting: JSON.stringify({
|
|
2216
|
+
EventId: eventId,
|
|
2217
|
+
NumDays: numDays,
|
|
2218
|
+
PageIds: pageIds
|
|
2219
|
+
})
|
|
2220
|
+
} : void 0
|
|
2221
|
+
};
|
|
2222
|
+
}
|
|
2223
|
+
function validateEstimateAudienceRequest(input) {
|
|
2224
|
+
const errors = [];
|
|
2225
|
+
if (!input || typeof input !== "object") {
|
|
2226
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2227
|
+
}
|
|
2228
|
+
const raw = input;
|
|
2229
|
+
const gender = typeof raw.gender === "number" ? raw.gender : 0;
|
|
2230
|
+
if (![0, 1, 2].includes(gender)) {
|
|
2231
|
+
errors.push("Tr\u01B0\u1EDDng 'gender' ph\u1EA3i l\xE0 0, 1 ho\u1EB7c 2.");
|
|
2232
|
+
}
|
|
2233
|
+
const ageRanges = Array.isArray(raw.ageRanges) && raw.ageRanges.length > 0 ? raw.ageRanges.map(Number) : [10283, 10284, 10285, 10286, 10287];
|
|
2234
|
+
const platforms = Array.isArray(raw.platforms) && raw.platforms.length > 0 ? raw.platforms.map(Number) : [0, 1, 3];
|
|
2235
|
+
const priceType = typeof raw.priceType === "number" ? raw.priceType : 2;
|
|
2236
|
+
const wardsTargeting = typeof raw.wardsTargeting === "string" && raw.wardsTargeting.trim() ? raw.wardsTargeting.trim() : JSON.stringify({ Includes: [], Excludes: [] });
|
|
2237
|
+
return {
|
|
2238
|
+
isValid: errors.length === 0,
|
|
2239
|
+
errors,
|
|
2240
|
+
data: errors.length === 0 ? {
|
|
2241
|
+
gender,
|
|
2242
|
+
ageRanges,
|
|
2243
|
+
platforms,
|
|
2244
|
+
locations: typeof raw.locations === "string" ? raw.locations : "",
|
|
2245
|
+
provinces: Array.isArray(raw.provinces) ? raw.provinces.map(Number) : [],
|
|
2246
|
+
wardsTargeting,
|
|
2247
|
+
priceType,
|
|
2248
|
+
number: typeof raw.number === "string" ? raw.number : String(raw.number || "0")
|
|
2249
|
+
} : void 0
|
|
2250
|
+
};
|
|
2251
|
+
}
|
|
2252
|
+
var ZaloAudiencesValidator = {
|
|
2253
|
+
createSavedAudience: validateCreateSavedAudienceRequest,
|
|
2254
|
+
createPhoneAudience: validateCreatePhoneAudienceRequest,
|
|
2255
|
+
createLookalikeAudience: validateCreateLookalikeAudienceRequest,
|
|
2256
|
+
createFormEventAudience: validateCreateFormEventAudienceRequest,
|
|
2257
|
+
createMessageOaEventAudience: validateCreateMessageOaEventAudienceRequest,
|
|
2258
|
+
createMessagePersonalEventAudience: validateCreateMessagePersonalEventAudienceRequest,
|
|
2259
|
+
estimateAudience: validateEstimateAudienceRequest
|
|
2260
|
+
};
|
|
2261
|
+
|
|
1837
2262
|
// src/services/audiences.service.ts
|
|
1838
2263
|
var OP_ZaloAdsCreateCustomAudience = {
|
|
1839
2264
|
"operationId": "ZaloAds_createCustomAudience",
|
|
@@ -1934,6 +2359,7 @@ var ZaloAudiencesService = class {
|
|
|
1934
2359
|
constructor(client) {
|
|
1935
2360
|
this.client = client;
|
|
1936
2361
|
}
|
|
2362
|
+
static validator = ZaloAudiencesValidator;
|
|
1937
2363
|
postApiAdEstimateaudience(request, options) {
|
|
1938
2364
|
return this.client.requestJson(OP_ZaloAdsPostApiAdEstimateaudience, this.client.toTransportInput(OP_ZaloAdsPostApiAdEstimateaudience, request), options);
|
|
1939
2365
|
}
|
|
@@ -1986,7 +2412,22 @@ var ZaloAudiencesService = class {
|
|
|
1986
2412
|
}
|
|
1987
2413
|
/** Tạo mới Nhóm đối tượng phát sinh sự kiện trên Kịch bản Tin nhắn cá nhân (`caType = 14` - `MESSAGE_PERSONAL_EVENT_AUDIENCE`). */
|
|
1988
2414
|
createMessagePersonalEventAudience(request, options) {
|
|
1989
|
-
|
|
2415
|
+
let targetingObj;
|
|
2416
|
+
if (typeof request.targeting === "string") {
|
|
2417
|
+
try {
|
|
2418
|
+
targetingObj = JSON.parse(request.targeting);
|
|
2419
|
+
} catch {
|
|
2420
|
+
targetingObj = null;
|
|
2421
|
+
}
|
|
2422
|
+
} else if (request.targeting && typeof request.targeting === "object") {
|
|
2423
|
+
targetingObj = { ...request.targeting };
|
|
2424
|
+
}
|
|
2425
|
+
if (targetingObj && typeof targetingObj === "object") {
|
|
2426
|
+
if (targetingObj.EventId === void 0 && targetingObj.EventType !== void 0) {
|
|
2427
|
+
targetingObj.EventId = targetingObj.EventType;
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
const targetingStr = targetingObj ? JSON.stringify(targetingObj) : typeof request.targeting === "string" ? request.targeting : JSON.stringify(request.targeting);
|
|
1990
2431
|
return this.createCustomAudience({ name: request.name, caType: 14, targeting: targetingStr }, options);
|
|
1991
2432
|
}
|
|
1992
2433
|
/** Tạo mới Nhóm đối tượng từ Trung tâm Lead - Zalo Form (`caType = 10` - `FORM_AUDIENCE`). */
|
|
@@ -2542,6 +2983,236 @@ var ZaloAutomatedRulesService = class {
|
|
|
2542
2983
|
}
|
|
2543
2984
|
};
|
|
2544
2985
|
|
|
2986
|
+
// src/validators/flows.validator.ts
|
|
2987
|
+
var MAX_INT_32 = 2147483647;
|
|
2988
|
+
function is32BitPositiveInteger(val) {
|
|
2989
|
+
if (typeof val === "number") {
|
|
2990
|
+
return Number.isInteger(val) && val > 0 && val <= MAX_INT_32;
|
|
2991
|
+
}
|
|
2992
|
+
if (typeof val === "string" && val.trim() !== "") {
|
|
2993
|
+
const num = Number(val);
|
|
2994
|
+
return Number.isInteger(num) && num > 0 && num <= MAX_INT_32;
|
|
2995
|
+
}
|
|
2996
|
+
return false;
|
|
2997
|
+
}
|
|
2998
|
+
function isPositiveInteger(val) {
|
|
2999
|
+
if (typeof val === "number") return Number.isInteger(val) && val > 0;
|
|
3000
|
+
if (typeof val === "string" && val.trim() !== "") {
|
|
3001
|
+
const num = Number(val);
|
|
3002
|
+
return Number.isInteger(num) && num > 0;
|
|
3003
|
+
}
|
|
3004
|
+
return false;
|
|
3005
|
+
}
|
|
3006
|
+
function isNonNegativeInteger(val) {
|
|
3007
|
+
if (typeof val === "number") return Number.isInteger(val) && val >= 0;
|
|
3008
|
+
if (typeof val === "string" && val.trim() !== "") {
|
|
3009
|
+
const num = Number(val);
|
|
3010
|
+
return Number.isInteger(num) && num >= 0;
|
|
3011
|
+
}
|
|
3012
|
+
return false;
|
|
3013
|
+
}
|
|
3014
|
+
function toPositiveInteger(val) {
|
|
3015
|
+
return typeof val === "number" ? Math.floor(val) : parseInt(String(val), 10);
|
|
3016
|
+
}
|
|
3017
|
+
function validateFlowButtons(buttons, errors, prefix) {
|
|
3018
|
+
if (!Array.isArray(buttons)) {
|
|
3019
|
+
errors.push(`${prefix}: Tr\u01B0\u1EDDng 'buttons' ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng.`);
|
|
3020
|
+
return [];
|
|
3021
|
+
}
|
|
3022
|
+
const cleanButtons = [];
|
|
3023
|
+
buttons.forEach((btn, idx) => {
|
|
3024
|
+
const btnPrefix = `${prefix}.buttons[${idx}]`;
|
|
3025
|
+
if (!btn || typeof btn !== "object") {
|
|
3026
|
+
errors.push(`${btnPrefix}: N\xFAt b\u1EA5m ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng.`);
|
|
3027
|
+
return;
|
|
3028
|
+
}
|
|
3029
|
+
const b = btn;
|
|
3030
|
+
if (typeof b.text !== "string" || b.text.trim() === "") {
|
|
3031
|
+
errors.push(`${btnPrefix}: Nh\xE3n n\xFAt 'text' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.`);
|
|
3032
|
+
}
|
|
3033
|
+
const btnType = Number(b.type);
|
|
3034
|
+
if (![3, 10, 12].includes(btnType)) {
|
|
3035
|
+
errors.push(`${btnPrefix}: Lo\u1EA1i n\xFAt 'type' ph\u1EA3i l\xE0 3 (nh\xE1nh h\u1ED9i tho\u1EA1i), 10 (m\u1EDF website), ho\u1EB7c 12 (g\u1ECDi hotline).`);
|
|
3036
|
+
}
|
|
3037
|
+
const cleanBtn = {
|
|
3038
|
+
type: btnType,
|
|
3039
|
+
text: String(b.text ?? "").trim(),
|
|
3040
|
+
editable: b.editable !== false
|
|
3041
|
+
};
|
|
3042
|
+
if (btnType === 10) {
|
|
3043
|
+
if (typeof b.url !== "string" || b.url.trim() === "") {
|
|
3044
|
+
errors.push(`${btnPrefix}: N\xFAt lo\u1EA1i 10 (m\u1EDF website) b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 tr\u01B0\u1EDDng 'url' h\u1EE3p l\u1EC7.`);
|
|
3045
|
+
} else {
|
|
3046
|
+
cleanBtn.url = b.url.trim();
|
|
3047
|
+
}
|
|
3048
|
+
} else if (btnType === 12) {
|
|
3049
|
+
if (typeof b.phone !== "string" || b.phone.trim() === "") {
|
|
3050
|
+
errors.push(`${btnPrefix}: N\xFAt lo\u1EA1i 12 (g\u1ECDi hotline) b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 tr\u01B0\u1EDDng 'phone' h\u1EE3p l\u1EC7.`);
|
|
3051
|
+
} else {
|
|
3052
|
+
cleanBtn.phone = b.phone.trim();
|
|
3053
|
+
}
|
|
3054
|
+
} else if (btnType === 3) {
|
|
3055
|
+
if (!Array.isArray(b.messages) || b.messages.length === 0) {
|
|
3056
|
+
errors.push(`${btnPrefix}: N\xFAt lo\u1EA1i 3 (nh\xE1nh h\u1ED9i tho\u1EA1i) b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 m\u1EA3ng 'messages' ch\u1EE9a \xEDt nh\u1EA5t 1 tin nh\u1EAFn con ph\u1EA3n h\u1ED3i.`);
|
|
3057
|
+
} else {
|
|
3058
|
+
const cleanChildMsgs = [];
|
|
3059
|
+
b.messages.forEach((child, cIdx) => {
|
|
3060
|
+
const childPrefix = `${btnPrefix}.messages[${cIdx}]`;
|
|
3061
|
+
if (!child || typeof child !== "object") {
|
|
3062
|
+
errors.push(`${childPrefix}: Tin nh\u1EAFn con ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng.`);
|
|
3063
|
+
return;
|
|
3064
|
+
}
|
|
3065
|
+
const c = child;
|
|
3066
|
+
if (typeof c.text !== "string" || c.text.trim() === "") {
|
|
3067
|
+
errors.push(`${childPrefix}: N\u1ED9i dung tin nh\u1EAFn con 'text' kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.`);
|
|
3068
|
+
} else if (c.text.length > 1961) {
|
|
3069
|
+
errors.push(`${childPrefix}: N\u1ED9i dung tin nh\u1EAFn con v\u01B0\u1EE3t qu\xE1 1961 k\xFD t\u1EF1 (hi\u1EC7n c\xF3 ${c.text.length} k\xFD t\u1EF1).`);
|
|
3070
|
+
}
|
|
3071
|
+
cleanChildMsgs.push({
|
|
3072
|
+
type: 8,
|
|
3073
|
+
text: String(c.text ?? "").trim()
|
|
3074
|
+
});
|
|
3075
|
+
});
|
|
3076
|
+
cleanBtn.messages = cleanChildMsgs;
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
cleanButtons.push(cleanBtn);
|
|
3080
|
+
});
|
|
3081
|
+
return cleanButtons;
|
|
3082
|
+
}
|
|
3083
|
+
function validateFlowMessages(messages, errors) {
|
|
3084
|
+
if (!Array.isArray(messages)) {
|
|
3085
|
+
errors.push("Tr\u01B0\u1EDDng 'messages' ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng ch\u1EE9a tin nh\u1EAFn k\u1ECBch b\u1EA3n.");
|
|
3086
|
+
return [];
|
|
3087
|
+
}
|
|
3088
|
+
if (messages.length !== 1) {
|
|
3089
|
+
errors.push(`Zalo Ads ch\u1EC9 cho ph\xE9p k\u1ECBch b\u1EA3n ch\u1EE9a DUY NH\u1EA4T 1 tin nh\u1EAFn ch\xE0o m\u1EEBng c\u1EA5p cao (hi\u1EC7n c\xF3 ${messages.length} tin nh\u1EAFn). C\xE1c nh\xE1nh h\u1ED9i tho\u1EA1i ti\u1EBFp theo ph\u1EA3i c\u1EA5u h\xECnh b\xEAn trong n\xFAt b\u1EA5m lo\u1EA1i 3 (type=3).`);
|
|
3090
|
+
return [];
|
|
3091
|
+
}
|
|
3092
|
+
const msg = messages[0];
|
|
3093
|
+
if (!msg || typeof msg !== "object") {
|
|
3094
|
+
errors.push("Tin nh\u1EAFn k\u1ECBch b\u1EA3n ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng.");
|
|
3095
|
+
return [];
|
|
3096
|
+
}
|
|
3097
|
+
const m = msg;
|
|
3098
|
+
const msgType = Number(m.type);
|
|
3099
|
+
if (![1, 2].includes(msgType)) {
|
|
3100
|
+
errors.push("Lo\u1EA1i tin nh\u1EAFn 'type' ph\u1EA3i l\xE0 1 (v\u0103n b\u1EA3n) ho\u1EB7c 2 (k\xE8m h\xECnh \u1EA3nh).");
|
|
3101
|
+
}
|
|
3102
|
+
if (typeof m.text !== "string" || m.text.trim() === "") {
|
|
3103
|
+
errors.push("N\u1ED9i dung tin nh\u1EAFn 'text' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
3104
|
+
} else if (m.text.length > 1961) {
|
|
3105
|
+
errors.push(`N\u1ED9i dung tin nh\u1EAFn v\u01B0\u1EE3t qu\xE1 1961 k\xFD t\u1EF1 (hi\u1EC7n c\xF3 ${m.text.length} k\xFD t\u1EF1).`);
|
|
3106
|
+
}
|
|
3107
|
+
const cleanMsg = {
|
|
3108
|
+
type: msgType,
|
|
3109
|
+
text: String(m.text ?? "").trim()
|
|
3110
|
+
};
|
|
3111
|
+
if (msgType === 2) {
|
|
3112
|
+
if (typeof m.url !== "string" || m.url.trim() === "") {
|
|
3113
|
+
errors.push("Tin nh\u1EAFn lo\u1EA1i 2 (k\xE8m \u1EA3nh) b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 tr\u01B0\u1EDDng 'url' ch\u1EE9a \u0111\u01B0\u1EDDng d\u1EABn h\xECnh \u1EA3nh.");
|
|
3114
|
+
} else {
|
|
3115
|
+
cleanMsg.url = m.url.trim();
|
|
3116
|
+
}
|
|
3117
|
+
}
|
|
3118
|
+
if (m.buttons !== void 0 && m.buttons !== null) {
|
|
3119
|
+
cleanMsg.buttons = validateFlowButtons(m.buttons, errors, "messages[0]");
|
|
3120
|
+
}
|
|
3121
|
+
return [cleanMsg];
|
|
3122
|
+
}
|
|
3123
|
+
function validateListFlowsByOfficialAccountRequest(input) {
|
|
3124
|
+
const errors = [];
|
|
3125
|
+
if (!input || typeof input !== "object") {
|
|
3126
|
+
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u l\u1EA5y danh s\xE1ch k\u1ECBch b\u1EA3n ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."] };
|
|
3127
|
+
}
|
|
3128
|
+
const obj = input;
|
|
3129
|
+
if (!is32BitPositiveInteger(obj.oaId)) {
|
|
3130
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 m\xE3 pageId n\u1ED9i b\u1ED9 ki\u1EC3u s\u1ED1 nguy\xEAn 32-bit (<= 2,147,483,647). Kh\xF4ng truy\u1EC1n chu\u1ED7i noisedId c\xF4ng khai (18 ch\u1EEF s\u1ED1) v\xEC backend Play Framework s\u1EBD t\u1EEB ch\u1ED1i.");
|
|
3131
|
+
}
|
|
3132
|
+
if (!isPositiveInteger(obj.limit)) {
|
|
3133
|
+
errors.push("Tr\u01B0\u1EDDng 'limit' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3134
|
+
}
|
|
3135
|
+
if (obj.offset !== void 0 && obj.offset !== null && !isNonNegativeInteger(obj.offset)) {
|
|
3136
|
+
errors.push("Tr\u01B0\u1EDDng 'offset' n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn kh\xF4ng \xE2m (>= 0).");
|
|
3137
|
+
}
|
|
3138
|
+
if (obj.flowId !== void 0 && obj.flowId !== null && !isPositiveInteger(obj.flowId)) {
|
|
3139
|
+
errors.push("Tr\u01B0\u1EDDng 'flowId' n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3140
|
+
}
|
|
3141
|
+
const cleanData = {
|
|
3142
|
+
oaId: toPositiveInteger(obj.oaId),
|
|
3143
|
+
limit: toPositiveInteger(obj.limit)
|
|
3144
|
+
};
|
|
3145
|
+
if (obj.offset !== void 0 && obj.offset !== null) cleanData.offset = toPositiveInteger(obj.offset);
|
|
3146
|
+
if (obj.flowId !== void 0 && obj.flowId !== null) cleanData.flowId = toPositiveInteger(obj.flowId);
|
|
3147
|
+
return {
|
|
3148
|
+
isValid: errors.length === 0,
|
|
3149
|
+
errors,
|
|
3150
|
+
data: errors.length === 0 ? cleanData : void 0
|
|
3151
|
+
};
|
|
3152
|
+
}
|
|
3153
|
+
function validateCreateFlowRequest(input) {
|
|
3154
|
+
const errors = [];
|
|
3155
|
+
if (!input || typeof input !== "object") {
|
|
3156
|
+
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u t\u1EA1o k\u1ECBch b\u1EA3n ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."] };
|
|
3157
|
+
}
|
|
3158
|
+
const obj = input;
|
|
3159
|
+
if (!is32BitPositiveInteger(obj.oaId)) {
|
|
3160
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 m\xE3 pageId n\u1ED9i b\u1ED9 ki\u1EC3u s\u1ED1 nguy\xEAn 32-bit (<= 2,147,483,647).");
|
|
3161
|
+
}
|
|
3162
|
+
if (typeof obj.name !== "string" || obj.name.trim() === "") {
|
|
3163
|
+
errors.push("Tr\u01B0\u1EDDng 'name' (t\xEAn k\u1ECBch b\u1EA3n) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
3164
|
+
} else if (obj.name.trim().length > 50) {
|
|
3165
|
+
errors.push(`T\xEAn k\u1ECBch b\u1EA3n kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 50 k\xFD t\u1EF1 (hi\u1EC7n c\xF3 ${obj.name.trim().length} k\xFD t\u1EF1).`);
|
|
3166
|
+
}
|
|
3167
|
+
const cleanMessages = validateFlowMessages(obj.messages, errors);
|
|
3168
|
+
const cleanData = {
|
|
3169
|
+
oaId: toPositiveInteger(obj.oaId),
|
|
3170
|
+
id: null,
|
|
3171
|
+
name: String(obj.name ?? "").trim(),
|
|
3172
|
+
messages: cleanMessages
|
|
3173
|
+
};
|
|
3174
|
+
return {
|
|
3175
|
+
isValid: errors.length === 0,
|
|
3176
|
+
errors,
|
|
3177
|
+
data: errors.length === 0 ? cleanData : void 0
|
|
3178
|
+
};
|
|
3179
|
+
}
|
|
3180
|
+
function validateUpdateFlowRequest(input) {
|
|
3181
|
+
const errors = [];
|
|
3182
|
+
if (!input || typeof input !== "object") {
|
|
3183
|
+
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u c\u1EADp nh\u1EADt k\u1ECBch b\u1EA3n ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."] };
|
|
3184
|
+
}
|
|
3185
|
+
const obj = input;
|
|
3186
|
+
if (!isPositiveInteger(obj.id)) {
|
|
3187
|
+
errors.push("Tr\u01B0\u1EDDng 'id' (ID Flow c\u1EA7n c\u1EADp nh\u1EADt) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3188
|
+
}
|
|
3189
|
+
if (!is32BitPositiveInteger(obj.oaId)) {
|
|
3190
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 m\xE3 pageId n\u1ED9i b\u1ED9 ki\u1EC3u s\u1ED1 nguy\xEAn 32-bit (<= 2,147,483,647).");
|
|
3191
|
+
}
|
|
3192
|
+
if (typeof obj.name !== "string" || obj.name.trim() === "") {
|
|
3193
|
+
errors.push("Tr\u01B0\u1EDDng 'name' (t\xEAn k\u1ECBch b\u1EA3n) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
3194
|
+
} else if (obj.name.trim().length > 50) {
|
|
3195
|
+
errors.push(`T\xEAn k\u1ECBch b\u1EA3n kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 50 k\xFD t\u1EF1 (hi\u1EC7n c\xF3 ${obj.name.trim().length} k\xFD t\u1EF1).`);
|
|
3196
|
+
}
|
|
3197
|
+
const cleanMessages = validateFlowMessages(obj.messages, errors);
|
|
3198
|
+
const cleanData = {
|
|
3199
|
+
id: toPositiveInteger(obj.id),
|
|
3200
|
+
oaId: toPositiveInteger(obj.oaId),
|
|
3201
|
+
name: String(obj.name ?? "").trim(),
|
|
3202
|
+
messages: cleanMessages
|
|
3203
|
+
};
|
|
3204
|
+
return {
|
|
3205
|
+
isValid: errors.length === 0,
|
|
3206
|
+
errors,
|
|
3207
|
+
data: errors.length === 0 ? cleanData : void 0
|
|
3208
|
+
};
|
|
3209
|
+
}
|
|
3210
|
+
var ZaloFlowsValidator = {
|
|
3211
|
+
listFlowsByOfficialAccount: validateListFlowsByOfficialAccountRequest,
|
|
3212
|
+
createFlow: validateCreateFlowRequest,
|
|
3213
|
+
updateFlow: validateUpdateFlowRequest
|
|
3214
|
+
};
|
|
3215
|
+
|
|
2545
3216
|
// src/services/flows.service.ts
|
|
2546
3217
|
var OP_ZaloAdsListFlowsByOfficialAccount = {
|
|
2547
3218
|
operationId: "ZaloAds_listFlowsByOfficialAccount",
|
|
@@ -2583,6 +3254,12 @@ var ZaloFlowsService = class {
|
|
|
2583
3254
|
constructor(client) {
|
|
2584
3255
|
this.client = client;
|
|
2585
3256
|
}
|
|
3257
|
+
/**
|
|
3258
|
+
* Bộ công cụ kiểm tra tính hợp lệ dữ liệu (Standalone Validators) cho Message Flows APIs.
|
|
3259
|
+
* Dùng để validate dữ liệu đầu vào trước khi lưu DB hoặc gọi Zalo Ads.
|
|
3260
|
+
*/
|
|
3261
|
+
static validator = ZaloFlowsValidator;
|
|
3262
|
+
validator = ZaloFlowsValidator;
|
|
2586
3263
|
listFlowsByOfficialAccount(request, options) {
|
|
2587
3264
|
return this.client.requestWithoutBody(OP_ZaloAdsListFlowsByOfficialAccount, this.client.toTransportInput(OP_ZaloAdsListFlowsByOfficialAccount, request), options);
|
|
2588
3265
|
}
|
|
@@ -3496,7 +4173,301 @@ var ZaloChatWidgetService = class {
|
|
|
3496
4173
|
}
|
|
3497
4174
|
};
|
|
3498
4175
|
|
|
4176
|
+
// src/validators/forms.validator.ts
|
|
4177
|
+
function isValidUrl(val) {
|
|
4178
|
+
if (typeof val !== "string" || val.trim() === "") return false;
|
|
4179
|
+
try {
|
|
4180
|
+
const url = new URL(val);
|
|
4181
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
4182
|
+
} catch {
|
|
4183
|
+
return false;
|
|
4184
|
+
}
|
|
4185
|
+
}
|
|
4186
|
+
function validateCreateFormRequest(input) {
|
|
4187
|
+
const errors = [];
|
|
4188
|
+
if (!input || typeof input !== "object") {
|
|
4189
|
+
return {
|
|
4190
|
+
isValid: false,
|
|
4191
|
+
errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u t\u1EA1o Form ph\u1EA3i l\xE0 m\u1ED9t object."],
|
|
4192
|
+
data: void 0
|
|
4193
|
+
};
|
|
4194
|
+
}
|
|
4195
|
+
let raw = input;
|
|
4196
|
+
if (typeof input.data === "string") {
|
|
4197
|
+
try {
|
|
4198
|
+
raw = JSON.parse(input.data);
|
|
4199
|
+
} catch {
|
|
4200
|
+
errors.push("Tr\u01B0\u1EDDng 'data' kh\xF4ng ph\u1EA3i l\xE0 chu\u1ED7i JSON h\u1EE3p l\u1EC7.");
|
|
4201
|
+
return { isValid: false, errors, data: void 0 };
|
|
4202
|
+
}
|
|
4203
|
+
} else if (typeof input.data === "object" && input.data !== null) {
|
|
4204
|
+
raw = input.data;
|
|
4205
|
+
}
|
|
4206
|
+
const oaIdRaw = raw.oaId;
|
|
4207
|
+
let cleanOaId = "";
|
|
4208
|
+
if (typeof oaIdRaw === "string" && /^[0-9]+$/.test(oaIdRaw.trim())) {
|
|
4209
|
+
cleanOaId = oaIdRaw.trim();
|
|
4210
|
+
} else if (typeof oaIdRaw === "number" && Number.isInteger(oaIdRaw) && oaIdRaw > 0) {
|
|
4211
|
+
cleanOaId = String(oaIdRaw);
|
|
4212
|
+
} else {
|
|
4213
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' b\u1EAFt bu\u1ED9c ph\u1EA3i l\xE0 chu\u1ED7i s\u1ED1 nguy\xEAn d\u01B0\u01A1ng \u0111\u1EA1i di\u1EC7n cho pageId n\u1ED9i b\u1ED9 c\u1EE7a OA (v\xED d\u1EE5: '429753475').");
|
|
4214
|
+
}
|
|
4215
|
+
const title = typeof raw.title === "string" ? raw.title.trim() : "";
|
|
4216
|
+
if (!title) {
|
|
4217
|
+
errors.push("Tr\u01B0\u1EDDng 'title' (ti\xEAu \u0111\u1EC1 form) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
4218
|
+
} else if (title.length < 2 || title.length > 40) {
|
|
4219
|
+
errors.push(`Tr\u01B0\u1EDDng 'title' ph\u1EA3i c\xF3 \u0111\u1ED9 d\xE0i t\u1EEB 2 \u0111\u1EBFn 40 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${title.length} k\xFD t\u1EF1).`);
|
|
4220
|
+
}
|
|
4221
|
+
const formName = typeof raw.formName === "string" ? raw.formName.trim() : "";
|
|
4222
|
+
if (!formName) {
|
|
4223
|
+
errors.push("Tr\u01B0\u1EDDng 'formName' (t\xEAn qu\u1EA3n tr\u1ECB form) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
4224
|
+
} else if (formName.length < 2 || formName.length > 100) {
|
|
4225
|
+
errors.push(`Tr\u01B0\u1EDDng 'formName' ph\u1EA3i c\xF3 \u0111\u1ED9 d\xE0i t\u1EEB 2 \u0111\u1EBFn 100 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${formName.length} k\xFD t\u1EF1).`);
|
|
4226
|
+
}
|
|
4227
|
+
let cleanDescription = void 0;
|
|
4228
|
+
if (raw.description !== void 0 && raw.description !== null) {
|
|
4229
|
+
const desc = String(raw.description).trim();
|
|
4230
|
+
if (desc.length > 600) {
|
|
4231
|
+
errors.push(`Tr\u01B0\u1EDDng 'description' kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 600 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${desc.length} k\xFD t\u1EF1).`);
|
|
4232
|
+
} else {
|
|
4233
|
+
cleanDescription = desc;
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
const coverPhoto = typeof raw.coverPhoto === "string" ? raw.coverPhoto.trim() : "";
|
|
4237
|
+
if (!coverPhoto) {
|
|
4238
|
+
errors.push("Tr\u01B0\u1EDDng 'coverPhoto' (\u1EA3nh b\xECa form) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
4239
|
+
} else if (!isValidUrl(coverPhoto)) {
|
|
4240
|
+
errors.push(`Tr\u01B0\u1EDDng 'coverPhoto' ph\u1EA3i l\xE0 URL h\u1EE3p l\u1EC7 (http:// ho\u1EB7c https://).`);
|
|
4241
|
+
}
|
|
4242
|
+
const submitTitle = typeof raw.submitTitle === "string" && raw.submitTitle.trim() !== "" ? raw.submitTitle.trim() : "G\u1EEDi th\xF4ng tin th\xE0nh c\xF4ng";
|
|
4243
|
+
if (submitTitle.length > 90) {
|
|
4244
|
+
errors.push(`Tr\u01B0\u1EDDng 'submitTitle' kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 90 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${submitTitle.length} k\xFD t\u1EF1).`);
|
|
4245
|
+
}
|
|
4246
|
+
const thanks = typeof raw.thanks === "string" && raw.thanks.trim() !== "" ? raw.thanks.trim() : "C\u1EA3m \u01A1n b\u1EA1n \u0111\xE3 g\u1EEDi th\xF4ng tin. Ch\xFAng t\xF4i s\u1EBD li\xEAn h\u1EC7 trong th\u1EDDi gian s\u1EDBm nh\u1EA5t.";
|
|
4247
|
+
if (thanks.length > 255) {
|
|
4248
|
+
errors.push(`Tr\u01B0\u1EDDng 'thanks' kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${thanks.length} k\xFD t\u1EF1).`);
|
|
4249
|
+
}
|
|
4250
|
+
const gotoActionType = raw.gotoActionType === 0 ? 0 : 1;
|
|
4251
|
+
const gotoText = typeof raw.gotoText === "string" && raw.gotoText.trim() !== "" ? raw.gotoText.trim() : gotoActionType === 1 ? "Xem trang Web" : "\u0110\xF3ng l\u1EA1i";
|
|
4252
|
+
let cleanWebsite = void 0;
|
|
4253
|
+
if (gotoActionType === 1) {
|
|
4254
|
+
if (!raw.website || !isValidUrl(raw.website)) {
|
|
4255
|
+
errors.push("Khi 'gotoActionType' = 1 (m\u1EDF website), tr\u01B0\u1EDDng 'website' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 URL h\u1EE3p l\u1EC7.");
|
|
4256
|
+
} else {
|
|
4257
|
+
cleanWebsite = String(raw.website).trim();
|
|
4258
|
+
}
|
|
4259
|
+
}
|
|
4260
|
+
const useCustomConsent = Boolean(raw.useCustomConsent);
|
|
4261
|
+
let cleanConsentName = void 0;
|
|
4262
|
+
let cleanConsentUrl = void 0;
|
|
4263
|
+
if (useCustomConsent) {
|
|
4264
|
+
const cName = typeof raw.consentName === "string" ? raw.consentName.trim() : "";
|
|
4265
|
+
if (!cName) {
|
|
4266
|
+
errors.push("Khi 'useCustomConsent' = true, tr\u01B0\u1EDDng 'consentName' (ti\xEAu \u0111\u1EC1 \u0111i\u1EC1u kho\u1EA3n) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
4267
|
+
} else if (cName.length > 255) {
|
|
4268
|
+
errors.push(`Tr\u01B0\u1EDDng 'consentName' kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${cName.length} k\xFD t\u1EF1).`);
|
|
4269
|
+
} else {
|
|
4270
|
+
cleanConsentName = cName;
|
|
4271
|
+
}
|
|
4272
|
+
if (!raw.consentUrl || !isValidUrl(raw.consentUrl)) {
|
|
4273
|
+
errors.push("Khi 'useCustomConsent' = true, tr\u01B0\u1EDDng 'consentUrl' ph\u1EA3i l\xE0 URL h\u1EE3p l\u1EC7 ch\u1EE9a ch\xEDnh s\xE1ch b\u1EA3o m\u1EADt.");
|
|
4274
|
+
} else {
|
|
4275
|
+
cleanConsentUrl = String(raw.consentUrl).trim();
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
if (!Array.isArray(raw.questions) || raw.questions.length === 0) {
|
|
4279
|
+
errors.push("Bi\u1EC3u m\u1EABu b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 \xEDt nh\u1EA5t 1 c\xE2u h\u1ECFi trong m\u1EA3ng 'questions'.");
|
|
4280
|
+
}
|
|
4281
|
+
const cleanQuestions = [];
|
|
4282
|
+
let hasPhonePrimary = false;
|
|
4283
|
+
let hasPhoneSecondary = false;
|
|
4284
|
+
if (Array.isArray(raw.questions)) {
|
|
4285
|
+
raw.questions.forEach((q, idx) => {
|
|
4286
|
+
const qPrefix = `C\xE2u h\u1ECFi [${idx}]`;
|
|
4287
|
+
if (!q || typeof q !== "object") {
|
|
4288
|
+
errors.push(`${qPrefix} ph\u1EA3i l\xE0 m\u1ED9t object.`);
|
|
4289
|
+
return;
|
|
4290
|
+
}
|
|
4291
|
+
const qTitle = typeof q.title === "string" ? q.title.trim() : "";
|
|
4292
|
+
if (qTitle.length < 2 || qTitle.length > 180) {
|
|
4293
|
+
errors.push(`${qPrefix}: Ti\xEAu \u0111\u1EC1 'title' ph\u1EA3i c\xF3 \u0111\u1ED9 d\xE0i t\u1EEB 2 \u0111\u1EBFn 180 k\xFD t\u1EF1.`);
|
|
4294
|
+
}
|
|
4295
|
+
if (!Array.isArray(q.answers) || q.answers.length === 0) {
|
|
4296
|
+
errors.push(`${qPrefix}: Ph\u1EA3i c\xF3 \xEDt nh\u1EA5t 1 \u0111\xE1p \xE1n trong m\u1EA3ng 'answers'.`);
|
|
4297
|
+
return;
|
|
4298
|
+
}
|
|
4299
|
+
const cleanAnswers = [];
|
|
4300
|
+
q.answers.forEach((ans, aIdx) => {
|
|
4301
|
+
const aType = Number(ans?.type);
|
|
4302
|
+
if (![2, 7, 13].includes(aType)) {
|
|
4303
|
+
errors.push(`${qPrefix} \u0111\xE1p \xE1n [${aIdx}]: 'type' ph\u1EA3i l\xE0 7 (H\u1ECD t\xEAn), 13 (S\u0110T chu\u1EA9n), ho\u1EB7c 2 (S\u0110T ph\u1EE5).`);
|
|
4304
|
+
}
|
|
4305
|
+
if (aType === 13) hasPhonePrimary = true;
|
|
4306
|
+
if (aType === 2) hasPhoneSecondary = true;
|
|
4307
|
+
cleanAnswers.push({
|
|
4308
|
+
type: aType,
|
|
4309
|
+
placeHolder: ans?.placeHolder ? String(ans.placeHolder).trim() : void 0,
|
|
4310
|
+
value: ans?.value ? String(ans.value).trim() : null,
|
|
4311
|
+
priority: typeof ans?.priority === "number" ? ans.priority : 500
|
|
4312
|
+
});
|
|
4313
|
+
});
|
|
4314
|
+
cleanQuestions.push({
|
|
4315
|
+
title: qTitle,
|
|
4316
|
+
type: typeof q.type === "number" ? q.type : 1,
|
|
4317
|
+
isRequired: q.isRequired !== void 0 ? Boolean(q.isRequired) : true,
|
|
4318
|
+
editDisabled: Boolean(q.editDisabled),
|
|
4319
|
+
priority: typeof q.priority === "number" ? q.priority : (idx + 1) * 100,
|
|
4320
|
+
answers: cleanAnswers
|
|
4321
|
+
});
|
|
4322
|
+
});
|
|
4323
|
+
}
|
|
4324
|
+
if (hasPhoneSecondary) {
|
|
4325
|
+
cleanQuestions.forEach((q) => {
|
|
4326
|
+
if (q.answers.some((a) => a.type === 13)) {
|
|
4327
|
+
q.editDisabled = true;
|
|
4328
|
+
}
|
|
4329
|
+
});
|
|
4330
|
+
}
|
|
4331
|
+
const cleanSections = [];
|
|
4332
|
+
if (Array.isArray(raw.sections)) {
|
|
4333
|
+
raw.sections.forEach((sec, sIdx) => {
|
|
4334
|
+
const sPrefix = `Section [${sIdx}]`;
|
|
4335
|
+
const sType = Number(sec?.type);
|
|
4336
|
+
if (isNaN(sType) || sType < 0 || sType > 4) {
|
|
4337
|
+
errors.push(`${sPrefix}: 'type' ph\u1EA3i l\xE0 s\u1ED1 t\u1EEB 0 \u0111\u1EBFn 4 (0=t\u1ED5ng quan, 1=chi ti\u1EBFt, 2=b\u1EA3ng gi\xE1, 3=\u01B0u \u0111i\u1EC3m, 4=\u01B0u \u0111\xE3i).`);
|
|
4338
|
+
}
|
|
4339
|
+
const sTitle = typeof sec?.title === "string" ? sec.title.trim() : "";
|
|
4340
|
+
if (sTitle.length > 60) {
|
|
4341
|
+
errors.push(`${sPrefix}: 'title' kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 60 k\xFD t\u1EF1.`);
|
|
4342
|
+
}
|
|
4343
|
+
cleanSections.push({
|
|
4344
|
+
type: sType,
|
|
4345
|
+
title: sTitle,
|
|
4346
|
+
disable: Boolean(sec?.disable),
|
|
4347
|
+
expand: Boolean(sec?.expand),
|
|
4348
|
+
content: sec?.content ? sec.content : {}
|
|
4349
|
+
});
|
|
4350
|
+
});
|
|
4351
|
+
}
|
|
4352
|
+
const cleanData = {
|
|
4353
|
+
oaId: cleanOaId,
|
|
4354
|
+
title,
|
|
4355
|
+
formName,
|
|
4356
|
+
description: cleanDescription,
|
|
4357
|
+
coverPhoto,
|
|
4358
|
+
submitTitle,
|
|
4359
|
+
thanks,
|
|
4360
|
+
gotoActionType,
|
|
4361
|
+
gotoText,
|
|
4362
|
+
website: cleanWebsite,
|
|
4363
|
+
reviewSubmit: raw.reviewSubmit !== void 0 ? Boolean(raw.reviewSubmit) : true,
|
|
4364
|
+
questions: cleanQuestions,
|
|
4365
|
+
sections: cleanSections.length > 0 ? cleanSections : void 0,
|
|
4366
|
+
useCustomConsent,
|
|
4367
|
+
consentName: cleanConsentName,
|
|
4368
|
+
consentUrl: cleanConsentUrl
|
|
4369
|
+
};
|
|
4370
|
+
return {
|
|
4371
|
+
isValid: errors.length === 0,
|
|
4372
|
+
errors,
|
|
4373
|
+
data: errors.length === 0 ? cleanData : void 0
|
|
4374
|
+
};
|
|
4375
|
+
}
|
|
4376
|
+
function validateListFormsByOfficialAccountRequest(input) {
|
|
4377
|
+
const errors = [];
|
|
4378
|
+
if (!input || typeof input !== "object") {
|
|
4379
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
4380
|
+
}
|
|
4381
|
+
const raw = input;
|
|
4382
|
+
let cleanOaId = "";
|
|
4383
|
+
if (typeof raw.oaId === "string" && /^[0-9]+$/.test(raw.oaId.trim())) {
|
|
4384
|
+
cleanOaId = raw.oaId.trim();
|
|
4385
|
+
} else if (typeof raw.oaId === "number" && Number.isInteger(raw.oaId) && raw.oaId > 0) {
|
|
4386
|
+
cleanOaId = String(raw.oaId);
|
|
4387
|
+
} else {
|
|
4388
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' b\u1EAFt bu\u1ED9c ph\u1EA3i l\xE0 chu\u1ED7i s\u1ED1 nguy\xEAn d\u01B0\u01A1ng \u0111\u1EA1i di\u1EC7n cho pageId c\u1EE7a OA.");
|
|
4389
|
+
}
|
|
4390
|
+
return {
|
|
4391
|
+
isValid: errors.length === 0,
|
|
4392
|
+
errors,
|
|
4393
|
+
data: errors.length === 0 ? { oaId: cleanOaId, isAll: raw.isAll !== void 0 ? Boolean(raw.isAll) : true } : void 0
|
|
4394
|
+
};
|
|
4395
|
+
}
|
|
4396
|
+
function validateListFormLeadsRequest(input) {
|
|
4397
|
+
const errors = [];
|
|
4398
|
+
if (!input || typeof input !== "object") {
|
|
4399
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
4400
|
+
}
|
|
4401
|
+
const raw = input;
|
|
4402
|
+
const oaId = typeof raw.oaId === "string" ? raw.oaId.trim() : "";
|
|
4403
|
+
if (!oaId) {
|
|
4404
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' l\xE0 b\u1EAFt bu\u1ED9c (m\xE3 ch\u1EEF t\u1EEB getAuthSession, v\xED d\u1EE5 'J4UB9MRE497YDQKKK').");
|
|
4405
|
+
} else if (/^[0-9]+$/.test(oaId)) {
|
|
4406
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' tr\xEAn Lead Center ph\u1EA3i l\xE0 m\xE3 ch\u1EEF alphanumeric t\u1EEB getAuthSession, kh\xF4ng d\xF9ng chu\u1ED7i s\u1ED1 pageId (s\u1EBD b\u1ECB l\u1ED7i 403 Forbidden).");
|
|
4407
|
+
}
|
|
4408
|
+
const type = Number(raw.type);
|
|
4409
|
+
if (![1, 5].includes(type)) {
|
|
4410
|
+
errors.push("Tr\u01B0\u1EDDng 'type' ph\u1EA3i l\xE0 1 (ZALOFORM) ho\u1EB7c 5 (COMMERCE).");
|
|
4411
|
+
}
|
|
4412
|
+
const limit = typeof raw.limit === "number" && raw.limit > 0 ? Math.floor(raw.limit) : 20;
|
|
4413
|
+
const offset = typeof raw.offset === "number" && raw.offset >= 0 ? Math.floor(raw.offset) : 0;
|
|
4414
|
+
const status = typeof raw.status === "string" && raw.status.trim() !== "" ? raw.status.trim() : "2,6,1,0,7,4,5,3";
|
|
4415
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
4416
|
+
const fromTime = typeof raw.fromTime === "number" && raw.fromTime >= 0 ? Math.floor(raw.fromTime) : now - 90 * 86400;
|
|
4417
|
+
const toTime = typeof raw.toTime === "number" && raw.toTime >= 0 ? Math.floor(raw.toTime) : now;
|
|
4418
|
+
if (toTime < fromTime) {
|
|
4419
|
+
errors.push("M\u1ED1c th\u1EDDi gian k\u1EBFt th\xFAc 'toTime' ph\u1EA3i l\u1EDBn h\u01A1n ho\u1EB7c b\u1EB1ng 'fromTime'.");
|
|
4420
|
+
}
|
|
4421
|
+
return {
|
|
4422
|
+
isValid: errors.length === 0,
|
|
4423
|
+
errors,
|
|
4424
|
+
data: errors.length === 0 ? {
|
|
4425
|
+
oaId,
|
|
4426
|
+
type,
|
|
4427
|
+
limit,
|
|
4428
|
+
offset,
|
|
4429
|
+
status,
|
|
4430
|
+
fromTime,
|
|
4431
|
+
toTime,
|
|
4432
|
+
formIds: raw.formIds ? String(raw.formIds).trim() : void 0,
|
|
4433
|
+
keyword: raw.keyword ? String(raw.keyword).trim() : void 0,
|
|
4434
|
+
reason: raw.reason ? String(raw.reason).trim() : void 0,
|
|
4435
|
+
labelIds: raw.labelIds ? String(raw.labelIds).trim() : void 0,
|
|
4436
|
+
isCommerce: raw.isCommerce !== void 0 ? Boolean(raw.isCommerce) : false
|
|
4437
|
+
} : void 0
|
|
4438
|
+
};
|
|
4439
|
+
}
|
|
4440
|
+
var ZaloFormsValidator = {
|
|
4441
|
+
createForm: validateCreateFormRequest,
|
|
4442
|
+
listFormsByOfficialAccount: validateListFormsByOfficialAccountRequest,
|
|
4443
|
+
listFormLeads: validateListFormLeadsRequest
|
|
4444
|
+
};
|
|
4445
|
+
|
|
3499
4446
|
// src/services/forms.service.ts
|
|
4447
|
+
var OP_ZaloAdsCreateForm2 = {
|
|
4448
|
+
operationId: "zalo_ads_create_form",
|
|
4449
|
+
method: "POST",
|
|
4450
|
+
endpoint: "/api/form/create",
|
|
4451
|
+
baseUrl: "https://ads.zalo.me",
|
|
4452
|
+
binaryFields: [],
|
|
4453
|
+
pathFields: [],
|
|
4454
|
+
queryFields: [],
|
|
4455
|
+
headerFields: [],
|
|
4456
|
+
cookieFields: [],
|
|
4457
|
+
bodyFields: ["data"]
|
|
4458
|
+
};
|
|
4459
|
+
var OP_ZaloAdsListFormsByOfficialAccount2 = {
|
|
4460
|
+
operationId: "zalo_ads_list_forms_by_official_account",
|
|
4461
|
+
method: "GET",
|
|
4462
|
+
endpoint: "/api/form/getByOaId",
|
|
4463
|
+
baseUrl: "https://ads.zalo.me",
|
|
4464
|
+
binaryFields: [],
|
|
4465
|
+
pathFields: [],
|
|
4466
|
+
queryFields: ["oaId", "isAll"],
|
|
4467
|
+
headerFields: [],
|
|
4468
|
+
cookieFields: [],
|
|
4469
|
+
bodyFields: []
|
|
4470
|
+
};
|
|
3500
4471
|
var OP_ZaloFormsDisableFormLeadNotification = {
|
|
3501
4472
|
"operationId": "ZaloForms_disableFormLeadNotification",
|
|
3502
4473
|
"method": "POST",
|
|
@@ -3570,7 +4541,8 @@ var OP_ZaloFormsListConversationLeads = {
|
|
|
3570
4541
|
"keyword",
|
|
3571
4542
|
"fromTime",
|
|
3572
4543
|
"labelIds",
|
|
3573
|
-
"sceneIds"
|
|
4544
|
+
"sceneIds",
|
|
4545
|
+
"reason"
|
|
3574
4546
|
],
|
|
3575
4547
|
"headerFields": [],
|
|
3576
4548
|
"cookieFields": [],
|
|
@@ -3594,7 +4566,8 @@ var OP_ZaloFormsListFormLeads = {
|
|
|
3594
4566
|
"keyword",
|
|
3595
4567
|
"fromTime",
|
|
3596
4568
|
"labelIds",
|
|
3597
|
-
"isCommerce"
|
|
4569
|
+
"isCommerce",
|
|
4570
|
+
"reason"
|
|
3598
4571
|
],
|
|
3599
4572
|
"headerFields": [],
|
|
3600
4573
|
"cookieFields": [],
|
|
@@ -3676,10 +4649,59 @@ var OP_ZaloFormsGetAuthSession = {
|
|
|
3676
4649
|
"cookieFields": [],
|
|
3677
4650
|
"bodyFields": []
|
|
3678
4651
|
};
|
|
4652
|
+
var OP_ZaloFormsTrackManageFormEvent = {
|
|
4653
|
+
operationId: "zalo_forms_track_manage_form_event",
|
|
4654
|
+
method: "GET",
|
|
4655
|
+
endpoint: "/client/manage/api/manageForm/tracking",
|
|
4656
|
+
baseUrl: "https://form.ads.zalo.me",
|
|
4657
|
+
binaryFields: [],
|
|
4658
|
+
pathFields: [],
|
|
4659
|
+
queryFields: ["eventId", "oaId", "formId"],
|
|
4660
|
+
headerFields: [],
|
|
4661
|
+
cookieFields: [],
|
|
4662
|
+
bodyFields: []
|
|
4663
|
+
};
|
|
3679
4664
|
var ZaloFormsService = class {
|
|
3680
4665
|
constructor(client) {
|
|
3681
4666
|
this.client = client;
|
|
3682
4667
|
}
|
|
4668
|
+
validator = ZaloFormsValidator;
|
|
4669
|
+
static validator = ZaloFormsValidator;
|
|
4670
|
+
/**
|
|
4671
|
+
* Tạo biểu mẫu mới gắn với Official Account (POST https://ads.zalo.me/api/form/create).
|
|
4672
|
+
* Hỗ trợ truyền thẳng Typed Payload (tự động validate qua ZaloFormsValidator và mã hóa urlencoded)
|
|
4673
|
+
* hoặc object dạng `{ data: JSON.stringify(...) }`.
|
|
4674
|
+
*/
|
|
4675
|
+
async createForm(request, options) {
|
|
4676
|
+
let payloadStr;
|
|
4677
|
+
if (typeof request.data === "string") {
|
|
4678
|
+
payloadStr = request.data;
|
|
4679
|
+
} else {
|
|
4680
|
+
const val = ZaloFormsValidator.createForm(request);
|
|
4681
|
+
if (!val.isValid || !val.data) {
|
|
4682
|
+
throw new Error(`[ZaloFormsValidator] D\u1EEF li\u1EC7u t\u1EA1o form kh\xF4ng h\u1EE3p l\u1EC7:
|
|
4683
|
+
- ${val.errors.join("\n - ")}`);
|
|
4684
|
+
}
|
|
4685
|
+
payloadStr = JSON.stringify(val.data);
|
|
4686
|
+
}
|
|
4687
|
+
return this.client.requestFormUrlEncoded(
|
|
4688
|
+
OP_ZaloAdsCreateForm2,
|
|
4689
|
+
this.client.toTransportInput(OP_ZaloAdsCreateForm2, { data: payloadStr }),
|
|
4690
|
+
options
|
|
4691
|
+
);
|
|
4692
|
+
}
|
|
4693
|
+
/**
|
|
4694
|
+
* Lấy danh sách biểu mẫu Zalo Ads theo Official Account (GET https://ads.zalo.me/api/form/getByOaId).
|
|
4695
|
+
*/
|
|
4696
|
+
listFormsByOfficialAccount(request, options) {
|
|
4697
|
+
const val = ZaloFormsValidator.listFormsByOfficialAccount(request);
|
|
4698
|
+
const cleanInput = val.isValid && val.data ? val.data : request;
|
|
4699
|
+
return this.client.requestWithoutBody(
|
|
4700
|
+
OP_ZaloAdsListFormsByOfficialAccount2,
|
|
4701
|
+
this.client.toTransportInput(OP_ZaloAdsListFormsByOfficialAccount2, cleanInput),
|
|
4702
|
+
options
|
|
4703
|
+
);
|
|
4704
|
+
}
|
|
3683
4705
|
getAuthSession(options) {
|
|
3684
4706
|
return this.client.requestWithoutBody(OP_ZaloFormsGetAuthSession, void 0, options);
|
|
3685
4707
|
}
|
|
@@ -3713,10 +4735,20 @@ var ZaloFormsService = class {
|
|
|
3713
4735
|
updateFormLeadNotificationInterval(request, options) {
|
|
3714
4736
|
return this.client.requestJson(OP_ZaloFormsUpdateFormLeadNotificationInterval, this.client.toTransportInput(OP_ZaloFormsUpdateFormLeadNotificationInterval, request), options);
|
|
3715
4737
|
}
|
|
4738
|
+
/**
|
|
4739
|
+
* Ghi nhận sự kiện tương tác trên Lead Center (GET /client/manage/api/manageForm/tracking).
|
|
4740
|
+
*/
|
|
4741
|
+
trackManageFormEvent(request, options) {
|
|
4742
|
+
return this.client.requestWithoutBody(
|
|
4743
|
+
OP_ZaloFormsTrackManageFormEvent,
|
|
4744
|
+
this.client.toTransportInput(OP_ZaloFormsTrackManageFormEvent, request),
|
|
4745
|
+
options
|
|
4746
|
+
);
|
|
4747
|
+
}
|
|
3716
4748
|
};
|
|
3717
4749
|
|
|
3718
4750
|
// src/validators/instant-pages.validator.ts
|
|
3719
|
-
function
|
|
4751
|
+
function isPositiveInteger2(val) {
|
|
3720
4752
|
if (typeof val === "number") return Number.isInteger(val) && val > 0;
|
|
3721
4753
|
if (typeof val === "string" && val.trim() !== "") {
|
|
3722
4754
|
const num = Number(val);
|
|
@@ -3724,7 +4756,7 @@ function isPositiveInteger(val) {
|
|
|
3724
4756
|
}
|
|
3725
4757
|
return false;
|
|
3726
4758
|
}
|
|
3727
|
-
function
|
|
4759
|
+
function toPositiveInteger2(val) {
|
|
3728
4760
|
return typeof val === "number" ? Math.floor(val) : parseInt(String(val), 10);
|
|
3729
4761
|
}
|
|
3730
4762
|
function validateCloneInstantPageRequest(input) {
|
|
@@ -3733,13 +4765,13 @@ function validateCloneInstantPageRequest(input) {
|
|
|
3733
4765
|
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u sao ch\xE9p Instant Page ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng (object)."] };
|
|
3734
4766
|
}
|
|
3735
4767
|
const obj = input;
|
|
3736
|
-
if (!
|
|
4768
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3737
4769
|
errors.push("Tr\u01B0\u1EDDng 'instantPageId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3738
4770
|
}
|
|
3739
4771
|
return {
|
|
3740
4772
|
isValid: errors.length === 0,
|
|
3741
4773
|
errors,
|
|
3742
|
-
data: errors.length === 0 ? { instantPageId:
|
|
4774
|
+
data: errors.length === 0 ? { instantPageId: toPositiveInteger2(obj.instantPageId) } : void 0
|
|
3743
4775
|
};
|
|
3744
4776
|
}
|
|
3745
4777
|
function validateGetInstantPageDetailRequest(input) {
|
|
@@ -3748,13 +4780,13 @@ function validateGetInstantPageDetailRequest(input) {
|
|
|
3748
4780
|
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u l\u1EA5y chi ti\u1EBFt Instant Page ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng (object)."] };
|
|
3749
4781
|
}
|
|
3750
4782
|
const obj = input;
|
|
3751
|
-
if (!
|
|
4783
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3752
4784
|
errors.push("Tr\u01B0\u1EDDng 'instantPageId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3753
4785
|
}
|
|
3754
4786
|
return {
|
|
3755
4787
|
isValid: errors.length === 0,
|
|
3756
4788
|
errors,
|
|
3757
|
-
data: errors.length === 0 ? { instantPageId:
|
|
4789
|
+
data: errors.length === 0 ? { instantPageId: toPositiveInteger2(obj.instantPageId) } : void 0
|
|
3758
4790
|
};
|
|
3759
4791
|
}
|
|
3760
4792
|
function validateGetInstantPageSharedUserRequest(input) {
|
|
@@ -3763,18 +4795,18 @@ function validateGetInstantPageSharedUserRequest(input) {
|
|
|
3763
4795
|
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u l\u1EA5y th\xF4ng tin ng\u01B0\u1EDDi d\xF9ng chia s\u1EBB ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng (object)."] };
|
|
3764
4796
|
}
|
|
3765
4797
|
const obj = input;
|
|
3766
|
-
if (!
|
|
4798
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3767
4799
|
errors.push("Tr\u01B0\u1EDDng 'instantPageId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3768
4800
|
}
|
|
3769
|
-
if (!
|
|
4801
|
+
if (!isPositiveInteger2(obj.userId)) {
|
|
3770
4802
|
errors.push("Tr\u01B0\u1EDDng 'userId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3771
4803
|
}
|
|
3772
4804
|
return {
|
|
3773
4805
|
isValid: errors.length === 0,
|
|
3774
4806
|
errors,
|
|
3775
4807
|
data: errors.length === 0 ? {
|
|
3776
|
-
instantPageId:
|
|
3777
|
-
userId:
|
|
4808
|
+
instantPageId: toPositiveInteger2(obj.instantPageId),
|
|
4809
|
+
userId: toPositiveInteger2(obj.userId)
|
|
3778
4810
|
} : void 0
|
|
3779
4811
|
};
|
|
3780
4812
|
}
|
|
@@ -3784,15 +4816,15 @@ function validateListInstantPageEditHistoryRequest(input) {
|
|
|
3784
4816
|
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u l\u1EA5y l\u1ECBch s\u1EED ch\u1EC9nh s\u1EEDa ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng (object)."] };
|
|
3785
4817
|
}
|
|
3786
4818
|
const obj = input;
|
|
3787
|
-
if (!
|
|
4819
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3788
4820
|
errors.push("Tr\u01B0\u1EDDng 'instantPageId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3789
4821
|
}
|
|
3790
4822
|
let limit = void 0;
|
|
3791
4823
|
if (obj.limit !== void 0 && obj.limit !== null) {
|
|
3792
|
-
if (!
|
|
4824
|
+
if (!isPositiveInteger2(obj.limit)) {
|
|
3793
4825
|
errors.push("Tr\u01B0\u1EDDng 'limit' n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn >= 1.");
|
|
3794
4826
|
} else {
|
|
3795
|
-
limit =
|
|
4827
|
+
limit = toPositiveInteger2(obj.limit);
|
|
3796
4828
|
}
|
|
3797
4829
|
}
|
|
3798
4830
|
let offset = void 0;
|
|
@@ -3808,7 +4840,7 @@ function validateListInstantPageEditHistoryRequest(input) {
|
|
|
3808
4840
|
isValid: errors.length === 0,
|
|
3809
4841
|
errors,
|
|
3810
4842
|
data: errors.length === 0 ? {
|
|
3811
|
-
instantPageId:
|
|
4843
|
+
instantPageId: toPositiveInteger2(obj.instantPageId),
|
|
3812
4844
|
...limit !== void 0 ? { limit } : {},
|
|
3813
4845
|
...offset !== void 0 ? { offset } : {}
|
|
3814
4846
|
} : void 0
|
|
@@ -3820,13 +4852,13 @@ function validateListInstantPageFormRecordsRequest(input) {
|
|
|
3820
4852
|
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u t\u1EA3i b\u1EA3n ghi form ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng (object)."] };
|
|
3821
4853
|
}
|
|
3822
4854
|
const obj = input;
|
|
3823
|
-
if (!
|
|
4855
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3824
4856
|
errors.push("Tr\u01B0\u1EDDng 'instantPageId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3825
4857
|
}
|
|
3826
4858
|
return {
|
|
3827
4859
|
isValid: errors.length === 0,
|
|
3828
4860
|
errors,
|
|
3829
|
-
data: errors.length === 0 ? { instantPageId:
|
|
4861
|
+
data: errors.length === 0 ? { instantPageId: toPositiveInteger2(obj.instantPageId) } : void 0
|
|
3830
4862
|
};
|
|
3831
4863
|
}
|
|
3832
4864
|
function validateListInstantPageSharesRequest(input) {
|
|
@@ -3835,13 +4867,13 @@ function validateListInstantPageSharesRequest(input) {
|
|
|
3835
4867
|
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u l\u1EA5y danh s\xE1ch ng\u01B0\u1EDDi \u0111\u01B0\u1EE3c chia s\u1EBB ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng (object)."] };
|
|
3836
4868
|
}
|
|
3837
4869
|
const obj = input;
|
|
3838
|
-
if (!
|
|
4870
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3839
4871
|
errors.push("Tr\u01B0\u1EDDng 'instantPageId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3840
4872
|
}
|
|
3841
4873
|
return {
|
|
3842
4874
|
isValid: errors.length === 0,
|
|
3843
4875
|
errors,
|
|
3844
|
-
data: errors.length === 0 ? { instantPageId:
|
|
4876
|
+
data: errors.length === 0 ? { instantPageId: toPositiveInteger2(obj.instantPageId) } : void 0
|
|
3845
4877
|
};
|
|
3846
4878
|
}
|
|
3847
4879
|
function validateListInstantPageUsersRequest(input) {
|
|
@@ -3867,10 +4899,10 @@ function validateSearchInstantPagesRequest(input) {
|
|
|
3867
4899
|
const obj = input;
|
|
3868
4900
|
const data = {};
|
|
3869
4901
|
if (obj.id !== void 0 && obj.id !== null && obj.id !== "") {
|
|
3870
|
-
if (!
|
|
4902
|
+
if (!isPositiveInteger2(obj.id)) {
|
|
3871
4903
|
errors.push("B\u1ED9 l\u1ECDc 'id' n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3872
4904
|
} else {
|
|
3873
|
-
data.id =
|
|
4905
|
+
data.id = toPositiveInteger2(obj.id);
|
|
3874
4906
|
}
|
|
3875
4907
|
}
|
|
3876
4908
|
if (obj.name !== void 0 && obj.name !== null) {
|
|
@@ -3901,10 +4933,10 @@ function validateUpdateInstantPageRequest(input) {
|
|
|
3901
4933
|
}
|
|
3902
4934
|
const obj = input;
|
|
3903
4935
|
const instantPageId = obj.instantPageId ?? obj.id;
|
|
3904
|
-
if (!
|
|
4936
|
+
if (!isPositiveInteger2(instantPageId)) {
|
|
3905
4937
|
errors.push("Tr\u01B0\u1EDDng 'instantPageId' (ho\u1EB7c 'id') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3906
4938
|
}
|
|
3907
|
-
const numericId =
|
|
4939
|
+
const numericId = toPositiveInteger2(instantPageId);
|
|
3908
4940
|
const data = {
|
|
3909
4941
|
instantPageId: numericId,
|
|
3910
4942
|
id: numericId
|
|
@@ -3998,7 +5030,7 @@ function validateListInstantPageLeadsRequest(input) {
|
|
|
3998
5030
|
errors.push("Tr\u01B0\u1EDDng 'ids' kh\xF4ng ch\u1EE9a b\u1EA5t k\u1EF3 ID h\u1EE3p l\u1EC7 n\xE0o.");
|
|
3999
5031
|
} else {
|
|
4000
5032
|
for (const id of idParts) {
|
|
4001
|
-
if (!
|
|
5033
|
+
if (!isPositiveInteger2(id)) {
|
|
4002
5034
|
errors.push(`M\xE3 trang '${id}' trong danh s\xE1ch 'ids' kh\xF4ng ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng h\u1EE3p l\u1EC7.`);
|
|
4003
5035
|
}
|
|
4004
5036
|
}
|
|
@@ -4022,7 +5054,7 @@ function validateUpsertInstantPageFormRequest(input) {
|
|
|
4022
5054
|
return { isValid: false, errors: ["D\u1EEF li\u1EC7u c\u1EA5u h\xECnh bi\u1EC3u m\u1EABu Instant Page ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."] };
|
|
4023
5055
|
}
|
|
4024
5056
|
const obj = input;
|
|
4025
|
-
if (!
|
|
5057
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
4026
5058
|
errors.push("Tr\u01B0\u1EDDng 'instantPageId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
4027
5059
|
}
|
|
4028
5060
|
if (!obj.oaId || typeof obj.oaId !== "string" || !/^\d+$/.test(obj.oaId.trim())) {
|
|
@@ -4075,7 +5107,7 @@ function validateUpsertInstantPageFormRequest(input) {
|
|
|
4075
5107
|
}
|
|
4076
5108
|
}
|
|
4077
5109
|
const data = {
|
|
4078
|
-
instantPageId:
|
|
5110
|
+
instantPageId: toPositiveInteger2(obj.instantPageId),
|
|
4079
5111
|
oaId: String(obj.oaId).trim(),
|
|
4080
5112
|
formName: String(obj.formName).trim(),
|
|
4081
5113
|
questions: obj.questions ?? [],
|
|
@@ -4885,8 +5917,10 @@ var ZaloAdsCreateFlowRequest = class {
|
|
|
4885
5917
|
messages;
|
|
4886
5918
|
};
|
|
4887
5919
|
var ZaloAdsCreateFlowResponse = class {
|
|
4888
|
-
/** 0 khi tạo thành công. */
|
|
5920
|
+
/** 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). */
|
|
4889
5921
|
code;
|
|
5922
|
+
/** Thông báo lỗi từ Zalo Ads khi code khác 0. */
|
|
5923
|
+
msg;
|
|
4890
5924
|
/** 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. */
|
|
4891
5925
|
data;
|
|
4892
5926
|
};
|
|
@@ -4992,13 +6026,16 @@ export {
|
|
|
4992
6026
|
ZaloAdsUpdateVideoAdRequest,
|
|
4993
6027
|
ZaloAdsUpdateVideoAdResponse,
|
|
4994
6028
|
ZaloAudiencesService,
|
|
6029
|
+
ZaloAudiencesValidator,
|
|
4995
6030
|
ZaloAuthManager,
|
|
4996
6031
|
ZaloAutomatedRulesService,
|
|
4997
6032
|
ZaloCampaignsService,
|
|
4998
6033
|
ZaloChatWidgetService,
|
|
4999
6034
|
ZaloConversionsService,
|
|
5000
6035
|
ZaloFlowsService,
|
|
6036
|
+
ZaloFlowsValidator,
|
|
5001
6037
|
ZaloFormsService,
|
|
6038
|
+
ZaloFormsValidator,
|
|
5002
6039
|
ZaloInstantPageBlockType,
|
|
5003
6040
|
ZaloInstantPagesService,
|
|
5004
6041
|
ZaloInstantPagesValidator,
|
|
@@ -5016,8 +6053,20 @@ export {
|
|
|
5016
6053
|
deriveAccountKeyFromZpsid,
|
|
5017
6054
|
parseZaloCookieInput,
|
|
5018
6055
|
validateCloneInstantPageRequest,
|
|
6056
|
+
validateCreateFlowRequest,
|
|
6057
|
+
validateCreateFormEventAudienceRequest,
|
|
6058
|
+
validateCreateFormRequest,
|
|
6059
|
+
validateCreateLookalikeAudienceRequest,
|
|
6060
|
+
validateCreateMessageOaEventAudienceRequest,
|
|
6061
|
+
validateCreateMessagePersonalEventAudienceRequest,
|
|
6062
|
+
validateCreatePhoneAudienceRequest,
|
|
6063
|
+
validateCreateSavedAudienceRequest,
|
|
6064
|
+
validateEstimateAudienceRequest,
|
|
5019
6065
|
validateGetInstantPageDetailRequest,
|
|
5020
6066
|
validateGetInstantPageSharedUserRequest,
|
|
6067
|
+
validateListFlowsByOfficialAccountRequest,
|
|
6068
|
+
validateListFormLeadsRequest,
|
|
6069
|
+
validateListFormsByOfficialAccountRequest,
|
|
5021
6070
|
validateListInstantPageEditHistoryRequest,
|
|
5022
6071
|
validateListInstantPageFormRecordsRequest,
|
|
5023
6072
|
validateListInstantPageLeadsRequest,
|
|
@@ -5026,6 +6075,7 @@ export {
|
|
|
5026
6075
|
validateListMiniPageTemplatesRequest,
|
|
5027
6076
|
validateListOfficialAccountsRequest,
|
|
5028
6077
|
validateSearchInstantPagesRequest,
|
|
6078
|
+
validateUpdateFlowRequest,
|
|
5029
6079
|
validateUpdateInstantPageRequest,
|
|
5030
6080
|
validateUpsertInstantPageFormRequest
|
|
5031
6081
|
};
|