@redonvn/zalo-ads-sdk 0.2.7 → 0.2.14
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 +881 -26
- package/dist/index.d.ts +881 -26
- package/dist/index.js +2486 -1085
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2447 -1085
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30,39 +30,72 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ALLOWED_CTAS_PER_AD_TYPE: () => ALLOWED_CTAS_PER_AD_TYPE,
|
|
33
34
|
ALL_ZALO_ADS_DOMAINS: () => ALL_ZALO_ADS_DOMAINS,
|
|
35
|
+
AutomatedRuleActionTypeEnum: () => AutomatedRuleActionTypeEnum,
|
|
36
|
+
AutomatedRuleConditionFieldEnum: () => AutomatedRuleConditionFieldEnum,
|
|
37
|
+
AutomatedRuleFrequencyEnum: () => AutomatedRuleFrequencyEnum,
|
|
38
|
+
AutomatedRuleOperatorEnum: () => AutomatedRuleOperatorEnum,
|
|
39
|
+
AutomatedRuleScopeEnum: () => AutomatedRuleScopeEnum,
|
|
40
|
+
AutomatedRuleTimeRangeEnum: () => AutomatedRuleTimeRangeEnum,
|
|
41
|
+
ConversionLabelEnum: () => ConversionLabelEnum,
|
|
42
|
+
ConversionUrlTypeEnum: () => ConversionUrlTypeEnum,
|
|
34
43
|
MemoryZaloSessionStore: () => MemoryZaloSessionStore,
|
|
35
44
|
RedisZaloSessionStore: () => RedisZaloSessionStore,
|
|
36
45
|
TieredZaloSessionStore: () => TieredZaloSessionStore,
|
|
46
|
+
VALID_AD_TYPES: () => VALID_AD_TYPES,
|
|
47
|
+
VALID_CAMPAIGN_TYPES: () => VALID_CAMPAIGN_TYPES,
|
|
48
|
+
ZALO_NEW_REGION_PROVINCE_CODES: () => ZALO_NEW_REGION_PROVINCE_CODES,
|
|
49
|
+
ZALO_PROVINCE_MERGE_MAPPING: () => ZALO_PROVINCE_MERGE_MAPPING,
|
|
50
|
+
ZALO_REGION_PROVINCE_CODES: () => ZALO_REGION_PROVINCE_CODES,
|
|
37
51
|
ZaloAccountService: () => ZaloAccountService,
|
|
38
52
|
ZaloAdsAccountPool: () => ZaloAdsIntegrationManager,
|
|
53
|
+
ZaloAdsActionType: () => ZaloAdsActionType,
|
|
54
|
+
ZaloAdsAgeRangeId: () => ZaloAdsAgeRangeId,
|
|
55
|
+
ZaloAdsBudgetScheduleType: () => ZaloAdsBudgetScheduleType,
|
|
56
|
+
ZaloAdsCampaignStatus: () => ZaloAdsCampaignStatus,
|
|
39
57
|
ZaloAdsCreateFlowRequest: () => ZaloAdsCreateFlowRequest,
|
|
40
58
|
ZaloAdsCreateFlowResponse: () => ZaloAdsCreateFlowResponse,
|
|
41
59
|
ZaloAdsCreatePostCampaignRequest: () => ZaloAdsCreatePostCampaignRequest,
|
|
42
60
|
ZaloAdsCreatePostCampaignResponse: () => ZaloAdsCreatePostCampaignResponse,
|
|
61
|
+
ZaloAdsDeliveryType: () => ZaloAdsDeliveryType,
|
|
43
62
|
ZaloAdsFlowButtonDto: () => ZaloAdsFlowButtonDto,
|
|
44
63
|
ZaloAdsFlowChildMessageDto: () => ZaloAdsFlowChildMessageDto,
|
|
45
64
|
ZaloAdsFlowMessageDto: () => ZaloAdsFlowMessageDto,
|
|
65
|
+
ZaloAdsImageRatio: () => ZaloAdsImageRatio,
|
|
46
66
|
ZaloAdsIntegrationManager: () => ZaloAdsIntegrationManager,
|
|
47
67
|
ZaloAdsMessageAdUpdateDataDto: () => ZaloAdsMessageAdUpdateDataDto,
|
|
68
|
+
ZaloAdsOsId: () => ZaloAdsOsId,
|
|
69
|
+
ZaloAdsPriceLimitType: () => ZaloAdsPriceLimitType,
|
|
70
|
+
ZaloAdsPriceType: () => ZaloAdsPriceType,
|
|
71
|
+
ZaloAdsProvinceCode: () => ZaloAdsProvinceCode,
|
|
72
|
+
ZaloAdsRegionId: () => ZaloAdsRegionId,
|
|
48
73
|
ZaloAdsSdk: () => ZaloAdsSdk,
|
|
49
74
|
ZaloAdsService: () => ZaloAdsService,
|
|
75
|
+
ZaloAdsSpendingMethod: () => ZaloAdsSpendingMethod,
|
|
50
76
|
ZaloAdsUpdateMessageAdRequest: () => ZaloAdsUpdateMessageAdRequest,
|
|
51
77
|
ZaloAdsUpdateMessageAdResponse: () => ZaloAdsUpdateMessageAdResponse,
|
|
52
78
|
ZaloAdsUpdateVideoAdRequest: () => ZaloAdsUpdateVideoAdRequest,
|
|
53
79
|
ZaloAdsUpdateVideoAdResponse: () => ZaloAdsUpdateVideoAdResponse,
|
|
80
|
+
ZaloAdsUseConversion: () => ZaloAdsUseConversion,
|
|
81
|
+
ZaloAdsVideoSrc: () => ZaloAdsVideoSrc,
|
|
82
|
+
ZaloAdsXTemplates: () => ZaloAdsXTemplates,
|
|
54
83
|
ZaloAudiencesService: () => ZaloAudiencesService,
|
|
55
84
|
ZaloAudiencesValidator: () => ZaloAudiencesValidator,
|
|
56
85
|
ZaloAuthManager: () => ZaloAuthManager,
|
|
57
86
|
ZaloAutomatedRulesService: () => ZaloAutomatedRulesService,
|
|
87
|
+
ZaloAutomatedRulesValidator: () => ZaloAutomatedRulesValidator,
|
|
58
88
|
ZaloCampaignsService: () => ZaloCampaignsService,
|
|
89
|
+
ZaloCampaignsValidator: () => ZaloCampaignsValidator,
|
|
59
90
|
ZaloChatWidgetService: () => ZaloChatWidgetService,
|
|
60
91
|
ZaloConversionsService: () => ZaloConversionsService,
|
|
92
|
+
ZaloConversionsValidator: () => ZaloConversionsValidator,
|
|
61
93
|
ZaloFlowsService: () => ZaloFlowsService,
|
|
62
94
|
ZaloFlowsValidator: () => ZaloFlowsValidator,
|
|
63
95
|
ZaloFormsService: () => ZaloFormsService,
|
|
64
96
|
ZaloFormsValidator: () => ZaloFormsValidator,
|
|
65
97
|
ZaloInstantPageBlockType: () => ZaloInstantPageBlockType,
|
|
98
|
+
ZaloInstantPageSharePermission: () => ZaloInstantPageSharePermission,
|
|
66
99
|
ZaloInstantPagesService: () => ZaloInstantPagesService,
|
|
67
100
|
ZaloInstantPagesValidator: () => ZaloInstantPagesValidator,
|
|
68
101
|
ZaloMediaService: () => ZaloMediaService,
|
|
@@ -78,15 +111,19 @@ __export(index_exports, {
|
|
|
78
111
|
defaultSharedMemorySessionStore: () => defaultSharedMemorySessionStore,
|
|
79
112
|
deriveAccountKeyFromZpsid: () => deriveAccountKeyFromZpsid,
|
|
80
113
|
parseZaloCookieInput: () => parseZaloCookieInput,
|
|
114
|
+
validateChangeCampaignStatusParams: () => validateChangeCampaignStatusParams,
|
|
81
115
|
validateCloneInstantPageRequest: () => validateCloneInstantPageRequest,
|
|
116
|
+
validateCreateCampaignPayload: () => validateCreateCampaignPayload,
|
|
82
117
|
validateCreateFlowRequest: () => validateCreateFlowRequest,
|
|
83
118
|
validateCreateFormEventAudienceRequest: () => validateCreateFormEventAudienceRequest,
|
|
84
119
|
validateCreateFormRequest: () => validateCreateFormRequest,
|
|
120
|
+
validateCreateInstantPageRequest: () => validateCreateInstantPageRequest,
|
|
85
121
|
validateCreateLookalikeAudienceRequest: () => validateCreateLookalikeAudienceRequest,
|
|
86
122
|
validateCreateMessageOaEventAudienceRequest: () => validateCreateMessageOaEventAudienceRequest,
|
|
87
123
|
validateCreateMessagePersonalEventAudienceRequest: () => validateCreateMessagePersonalEventAudienceRequest,
|
|
88
124
|
validateCreatePhoneAudienceRequest: () => validateCreatePhoneAudienceRequest,
|
|
89
125
|
validateCreateSavedAudienceRequest: () => validateCreateSavedAudienceRequest,
|
|
126
|
+
validateDuplicateAdParams: () => validateDuplicateAdParams,
|
|
90
127
|
validateEstimateAudienceRequest: () => validateEstimateAudienceRequest,
|
|
91
128
|
validateGetInstantPageDetailRequest: () => validateGetInstantPageDetailRequest,
|
|
92
129
|
validateGetInstantPageSharedUserRequest: () => validateGetInstantPageSharedUserRequest,
|
|
@@ -100,7 +137,9 @@ __export(index_exports, {
|
|
|
100
137
|
validateListInstantPageUsersRequest: () => validateListInstantPageUsersRequest,
|
|
101
138
|
validateListMiniPageTemplatesRequest: () => validateListMiniPageTemplatesRequest,
|
|
102
139
|
validateListOfficialAccountsRequest: () => validateListOfficialAccountsRequest,
|
|
140
|
+
validateRenameCampaignParams: () => validateRenameCampaignParams,
|
|
103
141
|
validateSearchInstantPagesRequest: () => validateSearchInstantPagesRequest,
|
|
142
|
+
validateUpdateAdPayload: () => validateUpdateAdPayload,
|
|
104
143
|
validateUpdateFlowRequest: () => validateUpdateFlowRequest,
|
|
105
144
|
validateUpdateInstantPageRequest: () => validateUpdateInstantPageRequest,
|
|
106
145
|
validateUpsertInstantPageFormRequest: () => validateUpsertInstantPageFormRequest
|
|
@@ -727,7 +766,10 @@ var ZaloAuthManager = class {
|
|
|
727
766
|
let adsProfile;
|
|
728
767
|
let formProfile;
|
|
729
768
|
if (domain === "ads.zalo.me") {
|
|
730
|
-
|
|
769
|
+
const explicitPlaySession = this.extraCookies?.PLAY_SESSION || cookies["PLAY_SESSION"];
|
|
770
|
+
if (!explicitPlaySession) {
|
|
771
|
+
await this.followOAuthRedirects("https://ads.zalo.me/api/login", cookies, true);
|
|
772
|
+
}
|
|
731
773
|
const whoamiRes = await this.fetchImpl("https://ads.zalo.me/api/whoami", {
|
|
732
774
|
method: "GET",
|
|
733
775
|
headers: {
|
|
@@ -737,12 +779,17 @@ var ZaloAuthManager = class {
|
|
|
737
779
|
}
|
|
738
780
|
});
|
|
739
781
|
this.mergeSetCookies(whoamiRes, cookies);
|
|
782
|
+
if (explicitPlaySession) {
|
|
783
|
+
cookies["PLAY_SESSION"] = explicitPlaySession;
|
|
784
|
+
}
|
|
740
785
|
const whoamiJson = await whoamiRes.json().catch(() => null);
|
|
741
786
|
if (whoamiJson?.data) {
|
|
742
787
|
adsProfile = whoamiJson.data;
|
|
743
788
|
if (adsProfile.id) {
|
|
744
789
|
cookies["ads_user_id"] = String(adsProfile.id);
|
|
745
790
|
}
|
|
791
|
+
} else if (this.extraCookies?.ads_user_id) {
|
|
792
|
+
cookies["ads_user_id"] = this.extraCookies.ads_user_id;
|
|
746
793
|
}
|
|
747
794
|
} else if (domain === "page.ads.zalo.me") {
|
|
748
795
|
await this.followOAuthRedirects("https://page.ads.zalo.me/api/login", cookies, false);
|
|
@@ -1031,7 +1078,8 @@ var ZaloSdkHttpClient = class {
|
|
|
1031
1078
|
const body = asRecord(input.body);
|
|
1032
1079
|
if (bodyType === "json") {
|
|
1033
1080
|
headers.set("content-type", headers.get("content-type") ?? "application/json");
|
|
1034
|
-
|
|
1081
|
+
const jsonPayload = input.body !== void 0 ? input.body : body;
|
|
1082
|
+
init.body = JSON.stringify(jsonPayload);
|
|
1035
1083
|
} else if (bodyType === "urlencoded") {
|
|
1036
1084
|
headers.set("content-type", headers.get("content-type") ?? "application/x-www-form-urlencoded;charset=UTF-8");
|
|
1037
1085
|
const encoded = new URLSearchParams();
|
|
@@ -1147,291 +1195,1402 @@ async function resolveCookies(auth, context) {
|
|
|
1147
1195
|
return { ...auth?.cookies ?? {}, ...await auth?.getCookies?.(context) ?? {} };
|
|
1148
1196
|
}
|
|
1149
1197
|
|
|
1150
|
-
// src/
|
|
1151
|
-
var
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
"
|
|
1175
|
-
"
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
"endpoint": "/zaapi/addNewCamp",
|
|
1182
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1183
|
-
"binaryFields": [],
|
|
1184
|
-
"pathFields": [],
|
|
1185
|
-
"queryFields": [],
|
|
1186
|
-
"headerFields": [],
|
|
1187
|
-
"cookieFields": [],
|
|
1188
|
-
"bodyFields": [
|
|
1189
|
-
"data"
|
|
1190
|
-
]
|
|
1191
|
-
};
|
|
1192
|
-
var OP_ZaloAdsCreateForm = {
|
|
1193
|
-
"operationId": "ZaloAds_createForm",
|
|
1194
|
-
"method": "POST",
|
|
1195
|
-
"endpoint": "/api/form/create",
|
|
1196
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1197
|
-
"binaryFields": [],
|
|
1198
|
-
"pathFields": [],
|
|
1199
|
-
"queryFields": [],
|
|
1200
|
-
"headerFields": [],
|
|
1201
|
-
"cookieFields": [],
|
|
1202
|
-
"bodyFields": [
|
|
1203
|
-
"data"
|
|
1204
|
-
]
|
|
1205
|
-
};
|
|
1206
|
-
var OP_ZaloAdsCreateFormCampaign = {
|
|
1207
|
-
"operationId": "ZaloAds_createFormCampaign",
|
|
1208
|
-
"method": "POST",
|
|
1209
|
-
"endpoint": "/zaapi/addNewCamp",
|
|
1210
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1211
|
-
"binaryFields": [],
|
|
1212
|
-
"pathFields": [],
|
|
1213
|
-
"queryFields": [],
|
|
1214
|
-
"headerFields": [],
|
|
1215
|
-
"cookieFields": [],
|
|
1216
|
-
"bodyFields": [
|
|
1217
|
-
"data"
|
|
1218
|
-
]
|
|
1219
|
-
};
|
|
1220
|
-
var OP_ZaloAdsCreateMessageCampaign = {
|
|
1221
|
-
"operationId": "ZaloAds_createMessageCampaign",
|
|
1222
|
-
"method": "POST",
|
|
1223
|
-
"endpoint": "/zaapi/addNewCamp",
|
|
1224
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1225
|
-
"binaryFields": [],
|
|
1226
|
-
"pathFields": [],
|
|
1227
|
-
"queryFields": [],
|
|
1228
|
-
"headerFields": [],
|
|
1229
|
-
"cookieFields": [],
|
|
1230
|
-
"bodyFields": [
|
|
1231
|
-
"data"
|
|
1232
|
-
]
|
|
1233
|
-
};
|
|
1234
|
-
var OP_ZaloAdsCreateOfficialAccountCampaign = {
|
|
1235
|
-
"operationId": "ZaloAds_createOfficialAccountCampaign",
|
|
1236
|
-
"method": "POST",
|
|
1237
|
-
"endpoint": "/zaapi/addNewCamp",
|
|
1238
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1239
|
-
"binaryFields": [],
|
|
1240
|
-
"pathFields": [],
|
|
1241
|
-
"queryFields": [],
|
|
1242
|
-
"headerFields": [],
|
|
1243
|
-
"cookieFields": [],
|
|
1244
|
-
"bodyFields": [
|
|
1245
|
-
"data"
|
|
1246
|
-
]
|
|
1247
|
-
};
|
|
1248
|
-
var OP_ZaloAdsCreatePostCampaign = {
|
|
1249
|
-
"operationId": "ZaloAds_createPostCampaign",
|
|
1250
|
-
"method": "POST",
|
|
1251
|
-
"endpoint": "/zaapi/addNewCamp",
|
|
1252
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1253
|
-
"binaryFields": [],
|
|
1254
|
-
"pathFields": [],
|
|
1255
|
-
"queryFields": [],
|
|
1256
|
-
"headerFields": [],
|
|
1257
|
-
"cookieFields": [],
|
|
1258
|
-
"bodyFields": [
|
|
1259
|
-
"data"
|
|
1260
|
-
]
|
|
1261
|
-
};
|
|
1262
|
-
var OP_ZaloAdsGetAdById = {
|
|
1263
|
-
"operationId": "ZaloAds_getAdById",
|
|
1264
|
-
"method": "GET",
|
|
1265
|
-
"endpoint": "/zaapi/getAdFromAdId",
|
|
1266
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1267
|
-
"binaryFields": [],
|
|
1268
|
-
"pathFields": [],
|
|
1269
|
-
"queryFields": [
|
|
1270
|
-
"adId"
|
|
1271
|
-
],
|
|
1272
|
-
"headerFields": [],
|
|
1273
|
-
"cookieFields": [],
|
|
1274
|
-
"bodyFields": []
|
|
1275
|
-
};
|
|
1276
|
-
var OP_ZaloAdsGetAdChangeLog = {
|
|
1277
|
-
"operationId": "ZaloAds_getAdChangeLog",
|
|
1278
|
-
"method": "GET",
|
|
1279
|
-
"endpoint": "/api/ad/log/{adId}",
|
|
1280
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1281
|
-
"binaryFields": [],
|
|
1282
|
-
"pathFields": [
|
|
1283
|
-
"adId"
|
|
1284
|
-
],
|
|
1285
|
-
"queryFields": [
|
|
1286
|
-
"type"
|
|
1287
|
-
],
|
|
1288
|
-
"headerFields": [],
|
|
1289
|
-
"cookieFields": [],
|
|
1290
|
-
"bodyFields": []
|
|
1291
|
-
};
|
|
1292
|
-
var OP_ZaloAdsGetApiPlaceGetalldistricts = {
|
|
1293
|
-
"operationId": "ZaloAds_getApiPlaceGetalldistricts",
|
|
1294
|
-
"method": "GET",
|
|
1295
|
-
"endpoint": "/api/place/getAllDistricts",
|
|
1296
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1297
|
-
"binaryFields": [],
|
|
1298
|
-
"pathFields": [],
|
|
1299
|
-
"queryFields": [],
|
|
1300
|
-
"headerFields": [],
|
|
1301
|
-
"cookieFields": [],
|
|
1302
|
-
"bodyFields": []
|
|
1303
|
-
};
|
|
1304
|
-
var OP_ZaloAdsGetApiSpellCheckV2 = {
|
|
1305
|
-
"operationId": "ZaloAds_getApiSpellCheckV2",
|
|
1306
|
-
"method": "GET",
|
|
1307
|
-
"endpoint": "/api/spell-check/v2",
|
|
1308
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1309
|
-
"binaryFields": [],
|
|
1310
|
-
"pathFields": [],
|
|
1311
|
-
"queryFields": [
|
|
1312
|
-
"text"
|
|
1313
|
-
],
|
|
1314
|
-
"headerFields": [],
|
|
1315
|
-
"cookieFields": [],
|
|
1316
|
-
"bodyFields": []
|
|
1317
|
-
};
|
|
1318
|
-
var OP_ZaloAdsGetZaapiCheckcamphasmanyads = {
|
|
1319
|
-
"operationId": "ZaloAds_getZaapiCheckcamphasmanyads",
|
|
1320
|
-
"method": "GET",
|
|
1321
|
-
"endpoint": "/zaapi/checkCampHasManyAds",
|
|
1322
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1323
|
-
"binaryFields": [],
|
|
1324
|
-
"pathFields": [],
|
|
1325
|
-
"queryFields": [
|
|
1326
|
-
"campaignId",
|
|
1327
|
-
"campId"
|
|
1328
|
-
],
|
|
1329
|
-
"headerFields": [],
|
|
1330
|
-
"cookieFields": [],
|
|
1331
|
-
"bodyFields": []
|
|
1332
|
-
};
|
|
1333
|
-
var OP_ZaloAdsGetZaapiGetadsfromcampaignid = {
|
|
1334
|
-
"operationId": "ZaloAds_getZaapiGetadsfromcampaignid",
|
|
1335
|
-
"method": "GET",
|
|
1336
|
-
"endpoint": "/zaapi/getAdsFromCampaignId",
|
|
1337
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1338
|
-
"binaryFields": [],
|
|
1339
|
-
"pathFields": [],
|
|
1340
|
-
"queryFields": [
|
|
1341
|
-
"campaignId",
|
|
1342
|
-
"campId"
|
|
1198
|
+
// src/validators/audiences.validator.ts
|
|
1199
|
+
var ZALO_REGION_PROVINCE_CODES = {
|
|
1200
|
+
1: [
|
|
1201
|
+
"VN58",
|
|
1202
|
+
"VN44",
|
|
1203
|
+
"VN72",
|
|
1204
|
+
"VN83",
|
|
1205
|
+
"VN50",
|
|
1206
|
+
"VN13",
|
|
1207
|
+
"VN82",
|
|
1208
|
+
"VN70",
|
|
1209
|
+
"VN53",
|
|
1210
|
+
"VN30",
|
|
1211
|
+
"VN74",
|
|
1212
|
+
"VN34",
|
|
1213
|
+
"VN52",
|
|
1214
|
+
"VN79",
|
|
1215
|
+
"VN80",
|
|
1216
|
+
"VN32",
|
|
1217
|
+
"VN71",
|
|
1218
|
+
"VN59",
|
|
1219
|
+
"VN86",
|
|
1220
|
+
"VN05",
|
|
1221
|
+
"VN85",
|
|
1222
|
+
"VN39",
|
|
1223
|
+
"VN35",
|
|
1224
|
+
"VN89",
|
|
1225
|
+
"VN81",
|
|
1226
|
+
"VN92",
|
|
1227
|
+
"VN90",
|
|
1228
|
+
"VN68"
|
|
1343
1229
|
],
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
"operationId": "ZaloAds_getZaapiGetownedarticles",
|
|
1362
|
-
"method": "GET",
|
|
1363
|
-
"endpoint": "/zaapi/getOwnedArticles",
|
|
1364
|
-
"baseUrl": "https://ads.zalo.me",
|
|
1365
|
-
"binaryFields": [],
|
|
1366
|
-
"pathFields": [],
|
|
1367
|
-
"queryFields": [
|
|
1368
|
-
"pageId"
|
|
1230
|
+
2: [
|
|
1231
|
+
"VN55",
|
|
1232
|
+
"VN88",
|
|
1233
|
+
"VN47",
|
|
1234
|
+
"VN62",
|
|
1235
|
+
"VN54",
|
|
1236
|
+
"VN61",
|
|
1237
|
+
"VN64",
|
|
1238
|
+
"VN49",
|
|
1239
|
+
"VN63",
|
|
1240
|
+
"VN46",
|
|
1241
|
+
"VN84",
|
|
1242
|
+
"VN66",
|
|
1243
|
+
"VN91",
|
|
1244
|
+
"VN60",
|
|
1245
|
+
"VN23",
|
|
1246
|
+
"VN78"
|
|
1369
1247
|
],
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1248
|
+
3: [
|
|
1249
|
+
"VN87",
|
|
1250
|
+
"VN03",
|
|
1251
|
+
"VN76",
|
|
1252
|
+
"VN43",
|
|
1253
|
+
"VN65",
|
|
1254
|
+
"VN21",
|
|
1255
|
+
"VN24",
|
|
1256
|
+
"VN75",
|
|
1257
|
+
"VN45",
|
|
1258
|
+
"VN67",
|
|
1259
|
+
"VN01",
|
|
1260
|
+
"VN73",
|
|
1261
|
+
"VN77",
|
|
1262
|
+
"VN37",
|
|
1263
|
+
"VN20",
|
|
1264
|
+
"VN09",
|
|
1265
|
+
"VN69",
|
|
1266
|
+
"VN33",
|
|
1267
|
+
"VN93"
|
|
1268
|
+
]
|
|
1385
1269
|
};
|
|
1386
|
-
var
|
|
1387
|
-
"
|
|
1388
|
-
"
|
|
1389
|
-
"
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
"
|
|
1393
|
-
"
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
"
|
|
1398
|
-
"
|
|
1399
|
-
"
|
|
1270
|
+
var ZALO_NEW_REGION_PROVINCE_CODES = {
|
|
1271
|
+
1: ["VN58", "VN44", "VN83", "VN32", "VN59", "VN13", "VN89", "VN30", "VN74", "VN34", "VN52", "VN05", "VN85", "VN39", "VN81", "VN92", "VN90", "VN68"],
|
|
1272
|
+
2: ["VN66", "VN88", "VN54", "VN64", "VN49", "VN63", "VN23", "VN78"],
|
|
1273
|
+
3: ["VN20", "VN87", "VN43", "VN33", "VN01", "VN77", "VN09", "VN69"]
|
|
1274
|
+
};
|
|
1275
|
+
var ZALO_PROVINCE_MERGE_MAPPING = {
|
|
1276
|
+
VN75: { newCode: "VN20", regionId: 3, name: "B\xECnh D\u01B0\u01A1ng (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m H\u1ED3 Ch\xED Minh VN20)" },
|
|
1277
|
+
VN45: { newCode: "VN20", regionId: 3, name: "B\xE0 R\u1ECBa - V\u0169ng T\xE0u (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m H\u1ED3 Ch\xED Minh VN20)" },
|
|
1278
|
+
VN76: { newCode: "VN43", regionId: 3, name: "B\xECnh Ph\u01B0\u1EDBc (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m \u0110\u1ED3ng Nai VN43)" },
|
|
1279
|
+
VN24: { newCode: "VN33", regionId: 3, name: "Long An (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m T\xE2y Ninh VN33)" },
|
|
1280
|
+
VN21: { newCode: "VN01", regionId: 3, name: "Ki\xEAn Giang (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m An Giang VN01)" },
|
|
1281
|
+
VN73: { newCode: "VN77", regionId: 3, name: "B\u1EA1c Li\xEAu (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m C\xE0 Mau VN77)" },
|
|
1282
|
+
VN37: { newCode: "VN09", regionId: 3, name: "Ti\u1EC1n Giang (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m \u0110\u1ED3ng Th\xE1p VN09)" },
|
|
1283
|
+
VN03: { newCode: "VN69", regionId: 3, name: "B\u1EBFn Tre (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m V\u0129nh Long VN69)" },
|
|
1284
|
+
VN67: { newCode: "VN69", regionId: 3, name: "Tr\xE0 Vinh (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m V\u0129nh Long VN69)" },
|
|
1285
|
+
VN65: { newCode: "VN87", regionId: 3, name: "S\xF3c Tr\u0103ng (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m C\u1EA7n Th\u01A1 VN87)" },
|
|
1286
|
+
VN93: { newCode: "VN87", regionId: 3, name: "H\u1EADu Giang (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m C\u1EA7n Th\u01A1 VN87)" },
|
|
1287
|
+
VN61: { newCode: "VN88", regionId: 2, name: "Ph\xFA Y\xEAn (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m \u0110\u1EAFk L\u1EAFk VN88)" },
|
|
1288
|
+
VN60: { newCode: "VN54", regionId: 2, name: "Ninh Thu\u1EADn (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Kh\xE1nh H\xF2a VN54)" },
|
|
1289
|
+
VN62: { newCode: "VN64", regionId: 2, name: "Qu\u1EA3ng B\xECnh (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Qu\u1EA3ng Tr\u1ECB VN64)" },
|
|
1290
|
+
VN46: { newCode: "VN49", regionId: 2, name: "B\xECnh \u0110\u1ECBnh (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Gia Lai VN49)" },
|
|
1291
|
+
VN55: { newCode: "VN63", regionId: 2, name: "Kon Tum (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Qu\u1EA3ng Ng\xE3i VN63)" },
|
|
1292
|
+
VN47: { newCode: "VN23", regionId: 2, name: "B\xECnh Thu\u1EADn (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m L\xE2m \u0110\u1ED3ng VN23)" },
|
|
1293
|
+
VN91: { newCode: "VN23", regionId: 2, name: "\u0110\u1EAFk N\xF4ng (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m L\xE2m \u0110\u1ED3ng VN23)" },
|
|
1294
|
+
VN84: { newCode: "VN78", regionId: 2, name: "Qu\u1EA3ng Nam (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m \u0110\xE0 N\u1EB5ng VN78)" },
|
|
1295
|
+
VN86: { newCode: "VN83", regionId: 1, name: "Ninh B\xECnh (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Ph\xFA Th\u1ECD VN83)" },
|
|
1296
|
+
VN53: { newCode: "VN83", regionId: 1, name: "B\u1EAFc K\u1EA1n (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Ph\xFA Th\u1ECD VN83)" },
|
|
1297
|
+
VN82: { newCode: "VN59", regionId: 1, name: "B\u1EAFc Giang (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Ninh B\xECnh VN59)" },
|
|
1298
|
+
VN80: { newCode: "VN59", regionId: 1, name: "Ph\xFA Th\u1ECD c\u0169 (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Ninh B\xECnh VN59)" },
|
|
1299
|
+
VN79: { newCode: "VN13", regionId: 1, name: "H\u1EA3i D\u01B0\u01A1ng (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m H\u1EA3i Ph\xF2ng VN13)" },
|
|
1300
|
+
VN71: { newCode: "VN74", regionId: 1, name: "H\u01B0ng Y\xEAn c\u0169 (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m B\u1EAFc Ninh VN74)" },
|
|
1301
|
+
VN72: { newCode: "VN85", regionId: 1, name: "Y\xEAn B\xE1i (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Th\xE1i Nguy\xEAn VN85)" },
|
|
1302
|
+
VN35: { newCode: "VN81", regionId: 1, name: "Th\xE1i B\xECnh (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m H\u01B0ng Y\xEAn VN81)" },
|
|
1303
|
+
VN70: { newCode: "VN90", regionId: 1, name: "V\u0129nh Ph\xFAc (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m L\xE0o Cai VN90)" },
|
|
1304
|
+
VN50: { newCode: "VN68", regionId: 1, name: "H\xF2a B\xECnh (\u0111\xE3 s\xE1p nh\u1EADp v\xE0o c\u1EE5m Tuy\xEAn Quang VN68)" }
|
|
1400
1305
|
};
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
"
|
|
1404
|
-
|
|
1405
|
-
|
|
1306
|
+
function validateCreateSavedAudienceRequest(input) {
|
|
1307
|
+
const errors = [];
|
|
1308
|
+
if (!input || typeof input !== "object") {
|
|
1309
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1310
|
+
}
|
|
1311
|
+
const raw = input;
|
|
1312
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
1313
|
+
if (!name) {
|
|
1314
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1315
|
+
} else if (name.length < 2 || name.length > 255) {
|
|
1316
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
1317
|
+
}
|
|
1318
|
+
let targetingObj;
|
|
1319
|
+
if (typeof raw.targeting === "string") {
|
|
1320
|
+
try {
|
|
1321
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
1322
|
+
} catch {
|
|
1323
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
1324
|
+
targetingObj = {};
|
|
1325
|
+
}
|
|
1326
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
1327
|
+
targetingObj = raw.targeting;
|
|
1328
|
+
} else {
|
|
1329
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c (chu\u1ED7i JSON ho\u1EB7c Object c\u1EA5u h\xECnh targeting).");
|
|
1330
|
+
targetingObj = {};
|
|
1331
|
+
}
|
|
1332
|
+
const gender = typeof targetingObj.Gender === "number" ? targetingObj.Gender : 0;
|
|
1333
|
+
if (![0, 1, 2].includes(gender)) {
|
|
1334
|
+
errors.push("Tr\u01B0\u1EDDng 'Gender' ph\u1EA3i l\xE0 0 (T\u1EA5t c\u1EA3), 1 (Nam), ho\u1EB7c 2 (N\u1EEF).");
|
|
1335
|
+
}
|
|
1336
|
+
const VALID_AGE_RANGES = [10282, 10283, 10284, 10285, 10286, 10287, 10288];
|
|
1337
|
+
const newAgeRanges = Array.isArray(targetingObj.NewAgeRanges) && targetingObj.NewAgeRanges.length > 0 ? targetingObj.NewAgeRanges.map(Number) : VALID_AGE_RANGES;
|
|
1338
|
+
for (const age of newAgeRanges) {
|
|
1339
|
+
if (!VALID_AGE_RANGES.includes(age)) {
|
|
1340
|
+
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(", ")}.`);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
const VALID_OS = [0, 1, 2, 3];
|
|
1344
|
+
const os = Array.isArray(targetingObj.Os) && targetingObj.Os.length > 0 ? targetingObj.Os.map(Number) : [0, 1, 3];
|
|
1345
|
+
for (const o of os) {
|
|
1346
|
+
if (!VALID_OS.includes(o)) {
|
|
1347
|
+
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).`);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
let location = targetingObj.Location;
|
|
1351
|
+
if (!location || typeof location !== "object") {
|
|
1352
|
+
location = {
|
|
1353
|
+
Addresses: [],
|
|
1354
|
+
Cities: [],
|
|
1355
|
+
DistrictTargeting: { Includes: [], Excludes: [] },
|
|
1356
|
+
WardTargeting: { Includes: [], Excludes: [] },
|
|
1357
|
+
IsConvertedToWard: false
|
|
1358
|
+
};
|
|
1359
|
+
} else {
|
|
1360
|
+
const rawWard = location.WardTargeting && typeof location.WardTargeting === "object" ? location.WardTargeting : void 0;
|
|
1361
|
+
const rawDistrict = location.DistrictTargeting && typeof location.DistrictTargeting === "object" ? location.DistrictTargeting : void 0;
|
|
1362
|
+
const baseTargeting = rawWard || rawDistrict || { Includes: [], Excludes: [] };
|
|
1363
|
+
location = {
|
|
1364
|
+
Addresses: Array.isArray(location.Addresses) ? location.Addresses : [],
|
|
1365
|
+
Cities: Array.isArray(location.Cities) ? location.Cities : [],
|
|
1366
|
+
DistrictTargeting: rawDistrict || baseTargeting,
|
|
1367
|
+
WardTargeting: rawWard || baseTargeting,
|
|
1368
|
+
IsConvertedToWard: location.IsConvertedToWard !== void 0 ? Boolean(location.IsConvertedToWard) : false
|
|
1369
|
+
};
|
|
1370
|
+
const includes = location.WardTargeting.Includes || location.DistrictTargeting.Includes;
|
|
1371
|
+
if (includes && !Array.isArray(includes)) {
|
|
1372
|
+
errors.push("Tr\u01B0\u1EDDng 'Location.WardTargeting.Includes' (ho\u1EB7c DistrictTargeting.Includes) ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng khu v\u1EF1c.");
|
|
1373
|
+
} else if (Array.isArray(includes)) {
|
|
1374
|
+
for (const inc of includes) {
|
|
1375
|
+
if (![1, 2, 3].includes(Number(inc.Id))) {
|
|
1376
|
+
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).`);
|
|
1377
|
+
}
|
|
1378
|
+
if (inc.Provinces && !Array.isArray(inc.Provinces)) {
|
|
1379
|
+
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.`);
|
|
1380
|
+
} else if (Array.isArray(inc.Provinces)) {
|
|
1381
|
+
for (const prov of inc.Provinces) {
|
|
1382
|
+
if (!prov.Id || typeof prov.Id !== "string") {
|
|
1383
|
+
errors.push(`M\xE3 t\u1EC9nh 'Id' (${JSON.stringify(prov)}) trong v\xF9ng mi\u1EC1n ${inc.Id} ph\u1EA3i l\xE0 chu\u1ED7i h\u1EE3p l\u1EC7 (v\xED d\u1EE5: 'VN44', 'VN20').`);
|
|
1384
|
+
} else {
|
|
1385
|
+
const mergeInfo = ZALO_PROVINCE_MERGE_MAPPING[prov.Id];
|
|
1386
|
+
if (mergeInfo) {
|
|
1387
|
+
errors.push(
|
|
1388
|
+
`M\xE3 t\u1EC9nh '${prov.Id}' (${mergeInfo.name}) \u0111\xE3 \u0111\u01B0\u1EE3c Zalo Ads g\u1ED9p/s\xE1p nh\u1EADp v\xE0o c\u1EE5m m\xE3 '${mergeInfo.newCode}'. Vui l\xF2ng s\u1EED d\u1EE5ng m\xE3 c\u1EE5m '${mergeInfo.newCode}' trong WardTargeting, n\u1EBFu kh\xF4ng giao di\u1EC7n Zalo Ads Web s\u1EBD b\xE1o l\u1ED7i \u0111\u1ECF 'Invalid wards params'.`
|
|
1389
|
+
);
|
|
1390
|
+
} else {
|
|
1391
|
+
const validNewRegionProvs = ZALO_NEW_REGION_PROVINCE_CODES[Number(inc.Id)] || [];
|
|
1392
|
+
if (!validNewRegionProvs.includes(prov.Id)) {
|
|
1393
|
+
const actualRegion = Object.keys(ZALO_NEW_REGION_PROVINCE_CODES).find((r) => ZALO_NEW_REGION_PROVINCE_CODES[Number(r)].includes(prov.Id));
|
|
1394
|
+
errors.push(
|
|
1395
|
+
`M\xE3 t\u1EC9nh '${prov.Id}' kh\xF4ng n\u1EB1m trong 34 C\u1EE5m T\u1EC9nh/Th\xE0nh m\u1EDBi c\u1EE7a V\xF9ng ${inc.Id} tr\xEAn Zalo Ads (s\u1EBD g\xE2y l\u1ED7i 'Invalid wards params' tr\xEAn UI). ` + (actualRegion ? `M\xE3 n\xE0y thu\u1ED9c V\xF9ng ${actualRegion}. ` : "")
|
|
1396
|
+
);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
if (prov.Districts && !Array.isArray(prov.Districts)) {
|
|
1401
|
+
errors.push(`Tr\u01B0\u1EDDng 'Districts' c\u1EE7a t\u1EC9nh ${prov.Id} ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng (ho\u1EB7c [] khi ch\u1ECDn c\u1EA3 t\u1EC9nh).`);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
const finalTargeting = {
|
|
1409
|
+
...targetingObj,
|
|
1410
|
+
CustomAudienceId: 0,
|
|
1411
|
+
Gender: gender,
|
|
1412
|
+
NewAgeRanges: newAgeRanges,
|
|
1413
|
+
Os: os,
|
|
1414
|
+
Location: location
|
|
1415
|
+
};
|
|
1416
|
+
return {
|
|
1417
|
+
isValid: errors.length === 0,
|
|
1418
|
+
errors,
|
|
1419
|
+
data: errors.length === 0 ? {
|
|
1420
|
+
name,
|
|
1421
|
+
caType: 1,
|
|
1422
|
+
targeting: JSON.stringify(finalTargeting)
|
|
1423
|
+
} : void 0
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
function validateCreatePhoneAudienceRequest(input) {
|
|
1427
|
+
const errors = [];
|
|
1428
|
+
if (!input || typeof input !== "object") {
|
|
1429
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1430
|
+
}
|
|
1431
|
+
const raw = input;
|
|
1432
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
1433
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
1434
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
1435
|
+
}
|
|
1436
|
+
let targetingObj = {};
|
|
1437
|
+
if (typeof raw.targeting === "string") {
|
|
1438
|
+
try {
|
|
1439
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
1440
|
+
} catch {
|
|
1441
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
1442
|
+
}
|
|
1443
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
1444
|
+
targetingObj = raw.targeting;
|
|
1445
|
+
} else {
|
|
1446
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1447
|
+
}
|
|
1448
|
+
const path = typeof targetingObj.Path === "string" ? targetingObj.Path.trim() : "";
|
|
1449
|
+
if (!path) {
|
|
1450
|
+
errors.push("Tr\u01B0\u1EDDng 'Path' (URL file .txt sau khi upload) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1451
|
+
}
|
|
1452
|
+
const total = typeof targetingObj.Total === "number" ? targetingObj.Total : 0;
|
|
1453
|
+
if (total <= 0) {
|
|
1454
|
+
errors.push("Tr\u01B0\u1EDDng 'Total' (s\u1ED1 l\u01B0\u1EE3ng S\u0110T trong file) ph\u1EA3i l\u1EDBn h\u01A1n 0.");
|
|
1455
|
+
}
|
|
1456
|
+
return {
|
|
1457
|
+
isValid: errors.length === 0,
|
|
1458
|
+
errors,
|
|
1459
|
+
data: errors.length === 0 ? {
|
|
1460
|
+
name,
|
|
1461
|
+
caType: 3,
|
|
1462
|
+
targeting: JSON.stringify({
|
|
1463
|
+
Name: String(targetingObj.Name || "phones.txt"),
|
|
1464
|
+
Path: path,
|
|
1465
|
+
Total: total,
|
|
1466
|
+
ZaloId: Number(targetingObj.ZaloId || 0),
|
|
1467
|
+
OriginAudience: 0
|
|
1468
|
+
})
|
|
1469
|
+
} : void 0
|
|
1470
|
+
};
|
|
1471
|
+
}
|
|
1472
|
+
function validateCreateLookalikeAudienceRequest(input) {
|
|
1473
|
+
const errors = [];
|
|
1474
|
+
if (!input || typeof input !== "object") {
|
|
1475
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1476
|
+
}
|
|
1477
|
+
const raw = input;
|
|
1478
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
1479
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
1480
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
1481
|
+
}
|
|
1482
|
+
let targetingObj = {};
|
|
1483
|
+
if (typeof raw.targeting === "string") {
|
|
1484
|
+
try {
|
|
1485
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
1486
|
+
} catch {
|
|
1487
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
1488
|
+
}
|
|
1489
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
1490
|
+
targetingObj = raw.targeting;
|
|
1491
|
+
} else {
|
|
1492
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1493
|
+
}
|
|
1494
|
+
const originAudience = Number(targetingObj.OriginAudience);
|
|
1495
|
+
if (!originAudience || originAudience <= 0) {
|
|
1496
|
+
errors.push("Tr\u01B0\u1EDDng 'OriginAudience' (ID nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng S\u0110T g\u1ED1c) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1497
|
+
}
|
|
1498
|
+
const total = Number(targetingObj.Total);
|
|
1499
|
+
if (![1e6, 15e5, 2e6].includes(total)) {
|
|
1500
|
+
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.");
|
|
1501
|
+
}
|
|
1502
|
+
return {
|
|
1503
|
+
isValid: errors.length === 0,
|
|
1504
|
+
errors,
|
|
1505
|
+
data: errors.length === 0 ? {
|
|
1506
|
+
name,
|
|
1507
|
+
caType: 6,
|
|
1508
|
+
targeting: JSON.stringify({
|
|
1509
|
+
OriginAudience: originAudience,
|
|
1510
|
+
Total: total,
|
|
1511
|
+
Name: String(targetingObj.Name || "Lookalike Audience"),
|
|
1512
|
+
Path: String(targetingObj.Path || "")
|
|
1513
|
+
})
|
|
1514
|
+
} : void 0
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
function validateCreateFormEventAudienceRequest(input) {
|
|
1518
|
+
const errors = [];
|
|
1519
|
+
if (!input || typeof input !== "object") {
|
|
1520
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1521
|
+
}
|
|
1522
|
+
const raw = input;
|
|
1523
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
1524
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
1525
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
1526
|
+
}
|
|
1527
|
+
let targetingObj = {};
|
|
1528
|
+
if (typeof raw.targeting === "string") {
|
|
1529
|
+
try {
|
|
1530
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
1531
|
+
} catch {
|
|
1532
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
1533
|
+
}
|
|
1534
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
1535
|
+
targetingObj = raw.targeting;
|
|
1536
|
+
}
|
|
1537
|
+
const eventType = Number(targetingObj.EventType);
|
|
1538
|
+
if (![1, 2, 3, 4].includes(eventType)) {
|
|
1539
|
+
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).");
|
|
1540
|
+
}
|
|
1541
|
+
const oaId = typeof targetingObj.OaId === "string" ? targetingObj.OaId.trim() : String(targetingObj.OaId || "");
|
|
1542
|
+
if (!oaId) {
|
|
1543
|
+
errors.push("Tr\u01B0\u1EDDng 'OaId' (d\u1EA1ng chu\u1ED7i c\u1EE7a pageId ho\u1EB7c noisedId) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1544
|
+
}
|
|
1545
|
+
const numDays = Number(targetingObj.NumDays);
|
|
1546
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
1547
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
1548
|
+
}
|
|
1549
|
+
const formIds = Array.isArray(targetingObj.FormIds) ? targetingObj.FormIds : [];
|
|
1550
|
+
if (formIds.length === 0) {
|
|
1551
|
+
errors.push("Tr\u01B0\u1EDDng 'FormIds' ph\u1EA3i ch\u1EE9a \xEDt nh\u1EA5t 1 ID Form.");
|
|
1552
|
+
}
|
|
1553
|
+
return {
|
|
1554
|
+
isValid: errors.length === 0,
|
|
1555
|
+
errors,
|
|
1556
|
+
data: errors.length === 0 ? {
|
|
1557
|
+
name,
|
|
1558
|
+
caType: 12,
|
|
1559
|
+
targeting: JSON.stringify({
|
|
1560
|
+
EventType: eventType,
|
|
1561
|
+
OaId: oaId,
|
|
1562
|
+
NumDays: numDays,
|
|
1563
|
+
FormIds: formIds
|
|
1564
|
+
})
|
|
1565
|
+
} : void 0
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
function validateCreateMessageOaEventAudienceRequest(input) {
|
|
1569
|
+
const errors = [];
|
|
1570
|
+
if (!input || typeof input !== "object") {
|
|
1571
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1572
|
+
}
|
|
1573
|
+
const raw = input;
|
|
1574
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
1575
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
1576
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
1577
|
+
}
|
|
1578
|
+
let targetingObj = {};
|
|
1579
|
+
if (typeof raw.targeting === "string") {
|
|
1580
|
+
try {
|
|
1581
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
1582
|
+
} catch {
|
|
1583
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
1584
|
+
}
|
|
1585
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
1586
|
+
targetingObj = raw.targeting;
|
|
1587
|
+
}
|
|
1588
|
+
const eventId = Number(targetingObj.EventId ?? targetingObj.EventType ?? 1);
|
|
1589
|
+
const oaId = typeof targetingObj.OaId === "string" ? targetingObj.OaId.trim() : String(targetingObj.OaId || "");
|
|
1590
|
+
if (!oaId) {
|
|
1591
|
+
errors.push("Tr\u01B0\u1EDDng 'OaId' (chu\u1ED7i pageId ho\u1EB7c noisedId c\u1EE7a OA) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
1592
|
+
}
|
|
1593
|
+
const numDays = Number(targetingObj.NumDays);
|
|
1594
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
1595
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
1596
|
+
}
|
|
1597
|
+
return {
|
|
1598
|
+
isValid: errors.length === 0,
|
|
1599
|
+
errors,
|
|
1600
|
+
data: errors.length === 0 ? {
|
|
1601
|
+
name,
|
|
1602
|
+
caType: 11,
|
|
1603
|
+
targeting: JSON.stringify({
|
|
1604
|
+
EventId: eventId,
|
|
1605
|
+
OaId: oaId,
|
|
1606
|
+
NumDays: numDays
|
|
1607
|
+
})
|
|
1608
|
+
} : void 0
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
function validateCreateMessagePersonalEventAudienceRequest(input) {
|
|
1612
|
+
const errors = [];
|
|
1613
|
+
if (!input || typeof input !== "object") {
|
|
1614
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1615
|
+
}
|
|
1616
|
+
const raw = input;
|
|
1617
|
+
const name = typeof raw.name === "string" ? raw.name.trim() : "";
|
|
1618
|
+
if (!name || name.length < 2 || name.length > 255) {
|
|
1619
|
+
errors.push("T\xEAn nh\xF3m \u0111\u1ED1i t\u01B0\u1EE3ng 'name' ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 255 k\xFD t\u1EF1.");
|
|
1620
|
+
}
|
|
1621
|
+
let targetingObj = {};
|
|
1622
|
+
if (typeof raw.targeting === "string") {
|
|
1623
|
+
try {
|
|
1624
|
+
targetingObj = JSON.parse(raw.targeting);
|
|
1625
|
+
} catch {
|
|
1626
|
+
errors.push("Tr\u01B0\u1EDDng 'targeting' l\xE0 chu\u1ED7i JSON kh\xF4ng h\u1EE3p l\u1EC7.");
|
|
1627
|
+
}
|
|
1628
|
+
} else if (raw.targeting && typeof raw.targeting === "object") {
|
|
1629
|
+
targetingObj = raw.targeting;
|
|
1630
|
+
}
|
|
1631
|
+
const eventId = Number(targetingObj.EventId ?? targetingObj.EventType ?? 1);
|
|
1632
|
+
if (![1, 2, 3].includes(eventId)) {
|
|
1633
|
+
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).");
|
|
1634
|
+
}
|
|
1635
|
+
const numDays = Number(targetingObj.NumDays);
|
|
1636
|
+
if (isNaN(numDays) || numDays < 1 || numDays > 90) {
|
|
1637
|
+
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
1638
|
+
}
|
|
1639
|
+
const pageIds = Array.isArray(targetingObj.PageIds) ? targetingObj.PageIds.map(String) : [];
|
|
1640
|
+
if (pageIds.length === 0) {
|
|
1641
|
+
errors.push("Tr\u01B0\u1EDDng 'PageIds' ph\u1EA3i ch\u1EE9a \xEDt nh\u1EA5t 1 ID trang c\xE1 nh\xE2n.");
|
|
1642
|
+
}
|
|
1643
|
+
return {
|
|
1644
|
+
isValid: errors.length === 0,
|
|
1645
|
+
errors,
|
|
1646
|
+
data: errors.length === 0 ? {
|
|
1647
|
+
name,
|
|
1648
|
+
caType: 14,
|
|
1649
|
+
targeting: JSON.stringify({
|
|
1650
|
+
EventId: eventId,
|
|
1651
|
+
NumDays: numDays,
|
|
1652
|
+
PageIds: pageIds
|
|
1653
|
+
})
|
|
1654
|
+
} : void 0
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
function validateEstimateAudienceRequest(input) {
|
|
1658
|
+
const errors = [];
|
|
1659
|
+
if (!input || typeof input !== "object") {
|
|
1660
|
+
return { isValid: false, errors: ["Input ph\u1EA3i l\xE0 m\u1ED9t object."], data: void 0 };
|
|
1661
|
+
}
|
|
1662
|
+
const raw = input;
|
|
1663
|
+
const gender = typeof raw.gender === "number" ? raw.gender : 0;
|
|
1664
|
+
if (![0, 1, 2].includes(gender)) {
|
|
1665
|
+
errors.push("Tr\u01B0\u1EDDng 'gender' ph\u1EA3i l\xE0 0, 1 ho\u1EB7c 2.");
|
|
1666
|
+
}
|
|
1667
|
+
const ageRanges = Array.isArray(raw.ageRanges) && raw.ageRanges.length > 0 ? raw.ageRanges.map(Number) : [10283, 10284, 10285, 10286, 10287];
|
|
1668
|
+
const platforms = Array.isArray(raw.platforms) && raw.platforms.length > 0 ? raw.platforms.map(Number) : [0, 1, 3];
|
|
1669
|
+
const priceType = typeof raw.priceType === "number" ? raw.priceType : 2;
|
|
1670
|
+
const wardsTargeting = typeof raw.wardsTargeting === "string" && raw.wardsTargeting.trim() ? raw.wardsTargeting.trim() : JSON.stringify({ Includes: [], Excludes: [] });
|
|
1671
|
+
return {
|
|
1672
|
+
isValid: errors.length === 0,
|
|
1673
|
+
errors,
|
|
1674
|
+
data: errors.length === 0 ? {
|
|
1675
|
+
gender,
|
|
1676
|
+
ageRanges,
|
|
1677
|
+
platforms,
|
|
1678
|
+
locations: typeof raw.locations === "string" ? raw.locations : "",
|
|
1679
|
+
provinces: Array.isArray(raw.provinces) ? raw.provinces.map(Number) : [],
|
|
1680
|
+
wardsTargeting,
|
|
1681
|
+
priceType,
|
|
1682
|
+
number: typeof raw.number === "string" ? raw.number : String(raw.number || "0")
|
|
1683
|
+
} : void 0
|
|
1684
|
+
};
|
|
1685
|
+
}
|
|
1686
|
+
var ZaloAudiencesValidator = {
|
|
1687
|
+
createSavedAudience: validateCreateSavedAudienceRequest,
|
|
1688
|
+
createPhoneAudience: validateCreatePhoneAudienceRequest,
|
|
1689
|
+
createLookalikeAudience: validateCreateLookalikeAudienceRequest,
|
|
1690
|
+
createFormEventAudience: validateCreateFormEventAudienceRequest,
|
|
1691
|
+
createMessageOaEventAudience: validateCreateMessageOaEventAudienceRequest,
|
|
1692
|
+
createMessagePersonalEventAudience: validateCreateMessagePersonalEventAudienceRequest,
|
|
1693
|
+
estimateAudience: validateEstimateAudienceRequest
|
|
1694
|
+
};
|
|
1695
|
+
|
|
1696
|
+
// src/dtos/ads.dto.ts
|
|
1697
|
+
var ZaloAdsFlowChildMessageDto = class {
|
|
1698
|
+
/** Mẫu Zalo đã xác minh dùng 8 cho tin nhắn văn bản trong nhánh. */
|
|
1699
|
+
type;
|
|
1700
|
+
/** Nội dung phản hồi trong nhánh. */
|
|
1701
|
+
text;
|
|
1702
|
+
};
|
|
1703
|
+
var ZaloAdsFlowButtonDto = class {
|
|
1704
|
+
/** 3 = Gửi tin nhắn vào nhánh hội thoại; 10 = Mở website; 12 = Thực hiện cuộc gọi. */
|
|
1705
|
+
type;
|
|
1706
|
+
/** Nhãn nút hiển thị cho người dùng. */
|
|
1707
|
+
text;
|
|
1708
|
+
/** URL website; bắt buộc với type 10. */
|
|
1709
|
+
url;
|
|
1710
|
+
/** Cờ của nút website; dùng true với type 10. */
|
|
1711
|
+
editable;
|
|
1712
|
+
/** Số hotline, bắt buộc khi type là 12. */
|
|
1713
|
+
phone;
|
|
1714
|
+
/** Nhánh tin nhắn, bắt buộc khi type là 3. Với type 10 hoặc 12, để null hoặc bỏ qua. */
|
|
1715
|
+
messages;
|
|
1716
|
+
};
|
|
1717
|
+
var ZaloAdsFlowMessageDto = class {
|
|
1718
|
+
/** 1 = Tin nhắn văn bản; 2 = Tin nhắn kèm hình ảnh. */
|
|
1719
|
+
type;
|
|
1720
|
+
/** Nội dung tin nhắn, tối đa 1961 ký tự. Hỗ trợ biến: {{user_name}}, {{page_name}}, {{user_gender}}, {{user_id}}, {{page_id}}, {{date}}, {{datetime}}. */
|
|
1721
|
+
text;
|
|
1722
|
+
/** URL media hoặc null với tin nhắn văn bản thuần. Bắt buộc và không được null khi type = 2. */
|
|
1723
|
+
url;
|
|
1724
|
+
/** Các nút đi kèm tin nhắn. */
|
|
1725
|
+
buttons;
|
|
1726
|
+
};
|
|
1727
|
+
var ZaloAdsCreateFlowRequest = class {
|
|
1728
|
+
/** ID Official Account sở hữu kịch bản. */
|
|
1729
|
+
oaId;
|
|
1730
|
+
/** Luôn null khi tạo kịch bản mới. */
|
|
1731
|
+
id;
|
|
1732
|
+
/** Tên kịch bản, tối đa 33 ký tự theo giao diện Zalo Ads. */
|
|
1733
|
+
name;
|
|
1734
|
+
/** Các tin nhắn được gửi theo thứ tự trong kịch bản. */
|
|
1735
|
+
messages;
|
|
1736
|
+
};
|
|
1737
|
+
var ZaloAdsCreateFlowResponse = class {
|
|
1738
|
+
/** 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). */
|
|
1739
|
+
code;
|
|
1740
|
+
/** Thông báo lỗi từ Zalo Ads khi code khác 0. */
|
|
1741
|
+
msg;
|
|
1742
|
+
/** 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. */
|
|
1743
|
+
data;
|
|
1744
|
+
};
|
|
1745
|
+
var ZaloAdsActionType = {
|
|
1746
|
+
DAT_NGAY: 1,
|
|
1747
|
+
MUA_NGAY: 2,
|
|
1748
|
+
THU_NGAY: 3,
|
|
1749
|
+
TAI_NGAY: 4,
|
|
1750
|
+
XEM_THEM: 5,
|
|
1751
|
+
NGHE_NGAY: 6,
|
|
1752
|
+
CHOI_NGAY: 7,
|
|
1753
|
+
DANG_KY: 8,
|
|
1754
|
+
GOI_DIEN: 9,
|
|
1755
|
+
/** Dành riêng cho Quảng cáo Official Account (Type 2) */
|
|
1756
|
+
QUAN_TAM_OA: 6
|
|
1757
|
+
};
|
|
1758
|
+
var ZaloAdsVideoSrc = {
|
|
1759
|
+
UNUSED: -1,
|
|
1760
|
+
/** Sử dụng mã Zalo Video được cấp từ kênh */
|
|
1761
|
+
VIDEO_CODE: 1,
|
|
1762
|
+
/** Tự tải video lên hoặc chọn từ Thư viện Media */
|
|
1763
|
+
SELF_UPLOAD: 2
|
|
1764
|
+
};
|
|
1765
|
+
var ZaloAdsBudgetScheduleType = {
|
|
1766
|
+
/** Toàn lịch chạy */
|
|
1767
|
+
TOTAL_SCHEDULE: 1,
|
|
1768
|
+
/** Mỗi ngày */
|
|
1769
|
+
DAILY: 2
|
|
1770
|
+
};
|
|
1771
|
+
var ZaloAdsAgeRangeId = {
|
|
1772
|
+
UNDER_18: 10282,
|
|
1773
|
+
FROM_18_TO_24: 10283,
|
|
1774
|
+
FROM_25_TO_34: 10284,
|
|
1775
|
+
FROM_35_TO_44: 10285,
|
|
1776
|
+
FROM_45_TO_54: 10286,
|
|
1777
|
+
FROM_55_TO_64: 10287,
|
|
1778
|
+
OVER_64: 10288
|
|
1779
|
+
};
|
|
1780
|
+
var ZaloAdsOsId = {
|
|
1781
|
+
ANDROID: 0,
|
|
1782
|
+
IOS: 1,
|
|
1783
|
+
PC: 3
|
|
1784
|
+
};
|
|
1785
|
+
var ZaloAdsRegionId = {
|
|
1786
|
+
/** Miền Bắc (28 tỉnh/thành phố) */
|
|
1787
|
+
NORTH: 1,
|
|
1788
|
+
/** Miền Trung (16 tỉnh/thành phố) */
|
|
1789
|
+
CENTRAL: 2,
|
|
1790
|
+
/** Miền Nam (19 tỉnh/thành phố) */
|
|
1791
|
+
SOUTH: 3
|
|
1792
|
+
};
|
|
1793
|
+
var ZaloAdsProvinceCode = {
|
|
1794
|
+
// Miền Bắc (Region 1 - 28 tỉnh/thành)
|
|
1795
|
+
HANOI: "VN44",
|
|
1796
|
+
HAI_PHONG: "VN13",
|
|
1797
|
+
BAC_NINH: "VN74",
|
|
1798
|
+
QUANG_NINH: "VN30",
|
|
1799
|
+
HAI_DUONG: "VN79",
|
|
1800
|
+
HUNG_YEN: "VN81",
|
|
1801
|
+
VINH_PHUC: "VN86",
|
|
1802
|
+
THAI_NGUYEN: "VN85",
|
|
1803
|
+
BAC_GIANG: "VN71",
|
|
1804
|
+
PHU_THO: "VN83",
|
|
1805
|
+
NAM_DINH: "VN82",
|
|
1806
|
+
THAI_BINH: "VN35",
|
|
1807
|
+
NINH_BINH: "VN59",
|
|
1808
|
+
THANH_HOA: "VN34",
|
|
1809
|
+
NGHE_AN: "VN58",
|
|
1810
|
+
HA_TINH: "VN52",
|
|
1811
|
+
HOA_BINH: "VN53",
|
|
1812
|
+
SON_LA: "VN32",
|
|
1813
|
+
DIEN_BIEN: "VN92",
|
|
1814
|
+
LAI_CHAU: "VN89",
|
|
1815
|
+
LAO_CAI: "VN90",
|
|
1816
|
+
YEN_BAI: "VN70",
|
|
1817
|
+
TUYEN_QUANG: "VN68",
|
|
1818
|
+
HA_GIANG: "VN50",
|
|
1819
|
+
CAO_BANG: "VN05",
|
|
1820
|
+
BAC_KAN: "VN72",
|
|
1821
|
+
LANG_SON: "VN39",
|
|
1822
|
+
HA_NAM: "VN80",
|
|
1823
|
+
// Miền Trung (Region 2 - 16 tỉnh/thành)
|
|
1824
|
+
DA_NANG: "VN78",
|
|
1825
|
+
THUA_THIEN_HUE: "VN66",
|
|
1826
|
+
QUANG_NAM: "VN84",
|
|
1827
|
+
QUANG_NGAI: "VN63",
|
|
1828
|
+
BINH_DINH: "VN46",
|
|
1829
|
+
PHU_YEN: "VN61",
|
|
1830
|
+
KHANH_HOA: "VN54",
|
|
1831
|
+
NINH_THUAN: "VN60",
|
|
1832
|
+
BINH_THUAN: "VN47",
|
|
1833
|
+
KON_TUM: "VN55",
|
|
1834
|
+
GIA_LAI: "VN49",
|
|
1835
|
+
DAK_LAK: "VN88",
|
|
1836
|
+
DAK_NONG: "VN91",
|
|
1837
|
+
LAM_DONG: "VN23",
|
|
1838
|
+
QUANG_BINH: "VN62",
|
|
1839
|
+
QUANG_TRI: "VN64",
|
|
1840
|
+
// Miền Nam (Region 3 - 19 tỉnh/thành)
|
|
1841
|
+
HO_CHI_MINH: "VN20",
|
|
1842
|
+
BINH_DUONG: "VN75",
|
|
1843
|
+
DONG_NAI: "VN43",
|
|
1844
|
+
BA_RIA_VUNG_TAU: "VN45",
|
|
1845
|
+
LONG_AN: "VN24",
|
|
1846
|
+
TIEN_GIANG: "VN37",
|
|
1847
|
+
BEN_TRE: "VN03",
|
|
1848
|
+
DONG_THAP: "VN09",
|
|
1849
|
+
VINH_LONG: "VN69",
|
|
1850
|
+
CAN_THO: "VN87",
|
|
1851
|
+
HAU_GIANG: "VN93",
|
|
1852
|
+
AN_GIANG: "VN01",
|
|
1853
|
+
KIEN_GIANG: "VN21",
|
|
1854
|
+
SOC_TRANG: "VN65",
|
|
1855
|
+
BAC_LIEU: "VN73",
|
|
1856
|
+
CA_MAU: "VN77",
|
|
1857
|
+
TAY_NINH: "VN33",
|
|
1858
|
+
BINH_PHUOC: "VN76",
|
|
1859
|
+
TRA_VINH: "VN67"
|
|
1860
|
+
};
|
|
1861
|
+
var ZaloAdsDeliveryType = {
|
|
1862
|
+
/** Tiêu chuẩn (0): Phân phối đồng đều nhất có thể theo giờ cao điểm (Standard). */
|
|
1863
|
+
STANDARD: 0,
|
|
1864
|
+
/** Tăng tốc (1): Phân phối nhanh nhất có thể để tối đa hóa tiếp cận (SpeedUp). */
|
|
1865
|
+
SPEED_UP: 1,
|
|
1866
|
+
/** Alias tương thích ngược cho SPEED_UP (1). */
|
|
1867
|
+
ACCELERATED: 1
|
|
1868
|
+
};
|
|
1869
|
+
var ZaloAdsSpendingMethod = {
|
|
1870
|
+
/** Tiêu chuẩn (0): Rải đều ngân sách xuyên suốt ngày. */
|
|
1871
|
+
STANDARD: 0,
|
|
1872
|
+
/** Tăng tốc (1): Phân phối nhanh, ưu tiên thắng thầu ngay khi có phiên đấu giá. */
|
|
1873
|
+
FAST: 1,
|
|
1874
|
+
/** Alias cho FAST (1). */
|
|
1875
|
+
ACCELERATED: 1
|
|
1876
|
+
};
|
|
1877
|
+
var ZaloAdsPriceType = {
|
|
1878
|
+
CPM: 1,
|
|
1879
|
+
CPC: 2,
|
|
1880
|
+
CPI: 3,
|
|
1881
|
+
CPF: 4,
|
|
1882
|
+
CPA: 5,
|
|
1883
|
+
CPO: 6,
|
|
1884
|
+
CPV: 7,
|
|
1885
|
+
CPD: 8,
|
|
1886
|
+
CPV1S: 9
|
|
1887
|
+
};
|
|
1888
|
+
var ZaloAdsPriceLimitType = {
|
|
1889
|
+
/** Áp dụng ngân sách cho toàn lịch chạy (Life time budget). */
|
|
1890
|
+
LIFE_TIME: 1,
|
|
1891
|
+
/** Áp dụng ngân sách cho mỗi ngày (Daily budget). */
|
|
1892
|
+
DAILY: 2
|
|
1893
|
+
};
|
|
1894
|
+
var ZaloAdsXTemplates = {
|
|
1895
|
+
/** Định dạng thẻ quay vòng lướt ngang nhiều hình ảnh. */
|
|
1896
|
+
CAROUSEL: 42,
|
|
1897
|
+
/** Định dạng bộ sưu tập album ảnh (lưới 4 ảnh). */
|
|
1898
|
+
ALBUM: 43,
|
|
1899
|
+
/** Định dạng video tự động phát trên Feed. */
|
|
1900
|
+
ZALO_VIDEO: 44,
|
|
1901
|
+
/** Định dạng ảnh dọc toàn màn hình. */
|
|
1902
|
+
PORTRAIT_IMAGE: 45,
|
|
1903
|
+
/** Định dạng ảnh đơn truyền thống (1024x533). */
|
|
1904
|
+
SINGLE_IMAGE: 46,
|
|
1905
|
+
/** Định dạng ảnh bìa cho quảng cáo video. */
|
|
1906
|
+
COVER_IMAGE_FOR_VIDEO_AD: 47,
|
|
1907
|
+
/** Định dạng ảnh vuông. */
|
|
1908
|
+
SQUARE_IMAGE: 48,
|
|
1909
|
+
/** Định dạng chú thích nội dung dài (tối đa 2.000 ký tự). */
|
|
1910
|
+
LONG_CAPTION: 49
|
|
1911
|
+
};
|
|
1912
|
+
var ZaloAdsImageRatio = {
|
|
1913
|
+
/** Tỉ lệ 16:9 (1024x576 px - Video / Banner phong cảnh). */
|
|
1914
|
+
RATIO_16_9: 0,
|
|
1915
|
+
/** Tỉ lệ 4:3 (1024x768 px - Ảnh phụ Album / Carousel). */
|
|
1916
|
+
RATIO_4_3: 1,
|
|
1917
|
+
/** Tỉ lệ 2:1 (1024x512 px - ẢNH BÌA NGANG BẮT BUỘC CỦA ALBUM). */
|
|
1918
|
+
RATIO_2_1: 2,
|
|
1919
|
+
/** Tỉ lệ 3:2. */
|
|
1920
|
+
RATIO_3_2: 3,
|
|
1921
|
+
/** Tỉ lệ 1:1 (1024x1024 px - Ảnh vuông). */
|
|
1922
|
+
RATIO_1_1: 4
|
|
1923
|
+
};
|
|
1924
|
+
var ZaloAdsUseConversion = {
|
|
1925
|
+
/** Không chọn pixel (0): Tắt tối ưu hóa chuyển đổi. */
|
|
1926
|
+
NOT_USE: 0,
|
|
1927
|
+
/** Pixel của tôi (1): Zalo Pixel tự host chèn script, cần kèm ConversionId. */
|
|
1928
|
+
USE: 1,
|
|
1929
|
+
/** Pixel liên kết Ladipage (2): Landing Page đối tác LadiPage. */
|
|
1930
|
+
LADI_PAGE: 2,
|
|
1931
|
+
/** Zalo Mini App (3): Ứng dụng Zalo Mini App. */
|
|
1932
|
+
MINI_APP: 3,
|
|
1933
|
+
/** Tạm thời tắt Pixel của tôi (-1): Cờ lưu nháp. */
|
|
1934
|
+
USE_OFF: -1,
|
|
1935
|
+
/** Tạm thời tắt Pixel Ladipage (-2): Cờ lưu nháp. */
|
|
1936
|
+
LADI_PAGE_OFF: -2,
|
|
1937
|
+
/** Tạm thời tắt Pixel Mini App (-3): Cờ lưu nháp. */
|
|
1938
|
+
MINI_APP_OFF: -3
|
|
1939
|
+
};
|
|
1940
|
+
var ZaloAdsUpdateVideoAdRequest = class {
|
|
1941
|
+
data;
|
|
1942
|
+
est;
|
|
1943
|
+
isBoostAd;
|
|
1944
|
+
stt;
|
|
1945
|
+
};
|
|
1946
|
+
var ZaloAdsUpdateVideoAdResponse = class {
|
|
1947
|
+
code;
|
|
1948
|
+
msg;
|
|
1949
|
+
data;
|
|
1950
|
+
};
|
|
1951
|
+
var ZaloAdsCampaignStatus = {
|
|
1952
|
+
OFF: 0,
|
|
1953
|
+
ACTIVE: 1,
|
|
1954
|
+
PAUSED: 2,
|
|
1955
|
+
DELETED: -2
|
|
1956
|
+
};
|
|
1957
|
+
var ZaloAdsCreatePostCampaignRequest = class {
|
|
1958
|
+
/** Cấu hình chiến dịch Bài viết (object hoặc chuỗi JSON). */
|
|
1959
|
+
data;
|
|
1960
|
+
};
|
|
1961
|
+
var ZaloAdsCreatePostCampaignResponse = class {
|
|
1962
|
+
code;
|
|
1963
|
+
/** Chuỗi ID quảng cáo mới trong response Zalo Ads. */
|
|
1964
|
+
msg;
|
|
1965
|
+
data;
|
|
1966
|
+
};
|
|
1967
|
+
var ZaloAdsMessageAdUpdateDataDto = class {
|
|
1968
|
+
AdId;
|
|
1969
|
+
CampaignId;
|
|
1970
|
+
MemberId;
|
|
1971
|
+
/** Phiên bản lạc quan lấy từ bản quảng cáo hiện tại. */
|
|
1972
|
+
RowVersion;
|
|
1973
|
+
AdName;
|
|
1974
|
+
/** 20 (hoặc 19) là quảng cáo Tin nhắn. */
|
|
1975
|
+
Type;
|
|
1976
|
+
Settings;
|
|
1977
|
+
Status;
|
|
1978
|
+
StartDate;
|
|
1979
|
+
EndDate;
|
|
1980
|
+
/** ID kịch bản, lấy từ createFlow hoặc listFlowsByOfficialAccount. */
|
|
1981
|
+
ZaloFlowId;
|
|
1982
|
+
ZaloPageId;
|
|
1983
|
+
ZaloFormId;
|
|
1984
|
+
UseConversion;
|
|
1985
|
+
ConversionId;
|
|
1986
|
+
Report;
|
|
1987
|
+
};
|
|
1988
|
+
var ZaloAdsUpdateMessageAdRequest = class {
|
|
1989
|
+
/** Payload quảng cáo đầy đủ (object hoặc chuỗi JSON); service tự tuần tự hóa thành field form data. */
|
|
1990
|
+
data;
|
|
1991
|
+
/** Tham số UI phụ trợ; capture Zalo Ads có giá trị literal "undefined". */
|
|
1992
|
+
est;
|
|
1993
|
+
/** 0 là quảng cáo thông thường, 1 là boost ad. */
|
|
1994
|
+
isBoostAd;
|
|
1995
|
+
/** Trạng thái thao tác của giao diện; mẫu đã ghi nhận 0. */
|
|
1996
|
+
stt;
|
|
1997
|
+
};
|
|
1998
|
+
var ZaloAdsUpdateMessageAdResponse = class {
|
|
1999
|
+
msg;
|
|
2000
|
+
code;
|
|
2001
|
+
data;
|
|
2002
|
+
};
|
|
2003
|
+
|
|
2004
|
+
// src/validators/campaigns.validator.ts
|
|
2005
|
+
var VALID_CAMPAIGN_TYPES = {
|
|
2006
|
+
WEBSITE: 6,
|
|
2007
|
+
FORM: 17,
|
|
2008
|
+
MESSAGE: 18,
|
|
2009
|
+
OA: 3,
|
|
2010
|
+
VIDEO: 14,
|
|
2011
|
+
COMMERCE: 22,
|
|
2012
|
+
ARTICLE: 4,
|
|
2013
|
+
DISPLAY: 20
|
|
2014
|
+
};
|
|
2015
|
+
var VALID_AD_TYPES = {
|
|
2016
|
+
WEBSITE: 5,
|
|
2017
|
+
FORM: 18,
|
|
2018
|
+
MESSAGE: 30,
|
|
2019
|
+
OA: 2,
|
|
2020
|
+
VIDEO: 11,
|
|
2021
|
+
COMMERCE: 28,
|
|
2022
|
+
// Server trả về 28 (không phải 23)
|
|
2023
|
+
ARTICLE: 3,
|
|
2024
|
+
DISPLAY: 21
|
|
2025
|
+
};
|
|
2026
|
+
var ALLOWED_CTAS_PER_AD_TYPE = {
|
|
2027
|
+
// Website (Type 5): 9 CTAs
|
|
2028
|
+
[VALID_AD_TYPES.WEBSITE]: [
|
|
2029
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
2030
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
2031
|
+
ZaloAdsActionType.THU_NGAY,
|
|
2032
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
2033
|
+
ZaloAdsActionType.XEM_THEM,
|
|
2034
|
+
ZaloAdsActionType.NGHE_NGAY,
|
|
2035
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
2036
|
+
ZaloAdsActionType.DANG_KY,
|
|
2037
|
+
ZaloAdsActionType.GOI_DIEN
|
|
2038
|
+
],
|
|
2039
|
+
// Video (Type 11): 8 CTAs
|
|
2040
|
+
[VALID_AD_TYPES.VIDEO]: [
|
|
2041
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
2042
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
2043
|
+
ZaloAdsActionType.THU_NGAY,
|
|
2044
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
2045
|
+
ZaloAdsActionType.XEM_THEM,
|
|
2046
|
+
ZaloAdsActionType.NGHE_NGAY,
|
|
2047
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
2048
|
+
ZaloAdsActionType.DANG_KY
|
|
2049
|
+
],
|
|
2050
|
+
// Article (Type 3): 7 CTAs
|
|
2051
|
+
[VALID_AD_TYPES.ARTICLE]: [
|
|
2052
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
2053
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
2054
|
+
ZaloAdsActionType.THU_NGAY,
|
|
2055
|
+
ZaloAdsActionType.TAI_NGAY,
|
|
2056
|
+
ZaloAdsActionType.XEM_THEM,
|
|
2057
|
+
ZaloAdsActionType.CHOI_NGAY,
|
|
2058
|
+
ZaloAdsActionType.DANG_KY
|
|
2059
|
+
],
|
|
2060
|
+
// Form (Type 18): 5 CTAs
|
|
2061
|
+
[VALID_AD_TYPES.FORM]: [
|
|
2062
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
2063
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
2064
|
+
ZaloAdsActionType.THU_NGAY,
|
|
2065
|
+
ZaloAdsActionType.XEM_THEM,
|
|
2066
|
+
ZaloAdsActionType.DANG_KY
|
|
2067
|
+
],
|
|
2068
|
+
// Commerce (Type 28): 3 CTAs
|
|
2069
|
+
[VALID_AD_TYPES.COMMERCE]: [
|
|
2070
|
+
ZaloAdsActionType.DAT_NGAY,
|
|
2071
|
+
ZaloAdsActionType.MUA_NGAY,
|
|
2072
|
+
ZaloAdsActionType.XEM_THEM
|
|
2073
|
+
],
|
|
2074
|
+
// OA (Type 2): Cố định Quan tâm OA (6)
|
|
2075
|
+
[VALID_AD_TYPES.OA]: [ZaloAdsActionType.QUAN_TAM_OA]
|
|
2076
|
+
};
|
|
2077
|
+
function validateCreateCampaignPayload(payload, options = {}) {
|
|
2078
|
+
const errors = [];
|
|
2079
|
+
const warnings = [];
|
|
2080
|
+
if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
|
|
2081
|
+
errors.push("name l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2082
|
+
} else if (payload.name.length > 255) {
|
|
2083
|
+
errors.push("name kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
|
|
2084
|
+
}
|
|
2085
|
+
const validTypes = Object.values(VALID_CAMPAIGN_TYPES);
|
|
2086
|
+
if (payload.campaignType === void 0 || payload.campaignType === null) {
|
|
2087
|
+
errors.push("campaignType l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2088
|
+
} else if (!validTypes.includes(payload.campaignType)) {
|
|
2089
|
+
errors.push(
|
|
2090
|
+
`campaignType: ${payload.campaignType} kh\xF4ng h\u1EE3p l\u1EC7. C\xE1c lo\u1EA1i h\u1ED7 tr\u1EE3: 6 (Website), 17 (Form), 18 (Message), 3 (OA), 14 (Video), 22 (Commerce), 4 (Article), 20 (Display).`
|
|
2091
|
+
);
|
|
2092
|
+
}
|
|
2093
|
+
if (payload.campaignType !== VALID_CAMPAIGN_TYPES.DISPLAY) {
|
|
2094
|
+
if (!payload.pageId || payload.pageId <= 0) {
|
|
2095
|
+
errors.push("pageId c\u1EE7a Official Account l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi lo\u1EA1i chi\u1EBFn d\u1ECBch n\xE0y (ph\u1EA3i > 0).");
|
|
2096
|
+
}
|
|
2097
|
+
} else {
|
|
2098
|
+
if (payload.pageId !== -1 && payload.pageId !== 0 && !payload.pageId) {
|
|
2099
|
+
warnings.push("Qu\u1EA3ng c\xE1o Display th\u01B0\u1EDDng s\u1EED d\u1EE5ng pageId = -1.");
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
switch (payload.campaignType) {
|
|
2103
|
+
case VALID_CAMPAIGN_TYPES.WEBSITE:
|
|
2104
|
+
if (!payload.targetUrl || typeof payload.targetUrl !== "string" || !payload.targetUrl.trim()) {
|
|
2105
|
+
errors.push("targetUrl l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Website.");
|
|
2106
|
+
} else if (!/^https?:\/\/.+/i.test(payload.targetUrl)) {
|
|
2107
|
+
errors.push("targetUrl ph\u1EA3i l\xE0 m\u1ED9t \u0111\u01B0\u1EDDng link h\u1EE3p l\u1EC7 b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https://.");
|
|
2108
|
+
}
|
|
2109
|
+
break;
|
|
2110
|
+
case VALID_CAMPAIGN_TYPES.ARTICLE:
|
|
2111
|
+
if (!payload.articleId || payload.articleId <= 0) {
|
|
2112
|
+
errors.push("articleId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o B\xE0i Vi\u1EBFt (ph\u1EA3i > 0, l\u1EA5y t\u1EEB getOwnedArticles).");
|
|
2113
|
+
}
|
|
2114
|
+
break;
|
|
2115
|
+
case VALID_CAMPAIGN_TYPES.COMMERCE:
|
|
2116
|
+
if (payload.productId === void 0 || payload.productId === null) {
|
|
2117
|
+
warnings.push("Qu\u1EA3ng c\xE1o Commerce n\xEAn ch\u1EC9 \u0111\u1ECBnh productId (ho\u1EB7c -1/0 khi d\xF9ng Instant Page s\u1EA3n ph\u1EA9m).");
|
|
2118
|
+
}
|
|
2119
|
+
break;
|
|
2120
|
+
case VALID_CAMPAIGN_TYPES.FORM:
|
|
2121
|
+
case VALID_CAMPAIGN_TYPES.MESSAGE:
|
|
2122
|
+
break;
|
|
2123
|
+
}
|
|
2124
|
+
if (payload.budgetType !== void 0 && payload.budgetlimit !== void 0) {
|
|
2125
|
+
if (payload.budgetType === 2) {
|
|
2126
|
+
if (payload.budgetlimit > 0 && payload.budgetlimit < 6e5) {
|
|
2127
|
+
errors.push("Ng\xE2n s\xE1ch cho To\xE0n l\u1ECBch ch\u1EA1y t\u1ED1i thi\u1EC3u l\xE0 600,000 VN\u0110.");
|
|
2128
|
+
}
|
|
2129
|
+
} else if (payload.budgetType === 1) {
|
|
2130
|
+
if (payload.budgetlimit > 0 && payload.budgetlimit < 50) {
|
|
2131
|
+
warnings.push("S\u1ED1 l\u01B0\u1EE3ng t\u01B0\u01A1ng t\xE1c m\u1ED7i ng\xE0y t\u1ED1i thi\u1EC3u \u0111\u01B0\u1EE3c khuy\u1EBFn ngh\u1ECB t\u1EEB 50 l\u01B0\u1EE3t.");
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
if (payload.campaignId && payload.campaignId > 0) {
|
|
2136
|
+
if (payload.adId !== 0) {
|
|
2137
|
+
warnings.push("Khi th\xEAm Ad m\u1EDBi v\xE0o chi\u1EBFn d\u1ECBch hi\u1EC7n c\xF3 (Multi-Ad), adId n\xEAn \u0111\u1EC3 b\u1EB1ng 0.");
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
return {
|
|
2141
|
+
isValid: errors.length === 0,
|
|
2142
|
+
errors,
|
|
2143
|
+
warnings
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
function validateUpdateAdPayload(payload, options = {}) {
|
|
2147
|
+
const errors = [];
|
|
2148
|
+
const warnings = [];
|
|
2149
|
+
if (!payload.AdId || payload.AdId <= 0) {
|
|
2150
|
+
errors.push("AdId l\xE0 b\u1EAFt bu\u1ED9c (ph\u1EA3i > 0).");
|
|
2151
|
+
}
|
|
2152
|
+
if (!payload.CampaignId || payload.CampaignId <= 0) {
|
|
2153
|
+
errors.push("CampaignId l\xE0 b\u1EAFt bu\u1ED9c (ph\u1EA3i > 0).");
|
|
2154
|
+
}
|
|
2155
|
+
if (!payload.AdName || !payload.AdName.trim()) {
|
|
2156
|
+
errors.push("AdName l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2157
|
+
} else if (payload.AdName.length > 255) {
|
|
2158
|
+
errors.push(`AdName qu\xE1 d\xE0i (${payload.AdName.length}/255 k\xFD t\u1EF1).`);
|
|
2159
|
+
}
|
|
2160
|
+
const adInfo = payload.Settings?.AdInfo;
|
|
2161
|
+
if (!adInfo) {
|
|
2162
|
+
errors.push("Settings.AdInfo l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2163
|
+
} else {
|
|
2164
|
+
if (!adInfo.Caption || !adInfo.Caption.trim()) {
|
|
2165
|
+
errors.push("Settings.AdInfo.Caption l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2166
|
+
} else {
|
|
2167
|
+
const captionLen = adInfo.Caption.trim().length;
|
|
2168
|
+
if (captionLen < 35) {
|
|
2169
|
+
errors.push(`Settings.AdInfo.Caption qu\xE1 ng\u1EAFn (${captionLen}/35 k\xFD t\u1EF1 t\u1ED1i thi\u1EC3u).`);
|
|
2170
|
+
} else if (captionLen > 90) {
|
|
2171
|
+
errors.push(`Settings.AdInfo.Caption qu\xE1 d\xE0i (${captionLen}/90 k\xFD t\u1EF1 t\u1ED1i \u0111a).`);
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
const longCaption = adInfo.LongCaption ?? adInfo.MoreInfo;
|
|
2175
|
+
if (longCaption !== void 0 && longCaption !== null && longCaption.trim().length > 0) {
|
|
2176
|
+
const longCaptionLen = longCaption.trim().length;
|
|
2177
|
+
if (longCaptionLen < 90) {
|
|
2178
|
+
errors.push(
|
|
2179
|
+
`Settings.AdInfo.LongCaption (Ch\xFA th\xEDch m\u1EDF r\u1ED9ng) qu\xE1 ng\u1EAFn (${longCaptionLen}/90 k\xFD t\u1EF1 t\u1ED1i thi\u1EC3u). Theo quy chu\u1EA9n Zalo Ads, tr\u01B0\u1EDDng n\xE0y kh\xF4ng b\u1EAFt bu\u1ED9c, nh\u01B0ng n\u1EBFu nh\u1EADp th\xEC b\u1EAFt bu\u1ED9c ph\u1EA3i t\u1EEB 90 \u0111\u1EBFn 2,000 k\xFD t\u1EF1.`
|
|
2180
|
+
);
|
|
2181
|
+
} else if (longCaptionLen > 2e3) {
|
|
2182
|
+
errors.push(
|
|
2183
|
+
`Settings.AdInfo.LongCaption (Ch\xFA th\xEDch m\u1EDF r\u1ED9ng) qu\xE1 d\xE0i (${longCaptionLen}/2000 k\xFD t\u1EF1 t\u1ED1i \u0111a).`
|
|
2184
|
+
);
|
|
2185
|
+
}
|
|
2186
|
+
if (adInfo.XTemplates && Array.isArray(adInfo.XTemplates) && !adInfo.XTemplates.includes(49)) {
|
|
2187
|
+
warnings.push(
|
|
2188
|
+
"Khi c\xF3 Ch\xFA th\xEDch m\u1EDF r\u1ED9ng (LongCaption), b\u1EA1n n\xEAn th\xEAm m\xE3 49 (LONG_CAPTION) v\xE0o Settings.AdInfo.XTemplates \u0111\u1EC3 k\xEDch ho\u1EA1t giao di\u1EC7n hi\u1EC3n th\u1ECB b\xE0i vi\u1EBFt d\xE0i tr\xEAn Zalo Feed."
|
|
2189
|
+
);
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
if (adInfo.Action !== void 0 && payload.Type) {
|
|
2193
|
+
const allowedCtas = ALLOWED_CTAS_PER_AD_TYPE[payload.Type];
|
|
2194
|
+
if (allowedCtas && !allowedCtas.includes(adInfo.Action)) {
|
|
2195
|
+
warnings.push(
|
|
2196
|
+
`M\xE3 h\xE0nh \u0111\u1ED9ng Action: ${adInfo.Action} c\xF3 th\u1EC3 kh\xF4ng n\u1EB1m trong danh m\u1EE5c n\xFAt CTA h\u1ED7 tr\u1EE3 cho Ad Type ${payload.Type}.`
|
|
2197
|
+
);
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
const price = payload.Settings?.Price;
|
|
2202
|
+
if (!price) {
|
|
2203
|
+
errors.push("Settings.Price l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
2204
|
+
} else {
|
|
2205
|
+
if (payload.Type === VALID_AD_TYPES.WEBSITE) {
|
|
2206
|
+
if (price.Type !== 1) {
|
|
2207
|
+
errors.push(
|
|
2208
|
+
"\u0110\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Website (Type 5), Price.Type b\u1EAFt bu\u1ED9c ph\u1EA3i b\u1EB1ng 1 (CPC). N\u1EBFu truy\u1EC1n 2 s\u1EBD b\u1ECB m\xE1y ch\u1EE7 l\u1ED7i."
|
|
2209
|
+
);
|
|
2210
|
+
}
|
|
2211
|
+
if (price.LimitType === 1) {
|
|
2212
|
+
errors.push(
|
|
2213
|
+
"Qu\u1EA3ng c\xE1o Website kh\xF4ng h\u1ED7 tr\u1EE3 LimitType: 1 (t\u1ED5ng ng\xE2n s\xE1ch). B\u1EAFt bu\u1ED9c ph\u1EA3i d\xF9ng LimitType: 0 (ng\xE2n s\xE1ch ng\xE0y)."
|
|
2214
|
+
);
|
|
2215
|
+
}
|
|
2216
|
+
} else if (payload.Type === VALID_AD_TYPES.VIDEO) {
|
|
2217
|
+
if (price.Type !== 1 && price.Type !== 7) {
|
|
2218
|
+
errors.push(
|
|
2219
|
+
"\u0110\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Video (Type 11) tr\xEAn Video Platform, Price.Type b\u1EAFt bu\u1ED9c l\xE0 1 (CPM - L\u01B0\u1EE3t hi\u1EC3n th\u1ECB) ho\u1EB7c 7 (CPV - L\u01B0\u1EE3t xem). N\u1EBFu truy\u1EC1n 2 (CPC), form ch\u1EC9nh s\u1EEDa c\u1EE7a Zalo Ads s\u1EBD kh\xF4ng hi\u1EC3n th\u1ECB \u0111\u01B0\u1EE3c gi\xE1 v\xE0 s\u1ED1 l\u01B0\u1EE3ng."
|
|
2220
|
+
);
|
|
2221
|
+
}
|
|
2222
|
+
if (price.Type === 1 && (price.Limit ?? 0) < 50) {
|
|
2223
|
+
errors.push(
|
|
2224
|
+
"\u0110\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Video CPM, s\u1ED1 l\u01B0\u1EE3ng hi\u1EC3n th\u1ECB t\u1ED1i thi\u1EC3u (Price.Limit) l\xE0 50 (t\u01B0\u01A1ng \u1EE9ng 50,000 l\u01B0\u1EE3t hi\u1EC3n th\u1ECB)."
|
|
2225
|
+
);
|
|
2226
|
+
}
|
|
2227
|
+
} else if (payload.Type === VALID_AD_TYPES.COMMERCE || payload.Type === VALID_AD_TYPES.ARTICLE || payload.Type === VALID_AD_TYPES.FORM) {
|
|
2228
|
+
if (price.Type !== 2) {
|
|
2229
|
+
errors.push(
|
|
2230
|
+
`\u0110\u1ED1i v\u1EDBi Ad Type ${payload.Type}, Price.Type b\u1EAFt bu\u1ED9c ph\u1EA3i b\u1EB1ng 2 (CPC).`
|
|
2231
|
+
);
|
|
2232
|
+
}
|
|
2233
|
+
} else if (payload.Type === VALID_AD_TYPES.OA) {
|
|
2234
|
+
if (price.Type !== 2 && price.Type !== 5) {
|
|
2235
|
+
errors.push(
|
|
2236
|
+
"\u0110\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o OA (Type 2), Price.Type ch\u1EC9 h\u1ED7 tr\u1EE3 2 (L\u01B0\u1EE3t nh\u1EA5n - CPC) ho\u1EB7c 5 (L\u01B0\u1EE3t quan t\xE2m - CPA Beta)."
|
|
2237
|
+
);
|
|
2238
|
+
}
|
|
2239
|
+
if (price.Type === 2) {
|
|
2240
|
+
if (price.SpendingMethod !== 0 && price.SpendingMethod !== void 0) {
|
|
2241
|
+
errors.push(
|
|
2242
|
+
"Khi t\xEDnh ti\u1EC1n theo L\u01B0\u1EE3t nh\u1EA5n (Price.Type = 2 / CPC), SpendingMethod b\u1EAFt bu\u1ED9c ph\u1EA3i b\u1EB1ng 0 (\u0110\u1EB7t gi\xE1 th\u1EA7u th\u1EE7 c\xF4ng theo s\u1ED1 l\u01B0\u1EE3ng t\u01B0\u01A1ng t\xE1c)."
|
|
2243
|
+
);
|
|
2244
|
+
}
|
|
2245
|
+
if (price.Bid !== void 0 && price.Bid < 650) {
|
|
2246
|
+
errors.push(
|
|
2247
|
+
`Gi\xE1 \u0111\u1EB7t m\u1ED7i l\u01B0\u1EE3t nh\u1EA5n (Price.Bid) t\u1ED1i thi\u1EC3u l\xE0 650 VN\u0110 (s\xE0n h\u1EC7 th\u1ED1ng Zalo Ads). Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Bid}\u0111.`
|
|
2248
|
+
);
|
|
2249
|
+
}
|
|
2250
|
+
if (price.Limit !== void 0 && price.Limit < 50) {
|
|
2251
|
+
errors.push(
|
|
2252
|
+
`S\u1ED1 l\u01B0\u1EE3ng l\u01B0\u1EE3t nh\u1EA5n (Price.Limit) t\u1ED1i thi\u1EC3u l\xE0 50 l\u01B0\u1EE3t/ng\xE0y (minCTA = 50). Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Limit}.`
|
|
2253
|
+
);
|
|
2254
|
+
} else if (price.Limit !== void 0 && price.Limit > 5e3) {
|
|
2255
|
+
warnings.push(
|
|
2256
|
+
`\u26A0\uFE0F C\u1EA2NH B\xC1O B\u1EAAY NG\xC2N S\xC1CH ZALO ADS: Khi Price.Type = 2 (CPC), tr\u01B0\u1EDDng Price.Limit mang \xFD ngh\u0129a l\xE0 S\u1ED0 L\u01AF\u1EE2NG L\u01AF\u1EE2T NH\u1EA4N (Clicks count), KH\xD4NG PH\u1EA2I S\u1ED0 TI\u1EC0N VN\u0110. B\u1EA1n \u0111ang truy\u1EC1n Limit = ${price.Limit} l\u01B0\u1EE3t nh\u1EA5n, c\xF3 th\u1EC3 khi\u1EBFn T\u1ED5ng chi ph\xED d\u1EF1 ki\u1EBFn t\u0103ng v\u1ECDt l\xEAn h\xE0ng tr\u0103m tri\u1EC7u VN\u0110.`
|
|
2257
|
+
);
|
|
2258
|
+
}
|
|
2259
|
+
} else if (price.Type === 5) {
|
|
2260
|
+
if (price.SpendingMethod === 1) {
|
|
2261
|
+
if (price.Bid !== void 0 && price.Bid !== 0) {
|
|
2262
|
+
errors.push(
|
|
2263
|
+
"Khi ch\u1ECDn 'T\u1ED5ng ng\xE2n s\xE1ch qu\u1EA3ng c\xE1o' cho L\u01B0\u1EE3t quan t\xE2m (SpendingMethod = 1), tr\u01B0\u1EDDng Bid b\u1EAFt bu\u1ED9c ph\u1EA3i b\u1EB1ng 0 (h\u1EC7 th\u1ED1ng t\u1EF1 \u0111\u1ED9ng \u0111\u1EA5u th\u1EA7u)."
|
|
2264
|
+
);
|
|
2265
|
+
}
|
|
2266
|
+
if (price.Limit !== void 0 && price.Limit < 5e5) {
|
|
2267
|
+
errors.push(
|
|
2268
|
+
`Ng\xE2n s\xE1ch t\u1ED1i thi\u1EC3u cho L\u01B0\u1EE3t quan t\xE2m theo T\u1ED5ng ng\xE2n s\xE1ch l\xE0 500,000 VN\u0110 / ng\xE0y (Price.Limit >= 500000). Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Limit}\u0111.`
|
|
2269
|
+
);
|
|
2270
|
+
}
|
|
2271
|
+
} else if (price.SpendingMethod === 0) {
|
|
2272
|
+
if (price.Bid !== void 0 && price.Bid < 1e4) {
|
|
2273
|
+
errors.push(
|
|
2274
|
+
`Gi\xE1 \u0111\u1EB7t m\u1ED7i L\u01B0\u1EE3t quan t\xE2m (Price.Bid) t\u1ED1i thi\u1EC3u l\xE0 10,000 VN\u0110 / l\u01B0\u1EE3t quan t\xE2m (s\xE0n h\u1EC7 th\u1ED1ng cho OA Follow). Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Bid}\u0111.`
|
|
2275
|
+
);
|
|
2276
|
+
}
|
|
2277
|
+
if (price.Limit !== void 0 && price.Limit < 100) {
|
|
2278
|
+
errors.push(
|
|
2279
|
+
`S\u1ED1 l\u01B0\u1EE3ng L\u01B0\u1EE3t quan t\xE2m (Price.Limit) t\u1ED1i thi\u1EC3u l\xE0 100 l\u01B0\u1EE3t (minCTA = 100). Hi\u1EC7n t\u1EA1i \u0111ang truy\u1EC1n: ${price.Limit}.`
|
|
2280
|
+
);
|
|
2281
|
+
} else if (price.Limit !== void 0 && price.Limit > 5e3) {
|
|
2282
|
+
warnings.push(
|
|
2283
|
+
`\u26A0\uFE0F C\u1EA2NH B\xC1O B\u1EAAY NG\xC2N S\xC1CH ZALO ADS: Khi ch\u1ECDn 'T\u1EF1 \u0111\u1EB7t gi\xE1' cho L\u01B0\u1EE3t quan t\xE2m (SpendingMethod = 0), tr\u01B0\u1EDDng Price.Limit l\xE0 S\u1ED0 L\u01AF\u1EE2NG L\u01AF\u1EE2T QUAN T\xC2M (t\u1ED1i thi\u1EC3u 100 l\u01B0\u1EE3t), KH\xD4NG PH\u1EA2I S\u1ED0 TI\u1EC0N VN\u0110.`
|
|
2284
|
+
);
|
|
2285
|
+
}
|
|
2286
|
+
} else if (price.SpendingMethod !== void 0) {
|
|
2287
|
+
errors.push(
|
|
2288
|
+
"C\xE1ch \u0111\u1EB7t gi\xE1 SpendingMethod cho L\u01B0\u1EE3t quan t\xE2m ch\u1EC9 ch\u1EA5p nh\u1EADn 1 (T\u1ED5ng ng\xE2n s\xE1ch qu\u1EA3ng c\xE1o) ho\u1EB7c 0 (T\u1EF1 \u0111\u1EB7t gi\xE1)."
|
|
2289
|
+
);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
} else if (payload.Type === VALID_AD_TYPES.MESSAGE) {
|
|
2293
|
+
if (price.Type !== 2 && price.Type !== 5) {
|
|
2294
|
+
errors.push(
|
|
2295
|
+
"\u0110\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Tin nh\u1EAFn (Type 30), Price.Type ch\u1EC9 h\u1ED7 tr\u1EE3 2 (L\u01B0\u1EE3t nh\u1EA5n - CPC) ho\u1EB7c 5 (L\u01B0\u1EE3t li\xEAn h\u1EC7 - CPA)."
|
|
2296
|
+
);
|
|
2297
|
+
}
|
|
2298
|
+
if (price.Type === 5) {
|
|
2299
|
+
if (price.SpendingMethod !== 1) {
|
|
2300
|
+
errors.push(
|
|
2301
|
+
"Khi t\xEDnh ti\u1EC1n theo L\u01B0\u1EE3t li\xEAn h\u1EC7 (Price.Type = 5 / CPA), SpendingMethod b\u1EAFt bu\u1ED9c ph\u1EA3i b\u1EB1ng 1 (T\u1ED1i \u01B0u t\u1EF1 \u0111\u1ED9ng theo ng\xE2n s\xE1ch)."
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
2304
|
+
if (price.Bid !== void 0 && price.Bid !== 0) {
|
|
2305
|
+
errors.push(
|
|
2306
|
+
"Khi t\xEDnh ti\u1EC1n theo L\u01B0\u1EE3t li\xEAn h\u1EC7 (Price.Type = 5 / CPA), tr\u01B0\u1EDDng Bid b\u1EAFt bu\u1ED9c ph\u1EA3i b\u1EB1ng 0 (Zalo Ads t\u1EF1 \u0111\u1ED9ng t\u1ED1i \u01B0u gi\xE1 th\u1EA7u, n\u1EBFu truy\u1EC1n > 0 m\xE1y ch\u1EE7 s\u1EBD b\xE1o l\u1ED7i code 13: Gi\xE1 \u0111\u1EB7t kh\xF4ng h\u1EE3p l\u1EC7)."
|
|
2307
|
+
);
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
if (price.Limit !== void 0 && price.Limit > 0 && price.Limit < 6e5) {
|
|
2311
|
+
errors.push(
|
|
2312
|
+
"Ng\xE2n s\xE1ch t\u1ED1i thi\u1EC3u cho Qu\u1EA3ng c\xE1o Tin nh\u1EAFn l\xE0 600,000 VN\u0110 (Price.Limit >= 600000). N\u1EBFu \u0111\u1EB7t d\u01B0\u1EDBi 600k m\xE1y ch\u1EE7 s\u1EBD t\u1EEB ch\u1ED1i."
|
|
2313
|
+
);
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
if (payload.Settings && payload.Settings.DeliveryType !== void 0) {
|
|
2317
|
+
const deliveryType = payload.Settings.DeliveryType;
|
|
2318
|
+
if (deliveryType !== 0 && deliveryType !== 1) {
|
|
2319
|
+
errors.push("C\xE0i \u0111\u1EB7t ph\xE2n ph\u1ED1i Settings.DeliveryType ch\u1EC9 ch\u1EA5p nh\u1EADn 0 (Ti\xEAu chu\u1EA9n - Standard) ho\u1EB7c 1 (T\u0103ng t\u1ED1c - SpeedUp).");
|
|
2320
|
+
}
|
|
2321
|
+
if ((price.LimitType === 2 || price.LimitType === 0) && deliveryType === 1) {
|
|
2322
|
+
warnings.push("Ph\xE2n ph\u1ED1i T\u0103ng t\u1ED1c (DeliveryType = 1) ch\u1EC9 c\xF3 hi\u1EC7u l\u1EF1c khi \u0111\u1EB7t Ng\xE2n s\xE1ch to\xE0n l\u1ECBch ch\u1EA1y (Price.LimitType = 1).");
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
if (price.SpendingMethod === 0 && price.Limit !== void 0 && price.Limit > 0 && price.Limit < 50) {
|
|
2326
|
+
warnings.push("S\u1ED1 l\u01B0\u1EE3ng l\u01B0\u1EE3t t\u01B0\u01A1ng t\xE1c \u0111\u1EB7t m\u1ED7i ng\xE0y t\u1ED1i thi\u1EC3u l\xE0 50 l\u01B0\u1EE3t.");
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
const targeting = payload.Settings?.Targeting;
|
|
2330
|
+
if (targeting) {
|
|
2331
|
+
const newAges = targeting.NewAgeRanges;
|
|
2332
|
+
const oldAges = targeting.AgeRanges;
|
|
2333
|
+
if (newAges && newAges.length > 0) {
|
|
2334
|
+
const validNewAgeKeys = ["13_17", "18_24", "25_34", "35_44", "45_54", "55_64", "65_plus", "10283", "10284", "10285", "10286", "10287", "10288"];
|
|
2335
|
+
const invalid = newAges.filter((a) => !validNewAgeKeys.includes(String(a)));
|
|
2336
|
+
if (invalid.length > 0) {
|
|
2337
|
+
warnings.push(`M\xE3 NewAgeRanges kh\xF4ng ph\u1ED5 bi\u1EBFn: ${invalid.join(", ")}.`);
|
|
2338
|
+
}
|
|
2339
|
+
} else if (oldAges && oldAges.length > 0) {
|
|
2340
|
+
const validAges = Object.values(ZaloAdsAgeRangeId);
|
|
2341
|
+
const invalidAges = oldAges.filter((a) => !validAges.includes(a));
|
|
2342
|
+
if (invalidAges.length > 0) {
|
|
2343
|
+
errors.push(`M\xE3 kho\u1EA3ng tu\u1ED5i kh\xF4ng h\u1EE3p l\u1EC7: ${invalidAges.join(", ")}. H\u1EE3p l\u1EC7: ${validAges.join(", ")}.`);
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
const osList = targeting.Os || targeting.OsTypes;
|
|
2347
|
+
if (osList && osList.length > 0) {
|
|
2348
|
+
const validOs = [0, 1, 2, 3];
|
|
2349
|
+
const invalidOs = osList.filter((os) => !validOs.includes(Number(os)));
|
|
2350
|
+
if (invalidOs.length > 0) {
|
|
2351
|
+
errors.push(`M\xE3 h\u1EC7 \u0111i\u1EC1u h\xE0nh kh\xF4ng h\u1EE3p l\u1EC7: ${invalidOs.join(", ")}. H\u1EE3p l\u1EC7: 0 (Android), 1 (iOS), 3 (PC).`);
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
const deliveryType = payload.Settings?.DeliveryType;
|
|
2355
|
+
if (deliveryType !== void 0 && deliveryType !== ZaloAdsDeliveryType.STANDARD && deliveryType !== ZaloAdsDeliveryType.SPEED_UP) {
|
|
2356
|
+
warnings.push(
|
|
2357
|
+
"DeliveryType kh\xF4ng h\u1EE3p l\u1EC7. Gi\xE1 tr\u1ECB chu\u1EA9n: 0 (Ti\xEAu chu\u1EA9n / Standard) ho\u1EB7c 1 (T\u0103ng t\u1ED1c / SpeedUp)."
|
|
2358
|
+
);
|
|
2359
|
+
}
|
|
2360
|
+
const location = targeting.Location;
|
|
2361
|
+
if (location) {
|
|
2362
|
+
const container = location.WardTargeting || location.DistrictTargeting;
|
|
2363
|
+
if (container && Array.isArray(container.Includes)) {
|
|
2364
|
+
const validRegions = [1, 2, 3];
|
|
2365
|
+
for (const item of container.Includes) {
|
|
2366
|
+
if (!validRegions.includes(Number(item.Id))) {
|
|
2367
|
+
warnings.push(
|
|
2368
|
+
`M\xE3 v\xF9ng mi\u1EC1n (Id: ${item.Id}) kh\xF4ng h\u1EE3p l\u1EC7. C\xE1c m\xE3 v\xF9ng chu\u1EA9n: 1 (Mi\u1EC1n B\u1EAFc), 2 (Mi\u1EC1n Trung), 3 (Mi\u1EC1n Nam).`
|
|
2369
|
+
);
|
|
2370
|
+
}
|
|
2371
|
+
if (item.Provinces && !Array.isArray(item.Provinces)) {
|
|
2372
|
+
warnings.push(`Tr\u01B0\u1EDDng 'Provinces' trong v\xF9ng mi\u1EC1n Id=${item.Id} ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng t\u1EC9nh/th\xE0nh.`);
|
|
2373
|
+
} else if (Array.isArray(item.Provinces)) {
|
|
2374
|
+
for (const prov of item.Provinces) {
|
|
2375
|
+
if (!prov.Id || typeof prov.Id !== "string") {
|
|
2376
|
+
warnings.push(
|
|
2377
|
+
`M\xE3 t\u1EC9nh 'Id' (${JSON.stringify(prov)}) trong v\xF9ng mi\u1EC1n ${item.Id} ph\u1EA3i l\xE0 chu\u1ED7i h\u1EE3p l\u1EC7 (v\xED d\u1EE5: 'VN44', 'VN20').`
|
|
2378
|
+
);
|
|
2379
|
+
} else {
|
|
2380
|
+
const mergeInfo = ZALO_PROVINCE_MERGE_MAPPING[prov.Id];
|
|
2381
|
+
if (mergeInfo) {
|
|
2382
|
+
errors.push(
|
|
2383
|
+
`M\xE3 t\u1EC9nh '${prov.Id}' (${mergeInfo.name}) \u0111\xE3 \u0111\u01B0\u1EE3c Zalo Ads g\u1ED9p/s\xE1p nh\u1EADp v\xE0o c\u1EE5m m\xE3 '${mergeInfo.newCode}'. Vui l\xF2ng s\u1EED d\u1EE5ng m\xE3 c\u1EE5m '${mergeInfo.newCode}' trong WardTargeting, n\u1EBFu kh\xF4ng giao di\u1EC7n Zalo Ads Web s\u1EBD b\xE1o l\u1ED7i \u0111\u1ECF 'Invalid wards params'.`
|
|
2384
|
+
);
|
|
2385
|
+
} else {
|
|
2386
|
+
const validNewRegionProvs = ZALO_NEW_REGION_PROVINCE_CODES[Number(item.Id)] || [];
|
|
2387
|
+
if (!validNewRegionProvs.includes(prov.Id)) {
|
|
2388
|
+
const actualRegion = Object.keys(ZALO_NEW_REGION_PROVINCE_CODES).find((r) => ZALO_NEW_REGION_PROVINCE_CODES[Number(r)].includes(prov.Id));
|
|
2389
|
+
errors.push(
|
|
2390
|
+
`M\xE3 t\u1EC9nh '${prov.Id}' kh\xF4ng n\u1EB1m trong 34 C\u1EE5m T\u1EC9nh/Th\xE0nh m\u1EDBi c\u1EE7a V\xF9ng ${item.Id} tr\xEAn Zalo Ads (s\u1EBD g\xE2y l\u1ED7i 'Invalid wards params' tr\xEAn UI). ` + (actualRegion ? `M\xE3 n\xE0y thu\u1ED9c V\xF9ng ${actualRegion}. ` : "")
|
|
2391
|
+
);
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
if (prov.Districts && !Array.isArray(prov.Districts)) {
|
|
2396
|
+
warnings.push(`Tr\u01B0\u1EDDng 'Districts' c\u1EE7a t\u1EC9nh ${prov.Id} ph\u1EA3i l\xE0 m\u1ED9t m\u1EA3ng (ho\u1EB7c [] khi ch\u1ECDn c\u1EA3 t\u1EC9nh).`);
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
if (payload.UseConversion !== void 0) {
|
|
2405
|
+
const validUseConversions = Object.values(ZaloAdsUseConversion);
|
|
2406
|
+
if (!validUseConversions.includes(payload.UseConversion)) {
|
|
2407
|
+
warnings.push(
|
|
2408
|
+
`UseConversion (${payload.UseConversion}) kh\xF4ng n\u1EB1m trong danh m\u1EE5c chu\u1EA9n: 0 (NOT_USE), 1 (USE), 2 (LADI_PAGE), 3 (MINI_APP), -1 (USE_OFF), -2 (LADI_PAGE_OFF), -3 (MINI_APP_OFF).`
|
|
2409
|
+
);
|
|
2410
|
+
}
|
|
2411
|
+
if (payload.UseConversion === ZaloAdsUseConversion.USE && (!payload.ConversionId || payload.ConversionId <= 0)) {
|
|
2412
|
+
warnings.push(
|
|
2413
|
+
"Khi ch\u1ECDn UseConversion = 1 (Pixel c\u1EE7a t\xF4i), n\xEAn c\u1EA5u h\xECnh ConversionId h\u1EE3p l\u1EC7 t\u1EEB danh s\xE1ch GET /api/conversion/all \u0111\u1EC3 thu\u1EADt to\xE1n m\xE1y h\u1ECDc Zalo Ads t\u1ED1i \u01B0u t\u1EF7 l\u1EC7 chuy\u1EC3n \u0111\u1ED5i."
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
if (payload.Type === VALID_AD_TYPES.FORM) {
|
|
2418
|
+
if (!payload.ZaloFormId || !payload.ZaloFormId.trim()) {
|
|
2419
|
+
errors.push("ZaloFormId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Form (Ad Type 18).");
|
|
2420
|
+
}
|
|
2421
|
+
} else if (payload.Type === VALID_AD_TYPES.MESSAGE) {
|
|
2422
|
+
if (!payload.Settings?.Image?.LogoUrl) {
|
|
2423
|
+
errors.push("Settings.Image.LogoUrl l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Tin Nh\u1EAFn (Ad Type 30).");
|
|
2424
|
+
}
|
|
2425
|
+
if (!payload.MiniPageId || payload.MiniPageId <= 0) {
|
|
2426
|
+
errors.push(
|
|
2427
|
+
"MiniPageId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Tin Nh\u1EAFn (Ad Type 30, Template 4 - K\u1ECBch b\u1EA3n gi\u1EDBi thi\u1EC7u th\u01B0\u01A1ng hi\u1EC7u / Tin nh\u1EAFn). N\u1EBFu thi\u1EBFu ho\u1EB7c = 0, m\xE1y ch\u1EE7 Zalo Ads s\u1EBD t\u1EEB ch\u1ED1i v\u1EDBi l\u1ED7i: 'Mini Page kh\xF4ng h\u1EE3p l\u1EC7.'."
|
|
2428
|
+
);
|
|
2429
|
+
}
|
|
2430
|
+
if (!payload.ZaloFlowId) {
|
|
2431
|
+
warnings.push("Qu\u1EA3ng c\xE1o Tin Nh\u1EAFn n\xEAn g\u1EAFn ZaloFlowId \u0111\u1EC3 t\u1EF1 \u0111\u1ED9ng k\xEDch ho\u1EA1t k\u1ECBch b\u1EA3n chatbot t\u01B0\u01A1ng t\xE1c khi ng\u01B0\u1EDDi d\xF9ng m\u1EDF tin nh\u1EAFn.");
|
|
2432
|
+
}
|
|
2433
|
+
if (payload.Settings?.Image?.ExtraImgs && payload.Settings?.Image?.ExtraImgs.length > 0) {
|
|
2434
|
+
errors.push(
|
|
2435
|
+
"Qu\u1EA3ng c\xE1o Tin Nh\u1EAFn \u0111\u1ECBnh d\u1EA1ng \u1EA3nh \u0111\u01A1n (Landscape Cover) kh\xF4ng \u0111\u01B0\u1EE3c truy\u1EC1n m\u1EA3ng 'ExtraImgs'. N\u1EBFu truy\u1EC1n th\u1EEBa s\u1EBD b\u1ECB m\xE1y ch\u1EE7 b\xE1o l\u1ED7i 'D\u1EEF li\u1EC7u kh\xF4ng h\u1EE3p l\u1EC7'."
|
|
2436
|
+
);
|
|
2437
|
+
}
|
|
2438
|
+
} else if (payload.Type === VALID_AD_TYPES.COMMERCE) {
|
|
2439
|
+
if (!payload.MiniPageId || payload.MiniPageId <= 0) {
|
|
2440
|
+
errors.push("MiniPageId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Commerce (Ad Type 28, Template 1/2/3).");
|
|
2441
|
+
}
|
|
2442
|
+
} else if (payload.Type === VALID_AD_TYPES.VIDEO) {
|
|
2443
|
+
if (!payload.ZaloVideoId && !payload.Settings?.Image?.VideoUrl) {
|
|
2444
|
+
errors.push("ZaloVideoId ho\u1EB7c Settings.Image.VideoUrl l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Video (Ad Type 11).");
|
|
2445
|
+
}
|
|
2446
|
+
if (payload.Settings?.Image?.VideoUrl && !payload.Settings.Image.VideoUrl.includes("zascdn.me")) {
|
|
2447
|
+
warnings.push("VideoUrl n\xEAn l\xE0 \u0111\u01B0\u1EDDng d\u1EABn CDN ch\xEDnh th\u1EE9c c\u1EE7a Zalo Ads (*.zascdn.me).");
|
|
2448
|
+
}
|
|
2449
|
+
} else if (payload.Type === VALID_AD_TYPES.ARTICLE) {
|
|
2450
|
+
if (!payload.ZaloFeedId && !payload.articleId) {
|
|
2451
|
+
errors.push("ZaloFeedId ho\u1EB7c articleId l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o B\xE0i Vi\u1EBFt (Ad Type 3).");
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
return {
|
|
2455
|
+
isValid: errors.length === 0,
|
|
2456
|
+
errors,
|
|
2457
|
+
warnings
|
|
2458
|
+
};
|
|
2459
|
+
}
|
|
2460
|
+
function validateRenameCampaignParams(params) {
|
|
2461
|
+
const errors = [];
|
|
2462
|
+
const warnings = [];
|
|
2463
|
+
const id = params.campid || params.campaignId;
|
|
2464
|
+
const name = params.newname || params.newName || params.name;
|
|
2465
|
+
if (!id || id <= 0) {
|
|
2466
|
+
errors.push("ID chi\u1EBFn d\u1ECBch (campid/campaignId) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i > 0.");
|
|
2467
|
+
}
|
|
2468
|
+
if (!name || !name.trim()) {
|
|
2469
|
+
errors.push("T\xEAn m\u1EDBi c\u1EE7a chi\u1EBFn d\u1ECBch (newname/name) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
2470
|
+
} else if (name.length > 255) {
|
|
2471
|
+
errors.push(`T\xEAn chi\u1EBFn d\u1ECBch qu\xE1 d\xE0i (${name.length}/255 k\xFD t\u1EF1).`);
|
|
2472
|
+
}
|
|
2473
|
+
return {
|
|
2474
|
+
isValid: errors.length === 0,
|
|
2475
|
+
errors,
|
|
2476
|
+
warnings
|
|
2477
|
+
};
|
|
2478
|
+
}
|
|
2479
|
+
function validateChangeCampaignStatusParams(params) {
|
|
2480
|
+
const errors = [];
|
|
2481
|
+
const warnings = [];
|
|
2482
|
+
if (!params.campaignId || params.campaignId <= 0) {
|
|
2483
|
+
errors.push("campaignId l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i > 0.");
|
|
2484
|
+
}
|
|
2485
|
+
if (![0, 1, 2, -2].includes(params.status)) {
|
|
2486
|
+
errors.push(`status: ${params.status} kh\xF4ng h\u1EE3p l\u1EC7. C\xE1c tr\u1EA1ng th\xE1i h\u1EE3p l\u1EC7: 1 (B\u1EADt), 0 (T\u1EAFt), 2 (T\u1EA1m d\u1EEBng), -2 (X\xF3a).`);
|
|
2487
|
+
}
|
|
2488
|
+
if (params.status === 2 && params.isDraft) {
|
|
2489
|
+
warnings.push(
|
|
2490
|
+
"Chi\u1EBFn d\u1ECBch nh\xE1p ch\u01B0a c\xF3 qu\u1EA3ng c\xE1o ho\u1EA1t \u0111\u1ED9ng khi g\u1ECDi status: 2 (T\u1EA1m d\u1EEBng) s\u1EBD b\u1ECB m\xE1y ch\u1EE7 n\xE9m l\u1ED7i HTTP 500 Internal Server Error. \u0110\u1EC3 d\u1ECDn d\u1EB9p h\xE3y d\xF9ng status: -2 (X\xF3a)."
|
|
2491
|
+
);
|
|
2492
|
+
}
|
|
2493
|
+
return {
|
|
2494
|
+
isValid: errors.length === 0,
|
|
2495
|
+
errors,
|
|
2496
|
+
warnings
|
|
2497
|
+
};
|
|
2498
|
+
}
|
|
2499
|
+
function validateDuplicateAdParams(params) {
|
|
2500
|
+
const errors = [];
|
|
2501
|
+
const warnings = [];
|
|
2502
|
+
const id = params.adid || params.adId;
|
|
2503
|
+
if (!id || id <= 0) {
|
|
2504
|
+
errors.push("ID m\u1EABu qu\u1EA3ng c\xE1o g\u1ED1c c\u1EA7n nh\xE2n b\u1EA3n (adid/adId) l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i > 0.");
|
|
2505
|
+
}
|
|
2506
|
+
return {
|
|
2507
|
+
isValid: errors.length === 0,
|
|
2508
|
+
errors,
|
|
2509
|
+
warnings
|
|
2510
|
+
};
|
|
2511
|
+
}
|
|
2512
|
+
var ZaloCampaignsValidator = {
|
|
2513
|
+
createCampaign: validateCreateCampaignPayload,
|
|
2514
|
+
updateAd: validateUpdateAdPayload,
|
|
2515
|
+
renameCampaign: validateRenameCampaignParams,
|
|
2516
|
+
changeStatus: validateChangeCampaignStatusParams,
|
|
2517
|
+
duplicateAd: validateDuplicateAdParams
|
|
2518
|
+
};
|
|
2519
|
+
|
|
2520
|
+
// src/services/campaigns.service.ts
|
|
2521
|
+
var OP_ZaloAdsUpdateVideoAd = {
|
|
2522
|
+
operationId: "ZaloAds_updateVideoAd",
|
|
2523
|
+
method: "POST",
|
|
2524
|
+
endpoint: "/zaapi/UpdateAd",
|
|
2525
|
+
baseUrl: "https://ads.zalo.me",
|
|
2526
|
+
binaryFields: [],
|
|
2527
|
+
pathFields: [],
|
|
2528
|
+
queryFields: [],
|
|
2529
|
+
headerFields: [],
|
|
2530
|
+
cookieFields: [],
|
|
2531
|
+
bodyFields: ["data", "est", "isBoostAd", "stt"]
|
|
2532
|
+
};
|
|
2533
|
+
var OP_ZaloAdsChangeCampaignStatus = {
|
|
2534
|
+
"operationId": "ZaloAds_changeCampaignStatus",
|
|
2535
|
+
"method": "POST",
|
|
2536
|
+
"endpoint": "/api/campaign/change-status",
|
|
2537
|
+
"baseUrl": "https://ads.zalo.me",
|
|
1406
2538
|
"binaryFields": [],
|
|
1407
2539
|
"pathFields": [],
|
|
1408
|
-
"queryFields": [
|
|
1409
|
-
"templateIds"
|
|
1410
|
-
],
|
|
2540
|
+
"queryFields": [],
|
|
1411
2541
|
"headerFields": [],
|
|
1412
2542
|
"cookieFields": [],
|
|
1413
|
-
"bodyFields": [
|
|
2543
|
+
"bodyFields": [
|
|
2544
|
+
"status",
|
|
2545
|
+
"campaignId"
|
|
2546
|
+
]
|
|
1414
2547
|
};
|
|
1415
|
-
var
|
|
1416
|
-
"operationId": "
|
|
2548
|
+
var OP_ZaloAdsCreateEcommerceCampaign = {
|
|
2549
|
+
"operationId": "ZaloAds_createEcommerceCampaign",
|
|
2550
|
+
"method": "POST",
|
|
2551
|
+
"endpoint": "/zaapi/addNewCamp",
|
|
2552
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2553
|
+
"binaryFields": [],
|
|
2554
|
+
"pathFields": [],
|
|
2555
|
+
"queryFields": [],
|
|
2556
|
+
"headerFields": [],
|
|
2557
|
+
"cookieFields": [],
|
|
2558
|
+
"bodyFields": [
|
|
2559
|
+
"data"
|
|
2560
|
+
]
|
|
2561
|
+
};
|
|
2562
|
+
var OP_ZaloAdsCreateForm = {
|
|
2563
|
+
"operationId": "ZaloAds_createForm",
|
|
2564
|
+
"method": "POST",
|
|
2565
|
+
"endpoint": "/api/form/create",
|
|
2566
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2567
|
+
"binaryFields": [],
|
|
2568
|
+
"pathFields": [],
|
|
2569
|
+
"queryFields": [],
|
|
2570
|
+
"headerFields": [],
|
|
2571
|
+
"cookieFields": [],
|
|
2572
|
+
"bodyFields": [
|
|
2573
|
+
"data"
|
|
2574
|
+
]
|
|
2575
|
+
};
|
|
2576
|
+
var OP_ZaloAdsCreateFormCampaign = {
|
|
2577
|
+
"operationId": "ZaloAds_createFormCampaign",
|
|
1417
2578
|
"method": "POST",
|
|
1418
|
-
"endpoint": "/zaapi/
|
|
2579
|
+
"endpoint": "/zaapi/addNewCamp",
|
|
1419
2580
|
"baseUrl": "https://ads.zalo.me",
|
|
1420
2581
|
"binaryFields": [],
|
|
1421
2582
|
"pathFields": [],
|
|
1422
|
-
"queryFields": [
|
|
1423
|
-
"adId"
|
|
1424
|
-
],
|
|
2583
|
+
"queryFields": [],
|
|
1425
2584
|
"headerFields": [],
|
|
1426
2585
|
"cookieFields": [],
|
|
1427
2586
|
"bodyFields": [
|
|
1428
|
-
"
|
|
2587
|
+
"data"
|
|
1429
2588
|
]
|
|
1430
2589
|
};
|
|
1431
|
-
var
|
|
1432
|
-
"operationId": "
|
|
2590
|
+
var OP_ZaloAdsCreateMessageCampaign = {
|
|
2591
|
+
"operationId": "ZaloAds_createMessageCampaign",
|
|
1433
2592
|
"method": "POST",
|
|
1434
|
-
"endpoint": "/
|
|
2593
|
+
"endpoint": "/zaapi/addNewCamp",
|
|
1435
2594
|
"baseUrl": "https://ads.zalo.me",
|
|
1436
2595
|
"binaryFields": [],
|
|
1437
2596
|
"pathFields": [],
|
|
@@ -1439,14 +2598,13 @@ var OP_ZaloAdsRenameCampaign = {
|
|
|
1439
2598
|
"headerFields": [],
|
|
1440
2599
|
"cookieFields": [],
|
|
1441
2600
|
"bodyFields": [
|
|
1442
|
-
"
|
|
1443
|
-
"newname"
|
|
2601
|
+
"data"
|
|
1444
2602
|
]
|
|
1445
2603
|
};
|
|
1446
|
-
var
|
|
1447
|
-
"operationId": "
|
|
2604
|
+
var OP_ZaloAdsCreateOfficialAccountCampaign = {
|
|
2605
|
+
"operationId": "ZaloAds_createOfficialAccountCampaign",
|
|
1448
2606
|
"method": "POST",
|
|
1449
|
-
"endpoint": "/zaapi/
|
|
2607
|
+
"endpoint": "/zaapi/addNewCamp",
|
|
1450
2608
|
"baseUrl": "https://ads.zalo.me",
|
|
1451
2609
|
"binaryFields": [],
|
|
1452
2610
|
"pathFields": [],
|
|
@@ -1454,16 +2612,13 @@ var OP_ZaloAdsUpdateEcommerceAd = {
|
|
|
1454
2612
|
"headerFields": [],
|
|
1455
2613
|
"cookieFields": [],
|
|
1456
2614
|
"bodyFields": [
|
|
1457
|
-
"
|
|
1458
|
-
"stt",
|
|
1459
|
-
"data",
|
|
1460
|
-
"isBoostAd"
|
|
2615
|
+
"data"
|
|
1461
2616
|
]
|
|
1462
2617
|
};
|
|
1463
|
-
var
|
|
1464
|
-
"operationId": "
|
|
2618
|
+
var OP_ZaloAdsCreatePostCampaign = {
|
|
2619
|
+
"operationId": "ZaloAds_createPostCampaign",
|
|
1465
2620
|
"method": "POST",
|
|
1466
|
-
"endpoint": "/zaapi/
|
|
2621
|
+
"endpoint": "/zaapi/addNewCamp",
|
|
1467
2622
|
"baseUrl": "https://ads.zalo.me",
|
|
1468
2623
|
"binaryFields": [],
|
|
1469
2624
|
"pathFields": [],
|
|
@@ -1471,88 +2626,186 @@ var OP_ZaloAdsUpdateFormAd = {
|
|
|
1471
2626
|
"headerFields": [],
|
|
1472
2627
|
"cookieFields": [],
|
|
1473
2628
|
"bodyFields": [
|
|
1474
|
-
"
|
|
1475
|
-
"stt",
|
|
1476
|
-
"data",
|
|
1477
|
-
"isBoostAd"
|
|
2629
|
+
"data"
|
|
1478
2630
|
]
|
|
1479
2631
|
};
|
|
1480
|
-
var
|
|
1481
|
-
"operationId": "
|
|
1482
|
-
"method": "
|
|
1483
|
-
"endpoint": "/zaapi/
|
|
2632
|
+
var OP_ZaloAdsGetAdById = {
|
|
2633
|
+
"operationId": "ZaloAds_getAdById",
|
|
2634
|
+
"method": "GET",
|
|
2635
|
+
"endpoint": "/zaapi/getAdFromAdId",
|
|
2636
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2637
|
+
"binaryFields": [],
|
|
2638
|
+
"pathFields": [],
|
|
2639
|
+
"queryFields": [
|
|
2640
|
+
"adId",
|
|
2641
|
+
"v",
|
|
2642
|
+
"newWard"
|
|
2643
|
+
],
|
|
2644
|
+
"headerFields": [],
|
|
2645
|
+
"cookieFields": [],
|
|
2646
|
+
"bodyFields": []
|
|
2647
|
+
};
|
|
2648
|
+
var OP_ZaloAdsGetAdChangeLog = {
|
|
2649
|
+
"operationId": "ZaloAds_getAdChangeLog",
|
|
2650
|
+
"method": "GET",
|
|
2651
|
+
"endpoint": "/api/ad/log/{adId}",
|
|
2652
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2653
|
+
"binaryFields": [],
|
|
2654
|
+
"pathFields": [
|
|
2655
|
+
"adId"
|
|
2656
|
+
],
|
|
2657
|
+
"queryFields": [
|
|
2658
|
+
"type"
|
|
2659
|
+
],
|
|
2660
|
+
"headerFields": [],
|
|
2661
|
+
"cookieFields": [],
|
|
2662
|
+
"bodyFields": []
|
|
2663
|
+
};
|
|
2664
|
+
var OP_ZaloAdsGetApiPlaceGetalldistricts = {
|
|
2665
|
+
"operationId": "ZaloAds_getApiPlaceGetalldistricts",
|
|
2666
|
+
"method": "GET",
|
|
2667
|
+
"endpoint": "/api/place/getAllDistricts",
|
|
1484
2668
|
"baseUrl": "https://ads.zalo.me",
|
|
1485
2669
|
"binaryFields": [],
|
|
1486
2670
|
"pathFields": [],
|
|
1487
2671
|
"queryFields": [],
|
|
1488
2672
|
"headerFields": [],
|
|
1489
2673
|
"cookieFields": [],
|
|
1490
|
-
"bodyFields": [
|
|
1491
|
-
"est",
|
|
1492
|
-
"stt",
|
|
1493
|
-
"data",
|
|
1494
|
-
"isBoostAd"
|
|
1495
|
-
]
|
|
2674
|
+
"bodyFields": []
|
|
1496
2675
|
};
|
|
1497
|
-
var
|
|
1498
|
-
"operationId": "
|
|
1499
|
-
"method": "
|
|
1500
|
-
"endpoint": "/
|
|
2676
|
+
var OP_ZaloAdsGetApiSpellCheckV2 = {
|
|
2677
|
+
"operationId": "ZaloAds_getApiSpellCheckV2",
|
|
2678
|
+
"method": "GET",
|
|
2679
|
+
"endpoint": "/api/spell-check/v2",
|
|
1501
2680
|
"baseUrl": "https://ads.zalo.me",
|
|
1502
|
-
"binaryFields": [
|
|
1503
|
-
|
|
2681
|
+
"binaryFields": [],
|
|
2682
|
+
"pathFields": [],
|
|
2683
|
+
"queryFields": [
|
|
2684
|
+
"text"
|
|
2685
|
+
],
|
|
2686
|
+
"headerFields": [],
|
|
2687
|
+
"cookieFields": [],
|
|
2688
|
+
"bodyFields": []
|
|
2689
|
+
};
|
|
2690
|
+
var OP_ZaloAdsGetZaapiCheckcamphasmanyads = {
|
|
2691
|
+
"operationId": "ZaloAds_getZaapiCheckcamphasmanyads",
|
|
2692
|
+
"method": "GET",
|
|
2693
|
+
"endpoint": "/zaapi/checkCampHasManyAds",
|
|
2694
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2695
|
+
"binaryFields": [],
|
|
2696
|
+
"pathFields": [],
|
|
2697
|
+
"queryFields": [
|
|
2698
|
+
"campaignId",
|
|
2699
|
+
"campId"
|
|
2700
|
+
],
|
|
2701
|
+
"headerFields": [],
|
|
2702
|
+
"cookieFields": [],
|
|
2703
|
+
"bodyFields": []
|
|
2704
|
+
};
|
|
2705
|
+
var OP_ZaloAdsGetZaapiGetadsfromcampaignid = {
|
|
2706
|
+
"operationId": "ZaloAds_getZaapiGetadsfromcampaignid",
|
|
2707
|
+
"method": "GET",
|
|
2708
|
+
"endpoint": "/zaapi/getAdsFromCampaignId",
|
|
2709
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2710
|
+
"binaryFields": [],
|
|
2711
|
+
"pathFields": [],
|
|
2712
|
+
"queryFields": [
|
|
2713
|
+
"campaignId",
|
|
2714
|
+
"campId",
|
|
2715
|
+
"dataType",
|
|
2716
|
+
"v"
|
|
1504
2717
|
],
|
|
2718
|
+
"headerFields": [],
|
|
2719
|
+
"cookieFields": [],
|
|
2720
|
+
"bodyFields": []
|
|
2721
|
+
};
|
|
2722
|
+
var OP_ZaloAdsGetZaapiGetallpages = {
|
|
2723
|
+
"operationId": "ZaloAds_getZaapiGetallpages",
|
|
2724
|
+
"method": "GET",
|
|
2725
|
+
"endpoint": "/zaapi/getAllPages",
|
|
2726
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2727
|
+
"binaryFields": [],
|
|
1505
2728
|
"pathFields": [],
|
|
1506
2729
|
"queryFields": [],
|
|
1507
2730
|
"headerFields": [],
|
|
1508
2731
|
"cookieFields": [],
|
|
1509
|
-
"bodyFields": [
|
|
1510
|
-
"File",
|
|
1511
|
-
"x",
|
|
1512
|
-
"y",
|
|
1513
|
-
"width",
|
|
1514
|
-
"height",
|
|
1515
|
-
"scale"
|
|
1516
|
-
]
|
|
2732
|
+
"bodyFields": []
|
|
1517
2733
|
};
|
|
1518
|
-
var
|
|
1519
|
-
"operationId": "
|
|
1520
|
-
"method": "
|
|
1521
|
-
"endpoint": "/zaapi/
|
|
2734
|
+
var OP_ZaloAdsGetZaapiGetownedarticles = {
|
|
2735
|
+
"operationId": "ZaloAds_getZaapiGetownedarticles",
|
|
2736
|
+
"method": "GET",
|
|
2737
|
+
"endpoint": "/zaapi/getOwnedArticles",
|
|
2738
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2739
|
+
"binaryFields": [],
|
|
2740
|
+
"pathFields": [],
|
|
2741
|
+
"queryFields": [
|
|
2742
|
+
"pageId"
|
|
2743
|
+
],
|
|
2744
|
+
"headerFields": [],
|
|
2745
|
+
"cookieFields": [],
|
|
2746
|
+
"bodyFields": []
|
|
2747
|
+
};
|
|
2748
|
+
var OP_ZaloAdsGetZaapiGetownedpages = {
|
|
2749
|
+
"operationId": "ZaloAds_getZaapiGetownedpages",
|
|
2750
|
+
"method": "GET",
|
|
2751
|
+
"endpoint": "/zaapi/getOwnedPages",
|
|
1522
2752
|
"baseUrl": "https://ads.zalo.me",
|
|
1523
2753
|
"binaryFields": [],
|
|
1524
2754
|
"pathFields": [],
|
|
1525
2755
|
"queryFields": [],
|
|
1526
2756
|
"headerFields": [],
|
|
1527
2757
|
"cookieFields": [],
|
|
1528
|
-
"bodyFields": [
|
|
1529
|
-
"est",
|
|
1530
|
-
"stt",
|
|
1531
|
-
"data",
|
|
1532
|
-
"isBoostAd"
|
|
1533
|
-
]
|
|
2758
|
+
"bodyFields": []
|
|
1534
2759
|
};
|
|
1535
|
-
var
|
|
1536
|
-
"operationId": "
|
|
2760
|
+
var OP_ZaloAdsListFormsByOfficialAccount = {
|
|
2761
|
+
"operationId": "ZaloAds_listFormsByOfficialAccount",
|
|
2762
|
+
"method": "GET",
|
|
2763
|
+
"endpoint": "/api/form/getByOaId",
|
|
2764
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2765
|
+
"binaryFields": [],
|
|
2766
|
+
"pathFields": [],
|
|
2767
|
+
"queryFields": [
|
|
2768
|
+
"oaId",
|
|
2769
|
+
"isAll"
|
|
2770
|
+
],
|
|
2771
|
+
"headerFields": [],
|
|
2772
|
+
"cookieFields": [],
|
|
2773
|
+
"bodyFields": []
|
|
2774
|
+
};
|
|
2775
|
+
var OP_ZaloAdsListMiniPagesByTemplate = {
|
|
2776
|
+
"operationId": "ZaloAds_listMiniPagesByTemplate",
|
|
2777
|
+
"method": "GET",
|
|
2778
|
+
"endpoint": "/api/mini-pages",
|
|
2779
|
+
"baseUrl": "https://ads.zalo.me",
|
|
2780
|
+
"binaryFields": [],
|
|
2781
|
+
"pathFields": [],
|
|
2782
|
+
"queryFields": [
|
|
2783
|
+
"templateIds"
|
|
2784
|
+
],
|
|
2785
|
+
"headerFields": [],
|
|
2786
|
+
"cookieFields": [],
|
|
2787
|
+
"bodyFields": []
|
|
2788
|
+
};
|
|
2789
|
+
var OP_ZaloAdsPostZaapiDeletead = {
|
|
2790
|
+
"operationId": "ZaloAds_postZaapiDeletead",
|
|
1537
2791
|
"method": "POST",
|
|
1538
|
-
"endpoint": "/zaapi/
|
|
2792
|
+
"endpoint": "/zaapi/deleteAd",
|
|
1539
2793
|
"baseUrl": "https://ads.zalo.me",
|
|
1540
2794
|
"binaryFields": [],
|
|
1541
2795
|
"pathFields": [],
|
|
1542
|
-
"queryFields": [
|
|
2796
|
+
"queryFields": [
|
|
2797
|
+
"adId"
|
|
2798
|
+
],
|
|
1543
2799
|
"headerFields": [],
|
|
1544
2800
|
"cookieFields": [],
|
|
1545
2801
|
"bodyFields": [
|
|
1546
|
-
"
|
|
1547
|
-
"stt",
|
|
1548
|
-
"data",
|
|
1549
|
-
"isBoostAd"
|
|
2802
|
+
"adId"
|
|
1550
2803
|
]
|
|
1551
2804
|
};
|
|
1552
|
-
var
|
|
1553
|
-
"operationId": "
|
|
2805
|
+
var OP_ZaloAdsRenameCampaign = {
|
|
2806
|
+
"operationId": "ZaloAds_renameCampaign",
|
|
1554
2807
|
"method": "POST",
|
|
1555
|
-
"endpoint": "/
|
|
2808
|
+
"endpoint": "/api/campaign/change-name",
|
|
1556
2809
|
"baseUrl": "https://ads.zalo.me",
|
|
1557
2810
|
"binaryFields": [],
|
|
1558
2811
|
"pathFields": [],
|
|
@@ -1560,11 +2813,12 @@ var OP_ZaloAdsCreateWebsiteCampaign = {
|
|
|
1560
2813
|
"headerFields": [],
|
|
1561
2814
|
"cookieFields": [],
|
|
1562
2815
|
"bodyFields": [
|
|
1563
|
-
"
|
|
2816
|
+
"campid",
|
|
2817
|
+
"newname"
|
|
1564
2818
|
]
|
|
1565
2819
|
};
|
|
1566
|
-
var
|
|
1567
|
-
"operationId": "
|
|
2820
|
+
var OP_ZaloAdsUpdateEcommerceAd = {
|
|
2821
|
+
"operationId": "ZaloAds_updateEcommerceAd",
|
|
1568
2822
|
"method": "POST",
|
|
1569
2823
|
"endpoint": "/zaapi/UpdateAd",
|
|
1570
2824
|
"baseUrl": "https://ads.zalo.me",
|
|
@@ -1580,10 +2834,10 @@ var OP_ZaloAdsUpdateWebsiteAd = {
|
|
|
1580
2834
|
"isBoostAd"
|
|
1581
2835
|
]
|
|
1582
2836
|
};
|
|
1583
|
-
var
|
|
1584
|
-
"operationId": "
|
|
2837
|
+
var OP_ZaloAdsUpdateFormAd = {
|
|
2838
|
+
"operationId": "ZaloAds_updateFormAd",
|
|
1585
2839
|
"method": "POST",
|
|
1586
|
-
"endpoint": "/zaapi/
|
|
2840
|
+
"endpoint": "/zaapi/UpdateAd",
|
|
1587
2841
|
"baseUrl": "https://ads.zalo.me",
|
|
1588
2842
|
"binaryFields": [],
|
|
1589
2843
|
"pathFields": [],
|
|
@@ -1591,11 +2845,14 @@ var OP_ZaloAdsCreateDisplayCampaign = {
|
|
|
1591
2845
|
"headerFields": [],
|
|
1592
2846
|
"cookieFields": [],
|
|
1593
2847
|
"bodyFields": [
|
|
1594
|
-
"
|
|
2848
|
+
"est",
|
|
2849
|
+
"stt",
|
|
2850
|
+
"data",
|
|
2851
|
+
"isBoostAd"
|
|
1595
2852
|
]
|
|
1596
2853
|
};
|
|
1597
|
-
var
|
|
1598
|
-
"operationId": "
|
|
2854
|
+
var OP_ZaloAdsUpdateMessageAd = {
|
|
2855
|
+
"operationId": "ZaloAds_updateMessageAd",
|
|
1599
2856
|
"method": "POST",
|
|
1600
2857
|
"endpoint": "/zaapi/UpdateAd",
|
|
1601
2858
|
"baseUrl": "https://ads.zalo.me",
|
|
@@ -1611,24 +2868,31 @@ var OP_ZaloAdsUpdateDisplayAd = {
|
|
|
1611
2868
|
"isBoostAd"
|
|
1612
2869
|
]
|
|
1613
2870
|
};
|
|
1614
|
-
var
|
|
1615
|
-
"operationId": "
|
|
2871
|
+
var OP_ZaloAdsUpdateNewAds = {
|
|
2872
|
+
"operationId": "ZaloAds_UpdateNewAds",
|
|
1616
2873
|
"method": "POST",
|
|
1617
|
-
"endpoint": "/zaapi/
|
|
2874
|
+
"endpoint": "/zaapi/UploadCrop",
|
|
1618
2875
|
"baseUrl": "https://ads.zalo.me",
|
|
1619
|
-
"binaryFields": [
|
|
2876
|
+
"binaryFields": [
|
|
2877
|
+
"File"
|
|
2878
|
+
],
|
|
1620
2879
|
"pathFields": [],
|
|
1621
2880
|
"queryFields": [],
|
|
1622
2881
|
"headerFields": [],
|
|
1623
2882
|
"cookieFields": [],
|
|
1624
2883
|
"bodyFields": [
|
|
1625
|
-
"
|
|
2884
|
+
"File",
|
|
2885
|
+
"x",
|
|
2886
|
+
"y",
|
|
2887
|
+
"width",
|
|
2888
|
+
"height",
|
|
2889
|
+
"scale"
|
|
1626
2890
|
]
|
|
1627
2891
|
};
|
|
1628
|
-
var
|
|
1629
|
-
"operationId": "
|
|
2892
|
+
var OP_ZaloAdsUpdateOfficialAccountAd = {
|
|
2893
|
+
"operationId": "ZaloAds_updateOfficialAccountAd",
|
|
1630
2894
|
"method": "POST",
|
|
1631
|
-
"endpoint": "/
|
|
2895
|
+
"endpoint": "/zaapi/UpdateAd",
|
|
1632
2896
|
"baseUrl": "https://ads.zalo.me",
|
|
1633
2897
|
"binaryFields": [],
|
|
1634
2898
|
"pathFields": [],
|
|
@@ -1636,736 +2900,537 @@ var OP_ZaloAdsDeleteCampaign = {
|
|
|
1636
2900
|
"headerFields": [],
|
|
1637
2901
|
"cookieFields": [],
|
|
1638
2902
|
"bodyFields": [
|
|
1639
|
-
"
|
|
1640
|
-
"
|
|
2903
|
+
"est",
|
|
2904
|
+
"stt",
|
|
2905
|
+
"data",
|
|
2906
|
+
"isBoostAd"
|
|
1641
2907
|
]
|
|
1642
2908
|
};
|
|
1643
|
-
var
|
|
1644
|
-
operationId: "
|
|
1645
|
-
method: "POST",
|
|
1646
|
-
endpoint: "/
|
|
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
|
-
};
|
|
1667
|
-
var ZaloCampaignsService = class {
|
|
1668
|
-
constructor(client) {
|
|
1669
|
-
this.client = client;
|
|
1670
|
-
}
|
|
1671
|
-
updateVideoAd(request, options) {
|
|
1672
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateVideoAd, this.client.toTransportInput(OP_ZaloAdsUpdateVideoAd, request), options);
|
|
1673
|
-
}
|
|
1674
|
-
changeCampaignStatus(request, options) {
|
|
1675
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsChangeCampaignStatus, this.client.toTransportInput(OP_ZaloAdsChangeCampaignStatus, request), options);
|
|
1676
|
-
}
|
|
1677
|
-
deleteCampaign(request, options) {
|
|
1678
|
-
const payload = { campaignId: request.campaignId, status: request.status ?? -2 };
|
|
1679
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsDeleteCampaign, this.client.toTransportInput(OP_ZaloAdsDeleteCampaign, payload), options);
|
|
1680
|
-
}
|
|
1681
|
-
createWebsiteCampaign(request, options) {
|
|
1682
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateWebsiteCampaign, this.client.toTransportInput(OP_ZaloAdsCreateWebsiteCampaign, request), options);
|
|
1683
|
-
}
|
|
1684
|
-
updateWebsiteAd(request, options) {
|
|
1685
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateWebsiteAd, this.client.toTransportInput(OP_ZaloAdsUpdateWebsiteAd, request), options);
|
|
1686
|
-
}
|
|
1687
|
-
createDisplayCampaign(request, options) {
|
|
1688
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateDisplayCampaign, this.client.toTransportInput(OP_ZaloAdsCreateDisplayCampaign, request), options);
|
|
1689
|
-
}
|
|
1690
|
-
updateDisplayAd(request, options) {
|
|
1691
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateDisplayAd, this.client.toTransportInput(OP_ZaloAdsUpdateDisplayAd, request), options);
|
|
1692
|
-
}
|
|
1693
|
-
createVideoCampaign(request, options) {
|
|
1694
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateVideoCampaign, this.client.toTransportInput(OP_ZaloAdsCreateVideoCampaign, request), options);
|
|
1695
|
-
}
|
|
1696
|
-
createEcommerceCampaign(request, options) {
|
|
1697
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateEcommerceCampaign, this.client.toTransportInput(OP_ZaloAdsCreateEcommerceCampaign, request), options);
|
|
1698
|
-
}
|
|
1699
|
-
/** Alias theo tên tool chuẩn `zalo_ads_create_commerce_campaign` trong Project Schema Zalo ADS (`campaignType = 22`). */
|
|
1700
|
-
createCommerceCampaign(request, options) {
|
|
1701
|
-
return this.createEcommerceCampaign(request, options);
|
|
1702
|
-
}
|
|
1703
|
-
createForm(request, options) {
|
|
1704
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateForm, this.client.toTransportInput(OP_ZaloAdsCreateForm, request), options);
|
|
1705
|
-
}
|
|
1706
|
-
createFormCampaign(request, options) {
|
|
1707
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateFormCampaign, this.client.toTransportInput(OP_ZaloAdsCreateFormCampaign, request), options);
|
|
1708
|
-
}
|
|
1709
|
-
createMessageCampaign(request, options) {
|
|
1710
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateMessageCampaign, this.client.toTransportInput(OP_ZaloAdsCreateMessageCampaign, request), options);
|
|
1711
|
-
}
|
|
1712
|
-
createOfficialAccountCampaign(request, options) {
|
|
1713
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateOfficialAccountCampaign, this.client.toTransportInput(OP_ZaloAdsCreateOfficialAccountCampaign, request), options);
|
|
1714
|
-
}
|
|
1715
|
-
/** Alias theo tên tool chuẩn `zalo_ads_create_oa_campaign` trong Project Schema Zalo ADS (`campaignType = 3`). */
|
|
1716
|
-
createOaCampaign(request, options) {
|
|
1717
|
-
return this.createOfficialAccountCampaign(request, options);
|
|
1718
|
-
}
|
|
1719
|
-
createPostCampaign(request, options) {
|
|
1720
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreatePostCampaign, this.client.toTransportInput(OP_ZaloAdsCreatePostCampaign, request), options);
|
|
1721
|
-
}
|
|
1722
|
-
/** Alias theo tên tool chuẩn `zalo_ads_create_article_campaign` trong Project Schema Zalo ADS (`campaignType = 4`). */
|
|
1723
|
-
createArticleCampaign(request, options) {
|
|
1724
|
-
return this.createPostCampaign(request, options);
|
|
1725
|
-
}
|
|
1726
|
-
getAdById(request = {}, options) {
|
|
1727
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetAdById, this.client.toTransportInput(OP_ZaloAdsGetAdById, request), options);
|
|
1728
|
-
}
|
|
1729
|
-
getAdChangeLog(request, options) {
|
|
1730
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetAdChangeLog, this.client.toTransportInput(OP_ZaloAdsGetAdChangeLog, request), options);
|
|
1731
|
-
}
|
|
1732
|
-
getApiPlaceGetalldistricts(request = {}, options) {
|
|
1733
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetApiPlaceGetalldistricts, this.client.toTransportInput(OP_ZaloAdsGetApiPlaceGetalldistricts, request), options);
|
|
1734
|
-
}
|
|
1735
|
-
getApiSpellCheckV2(request, options) {
|
|
1736
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetApiSpellCheckV2, this.client.toTransportInput(OP_ZaloAdsGetApiSpellCheckV2, request), options);
|
|
1737
|
-
}
|
|
1738
|
-
getZaapiCheckcamphasmanyads(request = {}, options) {
|
|
1739
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiCheckcamphasmanyads, this.client.toTransportInput(OP_ZaloAdsGetZaapiCheckcamphasmanyads, request), options);
|
|
1740
|
-
}
|
|
1741
|
-
getZaapiGetadsfromcampaignid(request = {}, options) {
|
|
1742
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetadsfromcampaignid, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetadsfromcampaignid, request), options);
|
|
1743
|
-
}
|
|
1744
|
-
getZaapiGetallpages(request = {}, options) {
|
|
1745
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetallpages, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetallpages, request), options);
|
|
1746
|
-
}
|
|
1747
|
-
getAllPages(request = {}, options) {
|
|
1748
|
-
return this.getZaapiGetallpages(request, options);
|
|
1749
|
-
}
|
|
1750
|
-
getZaapiGetownedarticles(request, options) {
|
|
1751
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetownedarticles, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetownedarticles, request), options);
|
|
1752
|
-
}
|
|
1753
|
-
getOwnedArticles(request, options) {
|
|
1754
|
-
return this.getZaapiGetownedarticles(request, options);
|
|
1755
|
-
}
|
|
1756
|
-
getZaapiGetownedpages(request = {}, options) {
|
|
1757
|
-
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetownedpages, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetownedpages, request), options);
|
|
1758
|
-
}
|
|
1759
|
-
getOwnedPages(request = {}, options) {
|
|
1760
|
-
return this.getZaapiGetownedpages(request, options);
|
|
1761
|
-
}
|
|
1762
|
-
listFormsByOfficialAccount(request, options) {
|
|
1763
|
-
return this.client.requestWithoutBody(OP_ZaloAdsListFormsByOfficialAccount, this.client.toTransportInput(OP_ZaloAdsListFormsByOfficialAccount, request), options);
|
|
1764
|
-
}
|
|
1765
|
-
listMiniPagesByTemplate(request, options) {
|
|
1766
|
-
return this.client.requestWithoutBody(OP_ZaloAdsListMiniPagesByTemplate, this.client.toTransportInput(OP_ZaloAdsListMiniPagesByTemplate, request), options);
|
|
1767
|
-
}
|
|
1768
|
-
postZaapiDeletead(request = {}, options) {
|
|
1769
|
-
return this.client.requestWithoutBody(OP_ZaloAdsPostZaapiDeletead, this.client.toTransportInput(OP_ZaloAdsPostZaapiDeletead, request), options);
|
|
1770
|
-
}
|
|
1771
|
-
renameCampaign(request, options) {
|
|
1772
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsRenameCampaign, this.client.toTransportInput(OP_ZaloAdsRenameCampaign, request), options);
|
|
1773
|
-
}
|
|
1774
|
-
updateEcommerceAd(request, options) {
|
|
1775
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateEcommerceAd, this.client.toTransportInput(OP_ZaloAdsUpdateEcommerceAd, request), options);
|
|
1776
|
-
}
|
|
1777
|
-
/** Alias theo tên tool chuẩn `zalo_ads_update_commerce_ad` trong Project Schema Zalo ADS (`Type = 23`, gắn `MiniPageId`). */
|
|
1778
|
-
updateCommerceAd(request, options) {
|
|
1779
|
-
return this.updateEcommerceAd(request, options);
|
|
1780
|
-
}
|
|
1781
|
-
updateFormAd(request, options) {
|
|
1782
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateFormAd, this.client.toTransportInput(OP_ZaloAdsUpdateFormAd, request), options);
|
|
1783
|
-
}
|
|
1784
|
-
updateMessageAd(request, options) {
|
|
1785
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateMessageAd, this.client.toTransportInput(OP_ZaloAdsUpdateMessageAd, request), options);
|
|
1786
|
-
}
|
|
1787
|
-
updateNewAds(request, options) {
|
|
1788
|
-
return this.client.requestMultipart(OP_ZaloAdsUpdateNewAds, this.client.toTransportInput(OP_ZaloAdsUpdateNewAds, request), options);
|
|
1789
|
-
}
|
|
1790
|
-
updateOfficialAccountAd(request, options) {
|
|
1791
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateOfficialAccountAd, this.client.toTransportInput(OP_ZaloAdsUpdateOfficialAccountAd, request), options);
|
|
1792
|
-
}
|
|
1793
|
-
/** Alias theo tên tool chuẩn `zalo_ads_update_oa_ad` trong Project Schema Zalo ADS (`Type = 2`, `Action = 6`). */
|
|
1794
|
-
updateOaAd(request, options) {
|
|
1795
|
-
return this.updateOfficialAccountAd(request, options);
|
|
1796
|
-
}
|
|
1797
|
-
updatePostAd(request, options) {
|
|
1798
|
-
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdatePostAd, this.client.toTransportInput(OP_ZaloAdsUpdatePostAd, request), options);
|
|
1799
|
-
}
|
|
1800
|
-
/** Alias theo tên tool chuẩn `zalo_ads_update_article_ad` trong Project Schema Zalo ADS (`Type = 3`, gắn `ZaloFeedId`). */
|
|
1801
|
-
updateArticleAd(request, options) {
|
|
1802
|
-
return this.updatePostAd(request, options);
|
|
1803
|
-
}
|
|
1804
|
-
/** Xóa quảng cáo */
|
|
1805
|
-
deleteAd(...args) {
|
|
1806
|
-
return this.postZaapiDeletead(...args);
|
|
1807
|
-
}
|
|
1808
|
-
/** Danh sách quận/huyện để nhắm mục tiêu */
|
|
1809
|
-
getAllDistricts(...args) {
|
|
1810
|
-
return this.getApiPlaceGetalldistricts(...args);
|
|
1811
|
-
}
|
|
1812
|
-
/** Kiểm tra chính tả văn bản quảng cáo */
|
|
1813
|
-
getSpellCheckV2(...args) {
|
|
1814
|
-
return this.getApiSpellCheckV2(...args);
|
|
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
|
-
}
|
|
1858
|
-
};
|
|
1859
|
-
|
|
1860
|
-
// src/services/account.service.ts
|
|
1861
|
-
var OP_ZaloAdsGetApiWhoami = {
|
|
1862
|
-
"operationId": "ZaloAds_getApiWhoami",
|
|
1863
|
-
"method": "GET",
|
|
1864
|
-
"endpoint": "/api/whoami",
|
|
2909
|
+
var OP_ZaloAdsUpdatePostAd = {
|
|
2910
|
+
"operationId": "ZaloAds_updatePostAd",
|
|
2911
|
+
"method": "POST",
|
|
2912
|
+
"endpoint": "/zaapi/UpdateAd",
|
|
1865
2913
|
"baseUrl": "https://ads.zalo.me",
|
|
1866
2914
|
"binaryFields": [],
|
|
1867
2915
|
"pathFields": [],
|
|
1868
2916
|
"queryFields": [],
|
|
1869
2917
|
"headerFields": [],
|
|
1870
2918
|
"cookieFields": [],
|
|
1871
|
-
"bodyFields": [
|
|
2919
|
+
"bodyFields": [
|
|
2920
|
+
"est",
|
|
2921
|
+
"stt",
|
|
2922
|
+
"data",
|
|
2923
|
+
"isBoostAd"
|
|
2924
|
+
]
|
|
1872
2925
|
};
|
|
1873
|
-
var
|
|
1874
|
-
"operationId": "
|
|
1875
|
-
"method": "
|
|
1876
|
-
"endpoint": "/
|
|
2926
|
+
var OP_ZaloAdsCreateWebsiteCampaign = {
|
|
2927
|
+
"operationId": "ZaloAds_createWebsiteCampaign",
|
|
2928
|
+
"method": "POST",
|
|
2929
|
+
"endpoint": "/zaapi/addNewCamp",
|
|
1877
2930
|
"baseUrl": "https://ads.zalo.me",
|
|
1878
2931
|
"binaryFields": [],
|
|
1879
2932
|
"pathFields": [],
|
|
1880
|
-
"queryFields": [
|
|
1881
|
-
"to",
|
|
1882
|
-
"from",
|
|
1883
|
-
"memberId"
|
|
1884
|
-
],
|
|
2933
|
+
"queryFields": [],
|
|
1885
2934
|
"headerFields": [],
|
|
1886
2935
|
"cookieFields": [],
|
|
1887
|
-
"bodyFields": [
|
|
2936
|
+
"bodyFields": [
|
|
2937
|
+
"data"
|
|
2938
|
+
]
|
|
1888
2939
|
};
|
|
1889
|
-
var
|
|
1890
|
-
"operationId": "
|
|
1891
|
-
"method": "
|
|
1892
|
-
"endpoint": "/
|
|
2940
|
+
var OP_ZaloAdsUpdateWebsiteAd = {
|
|
2941
|
+
"operationId": "ZaloAds_updateWebsiteAd",
|
|
2942
|
+
"method": "POST",
|
|
2943
|
+
"endpoint": "/zaapi/UpdateAd",
|
|
1893
2944
|
"baseUrl": "https://ads.zalo.me",
|
|
1894
2945
|
"binaryFields": [],
|
|
1895
2946
|
"pathFields": [],
|
|
1896
|
-
"queryFields": [
|
|
1897
|
-
"isShowAll"
|
|
1898
|
-
],
|
|
2947
|
+
"queryFields": [],
|
|
1899
2948
|
"headerFields": [],
|
|
1900
2949
|
"cookieFields": [],
|
|
1901
|
-
"bodyFields": [
|
|
2950
|
+
"bodyFields": [
|
|
2951
|
+
"est",
|
|
2952
|
+
"stt",
|
|
2953
|
+
"data",
|
|
2954
|
+
"isBoostAd"
|
|
2955
|
+
]
|
|
1902
2956
|
};
|
|
1903
|
-
var
|
|
1904
|
-
"operationId": "
|
|
1905
|
-
"method": "
|
|
1906
|
-
"endpoint": "/
|
|
2957
|
+
var OP_ZaloAdsCreateDisplayCampaign = {
|
|
2958
|
+
"operationId": "ZaloAds_createDisplayCampaign",
|
|
2959
|
+
"method": "POST",
|
|
2960
|
+
"endpoint": "/zaapi/addNewCamp",
|
|
1907
2961
|
"baseUrl": "https://ads.zalo.me",
|
|
1908
2962
|
"binaryFields": [],
|
|
1909
2963
|
"pathFields": [],
|
|
1910
2964
|
"queryFields": [],
|
|
1911
2965
|
"headerFields": [],
|
|
1912
2966
|
"cookieFields": [],
|
|
1913
|
-
"bodyFields": [
|
|
2967
|
+
"bodyFields": [
|
|
2968
|
+
"data"
|
|
2969
|
+
]
|
|
1914
2970
|
};
|
|
1915
|
-
var
|
|
1916
|
-
"operationId": "
|
|
1917
|
-
"method": "
|
|
1918
|
-
"endpoint": "/
|
|
2971
|
+
var OP_ZaloAdsUpdateDisplayAd = {
|
|
2972
|
+
"operationId": "ZaloAds_updateDisplayAd",
|
|
2973
|
+
"method": "POST",
|
|
2974
|
+
"endpoint": "/zaapi/UpdateAd",
|
|
1919
2975
|
"baseUrl": "https://ads.zalo.me",
|
|
1920
2976
|
"binaryFields": [],
|
|
1921
2977
|
"pathFields": [],
|
|
1922
|
-
"queryFields": [
|
|
1923
|
-
"limit",
|
|
1924
|
-
"offset",
|
|
1925
|
-
"joinDateAsc"
|
|
1926
|
-
],
|
|
2978
|
+
"queryFields": [],
|
|
1927
2979
|
"headerFields": [],
|
|
1928
2980
|
"cookieFields": [],
|
|
1929
|
-
"bodyFields": [
|
|
2981
|
+
"bodyFields": [
|
|
2982
|
+
"est",
|
|
2983
|
+
"stt",
|
|
2984
|
+
"data",
|
|
2985
|
+
"isBoostAd"
|
|
2986
|
+
]
|
|
1930
2987
|
};
|
|
1931
|
-
var
|
|
1932
|
-
"operationId": "
|
|
1933
|
-
"method": "
|
|
1934
|
-
"endpoint": "/
|
|
2988
|
+
var OP_ZaloAdsCreateVideoCampaign = {
|
|
2989
|
+
"operationId": "ZaloAds_createVideoCampaign",
|
|
2990
|
+
"method": "POST",
|
|
2991
|
+
"endpoint": "/zaapi/addNewCamp",
|
|
1935
2992
|
"baseUrl": "https://ads.zalo.me",
|
|
1936
2993
|
"binaryFields": [],
|
|
1937
2994
|
"pathFields": [],
|
|
1938
2995
|
"queryFields": [],
|
|
1939
2996
|
"headerFields": [],
|
|
1940
2997
|
"cookieFields": [],
|
|
1941
|
-
"bodyFields": [
|
|
2998
|
+
"bodyFields": [
|
|
2999
|
+
"data"
|
|
3000
|
+
]
|
|
1942
3001
|
};
|
|
1943
|
-
var
|
|
1944
|
-
"operationId": "
|
|
1945
|
-
"method": "
|
|
1946
|
-
"endpoint": "/api/
|
|
3002
|
+
var OP_ZaloAdsDeleteCampaign = {
|
|
3003
|
+
"operationId": "ZaloAds_deleteCampaign",
|
|
3004
|
+
"method": "POST",
|
|
3005
|
+
"endpoint": "/api/campaign/change-status",
|
|
1947
3006
|
"baseUrl": "https://ads.zalo.me",
|
|
1948
3007
|
"binaryFields": [],
|
|
1949
3008
|
"pathFields": [],
|
|
1950
3009
|
"queryFields": [],
|
|
1951
3010
|
"headerFields": [],
|
|
1952
3011
|
"cookieFields": [],
|
|
1953
|
-
"bodyFields": [
|
|
3012
|
+
"bodyFields": [
|
|
3013
|
+
"campaignId",
|
|
3014
|
+
"status"
|
|
3015
|
+
]
|
|
1954
3016
|
};
|
|
1955
|
-
var
|
|
3017
|
+
var OP_ZaloAdsDuplicateAd = {
|
|
3018
|
+
operationId: "zalo_ads_duplicate_ad",
|
|
3019
|
+
method: "POST",
|
|
3020
|
+
endpoint: "/zaapi/DuplicateAd",
|
|
3021
|
+
baseUrl: "https://ads.zalo.me",
|
|
3022
|
+
binaryFields: [],
|
|
3023
|
+
pathFields: [],
|
|
3024
|
+
queryFields: [],
|
|
3025
|
+
headerFields: [],
|
|
3026
|
+
cookieFields: [],
|
|
3027
|
+
bodyFields: ["adid"]
|
|
3028
|
+
};
|
|
3029
|
+
var OP_ZaloAdsCreateSpellCheckV3Job = {
|
|
3030
|
+
operationId: "zalo_ads_create_spell_check_v3_job",
|
|
3031
|
+
method: "POST",
|
|
3032
|
+
endpoint: "/api/spell-check/v3",
|
|
3033
|
+
baseUrl: "https://ads.zalo.me",
|
|
3034
|
+
binaryFields: [],
|
|
3035
|
+
pathFields: [],
|
|
3036
|
+
queryFields: [],
|
|
3037
|
+
headerFields: [],
|
|
3038
|
+
cookieFields: [],
|
|
3039
|
+
bodyFields: ["title", "caption"]
|
|
3040
|
+
};
|
|
3041
|
+
var OP_ZaloAdsGetSpellCheckV3Job = {
|
|
3042
|
+
operationId: "zalo_ads_get_spell_check_v3_job",
|
|
3043
|
+
method: "GET",
|
|
3044
|
+
endpoint: "/api/spell-check/v3/{jobId}",
|
|
3045
|
+
baseUrl: "https://ads.zalo.me",
|
|
3046
|
+
binaryFields: [],
|
|
3047
|
+
pathFields: ["jobId"],
|
|
3048
|
+
queryFields: [],
|
|
3049
|
+
headerFields: [],
|
|
3050
|
+
cookieFields: [],
|
|
3051
|
+
bodyFields: []
|
|
3052
|
+
};
|
|
3053
|
+
var ZaloCampaignsService = class {
|
|
1956
3054
|
constructor(client) {
|
|
1957
3055
|
this.client = client;
|
|
1958
3056
|
}
|
|
1959
|
-
|
|
1960
|
-
|
|
3057
|
+
validator = ZaloCampaignsValidator;
|
|
3058
|
+
static validator = ZaloCampaignsValidator;
|
|
3059
|
+
updateVideoAd(request, options) {
|
|
3060
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateVideoAd, this.client.toTransportInput(OP_ZaloAdsUpdateVideoAd, request), options);
|
|
1961
3061
|
}
|
|
1962
|
-
|
|
1963
|
-
return this.client.
|
|
3062
|
+
changeCampaignStatus(request, options) {
|
|
3063
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsChangeCampaignStatus, this.client.toTransportInput(OP_ZaloAdsChangeCampaignStatus, request), options);
|
|
1964
3064
|
}
|
|
1965
|
-
|
|
1966
|
-
|
|
3065
|
+
deleteCampaign(request, options) {
|
|
3066
|
+
const payload = { campaignId: request.campaignId, status: request.status ?? -2 };
|
|
3067
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsDeleteCampaign, this.client.toTransportInput(OP_ZaloAdsDeleteCampaign, payload), options);
|
|
1967
3068
|
}
|
|
1968
|
-
|
|
1969
|
-
return this.client.
|
|
3069
|
+
createWebsiteCampaign(request, options) {
|
|
3070
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateWebsiteCampaign, this.client.toTransportInput(OP_ZaloAdsCreateWebsiteCampaign, request), options);
|
|
1970
3071
|
}
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
limit: 15,
|
|
1974
|
-
offset: 0,
|
|
1975
|
-
joinDateAsc: true,
|
|
1976
|
-
...request
|
|
1977
|
-
};
|
|
1978
|
-
return this.client.requestWithoutBody(OP_ZaloAdsListAgencyCustomersWithBudget, this.client.toTransportInput(OP_ZaloAdsListAgencyCustomersWithBudget, normalized), options);
|
|
3072
|
+
updateWebsiteAd(request, options) {
|
|
3073
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateWebsiteAd, this.client.toTransportInput(OP_ZaloAdsUpdateWebsiteAd, request), options);
|
|
1979
3074
|
}
|
|
1980
|
-
|
|
1981
|
-
return this.client.
|
|
3075
|
+
createDisplayCampaign(request, options) {
|
|
3076
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateDisplayCampaign, this.client.toTransportInput(OP_ZaloAdsCreateDisplayCampaign, request), options);
|
|
1982
3077
|
}
|
|
1983
|
-
|
|
1984
|
-
return this.client.
|
|
3078
|
+
updateDisplayAd(request, options) {
|
|
3079
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateDisplayAd, this.client.toTransportInput(OP_ZaloAdsUpdateDisplayAd, request), options);
|
|
1985
3080
|
}
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
return this.getApiWhoami(...args);
|
|
3081
|
+
createVideoCampaign(request, options) {
|
|
3082
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateVideoCampaign, this.client.toTransportInput(OP_ZaloAdsCreateVideoCampaign, request), options);
|
|
1989
3083
|
}
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
return this.getApiPaymentTransactionHistory(...args);
|
|
3084
|
+
createEcommerceCampaign(request, options) {
|
|
3085
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateEcommerceCampaign, this.client.toTransportInput(OP_ZaloAdsCreateEcommerceCampaign, request), options);
|
|
1993
3086
|
}
|
|
1994
|
-
/**
|
|
1995
|
-
|
|
1996
|
-
return this.
|
|
3087
|
+
/** Alias theo tên tool chuẩn `zalo_ads_create_commerce_campaign` trong Project Schema Zalo ADS (`campaignType = 22`). */
|
|
3088
|
+
createCommerceCampaign(request, options) {
|
|
3089
|
+
return this.createEcommerceCampaign(request, options);
|
|
1997
3090
|
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
return this.getApiBaAccountAllgrantedmembers(...args);
|
|
3091
|
+
createForm(request, options) {
|
|
3092
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateForm, this.client.toTransportInput(OP_ZaloAdsCreateForm, request), options);
|
|
2001
3093
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
return this.getApiNotifiesHeader(...args);
|
|
3094
|
+
createFormCampaign(request, options) {
|
|
3095
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateFormCampaign, this.client.toTransportInput(OP_ZaloAdsCreateFormCampaign, request), options);
|
|
2005
3096
|
}
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
return this.getApiLpNews(...args);
|
|
3097
|
+
createMessageCampaign(request, options) {
|
|
3098
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateMessageCampaign, this.client.toTransportInput(OP_ZaloAdsCreateMessageCampaign, request), options);
|
|
2009
3099
|
}
|
|
2010
|
-
|
|
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 };
|
|
3100
|
+
createOfficialAccountCampaign(request, options) {
|
|
3101
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreateOfficialAccountCampaign, this.client.toTransportInput(OP_ZaloAdsCreateOfficialAccountCampaign, request), options);
|
|
2017
3102
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
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.");
|
|
3103
|
+
/** Alias theo tên tool chuẩn `zalo_ads_create_oa_campaign` trong Project Schema Zalo ADS (`campaignType = 3`). */
|
|
3104
|
+
createOaCampaign(request, options) {
|
|
3105
|
+
return this.createOfficialAccountCampaign(request, options);
|
|
2024
3106
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
3107
|
+
createPostCampaign(request, options) {
|
|
3108
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsCreatePostCampaign, this.client.toTransportInput(OP_ZaloAdsCreatePostCampaign, request), options);
|
|
3109
|
+
}
|
|
3110
|
+
/** Alias theo tên tool chuẩn `zalo_ads_create_article_campaign` trong Project Schema Zalo ADS (`campaignType = 4`). */
|
|
3111
|
+
createArticleCampaign(request, options) {
|
|
3112
|
+
return this.createPostCampaign(request, options);
|
|
3113
|
+
}
|
|
3114
|
+
getAdById(request = {}, options) {
|
|
3115
|
+
const normalized = {
|
|
3116
|
+
adId: request.adId,
|
|
3117
|
+
v: request.v ?? 2,
|
|
3118
|
+
newWard: request.newWard ?? true
|
|
3119
|
+
};
|
|
3120
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetAdById, this.client.toTransportInput(OP_ZaloAdsGetAdById, normalized), options);
|
|
3121
|
+
}
|
|
3122
|
+
getAdChangeLog(request, options) {
|
|
3123
|
+
const normalized = {
|
|
3124
|
+
adId: request.adId,
|
|
3125
|
+
type: request.type ?? 1
|
|
3126
|
+
};
|
|
3127
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetAdChangeLog, this.client.toTransportInput(OP_ZaloAdsGetAdChangeLog, normalized), options);
|
|
3128
|
+
}
|
|
3129
|
+
getApiPlaceGetalldistricts(request = {}, options) {
|
|
3130
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetApiPlaceGetalldistricts, this.client.toTransportInput(OP_ZaloAdsGetApiPlaceGetalldistricts, request), options);
|
|
3131
|
+
}
|
|
3132
|
+
getApiSpellCheckV2(request, options) {
|
|
3133
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetApiSpellCheckV2, this.client.toTransportInput(OP_ZaloAdsGetApiSpellCheckV2, request), options);
|
|
3134
|
+
}
|
|
3135
|
+
getZaapiCheckcamphasmanyads(request = {}, options) {
|
|
3136
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiCheckcamphasmanyads, this.client.toTransportInput(OP_ZaloAdsGetZaapiCheckcamphasmanyads, request), options);
|
|
3137
|
+
}
|
|
3138
|
+
getZaapiGetadsfromcampaignid(request = {}, options) {
|
|
3139
|
+
const normalized = {
|
|
3140
|
+
campaignId: request.campaignId ?? request.campId,
|
|
3141
|
+
dataType: request.dataType ?? 1,
|
|
3142
|
+
v: request.v ?? 2
|
|
3143
|
+
};
|
|
3144
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetadsfromcampaignid, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetadsfromcampaignid, normalized), options);
|
|
3145
|
+
}
|
|
3146
|
+
/** Alias lấy danh sách quảng cáo của chiến dịch kèm metadata extend và extra.appliedRuleInfo */
|
|
3147
|
+
getAdsFromCampaignId(request = {}, options) {
|
|
3148
|
+
return this.getZaapiGetadsfromcampaignid(request, options);
|
|
3149
|
+
}
|
|
3150
|
+
getZaapiGetallpages(request = {}, options) {
|
|
3151
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetallpages, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetallpages, request), options);
|
|
3152
|
+
}
|
|
3153
|
+
getAllPages(request = {}, options) {
|
|
3154
|
+
return this.getZaapiGetallpages(request, options);
|
|
3155
|
+
}
|
|
3156
|
+
getZaapiGetownedarticles(request, options) {
|
|
3157
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetownedarticles, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetownedarticles, request), options);
|
|
2038
3158
|
}
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
errors.push("Tr\u01B0\u1EDDng 'Gender' ph\u1EA3i l\xE0 0 (T\u1EA5t c\u1EA3), 1 (Nam), ho\u1EB7c 2 (N\u1EEF).");
|
|
3159
|
+
getOwnedArticles(request, options) {
|
|
3160
|
+
return this.getZaapiGetownedarticles(request, options);
|
|
2042
3161
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
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
|
-
}
|
|
3162
|
+
getZaapiGetownedpages(request = {}, options) {
|
|
3163
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetZaapiGetownedpages, this.client.toTransportInput(OP_ZaloAdsGetZaapiGetownedpages, request), options);
|
|
2049
3164
|
}
|
|
2050
|
-
|
|
2051
|
-
|
|
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
|
-
}
|
|
3165
|
+
getOwnedPages(request = {}, options) {
|
|
3166
|
+
return this.getZaapiGetownedpages(request, options);
|
|
2056
3167
|
}
|
|
2057
|
-
|
|
2058
|
-
|
|
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
|
-
}
|
|
3168
|
+
listFormsByOfficialAccount(request, options) {
|
|
3169
|
+
return this.client.requestWithoutBody(OP_ZaloAdsListFormsByOfficialAccount, this.client.toTransportInput(OP_ZaloAdsListFormsByOfficialAccount, request), options);
|
|
2082
3170
|
}
|
|
2083
|
-
|
|
2084
|
-
|
|
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 };
|
|
3171
|
+
listMiniPagesByTemplate(request, options) {
|
|
3172
|
+
return this.client.requestWithoutBody(OP_ZaloAdsListMiniPagesByTemplate, this.client.toTransportInput(OP_ZaloAdsListMiniPagesByTemplate, request), options);
|
|
2105
3173
|
}
|
|
2106
|
-
|
|
2107
|
-
|
|
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.");
|
|
3174
|
+
postZaapiDeletead(request = {}, options) {
|
|
3175
|
+
return this.client.requestWithoutBody(OP_ZaloAdsPostZaapiDeletead, this.client.toTransportInput(OP_ZaloAdsPostZaapiDeletead, request), options);
|
|
2110
3176
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
}
|
|
2116
|
-
|
|
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.");
|
|
3177
|
+
renameCampaign(request, options) {
|
|
3178
|
+
const normalized = {
|
|
3179
|
+
campid: request.campid ?? request.campaignId,
|
|
3180
|
+
newname: request.newname ?? request.campaignName ?? request.name
|
|
3181
|
+
};
|
|
3182
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsRenameCampaign, this.client.toTransportInput(OP_ZaloAdsRenameCampaign, normalized), options);
|
|
2122
3183
|
}
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
errors.push("Tr\u01B0\u1EDDng 'Path' (URL file .txt sau khi upload) l\xE0 b\u1EAFt bu\u1ED9c.");
|
|
3184
|
+
updateEcommerceAd(request, options) {
|
|
3185
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateEcommerceAd, this.client.toTransportInput(OP_ZaloAdsUpdateEcommerceAd, request), options);
|
|
2126
3186
|
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
3187
|
+
/** Alias theo tên tool chuẩn `zalo_ads_update_commerce_ad` trong Project Schema Zalo ADS (`Type = 23`, gắn `MiniPageId`). */
|
|
3188
|
+
updateCommerceAd(request, options) {
|
|
3189
|
+
return this.updateEcommerceAd(request, options);
|
|
2130
3190
|
}
|
|
2131
|
-
|
|
2132
|
-
|
|
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 };
|
|
3191
|
+
updateFormAd(request, options) {
|
|
3192
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateFormAd, this.client.toTransportInput(OP_ZaloAdsUpdateFormAd, request), options);
|
|
2151
3193
|
}
|
|
2152
|
-
|
|
2153
|
-
|
|
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.");
|
|
3194
|
+
updateMessageAd(request, options) {
|
|
3195
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateMessageAd, this.client.toTransportInput(OP_ZaloAdsUpdateMessageAd, request), options);
|
|
2156
3196
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
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.");
|
|
3197
|
+
updateNewAds(request, options) {
|
|
3198
|
+
return this.client.requestMultipart(OP_ZaloAdsUpdateNewAds, this.client.toTransportInput(OP_ZaloAdsUpdateNewAds, request), options);
|
|
2168
3199
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
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.");
|
|
3200
|
+
updateOfficialAccountAd(request, options) {
|
|
3201
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdateOfficialAccountAd, this.client.toTransportInput(OP_ZaloAdsUpdateOfficialAccountAd, request), options);
|
|
2172
3202
|
}
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
3203
|
+
/** Alias theo tên tool chuẩn `zalo_ads_update_oa_ad` trong Project Schema Zalo ADS (`Type = 2`, `Action = 6`). */
|
|
3204
|
+
updateOaAd(request, options) {
|
|
3205
|
+
return this.updateOfficialAccountAd(request, options);
|
|
2176
3206
|
}
|
|
2177
|
-
|
|
2178
|
-
|
|
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 };
|
|
3207
|
+
updatePostAd(request, options) {
|
|
3208
|
+
return this.client.requestFormUrlEncoded(OP_ZaloAdsUpdatePostAd, this.client.toTransportInput(OP_ZaloAdsUpdatePostAd, request), options);
|
|
2196
3209
|
}
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
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.");
|
|
3210
|
+
/** Alias theo tên tool chuẩn `zalo_ads_update_article_ad` trong Project Schema Zalo ADS (`Type = 3`, gắn `ZaloFeedId`). */
|
|
3211
|
+
updateArticleAd(request, options) {
|
|
3212
|
+
return this.updatePostAd(request, options);
|
|
2201
3213
|
}
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
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;
|
|
3214
|
+
/** Xóa quảng cáo */
|
|
3215
|
+
deleteAd(...args) {
|
|
3216
|
+
return this.postZaapiDeletead(...args);
|
|
2211
3217
|
}
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
3218
|
+
/** Danh sách quận/huyện để nhắm mục tiêu */
|
|
3219
|
+
getAllDistricts(...args) {
|
|
3220
|
+
return this.getApiPlaceGetalldistricts(...args);
|
|
2215
3221
|
}
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
3222
|
+
/** Kiểm tra chính tả văn bản quảng cáo */
|
|
3223
|
+
getSpellCheckV2(...args) {
|
|
3224
|
+
return this.getApiSpellCheckV2(...args);
|
|
2219
3225
|
}
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
3226
|
+
/**
|
|
3227
|
+
* 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).
|
|
3228
|
+
*/
|
|
3229
|
+
createSpellCheckV3Job(request, options) {
|
|
3230
|
+
return this.client.requestJson(
|
|
3231
|
+
OP_ZaloAdsCreateSpellCheckV3Job,
|
|
3232
|
+
this.client.toTransportInput(OP_ZaloAdsCreateSpellCheckV3Job, request),
|
|
3233
|
+
options
|
|
3234
|
+
);
|
|
2223
3235
|
}
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
3236
|
+
/**
|
|
3237
|
+
* Lấy kết quả kiểm tra chính tả AI V3 theo jobId (GET /api/spell-check/v3/{jobId}).
|
|
3238
|
+
*/
|
|
3239
|
+
getSpellCheckV3Job(request, options) {
|
|
3240
|
+
return this.client.requestWithoutBody(
|
|
3241
|
+
OP_ZaloAdsGetSpellCheckV3Job,
|
|
3242
|
+
this.client.toTransportInput(OP_ZaloAdsGetSpellCheckV3Job, request),
|
|
3243
|
+
options
|
|
3244
|
+
);
|
|
2227
3245
|
}
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
3246
|
+
/**
|
|
3247
|
+
* 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).
|
|
3248
|
+
* @param request Tiêu đề (title) và chú thích (caption) cần kiểm tra.
|
|
3249
|
+
* @param pollIntervalMs Chu kỳ polling kiểm tra trạng thái (mặc định: 600ms).
|
|
3250
|
+
* @param timeoutMs Thời gian chờ tối đa (mặc định: 15.000ms = 15 giây).
|
|
3251
|
+
*/
|
|
3252
|
+
async checkSpellV3AndWait(request, pollIntervalMs = 600, timeoutMs = 15e3, options) {
|
|
3253
|
+
const jobRes = await this.createSpellCheckV3Job(request, options);
|
|
3254
|
+
const jobId = jobRes?.data?.jobId;
|
|
3255
|
+
if (!jobId) {
|
|
3256
|
+
throw new Error(`[SpellCheckV3] Kh\xF4ng nh\u1EADn \u0111\u01B0\u1EE3c jobId t\u1EEB Zalo Ads (code: ${jobRes?.code})`);
|
|
3257
|
+
}
|
|
3258
|
+
const startTime = Date.now();
|
|
3259
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
3260
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
3261
|
+
const res = await this.getSpellCheckV3Job({ jobId }, options);
|
|
3262
|
+
if (res?.data?.status === "COMPLETED") {
|
|
3263
|
+
return res;
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
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}`);
|
|
2247
3267
|
}
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
3268
|
+
/**
|
|
3269
|
+
* Nhân bản (sao chép / duplicate) một mẫu quảng cáo đã tồn tại trên Zalo Ads (POST /zaapi/DuplicateAd).
|
|
3270
|
+
* Giúp tạo nhanh một bản sao Ad mới trong cùng chiến dịch để thực hiện A/B testing.
|
|
3271
|
+
*/
|
|
3272
|
+
duplicateAd(request, options) {
|
|
3273
|
+
const payload = {
|
|
3274
|
+
adid: request.adid ?? request.adId
|
|
3275
|
+
};
|
|
3276
|
+
return this.client.requestFormUrlEncoded(
|
|
3277
|
+
OP_ZaloAdsDuplicateAd,
|
|
3278
|
+
this.client.toTransportInput(OP_ZaloAdsDuplicateAd, payload),
|
|
3279
|
+
options
|
|
3280
|
+
);
|
|
2252
3281
|
}
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
3282
|
+
};
|
|
3283
|
+
|
|
3284
|
+
// src/services/account.service.ts
|
|
3285
|
+
var OP_ZaloAdsGetApiWhoami = {
|
|
3286
|
+
"operationId": "ZaloAds_getApiWhoami",
|
|
3287
|
+
"method": "GET",
|
|
3288
|
+
"endpoint": "/api/whoami",
|
|
3289
|
+
"baseUrl": "https://ads.zalo.me",
|
|
3290
|
+
"binaryFields": [],
|
|
3291
|
+
"pathFields": [],
|
|
3292
|
+
"queryFields": [],
|
|
3293
|
+
"headerFields": [],
|
|
3294
|
+
"cookieFields": [],
|
|
3295
|
+
"bodyFields": []
|
|
3296
|
+
};
|
|
3297
|
+
var OP_ZaloAdsGetApiPaymentTransactionHistory = {
|
|
3298
|
+
"operationId": "ZaloAds_getApiPaymentTransactionHistory",
|
|
3299
|
+
"method": "GET",
|
|
3300
|
+
"endpoint": "/api/payment/transaction-history",
|
|
3301
|
+
"baseUrl": "https://ads.zalo.me",
|
|
3302
|
+
"binaryFields": [],
|
|
3303
|
+
"pathFields": [],
|
|
3304
|
+
"queryFields": [
|
|
3305
|
+
"to",
|
|
3306
|
+
"from",
|
|
3307
|
+
"memberId"
|
|
3308
|
+
],
|
|
3309
|
+
"headerFields": [],
|
|
3310
|
+
"cookieFields": [],
|
|
3311
|
+
"bodyFields": []
|
|
3312
|
+
};
|
|
3313
|
+
var OP_ZaloAdsGetApiBaAccountAllaccessors = {
|
|
3314
|
+
"operationId": "ZaloAds_getApiBaAccountAllaccessors",
|
|
3315
|
+
"method": "GET",
|
|
3316
|
+
"endpoint": "/api/ba/account/allAccessors",
|
|
3317
|
+
"baseUrl": "https://ads.zalo.me",
|
|
3318
|
+
"binaryFields": [],
|
|
3319
|
+
"pathFields": [],
|
|
3320
|
+
"queryFields": [
|
|
3321
|
+
"isShowAll"
|
|
3322
|
+
],
|
|
3323
|
+
"headerFields": [],
|
|
3324
|
+
"cookieFields": [],
|
|
3325
|
+
"bodyFields": []
|
|
3326
|
+
};
|
|
3327
|
+
var OP_ZaloAdsGetApiBaAccountAllgrantedmembers = {
|
|
3328
|
+
"operationId": "ZaloAds_getApiBaAccountAllgrantedmembers",
|
|
3329
|
+
"method": "GET",
|
|
3330
|
+
"endpoint": "/api/ba/account/allGrantedMembers",
|
|
3331
|
+
"baseUrl": "https://ads.zalo.me",
|
|
3332
|
+
"binaryFields": [],
|
|
3333
|
+
"pathFields": [],
|
|
3334
|
+
"queryFields": [],
|
|
3335
|
+
"headerFields": [],
|
|
3336
|
+
"cookieFields": [],
|
|
3337
|
+
"bodyFields": []
|
|
3338
|
+
};
|
|
3339
|
+
var OP_ZaloAdsListAgencyCustomersWithBudget = {
|
|
3340
|
+
"operationId": "ZaloAds_listAgencyCustomersWithBudget",
|
|
3341
|
+
"method": "GET",
|
|
3342
|
+
"endpoint": "/api/ba/agency/customersWithBudget",
|
|
3343
|
+
"baseUrl": "https://ads.zalo.me",
|
|
3344
|
+
"binaryFields": [],
|
|
3345
|
+
"pathFields": [],
|
|
3346
|
+
"queryFields": [
|
|
3347
|
+
"limit",
|
|
3348
|
+
"offset",
|
|
3349
|
+
"joinDateAsc"
|
|
3350
|
+
],
|
|
3351
|
+
"headerFields": [],
|
|
3352
|
+
"cookieFields": [],
|
|
3353
|
+
"bodyFields": []
|
|
3354
|
+
};
|
|
3355
|
+
var OP_ZaloAdsGetApiNotifiesHeader = {
|
|
3356
|
+
"operationId": "ZaloAds_getApiNotifiesHeader",
|
|
3357
|
+
"method": "GET",
|
|
3358
|
+
"endpoint": "/api/notifies/header",
|
|
3359
|
+
"baseUrl": "https://ads.zalo.me",
|
|
3360
|
+
"binaryFields": [],
|
|
3361
|
+
"pathFields": [],
|
|
3362
|
+
"queryFields": [],
|
|
3363
|
+
"headerFields": [],
|
|
3364
|
+
"cookieFields": [],
|
|
3365
|
+
"bodyFields": []
|
|
3366
|
+
};
|
|
3367
|
+
var OP_ZaloAdsGetApiLpNews = {
|
|
3368
|
+
"operationId": "ZaloAds_getApiLpNews",
|
|
3369
|
+
"method": "GET",
|
|
3370
|
+
"endpoint": "/api/lp-news",
|
|
3371
|
+
"baseUrl": "https://ads.zalo.me",
|
|
3372
|
+
"binaryFields": [],
|
|
3373
|
+
"pathFields": [],
|
|
3374
|
+
"queryFields": [],
|
|
3375
|
+
"headerFields": [],
|
|
3376
|
+
"cookieFields": [],
|
|
3377
|
+
"bodyFields": []
|
|
3378
|
+
};
|
|
3379
|
+
var ZaloAccountService = class {
|
|
3380
|
+
constructor(client) {
|
|
3381
|
+
this.client = client;
|
|
2262
3382
|
}
|
|
2263
|
-
|
|
2264
|
-
|
|
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.");
|
|
3383
|
+
getApiWhoami(request = {}, options) {
|
|
3384
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetApiWhoami, this.client.toTransportInput(OP_ZaloAdsGetApiWhoami, request), options);
|
|
2267
3385
|
}
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
3386
|
+
getApiPaymentTransactionHistory(request, options) {
|
|
3387
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetApiPaymentTransactionHistory, this.client.toTransportInput(OP_ZaloAdsGetApiPaymentTransactionHistory, request), options);
|
|
2271
3388
|
}
|
|
2272
|
-
|
|
2273
|
-
|
|
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 };
|
|
3389
|
+
getApiBaAccountAllaccessors(request = {}, options) {
|
|
3390
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetApiBaAccountAllaccessors, this.client.toTransportInput(OP_ZaloAdsGetApiBaAccountAllaccessors, request), options);
|
|
2290
3391
|
}
|
|
2291
|
-
|
|
2292
|
-
|
|
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.");
|
|
3392
|
+
getApiBaAccountAllgrantedmembers(request = {}, options) {
|
|
3393
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetApiBaAccountAllgrantedmembers, this.client.toTransportInput(OP_ZaloAdsGetApiBaAccountAllgrantedmembers, request), options);
|
|
2295
3394
|
}
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
}
|
|
2303
|
-
|
|
2304
|
-
targetingObj = raw.targeting;
|
|
3395
|
+
listAgencyCustomersWithBudget(request = { limit: 15, offset: 0, joinDateAsc: true }, options) {
|
|
3396
|
+
const normalized = {
|
|
3397
|
+
limit: 15,
|
|
3398
|
+
offset: 0,
|
|
3399
|
+
joinDateAsc: true,
|
|
3400
|
+
...request
|
|
3401
|
+
};
|
|
3402
|
+
return this.client.requestWithoutBody(OP_ZaloAdsListAgencyCustomersWithBudget, this.client.toTransportInput(OP_ZaloAdsListAgencyCustomersWithBudget, normalized), options);
|
|
2305
3403
|
}
|
|
2306
|
-
|
|
2307
|
-
|
|
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).");
|
|
3404
|
+
getApiNotifiesHeader(request = {}, options) {
|
|
3405
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetApiNotifiesHeader, this.client.toTransportInput(OP_ZaloAdsGetApiNotifiesHeader, request), options);
|
|
2309
3406
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
errors.push("Tr\u01B0\u1EDDng 'NumDays' ph\u1EA3i n\u1EB1m trong kho\u1EA3ng t\u1EEB 1 \u0111\u1EBFn 90 ng\xE0y.");
|
|
3407
|
+
getApiLpNews(request = {}, options) {
|
|
3408
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetApiLpNews, this.client.toTransportInput(OP_ZaloAdsGetApiLpNews, request), options);
|
|
2313
3409
|
}
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
3410
|
+
/** Lấy thông tin tài khoản đang đăng nhập */
|
|
3411
|
+
getWhoami(...args) {
|
|
3412
|
+
return this.getApiWhoami(...args);
|
|
2317
3413
|
}
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
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 };
|
|
3414
|
+
/** Lịch sử giao dịch thanh toán */
|
|
3415
|
+
getPaymentTransactionHistory(...args) {
|
|
3416
|
+
return this.getApiPaymentTransactionHistory(...args);
|
|
2336
3417
|
}
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
3418
|
+
/** Danh sách accessor tài khoản BA */
|
|
3419
|
+
getBaAccountAllAccessors(...args) {
|
|
3420
|
+
return this.getApiBaAccountAllaccessors(...args);
|
|
3421
|
+
}
|
|
3422
|
+
/** Danh sách thành viên được cấp quyền BA */
|
|
3423
|
+
getBaAccountAllGrantedMembers(...args) {
|
|
3424
|
+
return this.getApiBaAccountAllgrantedmembers(...args);
|
|
3425
|
+
}
|
|
3426
|
+
/** Thông báo trên thanh tiêu đề */
|
|
3427
|
+
getNotifiesHeader(...args) {
|
|
3428
|
+
return this.getApiNotifiesHeader(...args);
|
|
3429
|
+
}
|
|
3430
|
+
/** Tin tức landing page / bảng tin */
|
|
3431
|
+
getLpNews(...args) {
|
|
3432
|
+
return this.getApiLpNews(...args);
|
|
2341
3433
|
}
|
|
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
3434
|
};
|
|
2370
3435
|
|
|
2371
3436
|
// src/services/audiences.service.ts
|
|
@@ -2756,6 +3821,25 @@ var OP_ZaloAdsUpsertCustomReport = {
|
|
|
2756
3821
|
"isDefault"
|
|
2757
3822
|
]
|
|
2758
3823
|
};
|
|
3824
|
+
var OP_ZaloAdsDownloadReport = {
|
|
3825
|
+
operationId: "zalo_ads_download_report",
|
|
3826
|
+
method: "POST",
|
|
3827
|
+
endpoint: "/api/collect",
|
|
3828
|
+
baseUrl: "https://ads.zalo.me",
|
|
3829
|
+
binaryFields: [],
|
|
3830
|
+
pathFields: [],
|
|
3831
|
+
queryFields: [],
|
|
3832
|
+
headerFields: [],
|
|
3833
|
+
cookieFields: [],
|
|
3834
|
+
bodyFields: [
|
|
3835
|
+
"t",
|
|
3836
|
+
"adIds",
|
|
3837
|
+
"status",
|
|
3838
|
+
"dateFilter",
|
|
3839
|
+
"reportKind",
|
|
3840
|
+
"et"
|
|
3841
|
+
]
|
|
3842
|
+
};
|
|
2759
3843
|
var ZaloReportsService = class {
|
|
2760
3844
|
constructor(client) {
|
|
2761
3845
|
this.client = client;
|
|
@@ -2818,6 +3902,18 @@ var ZaloReportsService = class {
|
|
|
2818
3902
|
getCampaignReportLegacy(...args) {
|
|
2819
3903
|
return this.getZaapiCampaignReportcampaign(...args);
|
|
2820
3904
|
}
|
|
3905
|
+
/** Xuất và tải trực tiếp tệp tin Excel (.xlsx / Blob) báo cáo hiệu quả quảng cáo (POST /api/collect) */
|
|
3906
|
+
downloadReport(request, options) {
|
|
3907
|
+
const payload = {
|
|
3908
|
+
t: request.t ?? "cd.download.report",
|
|
3909
|
+
status: request.status ?? 2,
|
|
3910
|
+
dateFilter: request.dateFilter ?? 0,
|
|
3911
|
+
reportKind: request.reportKind ?? 100001,
|
|
3912
|
+
et: request.et ?? Math.floor(Date.now() / 1e3),
|
|
3913
|
+
adIds: request.adIds
|
|
3914
|
+
};
|
|
3915
|
+
return this.client.requestJson(OP_ZaloAdsDownloadReport, this.client.toTransportInput(OP_ZaloAdsDownloadReport, payload), options);
|
|
3916
|
+
}
|
|
2821
3917
|
};
|
|
2822
3918
|
|
|
2823
3919
|
// src/services/conversions.service.ts
|
|
@@ -2978,6 +4074,20 @@ var OP_ZaloAdsListAutomatedRules = {
|
|
|
2978
4074
|
"cookieFields": [],
|
|
2979
4075
|
"bodyFields": []
|
|
2980
4076
|
};
|
|
4077
|
+
var OP_ZaloAdsGetAutomatedRuleDetail = {
|
|
4078
|
+
"operationId": "ZaloAds_getAutomatedRuleDetail",
|
|
4079
|
+
"method": "GET",
|
|
4080
|
+
"endpoint": "/api/automatedrules/{automatedRuleId}",
|
|
4081
|
+
"baseUrl": "https://ads.zalo.me",
|
|
4082
|
+
"binaryFields": [],
|
|
4083
|
+
"pathFields": [
|
|
4084
|
+
"automatedRuleId"
|
|
4085
|
+
],
|
|
4086
|
+
"queryFields": [],
|
|
4087
|
+
"headerFields": [],
|
|
4088
|
+
"cookieFields": [],
|
|
4089
|
+
"bodyFields": []
|
|
4090
|
+
};
|
|
2981
4091
|
var OP_ZaloAdsCreateAutomatedRule = {
|
|
2982
4092
|
"operationId": "ZaloAds_createAutomatedRule",
|
|
2983
4093
|
"method": "POST",
|
|
@@ -3004,7 +4114,7 @@ var OP_ZaloAdsCreateAutomatedRule = {
|
|
|
3004
4114
|
var OP_ZaloAdsUpdateAutomatedRule = {
|
|
3005
4115
|
"operationId": "ZaloAds_updateAutomatedRule",
|
|
3006
4116
|
"method": "POST",
|
|
3007
|
-
"endpoint": "/api/automatedrules/update",
|
|
4117
|
+
"endpoint": "/api/ad/automatedrules/update",
|
|
3008
4118
|
"baseUrl": "https://ads.zalo.me",
|
|
3009
4119
|
"binaryFields": [],
|
|
3010
4120
|
"pathFields": [],
|
|
@@ -3013,11 +4123,15 @@ var OP_ZaloAdsUpdateAutomatedRule = {
|
|
|
3013
4123
|
"cookieFields": [],
|
|
3014
4124
|
"bodyFields": [
|
|
3015
4125
|
"automatedRuleId",
|
|
3016
|
-
"
|
|
3017
|
-
"appliedTo",
|
|
4126
|
+
"scope",
|
|
3018
4127
|
"ruleName",
|
|
3019
4128
|
"action",
|
|
3020
4129
|
"conditions",
|
|
4130
|
+
"frequency",
|
|
4131
|
+
"appliedItems",
|
|
4132
|
+
"appliedIds",
|
|
4133
|
+
"rowVersion",
|
|
4134
|
+
"appliedTo",
|
|
3021
4135
|
"schedule",
|
|
3022
4136
|
"campaignIds",
|
|
3023
4137
|
"adIds"
|
|
@@ -3075,6 +4189,9 @@ var ZaloAutomatedRulesService = class {
|
|
|
3075
4189
|
const queryInput = { query_param: { ruleName: request.ruleName ?? "" } };
|
|
3076
4190
|
return this.client.requestWithoutBody(OP_ZaloAdsListAutomatedRules, queryInput, options);
|
|
3077
4191
|
}
|
|
4192
|
+
getAutomatedRuleDetail(request, options) {
|
|
4193
|
+
return this.client.requestWithoutBody(OP_ZaloAdsGetAutomatedRuleDetail, this.client.toTransportInput(OP_ZaloAdsGetAutomatedRuleDetail, request), options);
|
|
4194
|
+
}
|
|
3078
4195
|
createAutomatedRule(request, options) {
|
|
3079
4196
|
return this.client.requestJson(OP_ZaloAdsCreateAutomatedRule, this.client.toTransportInput(OP_ZaloAdsCreateAutomatedRule, request), options);
|
|
3080
4197
|
}
|
|
@@ -4186,6 +5303,9 @@ var ZaloAdsService = class extends ZaloCampaignsService {
|
|
|
4186
5303
|
listAutomatedRules(request = {}, options) {
|
|
4187
5304
|
return this.automatedRules.listAutomatedRules(request, options);
|
|
4188
5305
|
}
|
|
5306
|
+
getAutomatedRuleDetail(request, options) {
|
|
5307
|
+
return this.automatedRules.getAutomatedRuleDetail(request, options);
|
|
5308
|
+
}
|
|
4189
5309
|
createAutomatedRule(request, options) {
|
|
4190
5310
|
return this.automatedRules.createAutomatedRule(request, options);
|
|
4191
5311
|
}
|
|
@@ -4868,6 +5988,34 @@ function isPositiveInteger2(val) {
|
|
|
4868
5988
|
function toPositiveInteger2(val) {
|
|
4869
5989
|
return typeof val === "number" ? Math.floor(val) : parseInt(String(val), 10);
|
|
4870
5990
|
}
|
|
5991
|
+
function validateCreateInstantPageRequest(input) {
|
|
5992
|
+
const errors = [];
|
|
5993
|
+
if (!input || typeof input !== "object") {
|
|
5994
|
+
return { isValid: false, errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u t\u1EA1o Instant Page ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng (object)."] };
|
|
5995
|
+
}
|
|
5996
|
+
const obj = input;
|
|
5997
|
+
const validTemplates = [1, 3, 4, 5];
|
|
5998
|
+
if (!isPositiveInteger2(obj.templateId) || !validTemplates.includes(Number(obj.templateId))) {
|
|
5999
|
+
errors.push(`Tr\u01B0\u1EDDng 'templateId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i thu\u1ED9c danh m\u1EE5c m\u1EABu h\u1EE3p l\u1EC7: ${validTemplates.join(", ")} (1: S\u1EA3n ph\u1EA9m form nh\xFAng, 3: S\u1EA3n ph\u1EA9m popup, 4: K\u1ECBch b\u1EA3n tin nh\u1EAFn, 5: Mua s\u1EAFm).`);
|
|
6000
|
+
}
|
|
6001
|
+
if (obj.oaId !== void 0 && obj.oaId !== null) {
|
|
6002
|
+
const oaIdStr = String(obj.oaId).trim();
|
|
6003
|
+
if (!oaIdStr) {
|
|
6004
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' n\u1EBFu cung c\u1EA5p kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
6005
|
+
} else if (oaIdStr.length < 10) {
|
|
6006
|
+
errors.push("Tr\u01B0\u1EDDng 'oaId' tr\xEAn domain page.ads.zalo.me b\u1EAFt bu\u1ED9c ph\u1EA3i l\xE0 chu\u1ED7i \u0111\u1ECBnh danh 64-bit c\u1EE7a Official Account (l\u1EA5y t\u1EEB GET /api/official-accounts), kh\xF4ng d\xF9ng ID s\u1ED1 nguy\xEAn ng\u1EAFn.");
|
|
6007
|
+
}
|
|
6008
|
+
}
|
|
6009
|
+
const data = {
|
|
6010
|
+
templateId: toPositiveInteger2(obj.templateId),
|
|
6011
|
+
oaId: obj.oaId ? String(obj.oaId).trim() : void 0
|
|
6012
|
+
};
|
|
6013
|
+
return {
|
|
6014
|
+
isValid: errors.length === 0,
|
|
6015
|
+
errors,
|
|
6016
|
+
data: errors.length === 0 ? data : void 0
|
|
6017
|
+
};
|
|
6018
|
+
}
|
|
4871
6019
|
function validateCloneInstantPageRequest(input) {
|
|
4872
6020
|
const errors = [];
|
|
4873
6021
|
if (!input || typeof input !== "object") {
|
|
@@ -5076,7 +6224,7 @@ function validateUpdateInstantPageRequest(input) {
|
|
|
5076
6224
|
if (obj.status !== void 0 && obj.status !== null) {
|
|
5077
6225
|
const st = Number(obj.status);
|
|
5078
6226
|
if (![0, 1, 2, 3].includes(st)) {
|
|
5079
|
-
errors.push("Tr\u01B0\u1EDDng 'status' ph\u1EA3i l\xE0 m\u1ED9t trong c\xE1c m\xE3: 0 (B\u1EA3n sao m\u1EDBi), 1 (
|
|
6227
|
+
errors.push("Tr\u01B0\u1EDDng 'status' ph\u1EA3i l\xE0 m\u1ED9t trong c\xE1c m\xE3: 0 (B\u1EA3n sao m\u1EDBi t\u1EA1o ch\u01B0a l\u01B0u), 1 (\u0110ang ho\u1EA1t \u0111\u1ED9ng / \u0110\xE3 xu\u1EA5t b\u1EA3n), 3 (\u0110\xE3 k\u1EBFt th\xFAc / L\u01B0u tr\u1EEF).");
|
|
5080
6228
|
} else {
|
|
5081
6229
|
data.status = st;
|
|
5082
6230
|
}
|
|
@@ -5230,6 +6378,7 @@ function validateUpsertInstantPageFormRequest(input) {
|
|
|
5230
6378
|
};
|
|
5231
6379
|
}
|
|
5232
6380
|
var ZaloInstantPagesValidator = {
|
|
6381
|
+
validateCreateInstantPage: validateCreateInstantPageRequest,
|
|
5233
6382
|
validateCloneInstantPage: validateCloneInstantPageRequest,
|
|
5234
6383
|
validateGetInstantPageDetail: validateGetInstantPageDetailRequest,
|
|
5235
6384
|
validateGetInstantPageSharedUser: validateGetInstantPageSharedUserRequest,
|
|
@@ -5246,6 +6395,21 @@ var ZaloInstantPagesValidator = {
|
|
|
5246
6395
|
};
|
|
5247
6396
|
|
|
5248
6397
|
// src/services/instant-pages.service.ts
|
|
6398
|
+
var OP_ZaloInstantPagesCreateInstantPage = {
|
|
6399
|
+
"operationId": "ZaloInstantPages_createInstantPage",
|
|
6400
|
+
"method": "POST",
|
|
6401
|
+
"endpoint": "/api/instant-pages",
|
|
6402
|
+
"baseUrl": "https://page.ads.zalo.me",
|
|
6403
|
+
"binaryFields": [],
|
|
6404
|
+
"pathFields": [],
|
|
6405
|
+
"queryFields": [],
|
|
6406
|
+
"headerFields": [],
|
|
6407
|
+
"cookieFields": [],
|
|
6408
|
+
"bodyFields": [
|
|
6409
|
+
"templateId",
|
|
6410
|
+
"oaId"
|
|
6411
|
+
]
|
|
6412
|
+
};
|
|
5249
6413
|
var OP_ZaloInstantPagesCloneInstantPage = {
|
|
5250
6414
|
"operationId": "ZaloInstantPages_cloneInstantPage",
|
|
5251
6415
|
"method": "POST",
|
|
@@ -5335,6 +6499,20 @@ var OP_ZaloInstantPagesListInstantPageShares = {
|
|
|
5335
6499
|
"cookieFields": [],
|
|
5336
6500
|
"bodyFields": []
|
|
5337
6501
|
};
|
|
6502
|
+
var OP_ZaloInstantPagesUpdateInstantPageShares = {
|
|
6503
|
+
"operationId": "ZaloInstantPages_updateInstantPageShares",
|
|
6504
|
+
"method": "POST",
|
|
6505
|
+
"endpoint": "/api/instant-pages/{instantPageId}/shares",
|
|
6506
|
+
"baseUrl": "https://page.ads.zalo.me",
|
|
6507
|
+
"binaryFields": [],
|
|
6508
|
+
"pathFields": [
|
|
6509
|
+
"instantPageId"
|
|
6510
|
+
],
|
|
6511
|
+
"queryFields": [],
|
|
6512
|
+
"headerFields": [],
|
|
6513
|
+
"cookieFields": [],
|
|
6514
|
+
"bodyFields": []
|
|
6515
|
+
};
|
|
5338
6516
|
var OP_ZaloInstantPagesListInstantPageUsers = {
|
|
5339
6517
|
"operationId": "ZaloInstantPages_listInstantPageUsers",
|
|
5340
6518
|
"method": "GET",
|
|
@@ -5452,6 +6630,9 @@ var ZaloInstantPagesService = class {
|
|
|
5452
6630
|
* Dùng ở backend (NestJS/Express/Fastify), middleware hoặc AI Agent để verify payload trước khi gọi SDK.
|
|
5453
6631
|
*/
|
|
5454
6632
|
static validator = ZaloInstantPagesValidator;
|
|
6633
|
+
createInstantPage(request, options) {
|
|
6634
|
+
return this.client.requestJson(OP_ZaloInstantPagesCreateInstantPage, this.client.toTransportInput(OP_ZaloInstantPagesCreateInstantPage, request), options);
|
|
6635
|
+
}
|
|
5455
6636
|
cloneInstantPage(request, options) {
|
|
5456
6637
|
return this.client.requestJson(OP_ZaloInstantPagesCloneInstantPage, this.client.toTransportInput(OP_ZaloInstantPagesCloneInstantPage, request), options);
|
|
5457
6638
|
}
|
|
@@ -5470,6 +6651,13 @@ var ZaloInstantPagesService = class {
|
|
|
5470
6651
|
listInstantPageShares(request, options) {
|
|
5471
6652
|
return this.client.requestWithoutBody(OP_ZaloInstantPagesListInstantPageShares, this.client.toTransportInput(OP_ZaloInstantPagesListInstantPageShares, request), options);
|
|
5472
6653
|
}
|
|
6654
|
+
updateInstantPageShares(request, options) {
|
|
6655
|
+
const transportInput = {
|
|
6656
|
+
path_param: { instantPageId: request.instantPageId },
|
|
6657
|
+
body: request.shares
|
|
6658
|
+
};
|
|
6659
|
+
return this.client.requestJson(OP_ZaloInstantPagesUpdateInstantPageShares, transportInput, options);
|
|
6660
|
+
}
|
|
5473
6661
|
listInstantPageUsers(request = {}, options) {
|
|
5474
6662
|
return this.client.requestWithoutBody(OP_ZaloInstantPagesListInstantPageUsers, this.client.toTransportInput(OP_ZaloInstantPagesListInstantPageUsers, request), options);
|
|
5475
6663
|
}
|
|
@@ -5984,112 +7172,6 @@ var ZaloAdsIntegrationManager = class {
|
|
|
5984
7172
|
}
|
|
5985
7173
|
};
|
|
5986
7174
|
|
|
5987
|
-
// src/dtos/ads.dto.ts
|
|
5988
|
-
var ZaloAdsFlowChildMessageDto = class {
|
|
5989
|
-
/** Mẫu Zalo đã xác minh dùng 8 cho tin nhắn văn bản trong nhánh. */
|
|
5990
|
-
type;
|
|
5991
|
-
/** Nội dung phản hồi trong nhánh. */
|
|
5992
|
-
text;
|
|
5993
|
-
};
|
|
5994
|
-
var ZaloAdsFlowButtonDto = class {
|
|
5995
|
-
/** 3 = Gửi tin nhắn vào nhánh hội thoại; 10 = Mở website; 12 = Thực hiện cuộc gọi. */
|
|
5996
|
-
type;
|
|
5997
|
-
/** Nhãn nút hiển thị cho người dùng. */
|
|
5998
|
-
text;
|
|
5999
|
-
/** URL website; bắt buộc với type 10. */
|
|
6000
|
-
url;
|
|
6001
|
-
/** Cờ của nút website; dùng true với type 10. */
|
|
6002
|
-
editable;
|
|
6003
|
-
/** Số hotline, bắt buộc khi type là 12. */
|
|
6004
|
-
phone;
|
|
6005
|
-
/** Nhánh tin nhắn, bắt buộc khi type là 3. Với type 10 hoặc 12, để null hoặc bỏ qua. */
|
|
6006
|
-
messages;
|
|
6007
|
-
};
|
|
6008
|
-
var ZaloAdsFlowMessageDto = class {
|
|
6009
|
-
/** 1 = Tin nhắn văn bản; 2 = Tin nhắn kèm hình ảnh. */
|
|
6010
|
-
type;
|
|
6011
|
-
/** Nội dung tin nhắn, tối đa 1961 ký tự. Hỗ trợ biến: {{user_name}}, {{page_name}}, {{user_gender}}, {{user_id}}, {{page_id}}, {{date}}, {{datetime}}. */
|
|
6012
|
-
text;
|
|
6013
|
-
/** URL media hoặc null với tin nhắn văn bản thuần. Bắt buộc và không được null khi type = 2. */
|
|
6014
|
-
url;
|
|
6015
|
-
/** Các nút đi kèm tin nhắn. */
|
|
6016
|
-
buttons;
|
|
6017
|
-
};
|
|
6018
|
-
var ZaloAdsCreateFlowRequest = class {
|
|
6019
|
-
/** ID Official Account sở hữu kịch bản. */
|
|
6020
|
-
oaId;
|
|
6021
|
-
/** Luôn null khi tạo kịch bản mới. */
|
|
6022
|
-
id;
|
|
6023
|
-
/** Tên kịch bản, tối đa 33 ký tự theo giao diện Zalo Ads. */
|
|
6024
|
-
name;
|
|
6025
|
-
/** Các tin nhắn được gửi theo thứ tự trong kịch bản. */
|
|
6026
|
-
messages;
|
|
6027
|
-
};
|
|
6028
|
-
var ZaloAdsCreateFlowResponse = class {
|
|
6029
|
-
/** 0 khi tạo thành công; 1 khi lỗi (ví dụ: đã tới hạn mức 20 kịch bản). */
|
|
6030
|
-
code;
|
|
6031
|
-
/** Thông báo lỗi từ Zalo Ads khi code khác 0. */
|
|
6032
|
-
msg;
|
|
6033
|
-
/** ID kịch bản mới, truyền vào data.ZaloFlowId khi cập nhật quảng cáo Tin nhắn. */
|
|
6034
|
-
data;
|
|
6035
|
-
};
|
|
6036
|
-
var ZaloAdsUpdateVideoAdRequest = class {
|
|
6037
|
-
data;
|
|
6038
|
-
est;
|
|
6039
|
-
isBoostAd;
|
|
6040
|
-
stt;
|
|
6041
|
-
};
|
|
6042
|
-
var ZaloAdsUpdateVideoAdResponse = class {
|
|
6043
|
-
code;
|
|
6044
|
-
msg;
|
|
6045
|
-
data;
|
|
6046
|
-
};
|
|
6047
|
-
var ZaloAdsCreatePostCampaignRequest = class {
|
|
6048
|
-
/** Cấu hình chiến dịch Bài viết (object hoặc chuỗi JSON). */
|
|
6049
|
-
data;
|
|
6050
|
-
};
|
|
6051
|
-
var ZaloAdsCreatePostCampaignResponse = class {
|
|
6052
|
-
code;
|
|
6053
|
-
/** Chuỗi ID quảng cáo mới trong response Zalo Ads. */
|
|
6054
|
-
msg;
|
|
6055
|
-
data;
|
|
6056
|
-
};
|
|
6057
|
-
var ZaloAdsMessageAdUpdateDataDto = class {
|
|
6058
|
-
AdId;
|
|
6059
|
-
CampaignId;
|
|
6060
|
-
MemberId;
|
|
6061
|
-
/** Phiên bản lạc quan lấy từ bản quảng cáo hiện tại. */
|
|
6062
|
-
RowVersion;
|
|
6063
|
-
AdName;
|
|
6064
|
-
/** 20 (hoặc 19) là quảng cáo Tin nhắn. */
|
|
6065
|
-
Type;
|
|
6066
|
-
Settings;
|
|
6067
|
-
Status;
|
|
6068
|
-
StartDate;
|
|
6069
|
-
EndDate;
|
|
6070
|
-
/** ID kịch bản, lấy từ createFlow hoặc listFlowsByOfficialAccount. */
|
|
6071
|
-
ZaloFlowId;
|
|
6072
|
-
ZaloPageId;
|
|
6073
|
-
ZaloFormId;
|
|
6074
|
-
ConversionId;
|
|
6075
|
-
Report;
|
|
6076
|
-
};
|
|
6077
|
-
var ZaloAdsUpdateMessageAdRequest = class {
|
|
6078
|
-
/** Payload quảng cáo đầy đủ (object hoặc chuỗi JSON); service tự tuần tự hóa thành field form data. */
|
|
6079
|
-
data;
|
|
6080
|
-
/** Tham số UI phụ trợ; capture Zalo Ads có giá trị literal "undefined". */
|
|
6081
|
-
est;
|
|
6082
|
-
/** 0 là quảng cáo thông thường, 1 là boost ad. */
|
|
6083
|
-
isBoostAd;
|
|
6084
|
-
/** Trạng thái thao tác của giao diện; mẫu đã ghi nhận 0. */
|
|
6085
|
-
stt;
|
|
6086
|
-
};
|
|
6087
|
-
var ZaloAdsUpdateMessageAdResponse = class {
|
|
6088
|
-
msg;
|
|
6089
|
-
code;
|
|
6090
|
-
data;
|
|
6091
|
-
};
|
|
6092
|
-
|
|
6093
7175
|
// src/dtos/instant-pages.dto.ts
|
|
6094
7176
|
var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
6095
7177
|
ZaloInstantPageBlockType2[ZaloInstantPageBlockType2["CAROUSEL_SLIDER"] = 1] = "CAROUSEL_SLIDER";
|
|
@@ -6112,41 +7194,354 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
6112
7194
|
ZaloInstantPageBlockType2[ZaloInstantPageBlockType2["CONSENT_NOTICE"] = 27] = "CONSENT_NOTICE";
|
|
6113
7195
|
return ZaloInstantPageBlockType2;
|
|
6114
7196
|
})(ZaloInstantPageBlockType || {});
|
|
7197
|
+
var ZaloInstantPageSharePermission = {
|
|
7198
|
+
/** Quản trị viên: Toàn quyền quản trị, chỉnh sửa, phân quyền và gắn quảng cáo. */
|
|
7199
|
+
ADMIN: 1,
|
|
7200
|
+
/** Biên tập viên: Quyền chỉnh sửa nội dung trang. */
|
|
7201
|
+
UPDATE_PAGE: 2,
|
|
7202
|
+
/** Tải dữ liệu: Quyền tải thông tin khách hàng / Leads. */
|
|
7203
|
+
DOWNLOAD_INFO: 3,
|
|
7204
|
+
/** Chỉ xem: Quyền xem trước và thống kê. */
|
|
7205
|
+
READ_ONLY: 4
|
|
7206
|
+
};
|
|
7207
|
+
|
|
7208
|
+
// src/validators/automated-rules.validator.ts
|
|
7209
|
+
var AutomatedRuleScopeEnum = /* @__PURE__ */ ((AutomatedRuleScopeEnum2) => {
|
|
7210
|
+
AutomatedRuleScopeEnum2[AutomatedRuleScopeEnum2["Ads"] = 1] = "Ads";
|
|
7211
|
+
return AutomatedRuleScopeEnum2;
|
|
7212
|
+
})(AutomatedRuleScopeEnum || {});
|
|
7213
|
+
var AutomatedRuleActionTypeEnum = /* @__PURE__ */ ((AutomatedRuleActionTypeEnum2) => {
|
|
7214
|
+
AutomatedRuleActionTypeEnum2[AutomatedRuleActionTypeEnum2["Resume"] = 1] = "Resume";
|
|
7215
|
+
AutomatedRuleActionTypeEnum2[AutomatedRuleActionTypeEnum2["Pause"] = 2] = "Pause";
|
|
7216
|
+
AutomatedRuleActionTypeEnum2[AutomatedRuleActionTypeEnum2["IncreaseByAmount"] = 3] = "IncreaseByAmount";
|
|
7217
|
+
AutomatedRuleActionTypeEnum2[AutomatedRuleActionTypeEnum2["DecreaseByAmount"] = 4] = "DecreaseByAmount";
|
|
7218
|
+
AutomatedRuleActionTypeEnum2[AutomatedRuleActionTypeEnum2["IncreaseByPercentage"] = 5] = "IncreaseByPercentage";
|
|
7219
|
+
AutomatedRuleActionTypeEnum2[AutomatedRuleActionTypeEnum2["DecreaseByPercentage"] = 6] = "DecreaseByPercentage";
|
|
7220
|
+
return AutomatedRuleActionTypeEnum2;
|
|
7221
|
+
})(AutomatedRuleActionTypeEnum || {});
|
|
7222
|
+
var AutomatedRuleFrequencyEnum = /* @__PURE__ */ ((AutomatedRuleFrequencyEnum2) => {
|
|
7223
|
+
AutomatedRuleFrequencyEnum2[AutomatedRuleFrequencyEnum2["OneHour"] = 1] = "OneHour";
|
|
7224
|
+
AutomatedRuleFrequencyEnum2[AutomatedRuleFrequencyEnum2["HalfDay"] = 12] = "HalfDay";
|
|
7225
|
+
AutomatedRuleFrequencyEnum2[AutomatedRuleFrequencyEnum2["OneDay"] = 24] = "OneDay";
|
|
7226
|
+
AutomatedRuleFrequencyEnum2[AutomatedRuleFrequencyEnum2["OneWeek"] = 168] = "OneWeek";
|
|
7227
|
+
return AutomatedRuleFrequencyEnum2;
|
|
7228
|
+
})(AutomatedRuleFrequencyEnum || {});
|
|
7229
|
+
var AutomatedRuleConditionFieldEnum = /* @__PURE__ */ ((AutomatedRuleConditionFieldEnum2) => {
|
|
7230
|
+
AutomatedRuleConditionFieldEnum2[AutomatedRuleConditionFieldEnum2["Status"] = 1] = "Status";
|
|
7231
|
+
AutomatedRuleConditionFieldEnum2[AutomatedRuleConditionFieldEnum2["Impression"] = 11] = "Impression";
|
|
7232
|
+
AutomatedRuleConditionFieldEnum2[AutomatedRuleConditionFieldEnum2["Click"] = 16] = "Click";
|
|
7233
|
+
AutomatedRuleConditionFieldEnum2[AutomatedRuleConditionFieldEnum2["CTR"] = 9999] = "CTR";
|
|
7234
|
+
AutomatedRuleConditionFieldEnum2[AutomatedRuleConditionFieldEnum2["Cost"] = 100001] = "Cost";
|
|
7235
|
+
return AutomatedRuleConditionFieldEnum2;
|
|
7236
|
+
})(AutomatedRuleConditionFieldEnum || {});
|
|
7237
|
+
var AutomatedRuleOperatorEnum = /* @__PURE__ */ ((AutomatedRuleOperatorEnum2) => {
|
|
7238
|
+
AutomatedRuleOperatorEnum2[AutomatedRuleOperatorEnum2["GreaterThan"] = 1] = "GreaterThan";
|
|
7239
|
+
AutomatedRuleOperatorEnum2[AutomatedRuleOperatorEnum2["LessThan"] = 2] = "LessThan";
|
|
7240
|
+
AutomatedRuleOperatorEnum2[AutomatedRuleOperatorEnum2["Between"] = 3] = "Between";
|
|
7241
|
+
AutomatedRuleOperatorEnum2[AutomatedRuleOperatorEnum2["NotBetween"] = 4] = "NotBetween";
|
|
7242
|
+
AutomatedRuleOperatorEnum2[AutomatedRuleOperatorEnum2["Include"] = 5] = "Include";
|
|
7243
|
+
AutomatedRuleOperatorEnum2[AutomatedRuleOperatorEnum2["Exclude"] = 6] = "Exclude";
|
|
7244
|
+
return AutomatedRuleOperatorEnum2;
|
|
7245
|
+
})(AutomatedRuleOperatorEnum || {});
|
|
7246
|
+
var AutomatedRuleTimeRangeEnum = /* @__PURE__ */ ((AutomatedRuleTimeRangeEnum2) => {
|
|
7247
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["AllTime"] = 1] = "AllTime";
|
|
7248
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["AllTimeExcludeToday"] = 2] = "AllTimeExcludeToday";
|
|
7249
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Today"] = 3] = "Today";
|
|
7250
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Yesterday"] = 4] = "Yesterday";
|
|
7251
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous2Day"] = 1002] = "Previous2Day";
|
|
7252
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous3Day"] = 1003] = "Previous3Day";
|
|
7253
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous4Day"] = 1004] = "Previous4Day";
|
|
7254
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous5Day"] = 1005] = "Previous5Day";
|
|
7255
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous6Day"] = 1006] = "Previous6Day";
|
|
7256
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous7Day"] = 1007] = "Previous7Day";
|
|
7257
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous14Day"] = 1014] = "Previous14Day";
|
|
7258
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous21Day"] = 1021] = "Previous21Day";
|
|
7259
|
+
AutomatedRuleTimeRangeEnum2[AutomatedRuleTimeRangeEnum2["Previous30Day"] = 1030] = "Previous30Day";
|
|
7260
|
+
return AutomatedRuleTimeRangeEnum2;
|
|
7261
|
+
})(AutomatedRuleTimeRangeEnum || {});
|
|
7262
|
+
var ZaloAutomatedRulesValidator = class {
|
|
7263
|
+
/**
|
|
7264
|
+
* Kiểm tra và chuẩn hóa payload tạo mới quy tắc tự động (`POST /api/automatedrules/create`)
|
|
7265
|
+
*/
|
|
7266
|
+
static validateCreateRule(payload) {
|
|
7267
|
+
const errors = [];
|
|
7268
|
+
const warnings = [];
|
|
7269
|
+
if (!payload || typeof payload !== "object") {
|
|
7270
|
+
return { isValid: false, errors: ["Payload quy t\u1EAFc t\u1EF1 \u0111\u1ED9ng ph\u1EA3i l\xE0 m\u1ED9t object."], warnings };
|
|
7271
|
+
}
|
|
7272
|
+
const ruleName = String(payload.ruleName || "").trim();
|
|
7273
|
+
if (!ruleName) {
|
|
7274
|
+
errors.push("T\xEAn quy t\u1EAFc (ruleName) kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
7275
|
+
} else if (ruleName.length > 100) {
|
|
7276
|
+
errors.push(`T\xEAn quy t\u1EAFc kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 100 k\xFD t\u1EF1 (hi\u1EC7n c\xF3 ${ruleName.length} k\xFD t\u1EF1).`);
|
|
7277
|
+
}
|
|
7278
|
+
const scope = payload.scope !== void 0 ? Number(payload.scope) : 1;
|
|
7279
|
+
if (scope !== 1) {
|
|
7280
|
+
errors.push("Zalo Ads hi\u1EC7n ch\u1EC9 h\u1ED7 tr\u1EE3 scope: 1 (\xC1p d\u1EE5ng cho Qu\u1EA3ng c\xE1o).");
|
|
7281
|
+
}
|
|
7282
|
+
if (!payload.action || typeof payload.action !== "object") {
|
|
7283
|
+
errors.push("Thi\u1EBFu c\u1EA5u h\xECnh h\xE0nh \u0111\u1ED9ng (action).");
|
|
7284
|
+
} else {
|
|
7285
|
+
const act = payload.action;
|
|
7286
|
+
const actType2 = Number(act.type);
|
|
7287
|
+
if (![3, 4, 5, 6].includes(actType2)) {
|
|
7288
|
+
if ([1, 2].includes(actType2)) {
|
|
7289
|
+
errors.push(`H\xE0nh \u0111\u1ED9ng ${actType2 === 1 ? "Ti\u1EBFp t\u1EE5c" : "T\u1EA1m d\u1EEBng"} qu\u1EA3ng c\xE1o (type: ${actType2}) hi\u1EC7n ch\u01B0a \u0111\u01B0\u1EE3c backend Zalo Ads k\xEDch ho\u1EA1t trong scope n\xE0y.`);
|
|
7290
|
+
} else {
|
|
7291
|
+
errors.push(`Lo\u1EA1i h\xE0nh \u0111\u1ED9ng kh\xF4ng h\u1EE3p l\u1EC7: ${act.type}. Ch\u1EC9 h\u1ED7 tr\u1EE3 3 (T\u0103ng gi\xE1 \u0111), 4 (Gi\u1EA3m gi\xE1 \u0111), 5 (T\u0103ng gi\xE1 %), 6 (Gi\u1EA3m gi\xE1 %).`);
|
|
7292
|
+
}
|
|
7293
|
+
}
|
|
7294
|
+
if (!Array.isArray(act.values) || act.values.length === 0 || Number(act.values[0]) <= 0) {
|
|
7295
|
+
errors.push("Gi\xE1 tr\u1ECB thay \u0111\u1ED5i gi\xE1 th\u1EA7u (action.values) ph\u1EA3i l\xE0 m\u1EA3ng ch\u1EE9a s\u1ED1 d\u01B0\u01A1ng > 0.");
|
|
7296
|
+
} else {
|
|
7297
|
+
const val = Number(act.values[0]);
|
|
7298
|
+
if ([5, 6].includes(actType2) && (val < 1 || val > 100)) {
|
|
7299
|
+
errors.push(`Thay \u0111\u1ED5i theo % (type: ${actType2}) y\xEAu c\u1EA7u gi\xE1 tr\u1ECB trong kho\u1EA3ng t\u1EEB 1% \u0111\u1EBFn 100% (hi\u1EC7n l\xE0 ${val}%).`);
|
|
7300
|
+
}
|
|
7301
|
+
}
|
|
7302
|
+
if (act.limit !== void 0 && Number(act.limit) <= 0) {
|
|
7303
|
+
errors.push("H\u1EA1n m\u1EE9c gi\xE1 th\u1EA7u (action.limit) n\u1EBFu c\xF3 ph\u1EA3i l\xE0 s\u1ED1 ti\u1EC1n d\u01B0\u01A1ng > 0 VN\u0110.");
|
|
7304
|
+
}
|
|
7305
|
+
}
|
|
7306
|
+
const frequency = payload.frequency !== void 0 ? Number(payload.frequency) : 12;
|
|
7307
|
+
const actType = payload.action ? Number(payload.action.type) : 0;
|
|
7308
|
+
if ([3, 4, 5, 6].includes(actType)) {
|
|
7309
|
+
if (![1, 12, 24, 168].includes(frequency)) {
|
|
7310
|
+
errors.push(`T\u1EA7n su\u1EA5t h\xE0nh \u0111\u1ED9ng cho \u0111i\u1EC1u ch\u1EC9nh gi\xE1 th\u1EA7u ph\u1EA3i thu\u1ED9c [1 (1 gi\u1EDD), 12 (12 gi\u1EDD), 24 (1 ng\xE0y), 168 (1 tu\u1EA7n)]. Gi\xE1 tr\u1ECB ${frequency} s\u1EBD b\u1ECB t\u1EEB ch\u1ED1i v\u1EDBi l\u1ED7i "T\u1EA7n su\u1EA5t h\xE0nh \u0111\u1ED9ng kh\xF4ng h\u1EE3p l\u1EC7."`);
|
|
7311
|
+
}
|
|
7312
|
+
}
|
|
7313
|
+
if (!Array.isArray(payload.conditions) || payload.conditions.length === 0) {
|
|
7314
|
+
errors.push("Quy t\u1EAFc t\u1EF1 \u0111\u1ED9ng ph\u1EA3i c\xF3 \xEDt nh\u1EA5t 1 \u0111i\u1EC1u ki\u1EC7n ch\u1EC9 s\u1ED1 (conditions).");
|
|
7315
|
+
} else {
|
|
7316
|
+
payload.conditions.forEach((c, idx) => {
|
|
7317
|
+
const f = Number(c.field);
|
|
7318
|
+
if (![1, 11, 16, 9999, 100001].includes(f)) {
|
|
7319
|
+
errors.push(`\u0110i\u1EC1u ki\u1EC7n [${idx + 1}]: Ch\u1EC9 s\u1ED1 kh\xF4ng h\u1EE3p l\u1EC7 (field: ${c.field}). H\u1ED7 tr\u1EE3: 1 (Status), 11 (Impression), 16 (Click), 9999 (CTR), 100001 (Cost).`);
|
|
7320
|
+
}
|
|
7321
|
+
const op = Number(c.operator);
|
|
7322
|
+
if (![1, 2, 3, 4, 5, 6].includes(op)) {
|
|
7323
|
+
errors.push(`\u0110i\u1EC1u ki\u1EC7n [${idx + 1}]: Ph\xE9p to\xE1n kh\xF4ng h\u1EE3p l\u1EC7 (operator: ${c.operator}). H\u1ED7 tr\u1EE3 1 (>), 2 (<), 3 (between), 4 (not between), 5 (include), 6 (exclude).`);
|
|
7324
|
+
}
|
|
7325
|
+
if (!Array.isArray(c.values) || c.values.length === 0) {
|
|
7326
|
+
errors.push(`\u0110i\u1EC1u ki\u1EC7n [${idx + 1}]: values ph\u1EA3i l\xE0 m\u1EA3ng gi\xE1 tr\u1ECB ng\u01B0\u1EE1ng.`);
|
|
7327
|
+
}
|
|
7328
|
+
if (f !== 1 && !c.timeRange) {
|
|
7329
|
+
warnings.push(`\u0110i\u1EC1u ki\u1EC7n [${idx + 1}]: Thi\u1EBFu timeRange, h\u1EC7 th\u1ED1ng s\u1EBD m\u1EB7c \u0111\u1ECBnh l\xE0 1 (Lifetime).`);
|
|
7330
|
+
}
|
|
7331
|
+
});
|
|
7332
|
+
}
|
|
7333
|
+
const sanitizedData = {
|
|
7334
|
+
ruleName,
|
|
7335
|
+
scope: 1,
|
|
7336
|
+
action: {
|
|
7337
|
+
type: Number(payload.action?.type),
|
|
7338
|
+
field: 1,
|
|
7339
|
+
values: payload.action?.values?.map(Number) || [10],
|
|
7340
|
+
limit: payload.action?.limit !== void 0 ? Number(payload.action.limit) : 1e6
|
|
7341
|
+
},
|
|
7342
|
+
conditions: (payload.conditions || []).map((c) => ({
|
|
7343
|
+
field: Number(c.field),
|
|
7344
|
+
operator: Number(c.operator),
|
|
7345
|
+
values: c.values.map(Number),
|
|
7346
|
+
timeRange: c.timeRange !== void 0 ? Number(c.timeRange) : 1
|
|
7347
|
+
})),
|
|
7348
|
+
frequency,
|
|
7349
|
+
appliedIds: Array.isArray(payload.appliedIds) ? payload.appliedIds.map(Number) : []
|
|
7350
|
+
};
|
|
7351
|
+
return {
|
|
7352
|
+
isValid: errors.length === 0,
|
|
7353
|
+
errors,
|
|
7354
|
+
warnings,
|
|
7355
|
+
sanitizedData: errors.length === 0 ? sanitizedData : void 0
|
|
7356
|
+
};
|
|
7357
|
+
}
|
|
7358
|
+
/**
|
|
7359
|
+
* Kiểm tra và chuẩn hóa payload cập nhật quy tắc tự động (`POST /api/ad/automatedrules/update`)
|
|
7360
|
+
*/
|
|
7361
|
+
static validateUpdateRule(payload) {
|
|
7362
|
+
const base = this.validateCreateRule(payload);
|
|
7363
|
+
const errors = [...base.errors];
|
|
7364
|
+
const warnings = [...base.warnings];
|
|
7365
|
+
if (!payload.automatedRuleId || Number(payload.automatedRuleId) <= 0) {
|
|
7366
|
+
errors.unshift("ID quy t\u1EAFc t\u1EF1 \u0111\u1ED9ng (automatedRuleId) l\xE0 b\u1EAFt bu\u1ED9c khi c\u1EADp nh\u1EADt.");
|
|
7367
|
+
}
|
|
7368
|
+
const appliedItems = Array.isArray(payload.appliedItems) ? payload.appliedItems.map((item) => ({
|
|
7369
|
+
appliedId: Number(item.appliedId),
|
|
7370
|
+
mode: Number(item.mode) === -1 ? -1 : 1
|
|
7371
|
+
// -1: Unapply, 1: Apply
|
|
7372
|
+
})) : [];
|
|
7373
|
+
const sanitizedData = base.sanitizedData ? {
|
|
7374
|
+
automatedRuleId: Number(payload.automatedRuleId),
|
|
7375
|
+
...base.sanitizedData,
|
|
7376
|
+
appliedItems
|
|
7377
|
+
} : void 0;
|
|
7378
|
+
return {
|
|
7379
|
+
isValid: errors.length === 0,
|
|
7380
|
+
errors,
|
|
7381
|
+
warnings,
|
|
7382
|
+
sanitizedData
|
|
7383
|
+
};
|
|
7384
|
+
}
|
|
7385
|
+
};
|
|
7386
|
+
|
|
7387
|
+
// src/validators/conversions.validator.ts
|
|
7388
|
+
var ConversionLabelEnum = /* @__PURE__ */ ((ConversionLabelEnum2) => {
|
|
7389
|
+
ConversionLabelEnum2[ConversionLabelEnum2["AddToCart"] = 2] = "AddToCart";
|
|
7390
|
+
ConversionLabelEnum2[ConversionLabelEnum2["CompleteRegistration"] = 4] = "CompleteRegistration";
|
|
7391
|
+
ConversionLabelEnum2[ConversionLabelEnum2["Contact"] = 5] = "Contact";
|
|
7392
|
+
ConversionLabelEnum2[ConversionLabelEnum2["InitiateCheckout"] = 9] = "InitiateCheckout";
|
|
7393
|
+
ConversionLabelEnum2[ConversionLabelEnum2["Lead"] = 10] = "Lead";
|
|
7394
|
+
ConversionLabelEnum2[ConversionLabelEnum2["Purchase"] = 11] = "Purchase";
|
|
7395
|
+
ConversionLabelEnum2[ConversionLabelEnum2["Other"] = 19] = "Other";
|
|
7396
|
+
return ConversionLabelEnum2;
|
|
7397
|
+
})(ConversionLabelEnum || {});
|
|
7398
|
+
var ConversionUrlTypeEnum = /* @__PURE__ */ ((ConversionUrlTypeEnum2) => {
|
|
7399
|
+
ConversionUrlTypeEnum2[ConversionUrlTypeEnum2["Exact"] = 0] = "Exact";
|
|
7400
|
+
ConversionUrlTypeEnum2[ConversionUrlTypeEnum2["Contains"] = 1] = "Contains";
|
|
7401
|
+
return ConversionUrlTypeEnum2;
|
|
7402
|
+
})(ConversionUrlTypeEnum || {});
|
|
7403
|
+
var ZaloConversionsValidator = class {
|
|
7404
|
+
/**
|
|
7405
|
+
* Danh mục 7 nhãn chuẩn được Zalo Ads hỗ trợ chính thức
|
|
7406
|
+
*/
|
|
7407
|
+
static SUPPORTED_LABELS = {
|
|
7408
|
+
[10 /* Lead */]: "Tr\u1EDF th\xE0nh kh\xE1ch h\xE0ng ti\u1EC1m n\u0103ng",
|
|
7409
|
+
[11 /* Purchase */]: "Ho\xE0n t\u1EA5t mua h\xE0ng",
|
|
7410
|
+
[5 /* Contact */]: "Li\xEAn h\u1EC7",
|
|
7411
|
+
[4 /* CompleteRegistration */]: "Ho\xE0n t\u1EA5t \u0111\u0103ng k\xFD",
|
|
7412
|
+
[9 /* InitiateCheckout */]: "B\u1EAFt \u0111\u1EA7u thanh to\xE1n",
|
|
7413
|
+
[2 /* AddToCart */]: "Th\xEAm v\xE0o gi\u1ECF h\xE0ng",
|
|
7414
|
+
[19 /* Other */]: "Kh\xE1c"
|
|
7415
|
+
};
|
|
7416
|
+
/**
|
|
7417
|
+
* Kiểm tra và chuẩn hóa payload tạo mới Conversion (`POST /api/conversion/add`)
|
|
7418
|
+
*/
|
|
7419
|
+
static validateCreateConversion(payload) {
|
|
7420
|
+
const errors = [];
|
|
7421
|
+
const warnings = [];
|
|
7422
|
+
if (!payload || typeof payload !== "object") {
|
|
7423
|
+
return { isValid: false, errors: ["Payload conversion ph\u1EA3i l\xE0 m\u1ED9t object."], warnings };
|
|
7424
|
+
}
|
|
7425
|
+
const name = String(payload.name || "").trim();
|
|
7426
|
+
if (!name) {
|
|
7427
|
+
errors.push("T\xEAn conversion (name) kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
7428
|
+
} else if (name.length > 180) {
|
|
7429
|
+
errors.push(`T\xEAn conversion kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 180 k\xFD t\u1EF1 (hi\u1EC7n c\xF3 ${name.length} k\xFD t\u1EF1).`);
|
|
7430
|
+
}
|
|
7431
|
+
const landingPage = String(payload.landingPage || "").trim();
|
|
7432
|
+
if (!landingPage) {
|
|
7433
|
+
errors.push("Trang \u0111\xEDch (landingPage) kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
|
|
7434
|
+
} else {
|
|
7435
|
+
const urlPattern = /^https?:\/\/.+/i;
|
|
7436
|
+
if (!urlPattern.test(landingPage)) {
|
|
7437
|
+
errors.push("Trang \u0111\xEDch (landingPage) ph\u1EA3i l\xE0 m\u1ED9t URL h\u1EE3p l\u1EC7 b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https:// (v\xED d\u1EE5: https://redai.vn).");
|
|
7438
|
+
}
|
|
7439
|
+
}
|
|
7440
|
+
const urlType = payload.urlType !== void 0 ? Number(payload.urlType) : 1;
|
|
7441
|
+
if (![0, 1].includes(urlType)) {
|
|
7442
|
+
errors.push(`Lo\u1EA1i URL kh\xF4ng h\u1EE3p l\u1EC7: ${payload.urlType}. Ch\u1EC9 h\u1ED7 tr\u1EE3 0 (Exact URL) ho\u1EB7c 1 (Contains keywords).`);
|
|
7443
|
+
}
|
|
7444
|
+
const labelId = payload.labelId !== void 0 ? Number(payload.labelId) : 10;
|
|
7445
|
+
if (!Object.keys(this.SUPPORTED_LABELS).map(Number).includes(labelId)) {
|
|
7446
|
+
errors.push(`Nh\xE3n conversion kh\xF4ng h\u1EE3p l\u1EC7 (labelId: ${payload.labelId}). Zalo Ads ch\u1EC9 h\u1ED7 tr\u1EE3: 10 (Lead), 11 (Purchase), 5 (Contact), 4 (Registration), 9 (Checkout), 2 (AddToCart), 19 (Other).`);
|
|
7447
|
+
}
|
|
7448
|
+
const buttonIds = Array.isArray(payload.buttonIds) ? payload.buttonIds.map(String).map((s) => s.trim()).filter((s) => Boolean(s)) : [];
|
|
7449
|
+
const elements = Array.isArray(payload.elements) ? payload.elements : [];
|
|
7450
|
+
const keywords = Array.isArray(payload.keywords) ? payload.keywords.map(String).map((s) => s.trim()).filter((s) => Boolean(s)) : [];
|
|
7451
|
+
if (buttonIds.length === 0 && elements.length === 0 && keywords.length === 0) {
|
|
7452
|
+
errors.push("Conversion b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 \xEDt nh\u1EA5t 1 c\u01A1 ch\u1EBF nh\u1EADn di\u1EC7n s\u1EF1 ki\u1EC7n: URL ch\u1EE9a t\u1EEB kh\xF3a (keywords), ID n\xFAt b\u1EA5m (buttonIds), ho\u1EB7c ph\u1EA7n t\u1EED giao di\u1EC7n (elements).");
|
|
7453
|
+
}
|
|
7454
|
+
const sanitizedElements = elements.map((el) => {
|
|
7455
|
+
if (typeof el === "object" && Array.isArray(el.class)) {
|
|
7456
|
+
return { class: el.class.map(String).map((s) => s.trim()).filter((s) => Boolean(s)) };
|
|
7457
|
+
}
|
|
7458
|
+
return el;
|
|
7459
|
+
});
|
|
7460
|
+
const sanitizedData = {
|
|
7461
|
+
name,
|
|
7462
|
+
landingPage,
|
|
7463
|
+
urlType,
|
|
7464
|
+
labelId,
|
|
7465
|
+
buttonIds,
|
|
7466
|
+
elements: sanitizedElements,
|
|
7467
|
+
keywords
|
|
7468
|
+
};
|
|
7469
|
+
return {
|
|
7470
|
+
isValid: errors.length === 0,
|
|
7471
|
+
errors,
|
|
7472
|
+
warnings,
|
|
7473
|
+
sanitizedData: errors.length === 0 ? sanitizedData : void 0
|
|
7474
|
+
};
|
|
7475
|
+
}
|
|
7476
|
+
};
|
|
6115
7477
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6116
7478
|
0 && (module.exports = {
|
|
7479
|
+
ALLOWED_CTAS_PER_AD_TYPE,
|
|
6117
7480
|
ALL_ZALO_ADS_DOMAINS,
|
|
7481
|
+
AutomatedRuleActionTypeEnum,
|
|
7482
|
+
AutomatedRuleConditionFieldEnum,
|
|
7483
|
+
AutomatedRuleFrequencyEnum,
|
|
7484
|
+
AutomatedRuleOperatorEnum,
|
|
7485
|
+
AutomatedRuleScopeEnum,
|
|
7486
|
+
AutomatedRuleTimeRangeEnum,
|
|
7487
|
+
ConversionLabelEnum,
|
|
7488
|
+
ConversionUrlTypeEnum,
|
|
6118
7489
|
MemoryZaloSessionStore,
|
|
6119
7490
|
RedisZaloSessionStore,
|
|
6120
7491
|
TieredZaloSessionStore,
|
|
7492
|
+
VALID_AD_TYPES,
|
|
7493
|
+
VALID_CAMPAIGN_TYPES,
|
|
7494
|
+
ZALO_NEW_REGION_PROVINCE_CODES,
|
|
7495
|
+
ZALO_PROVINCE_MERGE_MAPPING,
|
|
7496
|
+
ZALO_REGION_PROVINCE_CODES,
|
|
6121
7497
|
ZaloAccountService,
|
|
6122
7498
|
ZaloAdsAccountPool,
|
|
7499
|
+
ZaloAdsActionType,
|
|
7500
|
+
ZaloAdsAgeRangeId,
|
|
7501
|
+
ZaloAdsBudgetScheduleType,
|
|
7502
|
+
ZaloAdsCampaignStatus,
|
|
6123
7503
|
ZaloAdsCreateFlowRequest,
|
|
6124
7504
|
ZaloAdsCreateFlowResponse,
|
|
6125
7505
|
ZaloAdsCreatePostCampaignRequest,
|
|
6126
7506
|
ZaloAdsCreatePostCampaignResponse,
|
|
7507
|
+
ZaloAdsDeliveryType,
|
|
6127
7508
|
ZaloAdsFlowButtonDto,
|
|
6128
7509
|
ZaloAdsFlowChildMessageDto,
|
|
6129
7510
|
ZaloAdsFlowMessageDto,
|
|
7511
|
+
ZaloAdsImageRatio,
|
|
6130
7512
|
ZaloAdsIntegrationManager,
|
|
6131
7513
|
ZaloAdsMessageAdUpdateDataDto,
|
|
7514
|
+
ZaloAdsOsId,
|
|
7515
|
+
ZaloAdsPriceLimitType,
|
|
7516
|
+
ZaloAdsPriceType,
|
|
7517
|
+
ZaloAdsProvinceCode,
|
|
7518
|
+
ZaloAdsRegionId,
|
|
6132
7519
|
ZaloAdsSdk,
|
|
6133
7520
|
ZaloAdsService,
|
|
7521
|
+
ZaloAdsSpendingMethod,
|
|
6134
7522
|
ZaloAdsUpdateMessageAdRequest,
|
|
6135
7523
|
ZaloAdsUpdateMessageAdResponse,
|
|
6136
7524
|
ZaloAdsUpdateVideoAdRequest,
|
|
6137
7525
|
ZaloAdsUpdateVideoAdResponse,
|
|
7526
|
+
ZaloAdsUseConversion,
|
|
7527
|
+
ZaloAdsVideoSrc,
|
|
7528
|
+
ZaloAdsXTemplates,
|
|
6138
7529
|
ZaloAudiencesService,
|
|
6139
7530
|
ZaloAudiencesValidator,
|
|
6140
7531
|
ZaloAuthManager,
|
|
6141
7532
|
ZaloAutomatedRulesService,
|
|
7533
|
+
ZaloAutomatedRulesValidator,
|
|
6142
7534
|
ZaloCampaignsService,
|
|
7535
|
+
ZaloCampaignsValidator,
|
|
6143
7536
|
ZaloChatWidgetService,
|
|
6144
7537
|
ZaloConversionsService,
|
|
7538
|
+
ZaloConversionsValidator,
|
|
6145
7539
|
ZaloFlowsService,
|
|
6146
7540
|
ZaloFlowsValidator,
|
|
6147
7541
|
ZaloFormsService,
|
|
6148
7542
|
ZaloFormsValidator,
|
|
6149
7543
|
ZaloInstantPageBlockType,
|
|
7544
|
+
ZaloInstantPageSharePermission,
|
|
6150
7545
|
ZaloInstantPagesService,
|
|
6151
7546
|
ZaloInstantPagesValidator,
|
|
6152
7547
|
ZaloMediaService,
|
|
@@ -6161,15 +7556,19 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
6161
7556
|
defaultSharedMemorySessionStore,
|
|
6162
7557
|
deriveAccountKeyFromZpsid,
|
|
6163
7558
|
parseZaloCookieInput,
|
|
7559
|
+
validateChangeCampaignStatusParams,
|
|
6164
7560
|
validateCloneInstantPageRequest,
|
|
7561
|
+
validateCreateCampaignPayload,
|
|
6165
7562
|
validateCreateFlowRequest,
|
|
6166
7563
|
validateCreateFormEventAudienceRequest,
|
|
6167
7564
|
validateCreateFormRequest,
|
|
7565
|
+
validateCreateInstantPageRequest,
|
|
6168
7566
|
validateCreateLookalikeAudienceRequest,
|
|
6169
7567
|
validateCreateMessageOaEventAudienceRequest,
|
|
6170
7568
|
validateCreateMessagePersonalEventAudienceRequest,
|
|
6171
7569
|
validateCreatePhoneAudienceRequest,
|
|
6172
7570
|
validateCreateSavedAudienceRequest,
|
|
7571
|
+
validateDuplicateAdParams,
|
|
6173
7572
|
validateEstimateAudienceRequest,
|
|
6174
7573
|
validateGetInstantPageDetailRequest,
|
|
6175
7574
|
validateGetInstantPageSharedUserRequest,
|
|
@@ -6183,7 +7582,9 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
|
|
|
6183
7582
|
validateListInstantPageUsersRequest,
|
|
6184
7583
|
validateListMiniPageTemplatesRequest,
|
|
6185
7584
|
validateListOfficialAccountsRequest,
|
|
7585
|
+
validateRenameCampaignParams,
|
|
6186
7586
|
validateSearchInstantPagesRequest,
|
|
7587
|
+
validateUpdateAdPayload,
|
|
6187
7588
|
validateUpdateFlowRequest,
|
|
6188
7589
|
validateUpdateInstantPageRequest,
|
|
6189
7590
|
validateUpsertInstantPageFormRequest
|