@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.js
CHANGED
|
@@ -52,13 +52,16 @@ __export(index_exports, {
|
|
|
52
52
|
ZaloAdsUpdateVideoAdRequest: () => ZaloAdsUpdateVideoAdRequest,
|
|
53
53
|
ZaloAdsUpdateVideoAdResponse: () => ZaloAdsUpdateVideoAdResponse,
|
|
54
54
|
ZaloAudiencesService: () => ZaloAudiencesService,
|
|
55
|
+
ZaloAudiencesValidator: () => ZaloAudiencesValidator,
|
|
55
56
|
ZaloAuthManager: () => ZaloAuthManager,
|
|
56
57
|
ZaloAutomatedRulesService: () => ZaloAutomatedRulesService,
|
|
57
58
|
ZaloCampaignsService: () => ZaloCampaignsService,
|
|
58
59
|
ZaloChatWidgetService: () => ZaloChatWidgetService,
|
|
59
60
|
ZaloConversionsService: () => ZaloConversionsService,
|
|
60
61
|
ZaloFlowsService: () => ZaloFlowsService,
|
|
62
|
+
ZaloFlowsValidator: () => ZaloFlowsValidator,
|
|
61
63
|
ZaloFormsService: () => ZaloFormsService,
|
|
64
|
+
ZaloFormsValidator: () => ZaloFormsValidator,
|
|
62
65
|
ZaloInstantPageBlockType: () => ZaloInstantPageBlockType,
|
|
63
66
|
ZaloInstantPagesService: () => ZaloInstantPagesService,
|
|
64
67
|
ZaloInstantPagesValidator: () => ZaloInstantPagesValidator,
|
|
@@ -76,8 +79,20 @@ __export(index_exports, {
|
|
|
76
79
|
deriveAccountKeyFromZpsid: () => deriveAccountKeyFromZpsid,
|
|
77
80
|
parseZaloCookieInput: () => parseZaloCookieInput,
|
|
78
81
|
validateCloneInstantPageRequest: () => validateCloneInstantPageRequest,
|
|
82
|
+
validateCreateFlowRequest: () => validateCreateFlowRequest,
|
|
83
|
+
validateCreateFormEventAudienceRequest: () => validateCreateFormEventAudienceRequest,
|
|
84
|
+
validateCreateFormRequest: () => validateCreateFormRequest,
|
|
85
|
+
validateCreateLookalikeAudienceRequest: () => validateCreateLookalikeAudienceRequest,
|
|
86
|
+
validateCreateMessageOaEventAudienceRequest: () => validateCreateMessageOaEventAudienceRequest,
|
|
87
|
+
validateCreateMessagePersonalEventAudienceRequest: () => validateCreateMessagePersonalEventAudienceRequest,
|
|
88
|
+
validateCreatePhoneAudienceRequest: () => validateCreatePhoneAudienceRequest,
|
|
89
|
+
validateCreateSavedAudienceRequest: () => validateCreateSavedAudienceRequest,
|
|
90
|
+
validateEstimateAudienceRequest: () => validateEstimateAudienceRequest,
|
|
79
91
|
validateGetInstantPageDetailRequest: () => validateGetInstantPageDetailRequest,
|
|
80
92
|
validateGetInstantPageSharedUserRequest: () => validateGetInstantPageSharedUserRequest,
|
|
93
|
+
validateListFlowsByOfficialAccountRequest: () => validateListFlowsByOfficialAccountRequest,
|
|
94
|
+
validateListFormLeadsRequest: () => validateListFormLeadsRequest,
|
|
95
|
+
validateListFormsByOfficialAccountRequest: () => validateListFormsByOfficialAccountRequest,
|
|
81
96
|
validateListInstantPageEditHistoryRequest: () => validateListInstantPageEditHistoryRequest,
|
|
82
97
|
validateListInstantPageFormRecordsRequest: () => validateListInstantPageFormRecordsRequest,
|
|
83
98
|
validateListInstantPageLeadsRequest: () => validateListInstantPageLeadsRequest,
|
|
@@ -86,6 +101,7 @@ __export(index_exports, {
|
|
|
86
101
|
validateListMiniPageTemplatesRequest: () => validateListMiniPageTemplatesRequest,
|
|
87
102
|
validateListOfficialAccountsRequest: () => validateListOfficialAccountsRequest,
|
|
88
103
|
validateSearchInstantPagesRequest: () => validateSearchInstantPagesRequest,
|
|
104
|
+
validateUpdateFlowRequest: () => validateUpdateFlowRequest,
|
|
89
105
|
validateUpdateInstantPageRequest: () => validateUpdateInstantPageRequest,
|
|
90
106
|
validateUpsertInstantPageFormRequest: () => validateUpsertInstantPageFormRequest
|
|
91
107
|
});
|
|
@@ -1624,6 +1640,30 @@ var OP_ZaloAdsDeleteCampaign = {
|
|
|
1624
1640
|
"status"
|
|
1625
1641
|
]
|
|
1626
1642
|
};
|
|
1643
|
+
var OP_ZaloAdsCreateSpellCheckV3Job = {
|
|
1644
|
+
operationId: "zalo_ads_create_spell_check_v3_job",
|
|
1645
|
+
method: "POST",
|
|
1646
|
+
endpoint: "/api/spell-check/v3",
|
|
1647
|
+
baseUrl: "https://ads.zalo.me",
|
|
1648
|
+
binaryFields: [],
|
|
1649
|
+
pathFields: [],
|
|
1650
|
+
queryFields: [],
|
|
1651
|
+
headerFields: [],
|
|
1652
|
+
cookieFields: [],
|
|
1653
|
+
bodyFields: ["title", "caption"]
|
|
1654
|
+
};
|
|
1655
|
+
var OP_ZaloAdsGetSpellCheckV3Job = {
|
|
1656
|
+
operationId: "zalo_ads_get_spell_check_v3_job",
|
|
1657
|
+
method: "GET",
|
|
1658
|
+
endpoint: "/api/spell-check/v3/{jobId}",
|
|
1659
|
+
baseUrl: "https://ads.zalo.me",
|
|
1660
|
+
binaryFields: [],
|
|
1661
|
+
pathFields: ["jobId"],
|
|
1662
|
+
queryFields: [],
|
|
1663
|
+
headerFields: [],
|
|
1664
|
+
cookieFields: [],
|
|
1665
|
+
bodyFields: []
|
|
1666
|
+
};
|
|
1627
1667
|
var ZaloCampaignsService = class {
|
|
1628
1668
|
constructor(client) {
|
|
1629
1669
|
this.client = client;
|
|
@@ -1773,6 +1813,48 @@ var ZaloCampaignsService = class {
|
|
|
1773
1813
|
getSpellCheckV2(...args) {
|
|
1774
1814
|
return this.getApiSpellCheckV2(...args);
|
|
1775
1815
|
}
|
|
1816
|
+
/**
|
|
1817
|
+
* 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).
|
|
1818
|
+
*/
|
|
1819
|
+
createSpellCheckV3Job(request, options) {
|
|
1820
|
+
return this.client.requestJson(
|
|
1821
|
+
OP_ZaloAdsCreateSpellCheckV3Job,
|
|
1822
|
+
this.client.toTransportInput(OP_ZaloAdsCreateSpellCheckV3Job, request),
|
|
1823
|
+
options
|
|
1824
|
+
);
|
|
1825
|
+
}
|
|
1826
|
+
/**
|
|
1827
|
+
* Lấy kết quả kiểm tra chính tả AI V3 theo jobId (GET /api/spell-check/v3/{jobId}).
|
|
1828
|
+
*/
|
|
1829
|
+
getSpellCheckV3Job(request, options) {
|
|
1830
|
+
return this.client.requestWithoutBody(
|
|
1831
|
+
OP_ZaloAdsGetSpellCheckV3Job,
|
|
1832
|
+
this.client.toTransportInput(OP_ZaloAdsGetSpellCheckV3Job, request),
|
|
1833
|
+
options
|
|
1834
|
+
);
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* 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).
|
|
1838
|
+
* @param request Tiêu đề (title) và chú thích (caption) cần kiểm tra.
|
|
1839
|
+
* @param pollIntervalMs Chu kỳ polling kiểm tra trạng thái (mặc định: 600ms).
|
|
1840
|
+
* @param timeoutMs Thời gian chờ tối đa (mặc định: 15.000ms = 15 giây).
|
|
1841
|
+
*/
|
|
1842
|
+
async checkSpellV3AndWait(request, pollIntervalMs = 600, timeoutMs = 15e3, options) {
|
|
1843
|
+
const jobRes = await this.createSpellCheckV3Job(request, options);
|
|
1844
|
+
const jobId = jobRes?.data?.jobId;
|
|
1845
|
+
if (!jobId) {
|
|
1846
|
+
throw new Error(`[SpellCheckV3] Kh\xF4ng nh\u1EADn \u0111\u01B0\u1EE3c jobId t\u1EEB Zalo Ads (code: ${jobRes?.code})`);
|
|
1847
|
+
}
|
|
1848
|
+
const startTime = Date.now();
|
|
1849
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
1850
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
1851
|
+
const res = await this.getSpellCheckV3Job({ jobId }, options);
|
|
1852
|
+
if (res?.data?.status === "COMPLETED") {
|
|
1853
|
+
return res;
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
throw new Error(`[SpellCheckV3] Qu\xE1 th\u1EDDi gian ch\u1EDD (${timeoutMs}ms) cho t\xE1c v\u1EE5 ki\u1EC3m tra ch\xEDnh t\u1EA3 jobId: ${jobId}`);
|
|
1857
|
+
}
|
|
1776
1858
|
};
|
|
1777
1859
|
|
|
1778
1860
|
// src/services/account.service.ts
|
|
@@ -1927,6 +2009,365 @@ var ZaloAccountService = class {
|
|
|
1927
2009
|
}
|
|
1928
2010
|
};
|
|
1929
2011
|
|
|
2012
|
+
// src/validators/audiences.validator.ts
|
|
2013
|
+
function validateCreateSavedAudienceRequest(input) {
|
|
2014
|
+
const errors = [];
|
|
2015
|
+
if (!input || typeof input !== "object") {
|
|
2016
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2017
|
+
}
|
|
2018
|
+
const raw = input;
|
|
2019
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2020
|
+
if (!name) {
|
|
2021
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2022
|
+
} else if (name.length < 2 || name.length > 255) {
|
|
2023
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2024
|
+
}
|
|
2025
|
+
let targetingObj;
|
|
2026
|
+
if (typeof raw.targeting === "string") {
|
|
2027
|
+
try {
|
|
2028
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2029
|
+
} catch {
|
|
2030
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2031
|
+
targetingObj = {};
|
|
2032
|
+
}
|
|
2033
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2034
|
+
targetingObj = raw.targeting;
|
|
2035
|
+
} else {
|
|
2036
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c (chu\u1ED7i JSON ho\u1EB7c Object c\u1EA5u h\xECnh targeting).");
|
|
2037
|
+
targetingObj = {};
|
|
2038
|
+
}
|
|
2039
|
+
const gender = typeof targetingObj.Gender === "number" ? targetingObj.Gender : 0;
|
|
2040
|
+
if (![0, 1, 2].includes(gender)) {
|
|
2041
|
+
errors.push("Tr\u01B0\u1EDDng 'Gender' ph\u1EA3i l\xE0 0 (T\u1EA5t c\u1EA3), 1 (Nam), ho\u1EB7c 2 (N\u1EEF).");
|
|
2042
|
+
}
|
|
2043
|
+
const VALID_AGE_RANGES = [10282, 10283, 10284, 10285, 10286, 10287, 10288];
|
|
2044
|
+
const newAgeRanges = Array.isArray(targetingObj.NewAgeRanges) && targetingObj.NewAgeRanges.length > 0 ? targetingObj.NewAgeRanges.map(Number) : VALID_AGE_RANGES;
|
|
2045
|
+
for (const age of newAgeRanges) {
|
|
2046
|
+
if (!VALID_AGE_RANGES.includes(age)) {
|
|
2047
|
+
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(", ")}.`);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
const VALID_OS = [0, 1, 2, 3];
|
|
2051
|
+
const os = Array.isArray(targetingObj.Os) && targetingObj.Os.length > 0 ? targetingObj.Os.map(Number) : [0, 1, 3];
|
|
2052
|
+
for (const o of os) {
|
|
2053
|
+
if (!VALID_OS.includes(o)) {
|
|
2054
|
+
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).`);
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
let location = targetingObj.Location;
|
|
2058
|
+
if (!location || typeof location !== "object") {
|
|
2059
|
+
location = {
|
|
2060
|
+
Addresses: [],
|
|
2061
|
+
Cities: [],
|
|
2062
|
+
WardTargeting: { Includes: [], Excludes: [] }
|
|
2063
|
+
};
|
|
2064
|
+
} else {
|
|
2065
|
+
location = {
|
|
2066
|
+
Addresses: Array.isArray(location.Addresses) ? location.Addresses : [],
|
|
2067
|
+
Cities: Array.isArray(location.Cities) ? location.Cities : [],
|
|
2068
|
+
WardTargeting: location.WardTargeting && typeof location.WardTargeting === "object" ? location.WardTargeting : { Includes: [], Excludes: [] }
|
|
2069
|
+
};
|
|
2070
|
+
if (location.WardTargeting.Includes && !Array.isArray(location.WardTargeting.Includes)) {
|
|
2071
|
+
errors.push("Tr\u01B0\u1EDDng 'Location.WardTargeting.Includes' ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng khu v\u1EF1c.");
|
|
2072
|
+
} else if (Array.isArray(location.WardTargeting.Includes)) {
|
|
2073
|
+
for (const inc of location.WardTargeting.Includes) {
|
|
2074
|
+
if (![1, 2, 3].includes(Number(inc.Id))) {
|
|
2075
|
+
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).`);
|
|
2076
|
+
}
|
|
2077
|
+
if (inc.Provinces && !Array.isArray(inc.Provinces)) {
|
|
2078
|
+
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.`);
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
const finalTargeting = {
|
|
2084
|
+
...targetingObj,
|
|
2085
|
+
CustomAudienceId: 0,
|
|
2086
|
+
Gender: gender,
|
|
2087
|
+
NewAgeRanges: newAgeRanges,
|
|
2088
|
+
Os: os,
|
|
2089
|
+
Location: location
|
|
2090
|
+
};
|
|
2091
|
+
return {
|
|
2092
|
+
isValid: errors.length === 0,
|
|
2093
|
+
errors,
|
|
2094
|
+
data: errors.length === 0 ? {
|
|
2095
|
+
name,
|
|
2096
|
+
caType: 1,
|
|
2097
|
+
targeting: JSON.stringify(finalTargeting)
|
|
2098
|
+
} : void 0
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
function validateCreatePhoneAudienceRequest(input) {
|
|
2102
|
+
const errors = [];
|
|
2103
|
+
if (!input || typeof input !== "object") {
|
|
2104
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2105
|
+
}
|
|
2106
|
+
const raw = input;
|
|
2107
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2108
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2109
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2110
|
+
}
|
|
2111
|
+
let targetingObj = {};
|
|
2112
|
+
if (typeof raw.targeting === "string") {
|
|
2113
|
+
try {
|
|
2114
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2115
|
+
} catch {
|
|
2116
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2117
|
+
}
|
|
2118
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2119
|
+
targetingObj = raw.targeting;
|
|
2120
|
+
} else {
|
|
2121
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2122
|
+
}
|
|
2123
|
+
const path = typeof targetingObj.Path === "string" ? targetingObj.Path.trim() : "";
|
|
2124
|
+
if (!path) {
|
|
2125
|
+
errors.push("Tr\u01B0\u1EDDng 'Path' (URL file .txt sau khi upload) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2126
|
+
}
|
|
2127
|
+
const total = typeof targetingObj.Total === "number" ? targetingObj.Total : 0;
|
|
2128
|
+
if (total <= 0) {
|
|
2129
|
+
errors.push("Tr\u01B0\u1EDDng 'Total' (s\u1ED1 l\u01B0\u1EE3ng S\u0110T trong file) ph\u1EA3i l\u1EDBn h\u01A1n 0.");
|
|
2130
|
+
}
|
|
2131
|
+
return {
|
|
2132
|
+
isValid: errors.length === 0,
|
|
2133
|
+
errors,
|
|
2134
|
+
data: errors.length === 0 ? {
|
|
2135
|
+
name,
|
|
2136
|
+
caType: 3,
|
|
2137
|
+
targeting: JSON.stringify({
|
|
2138
|
+
Name: String(targetingObj.Name || "phones.txt"),
|
|
2139
|
+
Path: path,
|
|
2140
|
+
Total: total,
|
|
2141
|
+
ZaloId: Number(targetingObj.ZaloId || 0),
|
|
2142
|
+
OriginAudience: 0
|
|
2143
|
+
})
|
|
2144
|
+
} : void 0
|
|
2145
|
+
};
|
|
2146
|
+
}
|
|
2147
|
+
function validateCreateLookalikeAudienceRequest(input) {
|
|
2148
|
+
const errors = [];
|
|
2149
|
+
if (!input || typeof input !== "object") {
|
|
2150
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2151
|
+
}
|
|
2152
|
+
const raw = input;
|
|
2153
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2154
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2155
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2156
|
+
}
|
|
2157
|
+
let targetingObj = {};
|
|
2158
|
+
if (typeof raw.targeting === "string") {
|
|
2159
|
+
try {
|
|
2160
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2161
|
+
} catch {
|
|
2162
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2163
|
+
}
|
|
2164
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2165
|
+
targetingObj = raw.targeting;
|
|
2166
|
+
} else {
|
|
2167
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2168
|
+
}
|
|
2169
|
+
const originAudience = Number(targetingObj.OriginAudience);
|
|
2170
|
+
if (!originAudience || originAudience <= 0) {
|
|
2171
|
+
errors.push("Tr\u01B0\u1EDDng 'OriginAudience' (ID nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng S\u0110T g\u1ED1c) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2172
|
+
}
|
|
2173
|
+
const total = Number(targetingObj.Total);
|
|
2174
|
+
if (![1e6, 15e5, 2e6].includes(total)) {
|
|
2175
|
+
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.");
|
|
2176
|
+
}
|
|
2177
|
+
return {
|
|
2178
|
+
isValid: errors.length === 0,
|
|
2179
|
+
errors,
|
|
2180
|
+
data: errors.length === 0 ? {
|
|
2181
|
+
name,
|
|
2182
|
+
caType: 6,
|
|
2183
|
+
targeting: JSON.stringify({
|
|
2184
|
+
OriginAudience: originAudience,
|
|
2185
|
+
Total: total,
|
|
2186
|
+
Name: String(targetingObj.Name || "Lookalike Audience"),
|
|
2187
|
+
Path: String(targetingObj.Path || "")
|
|
2188
|
+
})
|
|
2189
|
+
} : void 0
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
function validateCreateFormEventAudienceRequest(input) {
|
|
2193
|
+
const errors = [];
|
|
2194
|
+
if (!input || typeof input !== "object") {
|
|
2195
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2196
|
+
}
|
|
2197
|
+
const raw = input;
|
|
2198
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2199
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2200
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2201
|
+
}
|
|
2202
|
+
let targetingObj = {};
|
|
2203
|
+
if (typeof raw.targeting === "string") {
|
|
2204
|
+
try {
|
|
2205
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2206
|
+
} catch {
|
|
2207
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2208
|
+
}
|
|
2209
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2210
|
+
targetingObj = raw.targeting;
|
|
2211
|
+
}
|
|
2212
|
+
const eventType = Number(targetingObj.EventType);
|
|
2213
|
+
if (![1, 2, 3, 4].includes(eventType)) {
|
|
2214
|
+
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).");
|
|
2215
|
+
}
|
|
2216
|
+
const oaId = typeof targetingObj.OaId === "string" ? targetingObj.OaId.trim() : String(targetingObj.OaId || "");
|
|
2217
|
+
if (!oaId) {
|
|
2218
|
+
errors.push("Tr\u01B0\u1EDDng 'OaId' (d\u1EA1ng chu\u1ED7i c\u1EE7a pageId ho\u1EB7c noisedId) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2219
|
+
}
|
|
2220
|
+
const numDays = Number(targetingObj.NumDays);
|
|
2221
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
2222
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
2223
|
+
}
|
|
2224
|
+
const formIds = Array.isArray(targetingObj.FormIds) ? targetingObj.FormIds : [];
|
|
2225
|
+
if (formIds.length === 0) {
|
|
2226
|
+
errors.push("Tr\u01B0\u1EDDng 'FormIds' ph\u1EA3i ch\u1EE9a \xEDt nh\u1EA5t 1 ID Form.");
|
|
2227
|
+
}
|
|
2228
|
+
return {
|
|
2229
|
+
isValid: errors.length === 0,
|
|
2230
|
+
errors,
|
|
2231
|
+
data: errors.length === 0 ? {
|
|
2232
|
+
name,
|
|
2233
|
+
caType: 12,
|
|
2234
|
+
targeting: JSON.stringify({
|
|
2235
|
+
EventType: eventType,
|
|
2236
|
+
OaId: oaId,
|
|
2237
|
+
NumDays: numDays,
|
|
2238
|
+
FormIds: formIds
|
|
2239
|
+
})
|
|
2240
|
+
} : void 0
|
|
2241
|
+
};
|
|
2242
|
+
}
|
|
2243
|
+
function validateCreateMessageOaEventAudienceRequest(input) {
|
|
2244
|
+
const errors = [];
|
|
2245
|
+
if (!input || typeof input !== "object") {
|
|
2246
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2247
|
+
}
|
|
2248
|
+
const raw = input;
|
|
2249
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2250
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2251
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2252
|
+
}
|
|
2253
|
+
let targetingObj = {};
|
|
2254
|
+
if (typeof raw.targeting === "string") {
|
|
2255
|
+
try {
|
|
2256
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2257
|
+
} catch {
|
|
2258
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2259
|
+
}
|
|
2260
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2261
|
+
targetingObj = raw.targeting;
|
|
2262
|
+
}
|
|
2263
|
+
const eventId = Number(targetingObj.EventId ?? targetingObj.EventType ?? 1);
|
|
2264
|
+
const oaId = typeof targetingObj.OaId === "string" ? targetingObj.OaId.trim() : String(targetingObj.OaId || "");
|
|
2265
|
+
if (!oaId) {
|
|
2266
|
+
errors.push("Tr\u01B0\u1EDDng 'OaId' (chu\u1ED7i pageId ho\u1EB7c noisedId c\u1EE7a OA) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2267
|
+
}
|
|
2268
|
+
const numDays = Number(targetingObj.NumDays);
|
|
2269
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
2270
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
2271
|
+
}
|
|
2272
|
+
return {
|
|
2273
|
+
isValid: errors.length === 0,
|
|
2274
|
+
errors,
|
|
2275
|
+
data: errors.length === 0 ? {
|
|
2276
|
+
name,
|
|
2277
|
+
caType: 11,
|
|
2278
|
+
targeting: JSON.stringify({
|
|
2279
|
+
EventId: eventId,
|
|
2280
|
+
OaId: oaId,
|
|
2281
|
+
NumDays: numDays
|
|
2282
|
+
})
|
|
2283
|
+
} : void 0
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
function validateCreateMessagePersonalEventAudienceRequest(input) {
|
|
2287
|
+
const errors = [];
|
|
2288
|
+
if (!input || typeof input !== "object") {
|
|
2289
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2290
|
+
}
|
|
2291
|
+
const raw = input;
|
|
2292
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
2293
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
2294
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
2295
|
+
}
|
|
2296
|
+
let targetingObj = {};
|
|
2297
|
+
if (typeof raw.targeting === "string") {
|
|
2298
|
+
try {
|
|
2299
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
2300
|
+
} catch {
|
|
2301
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
2302
|
+
}
|
|
2303
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
2304
|
+
targetingObj = raw.targeting;
|
|
2305
|
+
}
|
|
2306
|
+
const eventId = Number(targetingObj.EventId ?? targetingObj.EventType ?? 1);
|
|
2307
|
+
if (![1, 2, 3].includes(eventId)) {
|
|
2308
|
+
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).");
|
|
2309
|
+
}
|
|
2310
|
+
const numDays = Number(targetingObj.NumDays);
|
|
2311
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
2312
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
2313
|
+
}
|
|
2314
|
+
const pageIds = Array.isArray(targetingObj.PageIds) ? targetingObj.PageIds.map(String) : [];
|
|
2315
|
+
if (pageIds.length === 0) {
|
|
2316
|
+
errors.push("Tr\u01B0\u1EDDng 'PageIds' ph\u1EA3i ch\u1EE9a \xEDt nh\u1EA5t 1 ID trang c\xE1 nh\xE2n.");
|
|
2317
|
+
}
|
|
2318
|
+
return {
|
|
2319
|
+
isValid: errors.length === 0,
|
|
2320
|
+
errors,
|
|
2321
|
+
data: errors.length === 0 ? {
|
|
2322
|
+
name,
|
|
2323
|
+
caType: 14,
|
|
2324
|
+
targeting: JSON.stringify({
|
|
2325
|
+
EventId: eventId,
|
|
2326
|
+
NumDays: numDays,
|
|
2327
|
+
PageIds: pageIds
|
|
2328
|
+
})
|
|
2329
|
+
} : void 0
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
function validateEstimateAudienceRequest(input) {
|
|
2333
|
+
const errors = [];
|
|
2334
|
+
if (!input || typeof input !== "object") {
|
|
2335
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
2336
|
+
}
|
|
2337
|
+
const raw = input;
|
|
2338
|
+
const gender = typeof raw.gender === "number" ? raw.gender : 0;
|
|
2339
|
+
if (![0, 1, 2].includes(gender)) {
|
|
2340
|
+
errors.push("Tr\u01B0\u1EDDng 'gender' ph\u1EA3i l\xE0 0, 1 ho\u1EB7c 2.");
|
|
2341
|
+
}
|
|
2342
|
+
const ageRanges = Array.isArray(raw.ageRanges) && raw.ageRanges.length > 0 ? raw.ageRanges.map(Number) : [10283, 10284, 10285, 10286, 10287];
|
|
2343
|
+
const platforms = Array.isArray(raw.platforms) && raw.platforms.length > 0 ? raw.platforms.map(Number) : [0, 1, 3];
|
|
2344
|
+
const priceType = typeof raw.priceType === "number" ? raw.priceType : 2;
|
|
2345
|
+
const wardsTargeting = typeof raw.wardsTargeting === "string" && raw.wardsTargeting.trim() ? raw.wardsTargeting.trim() : JSON.stringify({ Includes: [], Excludes: [] });
|
|
2346
|
+
return {
|
|
2347
|
+
isValid: errors.length === 0,
|
|
2348
|
+
errors,
|
|
2349
|
+
data: errors.length === 0 ? {
|
|
2350
|
+
gender,
|
|
2351
|
+
ageRanges,
|
|
2352
|
+
platforms,
|
|
2353
|
+
locations: typeof raw.locations === "string" ? raw.locations : "",
|
|
2354
|
+
provinces: Array.isArray(raw.provinces) ? raw.provinces.map(Number) : [],
|
|
2355
|
+
wardsTargeting,
|
|
2356
|
+
priceType,
|
|
2357
|
+
number: typeof raw.number === "string" ? raw.number : String(raw.number || "0")
|
|
2358
|
+
} : void 0
|
|
2359
|
+
};
|
|
2360
|
+
}
|
|
2361
|
+
var ZaloAudiencesValidator = {
|
|
2362
|
+
createSavedAudience: validateCreateSavedAudienceRequest,
|
|
2363
|
+
createPhoneAudience: validateCreatePhoneAudienceRequest,
|
|
2364
|
+
createLookalikeAudience: validateCreateLookalikeAudienceRequest,
|
|
2365
|
+
createFormEventAudience: validateCreateFormEventAudienceRequest,
|
|
2366
|
+
createMessageOaEventAudience: validateCreateMessageOaEventAudienceRequest,
|
|
2367
|
+
createMessagePersonalEventAudience: validateCreateMessagePersonalEventAudienceRequest,
|
|
2368
|
+
estimateAudience: validateEstimateAudienceRequest
|
|
2369
|
+
};
|
|
2370
|
+
|
|
1930
2371
|
// src/services/audiences.service.ts
|
|
1931
2372
|
var OP_ZaloAdsCreateCustomAudience = {
|
|
1932
2373
|
"operationId": "ZaloAds_createCustomAudience",
|
|
@@ -2027,6 +2468,7 @@ var ZaloAudiencesService = class {
|
|
|
2027
2468
|
constructor(client) {
|
|
2028
2469
|
this.client = client;
|
|
2029
2470
|
}
|
|
2471
|
+
static validator = ZaloAudiencesValidator;
|
|
2030
2472
|
postApiAdEstimateaudience(request, options) {
|
|
2031
2473
|
return this.client.requestJson(OP_ZaloAdsPostApiAdEstimateaudience, this.client.toTransportInput(OP_ZaloAdsPostApiAdEstimateaudience, request), options);
|
|
2032
2474
|
}
|
|
@@ -2079,7 +2521,22 @@ var ZaloAudiencesService = class {
|
|
|
2079
2521
|
}
|
|
2080
2522
|
/** 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`). */
|
|
2081
2523
|
createMessagePersonalEventAudience(request, options) {
|
|
2082
|
-
|
|
2524
|
+
let targetingObj;
|
|
2525
|
+
if (typeof request.targeting === "string") {
|
|
2526
|
+
try {
|
|
2527
|
+
targetingObj = JSON.parse(request.targeting);
|
|
2528
|
+
} catch {
|
|
2529
|
+
targetingObj = null;
|
|
2530
|
+
}
|
|
2531
|
+
} else if (request.targeting && typeof request.targeting === "object") {
|
|
2532
|
+
targetingObj = { ...request.targeting };
|
|
2533
|
+
}
|
|
2534
|
+
if (targetingObj && typeof targetingObj === "object") {
|
|
2535
|
+
if (targetingObj.EventId === void 0 && targetingObj.EventType !== void 0) {
|
|
2536
|
+
targetingObj.EventId = targetingObj.EventType;
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
const targetingStr = targetingObj ? JSON.stringify(targetingObj) : typeof request.targeting === "string" ? request.targeting : JSON.stringify(request.targeting);
|
|
2083
2540
|
return this.createCustomAudience({ name: request.name, caType: 14, targeting: targetingStr }, options);
|
|
2084
2541
|
}
|
|
2085
2542
|
/** Tạo mới Nhóm đối tượng từ Trung tâm Lead - Zalo Form (`caType = 10` - `FORM_AUDIENCE`). */
|
|
@@ -2635,6 +3092,236 @@ var ZaloAutomatedRulesService = class {
|
|
|
2635
3092
|
}
|
|
2636
3093
|
};
|
|
2637
3094
|
|
|
3095
|
+
// src/validators/flows.validator.ts
|
|
3096
|
+
var MAX_INT_32 = 2147483647;
|
|
3097
|
+
function is32BitPositiveInteger(val) {
|
|
3098
|
+
if (typeof val === "number") {
|
|
3099
|
+
return Number.isInteger(val) && val > 0 && val <= MAX_INT_32;
|
|
3100
|
+
}
|
|
3101
|
+
if (typeof val === "string" && val.trim() !== "") {
|
|
3102
|
+
const num = Number(val);
|
|
3103
|
+
return Number.isInteger(num) && num > 0 && num <= MAX_INT_32;
|
|
3104
|
+
}
|
|
3105
|
+
return false;
|
|
3106
|
+
}
|
|
3107
|
+
function isPositiveInteger(val) {
|
|
3108
|
+
if (typeof val === "number") return Number.isInteger(val) && val > 0;
|
|
3109
|
+
if (typeof val === "string" && val.trim() !== "") {
|
|
3110
|
+
const num = Number(val);
|
|
3111
|
+
return Number.isInteger(num) && num > 0;
|
|
3112
|
+
}
|
|
3113
|
+
return false;
|
|
3114
|
+
}
|
|
3115
|
+
function isNonNegativeInteger(val) {
|
|
3116
|
+
if (typeof val === "number") return Number.isInteger(val) && val >= 0;
|
|
3117
|
+
if (typeof val === "string" && val.trim() !== "") {
|
|
3118
|
+
const num = Number(val);
|
|
3119
|
+
return Number.isInteger(num) && num >= 0;
|
|
3120
|
+
}
|
|
3121
|
+
return false;
|
|
3122
|
+
}
|
|
3123
|
+
function toPositiveInteger(val) {
|
|
3124
|
+
return typeof val === "number" ? Math.floor(val) : parseInt(String(val), 10);
|
|
3125
|
+
}
|
|
3126
|
+
function validateFlowButtons(buttons, errors, prefix) {
|
|
3127
|
+
if (!Array.isArray(buttons)) {
|
|
3128
|
+
errors.push(`${prefix}: Tr\u01B0\u1EDDng 'buttons' ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng.`);
|
|
3129
|
+
return [];
|
|
3130
|
+
}
|
|
3131
|
+
const cleanButtons = [];
|
|
3132
|
+
buttons.forEach((btn, idx) => {
|
|
3133
|
+
const btnPrefix = `${prefix}.buttons[${idx}]`;
|
|
3134
|
+
if (!btn || typeof btn !== "object") {
|
|
3135
|
+
errors.push(`${btnPrefix}: N\xFAt b\u1EA5m ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng.`);
|
|
3136
|
+
return;
|
|
3137
|
+
}
|
|
3138
|
+
const b = btn;
|
|
3139
|
+
if (typeof b.text !== "string" || b.text.trim() === "") {
|
|
3140
|
+
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.`);
|
|
3141
|
+
}
|
|
3142
|
+
const btnType = Number(b.type);
|
|
3143
|
+
if (![3, 10, 12].includes(btnType)) {
|
|
3144
|
+
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).`);
|
|
3145
|
+
}
|
|
3146
|
+
const cleanBtn = {
|
|
3147
|
+
type: btnType,
|
|
3148
|
+
text: String(b.text ?? "").trim(),
|
|
3149
|
+
editable: b.editable !== false
|
|
3150
|
+
};
|
|
3151
|
+
if (btnType === 10) {
|
|
3152
|
+
if (typeof b.url !== "string" || b.url.trim() === "") {
|
|
3153
|
+
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.`);
|
|
3154
|
+
} else {
|
|
3155
|
+
cleanBtn.url = b.url.trim();
|
|
3156
|
+
}
|
|
3157
|
+
} else if (btnType === 12) {
|
|
3158
|
+
if (typeof b.phone !== "string" || b.phone.trim() === "") {
|
|
3159
|
+
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.`);
|
|
3160
|
+
} else {
|
|
3161
|
+
cleanBtn.phone = b.phone.trim();
|
|
3162
|
+
}
|
|
3163
|
+
} else if (btnType === 3) {
|
|
3164
|
+
if (!Array.isArray(b.messages) || b.messages.length === 0) {
|
|
3165
|
+
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.`);
|
|
3166
|
+
} else {
|
|
3167
|
+
const cleanChildMsgs = [];
|
|
3168
|
+
b.messages.forEach((child, cIdx) => {
|
|
3169
|
+
const childPrefix = `${btnPrefix}.messages[${cIdx}]`;
|
|
3170
|
+
if (!child || typeof child !== "object") {
|
|
3171
|
+
errors.push(`${childPrefix}: Tin nh\u1EAFn con ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng.`);
|
|
3172
|
+
return;
|
|
3173
|
+
}
|
|
3174
|
+
const c = child;
|
|
3175
|
+
if (typeof c.text !== "string" || c.text.trim() === "") {
|
|
3176
|
+
errors.push(`${childPrefix}: N\u1ED9i dung tin nh\u1EAFn con 'text' kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.`);
|
|
3177
|
+
} else if (c.text.length > 1961) {
|
|
3178
|
+
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).`);
|
|
3179
|
+
}
|
|
3180
|
+
cleanChildMsgs.push({
|
|
3181
|
+
type: 8,
|
|
3182
|
+
text: String(c.text ?? "").trim()
|
|
3183
|
+
});
|
|
3184
|
+
});
|
|
3185
|
+
cleanBtn.messages = cleanChildMsgs;
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
cleanButtons.push(cleanBtn);
|
|
3189
|
+
});
|
|
3190
|
+
return cleanButtons;
|
|
3191
|
+
}
|
|
3192
|
+
function validateFlowMessages(messages, errors) {
|
|
3193
|
+
if (!Array.isArray(messages)) {
|
|
3194
|
+
errors.push("Tr\u01B0\u1EDDng 'messages' ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng ch\u1EE9a tin nh\u1EAFn k\u1ECBch b\u1EA3n.");
|
|
3195
|
+
return [];
|
|
3196
|
+
}
|
|
3197
|
+
if (messages.length !== 1) {
|
|
3198
|
+
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).`);
|
|
3199
|
+
return [];
|
|
3200
|
+
}
|
|
3201
|
+
const msg = messages[0];
|
|
3202
|
+
if (!msg || typeof msg !== "object") {
|
|
3203
|
+
errors.push("Tin nh\u1EAFn k\u1ECBch b\u1EA3n ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng.");
|
|
3204
|
+
return [];
|
|
3205
|
+
}
|
|
3206
|
+
const m = msg;
|
|
3207
|
+
const msgType = Number(m.type);
|
|
3208
|
+
if (![1, 2].includes(msgType)) {
|
|
3209
|
+
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).");
|
|
3210
|
+
}
|
|
3211
|
+
if (typeof m.text !== "string" || m.text.trim() === "") {
|
|
3212
|
+
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.");
|
|
3213
|
+
} else if (m.text.length > 1961) {
|
|
3214
|
+
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).`);
|
|
3215
|
+
}
|
|
3216
|
+
const cleanMsg = {
|
|
3217
|
+
type: msgType,
|
|
3218
|
+
text: String(m.text ?? "").trim()
|
|
3219
|
+
};
|
|
3220
|
+
if (msgType === 2) {
|
|
3221
|
+
if (typeof m.url !== "string" || m.url.trim() === "") {
|
|
3222
|
+
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.");
|
|
3223
|
+
} else {
|
|
3224
|
+
cleanMsg.url = m.url.trim();
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
3227
|
+
if (m.buttons !== void 0 && m.buttons !== null) {
|
|
3228
|
+
cleanMsg.buttons = validateFlowButtons(m.buttons, errors, "messages[0]");
|
|
3229
|
+
}
|
|
3230
|
+
return [cleanMsg];
|
|
3231
|
+
}
|
|
3232
|
+
function validateListFlowsByOfficialAccountRequest(input) {
|
|
3233
|
+
const errors = [];
|
|
3234
|
+
if (!input || typeof input !== "object") {
|
|
3235
|
+
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."] };
|
|
3236
|
+
}
|
|
3237
|
+
const obj = input;
|
|
3238
|
+
if (!is32BitPositiveInteger(obj.oaId)) {
|
|
3239
|
+
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.");
|
|
3240
|
+
}
|
|
3241
|
+
if (!isPositiveInteger(obj.limit)) {
|
|
3242
|
+
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).");
|
|
3243
|
+
}
|
|
3244
|
+
if (obj.offset !== void 0 && obj.offset !== null && !isNonNegativeInteger(obj.offset)) {
|
|
3245
|
+
errors.push("Tr\u01B0\u1EDDng 'offset' n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn kh\xF4ng \xE2m (>= 0).");
|
|
3246
|
+
}
|
|
3247
|
+
if (obj.flowId !== void 0 && obj.flowId !== null && !isPositiveInteger(obj.flowId)) {
|
|
3248
|
+
errors.push("Tr\u01B0\u1EDDng 'flowId' n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3249
|
+
}
|
|
3250
|
+
const cleanData = {
|
|
3251
|
+
oaId: toPositiveInteger(obj.oaId),
|
|
3252
|
+
limit: toPositiveInteger(obj.limit)
|
|
3253
|
+
};
|
|
3254
|
+
if (obj.offset !== void 0 && obj.offset !== null) cleanData.offset = toPositiveInteger(obj.offset);
|
|
3255
|
+
if (obj.flowId !== void 0 && obj.flowId !== null) cleanData.flowId = toPositiveInteger(obj.flowId);
|
|
3256
|
+
return {
|
|
3257
|
+
isValid: errors.length === 0,
|
|
3258
|
+
errors,
|
|
3259
|
+
data: errors.length === 0 ? cleanData : void 0
|
|
3260
|
+
};
|
|
3261
|
+
}
|
|
3262
|
+
function validateCreateFlowRequest(input) {
|
|
3263
|
+
const errors = [];
|
|
3264
|
+
if (!input || typeof input !== "object") {
|
|
3265
|
+
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."] };
|
|
3266
|
+
}
|
|
3267
|
+
const obj = input;
|
|
3268
|
+
if (!is32BitPositiveInteger(obj.oaId)) {
|
|
3269
|
+
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).");
|
|
3270
|
+
}
|
|
3271
|
+
if (typeof obj.name !== "string" || obj.name.trim() === "") {
|
|
3272
|
+
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.");
|
|
3273
|
+
} else if (obj.name.trim().length > 50) {
|
|
3274
|
+
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).`);
|
|
3275
|
+
}
|
|
3276
|
+
const cleanMessages = validateFlowMessages(obj.messages, errors);
|
|
3277
|
+
const cleanData = {
|
|
3278
|
+
oaId: toPositiveInteger(obj.oaId),
|
|
3279
|
+
id: null,
|
|
3280
|
+
name: String(obj.name ?? "").trim(),
|
|
3281
|
+
messages: cleanMessages
|
|
3282
|
+
};
|
|
3283
|
+
return {
|
|
3284
|
+
isValid: errors.length === 0,
|
|
3285
|
+
errors,
|
|
3286
|
+
data: errors.length === 0 ? cleanData : void 0
|
|
3287
|
+
};
|
|
3288
|
+
}
|
|
3289
|
+
function validateUpdateFlowRequest(input) {
|
|
3290
|
+
const errors = [];
|
|
3291
|
+
if (!input || typeof input !== "object") {
|
|
3292
|
+
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."] };
|
|
3293
|
+
}
|
|
3294
|
+
const obj = input;
|
|
3295
|
+
if (!isPositiveInteger(obj.id)) {
|
|
3296
|
+
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).");
|
|
3297
|
+
}
|
|
3298
|
+
if (!is32BitPositiveInteger(obj.oaId)) {
|
|
3299
|
+
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).");
|
|
3300
|
+
}
|
|
3301
|
+
if (typeof obj.name !== "string" || obj.name.trim() === "") {
|
|
3302
|
+
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.");
|
|
3303
|
+
} else if (obj.name.trim().length > 50) {
|
|
3304
|
+
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).`);
|
|
3305
|
+
}
|
|
3306
|
+
const cleanMessages = validateFlowMessages(obj.messages, errors);
|
|
3307
|
+
const cleanData = {
|
|
3308
|
+
id: toPositiveInteger(obj.id),
|
|
3309
|
+
oaId: toPositiveInteger(obj.oaId),
|
|
3310
|
+
name: String(obj.name ?? "").trim(),
|
|
3311
|
+
messages: cleanMessages
|
|
3312
|
+
};
|
|
3313
|
+
return {
|
|
3314
|
+
isValid: errors.length === 0,
|
|
3315
|
+
errors,
|
|
3316
|
+
data: errors.length === 0 ? cleanData : void 0
|
|
3317
|
+
};
|
|
3318
|
+
}
|
|
3319
|
+
var ZaloFlowsValidator = {
|
|
3320
|
+
listFlowsByOfficialAccount: validateListFlowsByOfficialAccountRequest,
|
|
3321
|
+
createFlow: validateCreateFlowRequest,
|
|
3322
|
+
updateFlow: validateUpdateFlowRequest
|
|
3323
|
+
};
|
|
3324
|
+
|
|
2638
3325
|
// src/services/flows.service.ts
|
|
2639
3326
|
var OP_ZaloAdsListFlowsByOfficialAccount = {
|
|
2640
3327
|
operationId: "ZaloAds_listFlowsByOfficialAccount",
|
|
@@ -2676,6 +3363,12 @@ var ZaloFlowsService = class {
|
|
|
2676
3363
|
constructor(client) {
|
|
2677
3364
|
this.client = client;
|
|
2678
3365
|
}
|
|
3366
|
+
/**
|
|
3367
|
+
* Bộ công cụ kiểm tra tính hợp lệ dữ liệu (Standalone Validators) cho Message Flows APIs.
|
|
3368
|
+
* Dùng để validate dữ liệu đầu vào trước khi lưu DB hoặc gọi Zalo Ads.
|
|
3369
|
+
*/
|
|
3370
|
+
static validator = ZaloFlowsValidator;
|
|
3371
|
+
validator = ZaloFlowsValidator;
|
|
2679
3372
|
listFlowsByOfficialAccount(request, options) {
|
|
2680
3373
|
return this.client.requestWithoutBody(OP_ZaloAdsListFlowsByOfficialAccount, this.client.toTransportInput(OP_ZaloAdsListFlowsByOfficialAccount, request), options);
|
|
2681
3374
|
}
|
|
@@ -3589,7 +4282,301 @@ var ZaloChatWidgetService = class {
|
|
|
3589
4282
|
}
|
|
3590
4283
|
};
|
|
3591
4284
|
|
|
4285
|
+
// src/validators/forms.validator.ts
|
|
4286
|
+
function isValidUrl(val) {
|
|
4287
|
+
if (typeof val !== "string" || val.trim() === "") return false;
|
|
4288
|
+
try {
|
|
4289
|
+
const url = new URL(val);
|
|
4290
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
4291
|
+
} catch {
|
|
4292
|
+
return false;
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
4295
|
+
function validateCreateFormRequest(input) {
|
|
4296
|
+
const errors = [];
|
|
4297
|
+
if (!input || typeof input !== "object") {
|
|
4298
|
+
return {
|
|
4299
|
+
isValid: false,
|
|
4300
|
+
errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u t\u1EA1o Form ph\u1EA3i l\xE0 m\u1ED9t object."],
|
|
4301
|
+
data: void 0
|
|
4302
|
+
};
|
|
4303
|
+
}
|
|
4304
|
+
let raw = input;
|
|
4305
|
+
if (typeof input.data === "string") {
|
|
4306
|
+
try {
|
|
4307
|
+
raw = JSON.parse(input.data);
|
|
4308
|
+
} catch {
|
|
4309
|
+
errors.push("Tr\u01B0\u1EDDng 'data' kh\xF4ng ph\u1EA3i l\xE0 chu\u1ED7i JSON h\u1EE3p l\u1EC7.");
|
|
4310
|
+
return { isValid: false, errors, data: void 0 };
|
|
4311
|
+
}
|
|
4312
|
+
} else if (typeof input.data === "object" && input.data !== null) {
|
|
4313
|
+
raw = input.data;
|
|
4314
|
+
}
|
|
4315
|
+
const oaIdRaw = raw.oaId;
|
|
4316
|
+
let cleanOaId = "";
|
|
4317
|
+
if (typeof oaIdRaw === "string" && /^[0-9]+$/.test(oaIdRaw.trim())) {
|
|
4318
|
+
cleanOaId = oaIdRaw.trim();
|
|
4319
|
+
} else if (typeof oaIdRaw === "number" && Number.isInteger(oaIdRaw) && oaIdRaw > 0) {
|
|
4320
|
+
cleanOaId = String(oaIdRaw);
|
|
4321
|
+
} else {
|
|
4322
|
+
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').");
|
|
4323
|
+
}
|
|
4324
|
+
const title = typeof raw.title === "string" ? raw.title.trim() : "";
|
|
4325
|
+
if (!title) {
|
|
4326
|
+
errors.push("Tr\u01B0\u1EDDng 'title' (ti\xEAu \u0111\u1EC1 form) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
4327
|
+
} else if (title.length < 2 || title.length > 40) {
|
|
4328
|
+
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).`);
|
|
4329
|
+
}
|
|
4330
|
+
const formName = typeof raw.formName === "string" ? raw.formName.trim() : "";
|
|
4331
|
+
if (!formName) {
|
|
4332
|
+
errors.push("Tr\u01B0\u1EDDng 'formName' (t\xEAn qu\u1EA3n tr\u1ECB form) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
4333
|
+
} else if (formName.length < 2 || formName.length > 100) {
|
|
4334
|
+
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).`);
|
|
4335
|
+
}
|
|
4336
|
+
let cleanDescription = void 0;
|
|
4337
|
+
if (raw.description !== void 0 && raw.description !== null) {
|
|
4338
|
+
const desc = String(raw.description).trim();
|
|
4339
|
+
if (desc.length > 600) {
|
|
4340
|
+
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).`);
|
|
4341
|
+
} else {
|
|
4342
|
+
cleanDescription = desc;
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4345
|
+
const coverPhoto = typeof raw.coverPhoto === "string" ? raw.coverPhoto.trim() : "";
|
|
4346
|
+
if (!coverPhoto) {
|
|
4347
|
+
errors.push("Tr\u01B0\u1EDDng 'coverPhoto' (\u1EA3nh b\xECa form) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
4348
|
+
} else if (!isValidUrl(coverPhoto)) {
|
|
4349
|
+
errors.push(`Tr\u01B0\u1EDDng 'coverPhoto' ph\u1EA3i l\xE0 URL h\u1EE3p l\u1EC7 (http:// ho\u1EB7c https://).`);
|
|
4350
|
+
}
|
|
4351
|
+
const submitTitle = typeof raw.submitTitle === "string" && raw.submitTitle.trim() !== "" ? raw.submitTitle.trim() : "G\u1EEDi th\xF4ng tin th\xE0nh c\xF4ng";
|
|
4352
|
+
if (submitTitle.length > 90) {
|
|
4353
|
+
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).`);
|
|
4354
|
+
}
|
|
4355
|
+
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.";
|
|
4356
|
+
if (thanks.length > 255) {
|
|
4357
|
+
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).`);
|
|
4358
|
+
}
|
|
4359
|
+
const gotoActionType = raw.gotoActionType === 0 ? 0 : 1;
|
|
4360
|
+
const gotoText = typeof raw.gotoText === "string" && raw.gotoText.trim() !== "" ? raw.gotoText.trim() : gotoActionType === 1 ? "Xem trang Web" : "\u0110\xF3ng l\u1EA1i";
|
|
4361
|
+
let cleanWebsite = void 0;
|
|
4362
|
+
if (gotoActionType === 1) {
|
|
4363
|
+
if (!raw.website || !isValidUrl(raw.website)) {
|
|
4364
|
+
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.");
|
|
4365
|
+
} else {
|
|
4366
|
+
cleanWebsite = String(raw.website).trim();
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
const useCustomConsent = Boolean(raw.useCustomConsent);
|
|
4370
|
+
let cleanConsentName = void 0;
|
|
4371
|
+
let cleanConsentUrl = void 0;
|
|
4372
|
+
if (useCustomConsent) {
|
|
4373
|
+
const cName = typeof raw.consentName === "string" ? raw.consentName.trim() : "";
|
|
4374
|
+
if (!cName) {
|
|
4375
|
+
errors.push("Khi 'useCustomConsent' = true, tr\u01B0\u1EDDng 'consentName' (ti\xEAu \u0111\u1EC1 \u0111i\u1EC1u kho\u1EA3n) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
4376
|
+
} else if (cName.length > 255) {
|
|
4377
|
+
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).`);
|
|
4378
|
+
} else {
|
|
4379
|
+
cleanConsentName = cName;
|
|
4380
|
+
}
|
|
4381
|
+
if (!raw.consentUrl || !isValidUrl(raw.consentUrl)) {
|
|
4382
|
+
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.");
|
|
4383
|
+
} else {
|
|
4384
|
+
cleanConsentUrl = String(raw.consentUrl).trim();
|
|
4385
|
+
}
|
|
4386
|
+
}
|
|
4387
|
+
if (!Array.isArray(raw.questions) || raw.questions.length === 0) {
|
|
4388
|
+
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'.");
|
|
4389
|
+
}
|
|
4390
|
+
const cleanQuestions = [];
|
|
4391
|
+
let hasPhonePrimary = false;
|
|
4392
|
+
let hasPhoneSecondary = false;
|
|
4393
|
+
if (Array.isArray(raw.questions)) {
|
|
4394
|
+
raw.questions.forEach((q, idx) => {
|
|
4395
|
+
const qPrefix = `C\xE2u h\u1ECFi [${idx}]`;
|
|
4396
|
+
if (!q || typeof q !== "object") {
|
|
4397
|
+
errors.push(`${qPrefix} ph\u1EA3i l\xE0 m\u1ED9t object.`);
|
|
4398
|
+
return;
|
|
4399
|
+
}
|
|
4400
|
+
const qTitle = typeof q.title === "string" ? q.title.trim() : "";
|
|
4401
|
+
if (qTitle.length < 2 || qTitle.length > 180) {
|
|
4402
|
+
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.`);
|
|
4403
|
+
}
|
|
4404
|
+
if (!Array.isArray(q.answers) || q.answers.length === 0) {
|
|
4405
|
+
errors.push(`${qPrefix}: Ph\u1EA3i c\xF3 \xEDt nh\u1EA5t 1 \u0111\xE1p \xE1n trong m\u1EA3ng 'answers'.`);
|
|
4406
|
+
return;
|
|
4407
|
+
}
|
|
4408
|
+
const cleanAnswers = [];
|
|
4409
|
+
q.answers.forEach((ans, aIdx) => {
|
|
4410
|
+
const aType = Number(ans?.type);
|
|
4411
|
+
if (![2, 7, 13].includes(aType)) {
|
|
4412
|
+
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).`);
|
|
4413
|
+
}
|
|
4414
|
+
if (aType === 13) hasPhonePrimary = true;
|
|
4415
|
+
if (aType === 2) hasPhoneSecondary = true;
|
|
4416
|
+
cleanAnswers.push({
|
|
4417
|
+
type: aType,
|
|
4418
|
+
placeHolder: ans?.placeHolder ? String(ans.placeHolder).trim() : void 0,
|
|
4419
|
+
value: ans?.value ? String(ans.value).trim() : null,
|
|
4420
|
+
priority: typeof ans?.priority === "number" ? ans.priority : 500
|
|
4421
|
+
});
|
|
4422
|
+
});
|
|
4423
|
+
cleanQuestions.push({
|
|
4424
|
+
title: qTitle,
|
|
4425
|
+
type: typeof q.type === "number" ? q.type : 1,
|
|
4426
|
+
isRequired: q.isRequired !== void 0 ? Boolean(q.isRequired) : true,
|
|
4427
|
+
editDisabled: Boolean(q.editDisabled),
|
|
4428
|
+
priority: typeof q.priority === "number" ? q.priority : (idx + 1) * 100,
|
|
4429
|
+
answers: cleanAnswers
|
|
4430
|
+
});
|
|
4431
|
+
});
|
|
4432
|
+
}
|
|
4433
|
+
if (hasPhoneSecondary) {
|
|
4434
|
+
cleanQuestions.forEach((q) => {
|
|
4435
|
+
if (q.answers.some((a) => a.type === 13)) {
|
|
4436
|
+
q.editDisabled = true;
|
|
4437
|
+
}
|
|
4438
|
+
});
|
|
4439
|
+
}
|
|
4440
|
+
const cleanSections = [];
|
|
4441
|
+
if (Array.isArray(raw.sections)) {
|
|
4442
|
+
raw.sections.forEach((sec, sIdx) => {
|
|
4443
|
+
const sPrefix = `Section [${sIdx}]`;
|
|
4444
|
+
const sType = Number(sec?.type);
|
|
4445
|
+
if (isNaN(sType) || sType < 0 || sType > 4) {
|
|
4446
|
+
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).`);
|
|
4447
|
+
}
|
|
4448
|
+
const sTitle = typeof sec?.title === "string" ? sec.title.trim() : "";
|
|
4449
|
+
if (sTitle.length > 60) {
|
|
4450
|
+
errors.push(`${sPrefix}: 'title' kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 60 k\xFD t\u1EF1.`);
|
|
4451
|
+
}
|
|
4452
|
+
cleanSections.push({
|
|
4453
|
+
type: sType,
|
|
4454
|
+
title: sTitle,
|
|
4455
|
+
disable: Boolean(sec?.disable),
|
|
4456
|
+
expand: Boolean(sec?.expand),
|
|
4457
|
+
content: sec?.content ? sec.content : {}
|
|
4458
|
+
});
|
|
4459
|
+
});
|
|
4460
|
+
}
|
|
4461
|
+
const cleanData = {
|
|
4462
|
+
oaId: cleanOaId,
|
|
4463
|
+
title,
|
|
4464
|
+
formName,
|
|
4465
|
+
description: cleanDescription,
|
|
4466
|
+
coverPhoto,
|
|
4467
|
+
submitTitle,
|
|
4468
|
+
thanks,
|
|
4469
|
+
gotoActionType,
|
|
4470
|
+
gotoText,
|
|
4471
|
+
website: cleanWebsite,
|
|
4472
|
+
reviewSubmit: raw.reviewSubmit !== void 0 ? Boolean(raw.reviewSubmit) : true,
|
|
4473
|
+
questions: cleanQuestions,
|
|
4474
|
+
sections: cleanSections.length > 0 ? cleanSections : void 0,
|
|
4475
|
+
useCustomConsent,
|
|
4476
|
+
consentName: cleanConsentName,
|
|
4477
|
+
consentUrl: cleanConsentUrl
|
|
4478
|
+
};
|
|
4479
|
+
return {
|
|
4480
|
+
isValid: errors.length === 0,
|
|
4481
|
+
errors,
|
|
4482
|
+
data: errors.length === 0 ? cleanData : void 0
|
|
4483
|
+
};
|
|
4484
|
+
}
|
|
4485
|
+
function validateListFormsByOfficialAccountRequest(input) {
|
|
4486
|
+
const errors = [];
|
|
4487
|
+
if (!input || typeof input !== "object") {
|
|
4488
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
4489
|
+
}
|
|
4490
|
+
const raw = input;
|
|
4491
|
+
let cleanOaId = "";
|
|
4492
|
+
if (typeof raw.oaId === "string" && /^[0-9]+$/.test(raw.oaId.trim())) {
|
|
4493
|
+
cleanOaId = raw.oaId.trim();
|
|
4494
|
+
} else if (typeof raw.oaId === "number" && Number.isInteger(raw.oaId) && raw.oaId > 0) {
|
|
4495
|
+
cleanOaId = String(raw.oaId);
|
|
4496
|
+
} else {
|
|
4497
|
+
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.");
|
|
4498
|
+
}
|
|
4499
|
+
return {
|
|
4500
|
+
isValid: errors.length === 0,
|
|
4501
|
+
errors,
|
|
4502
|
+
data: errors.length === 0 ? { oaId: cleanOaId, isAll: raw.isAll !== void 0 ? Boolean(raw.isAll) : true } : void 0
|
|
4503
|
+
};
|
|
4504
|
+
}
|
|
4505
|
+
function validateListFormLeadsRequest(input) {
|
|
4506
|
+
const errors = [];
|
|
4507
|
+
if (!input || typeof input !== "object") {
|
|
4508
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
4509
|
+
}
|
|
4510
|
+
const raw = input;
|
|
4511
|
+
const oaId = typeof raw.oaId === "string" ? raw.oaId.trim() : "";
|
|
4512
|
+
if (!oaId) {
|
|
4513
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' l\xE0 b\u1EAFt bu\u1ED9c (m\xE3 ch\u1EEF t\u1EEB getAuthSession, v\xED d\u1EE5 'J4UB9MRE497YDQKKK').");
|
|
4514
|
+
} else if (/^[0-9]+$/.test(oaId)) {
|
|
4515
|
+
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).");
|
|
4516
|
+
}
|
|
4517
|
+
const type = Number(raw.type);
|
|
4518
|
+
if (![1, 5].includes(type)) {
|
|
4519
|
+
errors.push("Tr\u01B0\u1EDDng 'type' ph\u1EA3i l\xE0 1 (ZALOFORM) ho\u1EB7c 5 (COMMERCE).");
|
|
4520
|
+
}
|
|
4521
|
+
const limit = typeof raw.limit === "number" && raw.limit > 0 ? Math.floor(raw.limit) : 20;
|
|
4522
|
+
const offset = typeof raw.offset === "number" && raw.offset >= 0 ? Math.floor(raw.offset) : 0;
|
|
4523
|
+
const status = typeof raw.status === "string" && raw.status.trim() !== "" ? raw.status.trim() : "2,6,1,0,7,4,5,3";
|
|
4524
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
4525
|
+
const fromTime = typeof raw.fromTime === "number" && raw.fromTime >= 0 ? Math.floor(raw.fromTime) : now - 90 * 86400;
|
|
4526
|
+
const toTime = typeof raw.toTime === "number" && raw.toTime >= 0 ? Math.floor(raw.toTime) : now;
|
|
4527
|
+
if (toTime < fromTime) {
|
|
4528
|
+
errors.push("M\u1ED1c th\u1EDDi gian k\u1EBFt th\xFAc 'toTime' ph\u1EA3i l\u1EDBn h\u01A1n ho\u1EB7c b\u1EB1ng 'fromTime'.");
|
|
4529
|
+
}
|
|
4530
|
+
return {
|
|
4531
|
+
isValid: errors.length === 0,
|
|
4532
|
+
errors,
|
|
4533
|
+
data: errors.length === 0 ? {
|
|
4534
|
+
oaId,
|
|
4535
|
+
type,
|
|
4536
|
+
limit,
|
|
4537
|
+
offset,
|
|
4538
|
+
status,
|
|
4539
|
+
fromTime,
|
|
4540
|
+
toTime,
|
|
4541
|
+
formIds: raw.formIds ? String(raw.formIds).trim() : void 0,
|
|
4542
|
+
keyword: raw.keyword ? String(raw.keyword).trim() : void 0,
|
|
4543
|
+
reason: raw.reason ? String(raw.reason).trim() : void 0,
|
|
4544
|
+
labelIds: raw.labelIds ? String(raw.labelIds).trim() : void 0,
|
|
4545
|
+
isCommerce: raw.isCommerce !== void 0 ? Boolean(raw.isCommerce) : false
|
|
4546
|
+
} : void 0
|
|
4547
|
+
};
|
|
4548
|
+
}
|
|
4549
|
+
var ZaloFormsValidator = {
|
|
4550
|
+
createForm: validateCreateFormRequest,
|
|
4551
|
+
listFormsByOfficialAccount: validateListFormsByOfficialAccountRequest,
|
|
4552
|
+
listFormLeads: validateListFormLeadsRequest
|
|
4553
|
+
};
|
|
4554
|
+
|
|
3592
4555
|
// src/services/forms.service.ts
|
|
4556
|
+
var OP_ZaloAdsCreateForm2 = {
|
|
4557
|
+
operationId: "zalo_ads_create_form",
|
|
4558
|
+
method: "POST",
|
|
4559
|
+
endpoint: "/api/form/create",
|
|
4560
|
+
baseUrl: "https://ads.zalo.me",
|
|
4561
|
+
binaryFields: [],
|
|
4562
|
+
pathFields: [],
|
|
4563
|
+
queryFields: [],
|
|
4564
|
+
headerFields: [],
|
|
4565
|
+
cookieFields: [],
|
|
4566
|
+
bodyFields: ["data"]
|
|
4567
|
+
};
|
|
4568
|
+
var OP_ZaloAdsListFormsByOfficialAccount2 = {
|
|
4569
|
+
operationId: "zalo_ads_list_forms_by_official_account",
|
|
4570
|
+
method: "GET",
|
|
4571
|
+
endpoint: "/api/form/getByOaId",
|
|
4572
|
+
baseUrl: "https://ads.zalo.me",
|
|
4573
|
+
binaryFields: [],
|
|
4574
|
+
pathFields: [],
|
|
4575
|
+
queryFields: ["oaId", "isAll"],
|
|
4576
|
+
headerFields: [],
|
|
4577
|
+
cookieFields: [],
|
|
4578
|
+
bodyFields: []
|
|
4579
|
+
};
|
|
3593
4580
|
var OP_ZaloFormsDisableFormLeadNotification = {
|
|
3594
4581
|
"operationId": "ZaloForms_disableFormLeadNotification",
|
|
3595
4582
|
"method": "POST",
|
|
@@ -3663,7 +4650,8 @@ var OP_ZaloFormsListConversationLeads = {
|
|
|
3663
4650
|
"keyword",
|
|
3664
4651
|
"fromTime",
|
|
3665
4652
|
"labelIds",
|
|
3666
|
-
"sceneIds"
|
|
4653
|
+
"sceneIds",
|
|
4654
|
+
"reason"
|
|
3667
4655
|
],
|
|
3668
4656
|
"headerFields": [],
|
|
3669
4657
|
"cookieFields": [],
|
|
@@ -3687,7 +4675,8 @@ var OP_ZaloFormsListFormLeads = {
|
|
|
3687
4675
|
"keyword",
|
|
3688
4676
|
"fromTime",
|
|
3689
4677
|
"labelIds",
|
|
3690
|
-
"isCommerce"
|
|
4678
|
+
"isCommerce",
|
|
4679
|
+
"reason"
|
|
3691
4680
|
],
|
|
3692
4681
|
"headerFields": [],
|
|
3693
4682
|
"cookieFields": [],
|
|
@@ -3769,10 +4758,59 @@ var OP_ZaloFormsGetAuthSession = {
|
|
|
3769
4758
|
"cookieFields": [],
|
|
3770
4759
|
"bodyFields": []
|
|
3771
4760
|
};
|
|
4761
|
+
var OP_ZaloFormsTrackManageFormEvent = {
|
|
4762
|
+
operationId: "zalo_forms_track_manage_form_event",
|
|
4763
|
+
method: "GET",
|
|
4764
|
+
endpoint: "/client/manage/api/manageForm/tracking",
|
|
4765
|
+
baseUrl: "https://form.ads.zalo.me",
|
|
4766
|
+
binaryFields: [],
|
|
4767
|
+
pathFields: [],
|
|
4768
|
+
queryFields: ["eventId", "oaId", "formId"],
|
|
4769
|
+
headerFields: [],
|
|
4770
|
+
cookieFields: [],
|
|
4771
|
+
bodyFields: []
|
|
4772
|
+
};
|
|
3772
4773
|
var ZaloFormsService = class {
|
|
3773
4774
|
constructor(client) {
|
|
3774
4775
|
this.client = client;
|
|
3775
4776
|
}
|
|
4777
|
+
validator = ZaloFormsValidator;
|
|
4778
|
+
static validator = ZaloFormsValidator;
|
|
4779
|
+
/**
|
|
4780
|
+
* Tạo biểu mẫu mới gắn với Official Account (POST https://ads.zalo.me/api/form/create).
|
|
4781
|
+
* Hỗ trợ truyền thẳng Typed Payload (tự động validate qua ZaloFormsValidator và mã hóa urlencoded)
|
|
4782
|
+
* hoặc object dạng `{ data: JSON.stringify(...) }`.
|
|
4783
|
+
*/
|
|
4784
|
+
async createForm(request, options) {
|
|
4785
|
+
let payloadStr;
|
|
4786
|
+
if (typeof request.data === "string") {
|
|
4787
|
+
payloadStr = request.data;
|
|
4788
|
+
} else {
|
|
4789
|
+
const val = ZaloFormsValidator.createForm(request);
|
|
4790
|
+
if (!val.isValid || !val.data) {
|
|
4791
|
+
throw new Error(`[ZaloFormsValidator] D\u1EEF li\u1EC7u t\u1EA1o form kh\xF4ng h\u1EE3p l\u1EC7:
|
|
4792
|
+
- ${val.errors.join("\n - ")}`);
|
|
4793
|
+
}
|
|
4794
|
+
payloadStr = JSON.stringify(val.data);
|
|
4795
|
+
}
|
|
4796
|
+
return this.client.requestFormUrlEncoded(
|
|
4797
|
+
OP_ZaloAdsCreateForm2,
|
|
4798
|
+
this.client.toTransportInput(OP_ZaloAdsCreateForm2, { data: payloadStr }),
|
|
4799
|
+
options
|
|
4800
|
+
);
|
|
4801
|
+
}
|
|
4802
|
+
/**
|
|
4803
|
+
* Lấy danh sách biểu mẫu Zalo Ads theo Official Account (GET https://ads.zalo.me/api/form/getByOaId).
|
|
4804
|
+
*/
|
|
4805
|
+
listFormsByOfficialAccount(request, options) {
|
|
4806
|
+
const val = ZaloFormsValidator.listFormsByOfficialAccount(request);
|
|
4807
|
+
const cleanInput = val.isValid && val.data ? val.data : request;
|
|
4808
|
+
return this.client.requestWithoutBody(
|
|
4809
|
+
OP_ZaloAdsListFormsByOfficialAccount2,
|
|
4810
|
+
this.client.toTransportInput(OP_ZaloAdsListFormsByOfficialAccount2, cleanInput),
|
|
4811
|
+
options
|
|
4812
|
+
);
|
|
4813
|
+
}
|
|
3776
4814
|
getAuthSession(options) {
|
|
3777
4815
|
return this.client.requestWithoutBody(OP_ZaloFormsGetAuthSession, void 0, options);
|
|
3778
4816
|
}
|
|
@@ -3806,10 +4844,20 @@ var ZaloFormsService = class {
|
|
|
3806
4844
|
updateFormLeadNotificationInterval(request, options) {
|
|
3807
4845
|
return this.client.requestJson(OP_ZaloFormsUpdateFormLeadNotificationInterval, this.client.toTransportInput(OP_ZaloFormsUpdateFormLeadNotificationInterval, request), options);
|
|
3808
4846
|
}
|
|
4847
|
+
/**
|
|
4848
|
+
* Ghi nhận sự kiện tương tác trên Lead Center (GET /client/manage/api/manageForm/tracking).
|
|
4849
|
+
*/
|
|
4850
|
+
trackManageFormEvent(request, options) {
|
|
4851
|
+
return this.client.requestWithoutBody(
|
|
4852
|
+
OP_ZaloFormsTrackManageFormEvent,
|
|
4853
|
+
this.client.toTransportInput(OP_ZaloFormsTrackManageFormEvent, request),
|
|
4854
|
+
options
|
|
4855
|
+
);
|
|
4856
|
+
}
|
|
3809
4857
|
};
|
|
3810
4858
|
|
|
3811
4859
|
// src/validators/instant-pages.validator.ts
|
|
3812
|
-
function
|
|
4860
|
+
function isPositiveInteger2(val) {
|
|
3813
4861
|
if (typeof val === "number") return Number.isInteger(val) && val > 0;
|
|
3814
4862
|
if (typeof val === "string" && val.trim() !== "") {
|
|
3815
4863
|
const num = Number(val);
|
|
@@ -3817,7 +4865,7 @@ function isPositiveInteger(val) {
|
|
|
3817
4865
|
}
|
|
3818
4866
|
return false;
|
|
3819
4867
|
}
|
|
3820
|
-
function
|
|
4868
|
+
function toPositiveInteger2(val) {
|
|
3821
4869
|
return typeof val === "number" ? Math.floor(val) : parseInt(String(val), 10);
|
|
3822
4870
|
}
|
|
3823
4871
|
function validateCloneInstantPageRequest(input) {
|
|
@@ -3826,13 +4874,13 @@ function validateCloneInstantPageRequest(input) {
|
|
|
3826
4874
|
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)."] };
|
|
3827
4875
|
}
|
|
3828
4876
|
const obj = input;
|
|
3829
|
-
if (!
|
|
4877
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3830
4878
|
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).");
|
|
3831
4879
|
}
|
|
3832
4880
|
return {
|
|
3833
4881
|
isValid: errors.length === 0,
|
|
3834
4882
|
errors,
|
|
3835
|
-
data: errors.length === 0 ? { instantPageId:
|
|
4883
|
+
data: errors.length === 0 ? { instantPageId: toPositiveInteger2(obj.instantPageId) } : void 0
|
|
3836
4884
|
};
|
|
3837
4885
|
}
|
|
3838
4886
|
function validateGetInstantPageDetailRequest(input) {
|
|
@@ -3841,13 +4889,13 @@ function validateGetInstantPageDetailRequest(input) {
|
|
|
3841
4889
|
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)."] };
|
|
3842
4890
|
}
|
|
3843
4891
|
const obj = input;
|
|
3844
|
-
if (!
|
|
4892
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3845
4893
|
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).");
|
|
3846
4894
|
}
|
|
3847
4895
|
return {
|
|
3848
4896
|
isValid: errors.length === 0,
|
|
3849
4897
|
errors,
|
|
3850
|
-
data: errors.length === 0 ? { instantPageId:
|
|
4898
|
+
data: errors.length === 0 ? { instantPageId: toPositiveInteger2(obj.instantPageId) } : void 0
|
|
3851
4899
|
};
|
|
3852
4900
|
}
|
|
3853
4901
|
function validateGetInstantPageSharedUserRequest(input) {
|
|
@@ -3856,18 +4904,18 @@ function validateGetInstantPageSharedUserRequest(input) {
|
|
|
3856
4904
|
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)."] };
|
|
3857
4905
|
}
|
|
3858
4906
|
const obj = input;
|
|
3859
|
-
if (!
|
|
4907
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3860
4908
|
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).");
|
|
3861
4909
|
}
|
|
3862
|
-
if (!
|
|
4910
|
+
if (!isPositiveInteger2(obj.userId)) {
|
|
3863
4911
|
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).");
|
|
3864
4912
|
}
|
|
3865
4913
|
return {
|
|
3866
4914
|
isValid: errors.length === 0,
|
|
3867
4915
|
errors,
|
|
3868
4916
|
data: errors.length === 0 ? {
|
|
3869
|
-
instantPageId:
|
|
3870
|
-
userId:
|
|
4917
|
+
instantPageId: toPositiveInteger2(obj.instantPageId),
|
|
4918
|
+
userId: toPositiveInteger2(obj.userId)
|
|
3871
4919
|
} : void 0
|
|
3872
4920
|
};
|
|
3873
4921
|
}
|
|
@@ -3877,15 +4925,15 @@ function validateListInstantPageEditHistoryRequest(input) {
|
|
|
3877
4925
|
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)."] };
|
|
3878
4926
|
}
|
|
3879
4927
|
const obj = input;
|
|
3880
|
-
if (!
|
|
4928
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3881
4929
|
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).");
|
|
3882
4930
|
}
|
|
3883
4931
|
let limit = void 0;
|
|
3884
4932
|
if (obj.limit !== void 0 && obj.limit !== null) {
|
|
3885
|
-
if (!
|
|
4933
|
+
if (!isPositiveInteger2(obj.limit)) {
|
|
3886
4934
|
errors.push("Tr\u01B0\u1EDDng 'limit' n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn >= 1.");
|
|
3887
4935
|
} else {
|
|
3888
|
-
limit =
|
|
4936
|
+
limit = toPositiveInteger2(obj.limit);
|
|
3889
4937
|
}
|
|
3890
4938
|
}
|
|
3891
4939
|
let offset = void 0;
|
|
@@ -3901,7 +4949,7 @@ function validateListInstantPageEditHistoryRequest(input) {
|
|
|
3901
4949
|
isValid: errors.length === 0,
|
|
3902
4950
|
errors,
|
|
3903
4951
|
data: errors.length === 0 ? {
|
|
3904
|
-
instantPageId:
|
|
4952
|
+
instantPageId: toPositiveInteger2(obj.instantPageId),
|
|
3905
4953
|
...limit !== void 0 ? { limit } : {},
|
|
3906
4954
|
...offset !== void 0 ? { offset } : {}
|
|
3907
4955
|
} : void 0
|
|
@@ -3913,13 +4961,13 @@ function validateListInstantPageFormRecordsRequest(input) {
|
|
|
3913
4961
|
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)."] };
|
|
3914
4962
|
}
|
|
3915
4963
|
const obj = input;
|
|
3916
|
-
if (!
|
|
4964
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3917
4965
|
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).");
|
|
3918
4966
|
}
|
|
3919
4967
|
return {
|
|
3920
4968
|
isValid: errors.length === 0,
|
|
3921
4969
|
errors,
|
|
3922
|
-
data: errors.length === 0 ? { instantPageId:
|
|
4970
|
+
data: errors.length === 0 ? { instantPageId: toPositiveInteger2(obj.instantPageId) } : void 0
|
|
3923
4971
|
};
|
|
3924
4972
|
}
|
|
3925
4973
|
function validateListInstantPageSharesRequest(input) {
|
|
@@ -3928,13 +4976,13 @@ function validateListInstantPageSharesRequest(input) {
|
|
|
3928
4976
|
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)."] };
|
|
3929
4977
|
}
|
|
3930
4978
|
const obj = input;
|
|
3931
|
-
if (!
|
|
4979
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
3932
4980
|
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).");
|
|
3933
4981
|
}
|
|
3934
4982
|
return {
|
|
3935
4983
|
isValid: errors.length === 0,
|
|
3936
4984
|
errors,
|
|
3937
|
-
data: errors.length === 0 ? { instantPageId:
|
|
4985
|
+
data: errors.length === 0 ? { instantPageId: toPositiveInteger2(obj.instantPageId) } : void 0
|
|
3938
4986
|
};
|
|
3939
4987
|
}
|
|
3940
4988
|
function validateListInstantPageUsersRequest(input) {
|
|
@@ -3960,10 +5008,10 @@ function validateSearchInstantPagesRequest(input) {
|
|
|
3960
5008
|
const obj = input;
|
|
3961
5009
|
const data = {};
|
|
3962
5010
|
if (obj.id !== void 0 && obj.id !== null && obj.id !== "") {
|
|
3963
|
-
if (!
|
|
5011
|
+
if (!isPositiveInteger2(obj.id)) {
|
|
3964
5012
|
errors.push("B\u1ED9 l\u1ECDc 'id' n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
|
|
3965
5013
|
} else {
|
|
3966
|
-
data.id =
|
|
5014
|
+
data.id = toPositiveInteger2(obj.id);
|
|
3967
5015
|
}
|
|
3968
5016
|
}
|
|
3969
5017
|
if (obj.name !== void 0 && obj.name !== null) {
|
|
@@ -3994,10 +5042,10 @@ function validateUpdateInstantPageRequest(input) {
|
|
|
3994
5042
|
}
|
|
3995
5043
|
const obj = input;
|
|
3996
5044
|
const instantPageId = obj.instantPageId ?? obj.id;
|
|
3997
|
-
if (!
|
|
5045
|
+
if (!isPositiveInteger2(instantPageId)) {
|
|
3998
5046
|
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).");
|
|
3999
5047
|
}
|
|
4000
|
-
const numericId =
|
|
5048
|
+
const numericId = toPositiveInteger2(instantPageId);
|
|
4001
5049
|
const data = {
|
|
4002
5050
|
instantPageId: numericId,
|
|
4003
5051
|
id: numericId
|
|
@@ -4091,7 +5139,7 @@ function validateListInstantPageLeadsRequest(input) {
|
|
|
4091
5139
|
errors.push("Tr\u01B0\u1EDDng 'ids' kh\xF4ng ch\u1EE9a b\u1EA5t k\u1EF3 ID h\u1EE3p l\u1EC7 n\xE0o.");
|
|
4092
5140
|
} else {
|
|
4093
5141
|
for (const id of idParts) {
|
|
4094
|
-
if (!
|
|
5142
|
+
if (!isPositiveInteger2(id)) {
|
|
4095
5143
|
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.`);
|
|
4096
5144
|
}
|
|
4097
5145
|
}
|
|
@@ -4115,7 +5163,7 @@ function validateUpsertInstantPageFormRequest(input) {
|
|
|
4115
5163
|
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."] };
|
|
4116
5164
|
}
|
|
4117
5165
|
const obj = input;
|
|
4118
|
-
if (!
|
|
5166
|
+
if (!isPositiveInteger2(obj.instantPageId)) {
|
|
4119
5167
|
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).");
|
|
4120
5168
|
}
|
|
4121
5169
|
if (!obj.oaId || typeof obj.oaId !== "string" || !/^\d+$/.test(obj.oaId.trim())) {
|
|
@@ -4168,7 +5216,7 @@ function validateUpsertInstantPageFormRequest(input) {
|
|
|
4168
5216
|
}
|
|
4169
5217
|
}
|
|
4170
5218
|
const data = {
|
|
4171
|
-
instantPageId:
|
|
5219
|
+
instantPageId: toPositiveInteger2(obj.instantPageId),
|
|
4172
5220
|
oaId: String(obj.oaId).trim(),
|
|
4173
5221
|
formName: String(obj.formName).trim(),
|
|
4174
5222
|
questions: obj.questions ?? [],
|
|
@@ -4978,8 +6026,10 @@ var ZaloAdsCreateFlowRequest = class {
|
|
|
4978
6026
|
messages;
|
|
4979
6027
|
};
|
|
4980
6028
|
var ZaloAdsCreateFlowResponse = class {
|
|
4981
|
-
/** 0 khi tạo thành công. */
|
|
6029
|
+
/** 0 khi tạo thành công; 1 khi lỗi (ví dụ: đã tới hạn mức 20 kịch bản). */
|
|
4982
6030
|
code;
|
|
6031
|
+
/** Thông báo lỗi từ Zalo Ads khi code khác 0. */
|
|
6032
|
+
msg;
|
|
4983
6033
|
/** ID kịch bản mới, truyền vào data.ZaloFlowId khi cập nhật quảng cáo Tin nhắn. */
|
|
4984
6034
|
data;
|
|
4985
6035
|
};
|
|
@@ -5086,13 +6136,16 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
5086
6136
|
ZaloAdsUpdateVideoAdRequest,
|
|
5087
6137
|
ZaloAdsUpdateVideoAdResponse,
|
|
5088
6138
|
ZaloAudiencesService,
|
|
6139
|
+
ZaloAudiencesValidator,
|
|
5089
6140
|
ZaloAuthManager,
|
|
5090
6141
|
ZaloAutomatedRulesService,
|
|
5091
6142
|
ZaloCampaignsService,
|
|
5092
6143
|
ZaloChatWidgetService,
|
|
5093
6144
|
ZaloConversionsService,
|
|
5094
6145
|
ZaloFlowsService,
|
|
6146
|
+
ZaloFlowsValidator,
|
|
5095
6147
|
ZaloFormsService,
|
|
6148
|
+
ZaloFormsValidator,
|
|
5096
6149
|
ZaloInstantPageBlockType,
|
|
5097
6150
|
ZaloInstantPagesService,
|
|
5098
6151
|
ZaloInstantPagesValidator,
|
|
@@ -5109,8 +6162,20 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
5109
6162
|
deriveAccountKeyFromZpsid,
|
|
5110
6163
|
parseZaloCookieInput,
|
|
5111
6164
|
validateCloneInstantPageRequest,
|
|
6165
|
+
validateCreateFlowRequest,
|
|
6166
|
+
validateCreateFormEventAudienceRequest,
|
|
6167
|
+
validateCreateFormRequest,
|
|
6168
|
+
validateCreateLookalikeAudienceRequest,
|
|
6169
|
+
validateCreateMessageOaEventAudienceRequest,
|
|
6170
|
+
validateCreateMessagePersonalEventAudienceRequest,
|
|
6171
|
+
validateCreatePhoneAudienceRequest,
|
|
6172
|
+
validateCreateSavedAudienceRequest,
|
|
6173
|
+
validateEstimateAudienceRequest,
|
|
5112
6174
|
validateGetInstantPageDetailRequest,
|
|
5113
6175
|
validateGetInstantPageSharedUserRequest,
|
|
6176
|
+
validateListFlowsByOfficialAccountRequest,
|
|
6177
|
+
validateListFormLeadsRequest,
|
|
6178
|
+
validateListFormsByOfficialAccountRequest,
|
|
5114
6179
|
validateListInstantPageEditHistoryRequest,
|
|
5115
6180
|
validateListInstantPageFormRecordsRequest,
|
|
5116
6181
|
validateListInstantPageLeadsRequest,
|
|
@@ -5119,6 +6184,7 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
5119
6184
|
validateListMiniPageTemplatesRequest,
|
|
5120
6185
|
validateListOfficialAccountsRequest,
|
|
5121
6186
|
validateSearchInstantPagesRequest,
|
|
6187
|
+
validateUpdateFlowRequest,
|
|
5122
6188
|
validateUpdateInstantPageRequest,
|
|
5123
6189
|
validateUpsertInstantPageFormRequest
|
|
5124
6190
|
});
|