@redonvn/zalo-ads-sdk 0.2.18 → 0.2.20

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.js CHANGED
@@ -40,6 +40,7 @@ __export(index_exports, {
40
40
  AutomatedRuleTimeRangeEnum: () => AutomatedRuleTimeRangeEnum,
41
41
  ConversionLabelEnum: () => ConversionLabelEnum,
42
42
  ConversionUrlTypeEnum: () => ConversionUrlTypeEnum,
43
+ InstantPageFactory: () => InstantPageFactory,
43
44
  MAX_REPORT_RANGE_MS: () => MAX_REPORT_RANGE_MS,
44
45
  MAX_REPORT_RANGE_SECONDS: () => MAX_REPORT_RANGE_SECONDS,
45
46
  MemoryZaloSessionStore: () => MemoryZaloSessionStore,
@@ -119,26 +120,36 @@ __export(index_exports, {
119
120
  defaultSharedMemorySessionStore: () => defaultSharedMemorySessionStore,
120
121
  deriveAccountKeyFromZpsid: () => deriveAccountKeyFromZpsid,
121
122
  parseZaloCookieInput: () => parseZaloCookieInput,
123
+ sanitizeCanvasKeys: () => sanitizeCanvasKeys,
122
124
  validateChangeCampaignStatusParams: () => validateChangeCampaignStatusParams,
123
125
  validateCloneInstantPageRequest: () => validateCloneInstantPageRequest,
126
+ validateCreateArticleCampaign: () => validateCreateArticleCampaign,
124
127
  validateCreateCampaignPayload: () => validateCreateCampaignPayload,
128
+ validateCreateCommerceCampaign: () => validateCreateCommerceCampaign,
125
129
  validateCreateCustomAudienceRequest: () => validateCreateCustomAudienceRequest,
130
+ validateCreateDisplayCampaign: () => validateCreateDisplayCampaign,
126
131
  validateCreateFlowRequest: () => validateCreateFlowRequest,
132
+ validateCreateFormCampaign: () => validateCreateFormCampaign,
127
133
  validateCreateFormEventAudienceRequest: () => validateCreateFormEventAudienceRequest,
128
134
  validateCreateFormRequest: () => validateCreateFormRequest,
129
135
  validateCreateInstantPageRequest: () => validateCreateInstantPageRequest,
130
136
  validateCreateLookalikeAudienceRequest: () => validateCreateLookalikeAudienceRequest,
137
+ validateCreateMessageCampaign: () => validateCreateMessageCampaign,
131
138
  validateCreateMessageOaEventAudienceRequest: () => validateCreateMessageOaEventAudienceRequest,
132
139
  validateCreateMessagePersonalEventAudienceRequest: () => validateCreateMessagePersonalEventAudienceRequest,
133
140
  validateCreateOaPageRequest: () => validateCreateOaPageRequest,
141
+ validateCreateOfficialAccountCampaign: () => validateCreateOfficialAccountCampaign,
134
142
  validateCreatePhoneAudienceRequest: () => validateCreatePhoneAudienceRequest,
135
143
  validateCreateSavedAudienceRequest: () => validateCreateSavedAudienceRequest,
144
+ validateCreateVideoCampaign: () => validateCreateVideoCampaign,
145
+ validateCreateWebsiteCampaign: () => validateCreateWebsiteCampaign,
136
146
  validateCropCoordinates: () => validateCropCoordinates,
137
147
  validateDateRangeReportRequest: () => validateDateRangeReportRequest,
138
148
  validateDuplicateAdParams: () => validateDuplicateAdParams,
139
149
  validateEstimateAudienceRequest: () => validateEstimateAudienceRequest,
140
150
  validateGetInstantPageDetailRequest: () => validateGetInstantPageDetailRequest,
141
151
  validateGetInstantPageSharedUserRequest: () => validateGetInstantPageSharedUserRequest,
152
+ validateInstantPageCanvas: () => validateInstantPageCanvas,
142
153
  validateListFlowsByOfficialAccountRequest: () => validateListFlowsByOfficialAccountRequest,
143
154
  validateListFormLeadsRequest: () => validateListFormLeadsRequest,
144
155
  validateListFormsByOfficialAccountRequest: () => validateListFormsByOfficialAccountRequest,
@@ -154,10 +165,18 @@ __export(index_exports, {
154
165
  validateSearchInstantPagesRequest: () => validateSearchInstantPagesRequest,
155
166
  validateToggleLeadNotificationRequest: () => validateToggleLeadNotificationRequest,
156
167
  validateUpdateAdPayload: () => validateUpdateAdPayload,
168
+ validateUpdateArticleAd: () => validateUpdateArticleAd,
169
+ validateUpdateCommerceAd: () => validateUpdateCommerceAd,
170
+ validateUpdateDisplayAd: () => validateUpdateDisplayAd,
157
171
  validateUpdateFlowRequest: () => validateUpdateFlowRequest,
172
+ validateUpdateFormAd: () => validateUpdateFormAd,
158
173
  validateUpdateInstantPageRequest: () => validateUpdateInstantPageRequest,
159
174
  validateUpdateInstantPageSharesRequest: () => validateUpdateInstantPageSharesRequest,
160
175
  validateUpdateLeadNotificationIntervalRequest: () => validateUpdateLeadNotificationIntervalRequest,
176
+ validateUpdateMessageAd: () => validateUpdateMessageAd,
177
+ validateUpdateOfficialAccountAd: () => validateUpdateOfficialAccountAd,
178
+ validateUpdateVideoAd: () => validateUpdateVideoAd,
179
+ validateUpdateWebsiteAd: () => validateUpdateWebsiteAd,
161
180
  validateUploadCustomAudiencePhoneListRequest: () => validateUploadCustomAudiencePhoneListRequest,
162
181
  validateUploadMediaRequest: () => validateUploadMediaRequest,
163
182
  validateUpsertCustomReportRequest: () => validateUpsertCustomReportRequest,
@@ -2284,11 +2303,18 @@ function validateCreateCampaignPayload(payload, options = {}) {
2284
2303
  `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).`
2285
2304
  );
2286
2305
  }
2287
- if (payload.campaignType !== VALID_CAMPAIGN_TYPES.DISPLAY) {
2306
+ const OA_REQUIRED_CAMPAIGN_TYPES = [
2307
+ VALID_CAMPAIGN_TYPES.FORM,
2308
+ VALID_CAMPAIGN_TYPES.MESSAGE,
2309
+ VALID_CAMPAIGN_TYPES.OA,
2310
+ VALID_CAMPAIGN_TYPES.COMMERCE,
2311
+ VALID_CAMPAIGN_TYPES.ARTICLE
2312
+ ];
2313
+ if (payload.campaignType !== void 0 && OA_REQUIRED_CAMPAIGN_TYPES.includes(payload.campaignType)) {
2288
2314
  if (!payload.pageId || payload.pageId <= 0) {
2289
- 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).");
2315
+ errors.push("pageId c\u1EE7a Official Account l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi lo\u1EA1i chi\u1EBFn d\u1ECBch n\xE0y (ph\u1EA3i > 0, ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA).");
2290
2316
  }
2291
- } else {
2317
+ } else if (payload.campaignType === VALID_CAMPAIGN_TYPES.DISPLAY) {
2292
2318
  if (payload.pageId !== -1 && payload.pageId !== 0 && !payload.pageId) {
2293
2319
  warnings.push("Qu\u1EA3ng c\xE1o Display th\u01B0\u1EDDng s\u1EED d\u1EE5ng pageId = -1.");
2294
2320
  }
@@ -2767,14 +2793,171 @@ function validateCropCoordinates(input) {
2767
2793
  data: errors.length === 0 ? cleanData : void 0
2768
2794
  };
2769
2795
  }
2796
+ function validateCreateCommerceCampaign(payload, options = {}) {
2797
+ const errors = [];
2798
+ const warnings = [];
2799
+ if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
2800
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
2801
+ } else if (payload.name.length > 255) {
2802
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
2803
+ }
2804
+ if (!payload.pageId || payload.pageId <= 0) {
2805
+ errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Commerce (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
2806
+ }
2807
+ if (payload.productId === void 0 || payload.productId === null || payload.productId <= 0) {
2808
+ 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).");
2809
+ }
2810
+ return { isValid: errors.length === 0, errors, warnings };
2811
+ }
2812
+ function validateCreateDisplayCampaign(payload, options = {}) {
2813
+ const errors = [];
2814
+ const warnings = [];
2815
+ if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
2816
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
2817
+ } else if (payload.name.length > 255) {
2818
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
2819
+ }
2820
+ if (payload.targetUrl && !/^https?:\/\/.+/i.test(payload.targetUrl)) {
2821
+ 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://.");
2822
+ }
2823
+ return { isValid: errors.length === 0, errors, warnings };
2824
+ }
2825
+ function validateCreateWebsiteCampaign(payload, options = {}) {
2826
+ const errors = [];
2827
+ const warnings = [];
2828
+ if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
2829
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
2830
+ } else if (payload.name.length > 255) {
2831
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
2832
+ }
2833
+ if (!payload.targetUrl || typeof payload.targetUrl !== "string" || !payload.targetUrl.trim()) {
2834
+ errors.push("Li\xEAn k\u1EBFt website ('targetUrl') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Website.");
2835
+ } else if (!/^https?:\/\/.+/i.test(payload.targetUrl)) {
2836
+ errors.push("Li\xEAn k\u1EBFt website ('targetUrl') ph\u1EA3i l\xE0 \u0111\u01B0\u1EDDng link h\u1EE3p l\u1EC7 b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https://.");
2837
+ }
2838
+ return { isValid: errors.length === 0, errors, warnings };
2839
+ }
2840
+ function validateCreateFormCampaign(payload, options = {}) {
2841
+ const errors = [];
2842
+ const warnings = [];
2843
+ if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
2844
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
2845
+ } else if (payload.name.length > 255) {
2846
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
2847
+ }
2848
+ if (!payload.pageId || payload.pageId <= 0) {
2849
+ errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Form (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
2850
+ }
2851
+ return { isValid: errors.length === 0, errors, warnings };
2852
+ }
2853
+ function validateCreateMessageCampaign(payload, options = {}) {
2854
+ const errors = [];
2855
+ const warnings = [];
2856
+ if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
2857
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
2858
+ } else if (payload.name.length > 255) {
2859
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
2860
+ }
2861
+ if (!payload.pageId || payload.pageId <= 0) {
2862
+ errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Tin nh\u1EAFn (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
2863
+ }
2864
+ return { isValid: errors.length === 0, errors, warnings };
2865
+ }
2866
+ function validateCreateOfficialAccountCampaign(payload, options = {}) {
2867
+ const errors = [];
2868
+ const warnings = [];
2869
+ if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
2870
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
2871
+ } else if (payload.name.length > 255) {
2872
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
2873
+ }
2874
+ if (!payload.pageId || payload.pageId <= 0) {
2875
+ errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Zalo Official Account (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
2876
+ }
2877
+ return { isValid: errors.length === 0, errors, warnings };
2878
+ }
2879
+ function validateCreateArticleCampaign(payload, options = {}) {
2880
+ const errors = [];
2881
+ const warnings = [];
2882
+ if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
2883
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
2884
+ } else if (payload.name.length > 255) {
2885
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
2886
+ }
2887
+ if (!payload.pageId || payload.pageId <= 0) {
2888
+ errors.push("T\xE0i kho\u1EA3n OA ('pageId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o B\xE0i vi\u1EBFt (ch\u1ECDn t\u1EEB Danh s\xE1ch t\xE0i kho\u1EA3n OA, ph\u1EA3i > 0).");
2889
+ }
2890
+ if (!payload.articleId || payload.articleId <= 0) {
2891
+ errors.push("B\xE0i vi\u1EBFt ('articleId') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o B\xE0i vi\u1EBFt (ch\u1ECDn t\u1EEB Danh s\xE1ch b\xE0i vi\u1EBFt c\u1EE7a OA \u0111\xF3, l\u1EA5y qua getOwnedArticles).");
2892
+ }
2893
+ return { isValid: errors.length === 0, errors, warnings };
2894
+ }
2895
+ function validateCreateVideoCampaign(payload, options = {}) {
2896
+ const errors = [];
2897
+ const warnings = [];
2898
+ if (!payload.name || typeof payload.name !== "string" || !payload.name.trim()) {
2899
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
2900
+ } else if (payload.name.length > 255) {
2901
+ errors.push("T\xEAn chi\u1EBFn d\u1ECBch ('name') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1.");
2902
+ }
2903
+ if (!payload.targetUrl || typeof payload.targetUrl !== "string" || !payload.targetUrl.trim()) {
2904
+ errors.push("Li\xEAn k\u1EBFt Website ('targetUrl') l\xE0 b\u1EAFt bu\u1ED9c \u0111\u1ED1i v\u1EDBi Qu\u1EA3ng c\xE1o Video.");
2905
+ } else if (!/^https?:\/\/.+/i.test(payload.targetUrl)) {
2906
+ errors.push("Li\xEAn k\u1EBFt Website ('targetUrl') ph\u1EA3i l\xE0 \u0111\u01B0\u1EDDng link h\u1EE3p l\u1EC7 b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https://.");
2907
+ }
2908
+ return { isValid: errors.length === 0, errors, warnings };
2909
+ }
2910
+ function validateUpdateWebsiteAd(payload, options = {}) {
2911
+ return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.WEBSITE }, options);
2912
+ }
2913
+ function validateUpdateDisplayAd(payload, options = {}) {
2914
+ return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.DISPLAY }, options);
2915
+ }
2916
+ function validateUpdateVideoAd(payload, options = {}) {
2917
+ return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.VIDEO }, options);
2918
+ }
2919
+ function validateUpdateCommerceAd(payload, options = {}) {
2920
+ return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.COMMERCE }, options);
2921
+ }
2922
+ function validateUpdateFormAd(payload, options = {}) {
2923
+ return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.FORM }, options);
2924
+ }
2925
+ function validateUpdateMessageAd(payload, options = {}) {
2926
+ return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.MESSAGE }, options);
2927
+ }
2928
+ function validateUpdateOfficialAccountAd(payload, options = {}) {
2929
+ return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.OA }, options);
2930
+ }
2931
+ function validateUpdateArticleAd(payload, options = {}) {
2932
+ return validateUpdateAdPayload({ ...payload, Type: VALID_AD_TYPES.ARTICLE }, options);
2933
+ }
2770
2934
  var ZaloCampaignsValidator = {
2935
+ // Generic
2771
2936
  createCampaign: validateCreateCampaignPayload,
2772
2937
  updateAd: validateUpdateAdPayload,
2773
2938
  renameCampaign: validateRenameCampaignParams,
2774
2939
  changeStatus: validateChangeCampaignStatusParams,
2775
2940
  duplicateAd: validateDuplicateAdParams,
2776
2941
  validateCropCoordinates,
2777
- validateUploadCropAdImage: validateCropCoordinates
2942
+ validateUploadCropAdImage: validateCropCoordinates,
2943
+ // Specific Create Campaign
2944
+ createCommerceCampaign: validateCreateCommerceCampaign,
2945
+ createDisplayCampaign: validateCreateDisplayCampaign,
2946
+ createWebsiteCampaign: validateCreateWebsiteCampaign,
2947
+ createFormCampaign: validateCreateFormCampaign,
2948
+ createMessageCampaign: validateCreateMessageCampaign,
2949
+ createOfficialAccountCampaign: validateCreateOfficialAccountCampaign,
2950
+ createArticleCampaign: validateCreateArticleCampaign,
2951
+ createVideoCampaign: validateCreateVideoCampaign,
2952
+ // Specific Update Ad
2953
+ updateWebsiteAd: validateUpdateWebsiteAd,
2954
+ updateDisplayAd: validateUpdateDisplayAd,
2955
+ updateVideoAd: validateUpdateVideoAd,
2956
+ updateCommerceAd: validateUpdateCommerceAd,
2957
+ updateFormAd: validateUpdateFormAd,
2958
+ updateMessageAd: validateUpdateMessageAd,
2959
+ updateOfficialAccountAd: validateUpdateOfficialAccountAd,
2960
+ updateArticleAd: validateUpdateArticleAd
2778
2961
  };
2779
2962
 
2780
2963
  // src/services/campaigns.service.ts
@@ -5926,8 +6109,8 @@ function validateListFormLeadsRequest(input) {
5926
6109
  const offset = typeof raw.offset === "number" && raw.offset >= 0 ? Math.floor(raw.offset) : 0;
5927
6110
  const status = typeof raw.status === "string" && raw.status.trim() !== "" ? raw.status.trim() : "2,6,1,0,7,4,5,3";
5928
6111
  const now = Math.floor(Date.now() / 1e3);
5929
- const fromTime = typeof raw.fromTime === "number" && raw.fromTime >= 0 ? Math.floor(raw.fromTime) : now - 90 * 86400;
5930
- const toTime = typeof raw.toTime === "number" && raw.toTime >= 0 ? Math.floor(raw.toTime) : now;
6112
+ const fromTime = typeof raw.fromTime === "number" && raw.fromTime >= 0 ? raw.fromTime >= 1e10 ? Math.floor(raw.fromTime / 1e3) : Math.floor(raw.fromTime) : now - 90 * 86400;
6113
+ const toTime = typeof raw.toTime === "number" && raw.toTime >= 0 ? raw.toTime >= 1e10 ? Math.floor(raw.toTime / 1e3) : Math.floor(raw.toTime) : now;
5931
6114
  if (toTime < fromTime) {
5932
6115
  errors.push("M\u1ED1c th\u1EDDi gian k\u1EBFt th\xFAc 'toTime' ph\u1EA3i l\u1EDBn h\u01A1n ho\u1EB7c b\u1EB1ng 'fromTime'.");
5933
6116
  }
@@ -6517,6 +6700,127 @@ function validateSearchInstantPagesRequest(input) {
6517
6700
  data: errors.length === 0 ? data : void 0
6518
6701
  };
6519
6702
  }
6703
+ function sanitizeCanvasKeys(data) {
6704
+ const cleanData = {};
6705
+ for (const [key, value] of Object.entries(data)) {
6706
+ const cleanKey = key.replace(/^["']+|["']+$/g, "").trim();
6707
+ if (value && typeof value === "object" && !Array.isArray(value)) {
6708
+ const valObj = value;
6709
+ const sanitizedSub = { ...valObj };
6710
+ if (sanitizedSub.images && typeof sanitizedSub.images === "object" && !Array.isArray(sanitizedSub.images)) {
6711
+ sanitizedSub.images = sanitizeCanvasKeys(sanitizedSub.images);
6712
+ }
6713
+ if (sanitizedSub.videos && typeof sanitizedSub.videos === "object" && !Array.isArray(sanitizedSub.videos)) {
6714
+ sanitizedSub.videos = sanitizeCanvasKeys(sanitizedSub.videos);
6715
+ }
6716
+ cleanData[cleanKey] = sanitizedSub;
6717
+ } else {
6718
+ cleanData[cleanKey] = value;
6719
+ }
6720
+ }
6721
+ return cleanData;
6722
+ }
6723
+ function validateInstantPageCanvas(input, isPublishing = false) {
6724
+ const errors = [];
6725
+ if (!input) {
6726
+ return { isValid: false, errors: ["Canvas Instant Page kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng."] };
6727
+ }
6728
+ let canvasObj;
6729
+ if (typeof input === "string") {
6730
+ if (input.trim() === "") {
6731
+ return { isValid: false, errors: ["Chu\u1ED7i Canvas JSON kh\xF4ng \u0111\u01B0\u1EE3c r\u1ED7ng."] };
6732
+ }
6733
+ try {
6734
+ canvasObj = JSON.parse(input);
6735
+ } catch (e) {
6736
+ return { isValid: false, errors: [`Canvas JSON kh\xF4ng h\u1EE3p l\u1EC7: ${e.message}`] };
6737
+ }
6738
+ } else if (typeof input === "object" && input !== null) {
6739
+ canvasObj = input;
6740
+ } else {
6741
+ return { isValid: false, errors: ["Canvas ph\u1EA3i l\xE0 \u0111\u1ED1i t\u01B0\u1EE3ng (Object) ho\u1EB7c chu\u1ED7i JSON h\u1EE3p l\u1EC7."] };
6742
+ }
6743
+ if (!canvasObj.renderList || !Array.isArray(canvasObj.renderList)) {
6744
+ errors.push("Canvas b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 m\u1EA3ng 'renderList' \u0111\u1ECBnh ngh\u0129a th\u1EE9 t\u1EF1 hi\u1EC3n th\u1ECB c\xE1c kh\u1ED1i giao di\u1EC7n (v\xED d\u1EE5: ['0', '1', '2']). Kh\xF4ng \u0111\u01B0\u1EE3c d\xF9ng { blocks: [] }.");
6745
+ } else if (canvasObj.renderList.length === 0) {
6746
+ errors.push("M\u1EA3ng 'renderList' kh\xF4ng \u0111\u01B0\u1EE3c r\u1ED7ng, ph\u1EA3i ch\u1EE9a \xEDt nh\u1EA5t 1 ID kh\u1ED1i giao di\u1EC7n.");
6747
+ }
6748
+ if (!canvasObj.data || typeof canvasObj.data !== "object" || Array.isArray(canvasObj.data)) {
6749
+ errors.push("Canvas b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 \u0111\u1ED1i t\u01B0\u1EE3ng 'data' ch\u1EE9a c\u1EA5u h\xECnh chi ti\u1EBFt c\u1EE7a t\u1EEBng kh\u1ED1i giao di\u1EC7n.");
6750
+ }
6751
+ if (errors.length > 0) {
6752
+ return { isValid: false, errors };
6753
+ }
6754
+ const renderList = canvasObj.renderList.map(
6755
+ (id) => String(id).replace(/^["']+|["']+$/g, "").trim()
6756
+ );
6757
+ const rawData = canvasObj.data;
6758
+ const cleanData = sanitizeCanvasKeys(rawData);
6759
+ for (const blockId of renderList) {
6760
+ if (!(blockId in cleanData)) {
6761
+ errors.push(`Kh\u1ED1i ID '${blockId}' c\xF3 trong 'renderList' nh\u01B0ng kh\xF4ng t\u1ED3n t\u1EA1i trong t\u1EEB \u0111i\u1EC3n 'data'.`);
6762
+ } else {
6763
+ const block = cleanData[blockId];
6764
+ if (!block || typeof block !== "object") {
6765
+ errors.push(`Kh\u1ED1i d\u1EEF li\u1EC7u data['${blockId}'] ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng.`);
6766
+ } else if (block.type === void 0 || typeof block.type !== "number") {
6767
+ errors.push(`Kh\u1ED1i data['${blockId}'] b\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 tr\u01B0\u1EDDng 'type' l\xE0 m\xE3 s\u1ED1 nguy\xEAn (Block Type).`);
6768
+ }
6769
+ }
6770
+ }
6771
+ if (isPublishing) {
6772
+ for (const blockId of renderList) {
6773
+ const block = cleanData[blockId];
6774
+ if (!block) continue;
6775
+ if (block.type === 28) {
6776
+ const name = typeof block.name === "string" ? block.name.trim() : "";
6777
+ if (name.length < 2 || name.length > 30) {
6778
+ errors.push(`Kh\u1ED1i Th\xF4ng tin Mini Shop (ID: '${blockId}'): T\xEAn Mini Shop ('name') ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 30 k\xFD t\u1EF1.`);
6779
+ }
6780
+ const img = block.image;
6781
+ if (!img || typeof img.url !== "string" || !img.url.startsWith("http")) {
6782
+ errors.push(`Kh\u1ED1i Th\xF4ng tin Mini Shop (ID: '${blockId}'): B\u1EAFt bu\u1ED9c ph\u1EA3i c\xF3 \u1EA3nh logo v\u1EDBi URL h\u1EE3p l\u1EC7 ('image.url').`);
6783
+ }
6784
+ }
6785
+ if (block.type === 29) {
6786
+ const len = typeof block.length === "number" ? block.length : 0;
6787
+ const html = typeof block.outputHtml === "string" ? block.outputHtml.trim() : "";
6788
+ if (len === 0 && html === "") {
6789
+ errors.push(`Kh\u1ED1i M\xF4 t\u1EA3 (ID: '${blockId}'): Kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng n\u1ED9i dung m\xF4 t\u1EA3.`);
6790
+ }
6791
+ }
6792
+ if (block.type === 1) {
6793
+ const indexes = Array.isArray(block.indexes) ? block.indexes : [];
6794
+ const images = block.images && typeof block.images === "object" ? block.images : {};
6795
+ for (const idx of indexes) {
6796
+ const img = images[String(idx)];
6797
+ if (img && typeof img.url === "string" && img.url.trim() === "") {
6798
+ errors.push(`Kh\u1ED1i Carousel (ID: '${blockId}'): \u1EA2nh t\u1EA1i ch\u1EC9 m\u1EE5c '${idx}' kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 URL r\u1ED7ng.`);
6799
+ }
6800
+ }
6801
+ }
6802
+ if (block.type === 21) {
6803
+ const msg = typeof block.content === "string" ? block.content.trim() : "";
6804
+ if (msg.length === 0 || msg.length > 40) {
6805
+ errors.push(`Kh\u1ED1i Tin nh\u1EAFn m\u1EB7c \u0111\u1ECBnh (ID: '${blockId}'): N\u1ED9i dung tin nh\u1EAFn ph\u1EA3i t\u1EEB 1 \u0111\u1EBFn 40 k\xFD t\u1EF1.`);
6806
+ }
6807
+ }
6808
+ }
6809
+ }
6810
+ const resultCanvas = {
6811
+ version: typeof canvasObj.version === "number" || typeof canvasObj.version === "string" ? canvasObj.version : "1",
6812
+ renderList,
6813
+ data: cleanData,
6814
+ ...canvasObj.freezedTop !== void 0 ? { freezedTop: Number(canvasObj.freezedTop) } : {},
6815
+ ...canvasObj.freezedBottom !== void 0 ? { freezedBottom: Number(canvasObj.freezedBottom) } : {},
6816
+ ...canvasObj.pageTitle !== void 0 ? { pageTitle: String(canvasObj.pageTitle) } : {}
6817
+ };
6818
+ return {
6819
+ isValid: errors.length === 0,
6820
+ errors,
6821
+ data: errors.length === 0 ? resultCanvas : void 0
6822
+ };
6823
+ }
6520
6824
  function validateUpdateInstantPageRequest(input) {
6521
6825
  const errors = [];
6522
6826
  if (!input || typeof input !== "object") {
@@ -6555,40 +6859,42 @@ function validateUpdateInstantPageRequest(input) {
6555
6859
  data.active = obj.active;
6556
6860
  }
6557
6861
  }
6862
+ let isPublishing = false;
6558
6863
  if (obj.status !== void 0 && obj.status !== null) {
6559
6864
  const st = Number(obj.status);
6560
6865
  if (![0, 1, 2, 3].includes(st)) {
6561
6866
  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).");
6562
6867
  } else {
6563
6868
  data.status = st;
6869
+ if (st === 1) isPublishing = true;
6564
6870
  }
6565
6871
  }
6872
+ let validatedDraftCanvas;
6566
6873
  if (obj.draft !== void 0 && obj.draft !== null) {
6567
- if (typeof obj.draft !== "string") {
6568
- errors.push("Tr\u01B0\u1EDDng 'draft' ph\u1EA3i l\xE0 chu\u1ED7i JSON (JSON-encoded string).");
6569
- } else if (obj.draft.trim() !== "") {
6570
- try {
6571
- JSON.parse(obj.draft);
6572
- data.draft = obj.draft;
6573
- } catch (err) {
6574
- errors.push(`Tr\u01B0\u1EDDng 'draft' kh\xF4ng ph\u1EA3i l\xE0 chu\u1ED7i JSON h\u1EE3p l\u1EC7: ${err.message}`);
6575
- }
6874
+ const canvasRes = validateInstantPageCanvas(obj.draft, isPublishing);
6875
+ if (!canvasRes.isValid) {
6876
+ errors.push(...canvasRes.errors.map((err) => `[draft] ${err}`));
6576
6877
  } else {
6577
- data.draft = "";
6878
+ validatedDraftCanvas = canvasRes.data;
6879
+ data.draft = JSON.stringify(canvasRes.data);
6578
6880
  }
6579
6881
  }
6882
+ let validatedContentCanvas;
6580
6883
  if (obj.content !== void 0 && obj.content !== null) {
6581
- if (typeof obj.content !== "string") {
6582
- errors.push("Tr\u01B0\u1EDDng 'content' ph\u1EA3i l\xE0 chu\u1ED7i JSON (JSON-encoded string).");
6583
- } else if (obj.content.trim() !== "") {
6584
- try {
6585
- JSON.parse(obj.content);
6586
- data.content = obj.content;
6587
- } catch (err) {
6588
- errors.push(`Tr\u01B0\u1EDDng 'content' kh\xF4ng ph\u1EA3i l\xE0 chu\u1ED7i JSON h\u1EE3p l\u1EC7: ${err.message}`);
6589
- }
6884
+ const canvasRes = validateInstantPageCanvas(obj.content, isPublishing);
6885
+ if (!canvasRes.isValid) {
6886
+ errors.push(...canvasRes.errors.map((err) => `[content] ${err}`));
6590
6887
  } else {
6591
- data.content = "";
6888
+ validatedContentCanvas = canvasRes.data;
6889
+ data.content = JSON.stringify(canvasRes.data);
6890
+ }
6891
+ }
6892
+ if (isPublishing) {
6893
+ if (data.draft && !data.content) {
6894
+ data.content = data.draft;
6895
+ } else if (data.content && !data.draft) {
6896
+ data.draft = data.content;
6897
+ } else if (!data.draft && !data.content) {
6592
6898
  }
6593
6899
  }
6594
6900
  const hasUpdateField = data.name !== void 0 || data.oaId !== void 0 || data.active !== void 0 || data.status !== void 0 || data.draft !== void 0 || data.content !== void 0;
@@ -7599,6 +7905,8 @@ var ZaloInstantPageBlockType = /* @__PURE__ */ ((ZaloInstantPageBlockType2) => {
7599
7905
  ZaloInstantPageBlockType2[ZaloInstantPageBlockType2["CALL_HOTLINE_BUTTON"] = 23] = "CALL_HOTLINE_BUTTON";
7600
7906
  ZaloInstantPageBlockType2[ZaloInstantPageBlockType2["KEY_VALUE_TABLE"] = 25] = "KEY_VALUE_TABLE";
7601
7907
  ZaloInstantPageBlockType2[ZaloInstantPageBlockType2["CONSENT_NOTICE"] = 27] = "CONSENT_NOTICE";
7908
+ ZaloInstantPageBlockType2[ZaloInstantPageBlockType2["SHOP_INFO"] = 28] = "SHOP_INFO";
7909
+ ZaloInstantPageBlockType2[ZaloInstantPageBlockType2["SHOP_DESCRIPTION"] = 29] = "SHOP_DESCRIPTION";
7602
7910
  return ZaloInstantPageBlockType2;
7603
7911
  })(ZaloInstantPageBlockType || {});
7604
7912
  var ZaloInstantPageSharePermission = {
@@ -7612,6 +7920,399 @@ var ZaloInstantPageSharePermission = {
7612
7920
  READ_ONLY: 4
7613
7921
  };
7614
7922
 
7923
+ // src/helpers/instant-page-factory.ts
7924
+ var InstantPageFactory = class {
7925
+ /**
7926
+ * Khởi tạo Canvas hoàn chỉnh từ Template ID (1, 3, 4, 5) được điền sẵn dữ liệu hợp lệ.
7927
+ */
7928
+ static createFromTemplate(templateId, options = {}) {
7929
+ const brandName = options.brandName || "RedAI Official Store";
7930
+ const brandLogoUrl = options.brandLogoUrl || "https://adtima-media.zascdn.me/2023/10/58117541-e206-4f9d-b4cf-69e50f963288.svg";
7931
+ const productName = options.productName || "S\u1EA3n ph\u1EA9m / D\u1ECBch v\u1EE5 \u0110\u1ED9t ph\xE1 2026";
7932
+ const price = options.price ?? 299e3;
7933
+ const rawPrice = options.rawPrice ?? 499e3;
7934
+ const defaultMsg = options.defaultMessage || "T\xF4i mu\u1ED1n t\xECm hi\u1EC3u th\xEAm v\u1EC1 s\u1EA3n ph\u1EA9m n\xE0y";
7935
+ const defaultImages = [
7936
+ "https://adtima-media.zascdn.me/2023/06/84cba4c9-be13-425a-8daa-40e695ca9805.jpg",
7937
+ "https://adtima-media.zascdn.me/2023/06/805587cd-4699-47e6-a9bb-3cbbb4039b40.jpg",
7938
+ "https://adtima-media.zascdn.me/2023/06/aca98d2c-1739-4f03-a366-43a6d6c4ef53.jpg",
7939
+ "https://adtima-media.zascdn.me/2023/06/8cc5692b-2899-4862-9957-d3f66e8778cd.jpg"
7940
+ ];
7941
+ switch (templateId) {
7942
+ case 5: {
7943
+ const carouselImgs = options.carouselImages && options.carouselImages.length > 0 ? options.carouselImages : defaultImages.map((url, i) => ({ url, name: `image-${i + 1}.jpg` }));
7944
+ const indexes = carouselImgs.map((_, i) => String(i));
7945
+ const imagesMap = {};
7946
+ carouselImgs.forEach((img, i) => {
7947
+ imagesMap[String(i)] = {
7948
+ name: img.name || `image-${i + 1}.jpg`,
7949
+ url: img.url
7950
+ };
7951
+ });
7952
+ const descText = options.description || "H\u1EC7 sinh th\xE1i c\xF4ng ngh\u1EC7 t\u1EF1 \u0111\u1ED9ng h\xF3a RedAI. T\xEDch h\u1EE3p \u0111a k\xEAnh Zalo OA, Website & CRM; h\u1ED7 tr\u1EE3 t\u1EF1 \u0111\u1ED9ng ph\u1EA3n h\u1ED3i v\xE0 ch\u1ED1t \u0111\u01A1n 24/7.";
7953
+ return {
7954
+ version: 1,
7955
+ renderList: ["1", "2", "3", "4"],
7956
+ freezedBottom: 4,
7957
+ pageTitle: "Chi ti\u1EBFt",
7958
+ data: {
7959
+ "1": {
7960
+ id: "-1",
7961
+ type: 28,
7962
+ name: brandName,
7963
+ image: {
7964
+ name: "logo.png",
7965
+ url: brandLogoUrl
7966
+ }
7967
+ },
7968
+ "2": {
7969
+ id: "-1",
7970
+ type: 29,
7971
+ delta: {
7972
+ ops: [
7973
+ { attributes: { bold: true, size: "18px" }, insert: `${brandName}
7974
+ ` },
7975
+ { insert: `
7976
+ ${descText}
7977
+ ` }
7978
+ ]
7979
+ },
7980
+ outputHtml: `<p><strong style="font-size: 18px;">${brandName}</strong></p><p><br>${descText}</p>`,
7981
+ length: brandName.length + descText.length + 10
7982
+ },
7983
+ "3": {
7984
+ id: "-1",
7985
+ type: 1,
7986
+ indexes,
7987
+ images: imagesMap,
7988
+ videos: {
7989
+ "0": { name: "", thumbnail: "", url: "" }
7990
+ }
7991
+ },
7992
+ "4": {
7993
+ id: "-1",
7994
+ type: 21,
7995
+ content: defaultMsg,
7996
+ marginTop: 0,
7997
+ marginBottom: 0
7998
+ }
7999
+ }
8000
+ };
8001
+ }
8002
+ case 4: {
8003
+ return {
8004
+ version: 4,
8005
+ renderList: ["1", "2", "3"],
8006
+ freezedBottom: 3,
8007
+ data: {
8008
+ "1": {
8009
+ id: "-1",
8010
+ indexes: ["0", "1", "2"],
8011
+ images: {
8012
+ "1": { name: "banner-1.jpg", url: defaultImages[0] },
8013
+ "2": { name: "banner-2.jpg", url: defaultImages[1] }
8014
+ },
8015
+ textEditor: {
8016
+ delta: {
8017
+ ops: [
8018
+ { attributes: { bold: true }, insert: `Ch\xE0o m\u1EEBng b\u1EA1n \u0111\u1EBFn v\u1EDBi ${brandName}` },
8019
+ { insert: "\n\nB\u1EA1n \u0111ang quan t\xE2m gi\u1EA3i ph\xE1p n\xE0o \u0111\u1EC3 chuy\xEAn vi\xEAn h\u1ED7 tr\u1EE3 ngay?\n\n" }
8020
+ ]
8021
+ },
8022
+ outputHtml: `<p><strong>Ch\xE0o m\u1EEBng b\u1EA1n \u0111\u1EBFn v\u1EDBi ${brandName}</strong></p><p><br></p><p>B\u1EA1n \u0111ang quan t\xE2m gi\u1EA3i ph\xE1p n\xE0o \u0111\u1EC3 chuy\xEAn vi\xEAn h\u1ED7 tr\u1EE3 ngay?</p>`
8023
+ },
8024
+ type: 1,
8025
+ videos: {
8026
+ "0": { name: "", thumbnail: "", url: "" }
8027
+ }
8028
+ },
8029
+ "2": {
8030
+ rows: [{ id: 0, left: "\u01AFu \u0111\xE3i tr\u1EA3i nghi\u1EC7m", right: "D\xF9ng th\u1EED mi\u1EC5n ph\xED" }],
8031
+ type: 25
8032
+ },
8033
+ "3": {
8034
+ list: [
8035
+ "T\u01B0 v\u1EA5n gi\u1EA3i ph\xE1p t\u1EF1 \u0111\u1ED9ng h\xF3a",
8036
+ "B\xE1o gi\xE1 chi ti\u1EBFt g\xF3i doanh nghi\u1EC7p",
8037
+ "H\u1ED7 tr\u1EE3 k\u1EF9 thu\u1EADt 24/7"
8038
+ ],
8039
+ marginBottom: 16,
8040
+ marginTop: 0,
8041
+ type: 20
8042
+ }
8043
+ }
8044
+ };
8045
+ }
8046
+ case 3:
8047
+ case 1:
8048
+ default: {
8049
+ return {
8050
+ version: "1",
8051
+ renderList: [
8052
+ "0",
8053
+ "1",
8054
+ "2",
8055
+ "11",
8056
+ "16",
8057
+ "17",
8058
+ "18",
8059
+ "26",
8060
+ "3",
8061
+ "4",
8062
+ "5",
8063
+ "7",
8064
+ "8",
8065
+ "9",
8066
+ "12",
8067
+ "10",
8068
+ "27"
8069
+ ],
8070
+ freezedTop: 3,
8071
+ freezedBottom: 10,
8072
+ data: {
8073
+ "0": {
8074
+ id: "-1",
8075
+ type: 1,
8076
+ indexes: ["0", "1", "2"],
8077
+ images: {
8078
+ "0": { name: "prod-1.jpg", url: defaultImages[0] },
8079
+ "1": { name: "prod-2.jpg", url: defaultImages[1] },
8080
+ "2": { name: "prod-3.jpg", url: defaultImages[2] }
8081
+ },
8082
+ videos: { "5": { name: "", thumbnail: "", url: "" } }
8083
+ },
8084
+ "1": {
8085
+ id: "-1",
8086
+ discountValue: 35,
8087
+ visible: true,
8088
+ countdownType: 4,
8089
+ type: 2,
8090
+ startDate: Date.now(),
8091
+ loopDays: 1,
8092
+ label: "<p>Th\u1EDDi gian \u01B0u \u0111\xE3i c\xF2n l\u1EA1i:</p>",
8093
+ labelDelta: { ops: [{ insert: "Th\u1EDDi gian \u01B0u \u0111\xE3i c\xF2n l\u1EA1i:\n" }] },
8094
+ marginTop: 8,
8095
+ marginBottom: 0,
8096
+ visibility: { days: true, hours: true, minutes: true, seconds: true }
8097
+ },
8098
+ "2": {
8099
+ type: 19,
8100
+ name: productName,
8101
+ price,
8102
+ rawPrice,
8103
+ marginTop: 8,
8104
+ marginBottom: 8
8105
+ },
8106
+ "3": {
8107
+ id: "-1",
8108
+ type: 18,
8109
+ visible: true,
8110
+ formQuestion: {
8111
+ type: 2,
8112
+ title: "Phi\xEAn b\u1EA3n",
8113
+ isRequired: true,
8114
+ disable: false,
8115
+ answers: [
8116
+ { type: 1, value: "B\u1EA3n Ti\xEAu Chu\u1EA9n", priority: 0 },
8117
+ { type: 1, value: "B\u1EA3n Cao C\u1EA5p", priority: 1 }
8118
+ ],
8119
+ description: "",
8120
+ priority: 0
8121
+ },
8122
+ marginTop: 8,
8123
+ marginBottom: 8
8124
+ },
8125
+ "4": {
8126
+ id: "-1",
8127
+ type: 18,
8128
+ visible: true,
8129
+ formQuestion: {
8130
+ type: 2,
8131
+ title: "G\xF3i dung l\u01B0\u1EE3ng",
8132
+ isRequired: true,
8133
+ disable: false,
8134
+ answers: [
8135
+ { type: 1, value: "G\xF3i 1 Th\xE1ng", priority: 0 },
8136
+ { type: 1, value: "G\xF3i 1 N\u0103m", priority: 1 }
8137
+ ],
8138
+ description: "",
8139
+ priority: 0
8140
+ },
8141
+ marginTop: 8,
8142
+ marginBottom: 8
8143
+ },
8144
+ "5": {
8145
+ id: "-1",
8146
+ type: 16,
8147
+ formQuestion: {
8148
+ type: 1,
8149
+ title: "S\u1ED1 l\u01B0\u1EE3ng",
8150
+ isRequired: true,
8151
+ disable: false,
8152
+ answers: [{ type: 5, value: "", priority: 0 }],
8153
+ description: "",
8154
+ priority: 0
8155
+ },
8156
+ marginTop: 8,
8157
+ marginBottom: 8
8158
+ },
8159
+ "7": {
8160
+ id: "-1",
8161
+ type: 7,
8162
+ formQuestion: {
8163
+ type: 1,
8164
+ title: "H\u1ECD v\xE0 t\xEAn",
8165
+ isRequired: true,
8166
+ disable: false,
8167
+ answers: [{ type: 7, value: "", placeHolder: "Nh\u1EADp h\u1ECD v\xE0 t\xEAn c\u1EE7a b\u1EA1n", priority: 0 }],
8168
+ description: "",
8169
+ priority: 0
8170
+ },
8171
+ marginTop: 8,
8172
+ marginBottom: 8
8173
+ },
8174
+ "8": {
8175
+ id: "-1",
8176
+ type: 9,
8177
+ formQuestion: {
8178
+ type: 1,
8179
+ title: "S\u1ED1 \u0111i\u1EC7n tho\u1EA1i",
8180
+ isRequired: true,
8181
+ disable: false,
8182
+ answers: [{ type: 13, value: "", placeHolder: "Nh\u1EADp s\u1ED1 \u0111i\u1EC7n tho\u1EA1i li\xEAn h\u1EC7", priority: 0 }],
8183
+ description: "",
8184
+ priority: 0
8185
+ },
8186
+ marginTop: 8,
8187
+ marginBottom: 8
8188
+ },
8189
+ "9": {
8190
+ id: "-1",
8191
+ type: 10,
8192
+ formQuestion: {
8193
+ type: 1,
8194
+ title: "\u0110\u1ECBa ch\u1EC9",
8195
+ isRequired: true,
8196
+ disable: false,
8197
+ answers: [{ type: 15, value: "", placeHolder: "Nh\u1EADp \u0111\u1ECBa ch\u1EC9 giao h\xE0ng ho\u1EB7c nh\u1EADn t\u01B0 v\u1EA5n", priority: 0 }],
8198
+ description: "",
8199
+ priority: 0
8200
+ },
8201
+ marginTop: 8,
8202
+ marginBottom: 8
8203
+ },
8204
+ "10": {
8205
+ id: "-1",
8206
+ type: 8,
8207
+ background: "#008FE5",
8208
+ borderColor: "#000000",
8209
+ borderRadius: 4,
8210
+ borderSize: 1,
8211
+ showBorder: false,
8212
+ formPopup: templateId === 3,
8213
+ fixedPosition: true,
8214
+ image: {
8215
+ name: "cart.svg",
8216
+ url: "https://adtima-media.zascdn.me/2023/10/58117541-e206-4f9d-b4cf-69e50f963288.svg"
8217
+ },
8218
+ content2: "\u0110\u1EB7t h\xE0ng ngay"
8219
+ },
8220
+ "11": {
8221
+ id: "-1",
8222
+ type: 4,
8223
+ delta: {
8224
+ ops: [
8225
+ { attributes: { color: "#bf2600", bold: true }, insert: "\u01AFU \u0110\xC3I \u0110\u1EB6C BI\u1EC6T H\xD4M NAY\n" },
8226
+ { insert: `Tr\u1EA3i nghi\u1EC7m tr\u1ECDn b\u1ED9 t\xEDnh n\u0103ng v\u01B0\u1EE3t tr\u1ED9i c\u1EE7a ${productName}.
8227
+ ` }
8228
+ ]
8229
+ },
8230
+ marginTop: 16,
8231
+ marginBottom: 16,
8232
+ outputHtml: `<p><strong style="color: rgb(191, 38, 0);">\u01AFU \u0110\xC3I \u0110\u1EB6C BI\u1EC6T H\xD4M NAY</strong></p><p>Tr\u1EA3i nghi\u1EC7m tr\u1ECDn b\u1ED9 t\xEDnh n\u0103ng v\u01B0\u1EE3t tr\u1ED9i c\u1EE7a ${productName}.</p>`
8233
+ },
8234
+ "12": {
8235
+ id: "-1",
8236
+ type: 23,
8237
+ actionType: "1",
8238
+ content: "Li\xEAn h\u1EC7 Hotline",
8239
+ borderColor: "#008fe5",
8240
+ borderRadius: 4,
8241
+ borderSize: 2,
8242
+ showBorder: true,
8243
+ fixedPosition: true,
8244
+ visible: true,
8245
+ phone: options.hotline || "",
8246
+ image: {
8247
+ name: "phone.svg",
8248
+ url: "https://adtima-media.zascdn.me/2023/10/03d065a4-90b2-4deb-b684-5ff61407a47d.svg"
8249
+ },
8250
+ color: "#008fe5",
8251
+ background: "#ffffff",
8252
+ marginTop: 16,
8253
+ marginBottom: 16
8254
+ },
8255
+ "16": {
8256
+ id: "-1",
8257
+ type: 6,
8258
+ mediaType: "image",
8259
+ image: { url: defaultImages[0], name: "hero-1.png" },
8260
+ videoSetting: { autoPlay: true, loop: true }
8261
+ },
8262
+ "17": {
8263
+ id: "-1",
8264
+ type: 6,
8265
+ mediaType: "image",
8266
+ image: { url: defaultImages[1], name: "hero-2.png" },
8267
+ videoSetting: { autoPlay: true, loop: true }
8268
+ },
8269
+ "18": {
8270
+ id: "-1",
8271
+ type: 6,
8272
+ mediaType: "image",
8273
+ image: { url: defaultImages[2], name: "hero-3.png" },
8274
+ videoSetting: { autoPlay: true, loop: true }
8275
+ },
8276
+ "26": {
8277
+ id: "-1",
8278
+ type: 14,
8279
+ backgroundColor: "#f2f3f3",
8280
+ textDelta: { ops: [{ attributes: { size: "18px", bold: true }, insert: `${brandName}
8281
+ ` }] },
8282
+ textHtml: `<p><strong style="font-size: 18px;">${brandName}</strong></p>`,
8283
+ detailings: [
8284
+ {
8285
+ image: {
8286
+ url: "https://adtima-media.zascdn.me/2023/10/cba64b4d-0bd5-4504-8b6d-5f2d2562854a.png",
8287
+ name: "home.png"
8288
+ },
8289
+ textDelta: { ops: [{ insert: `\u0110\u1ECBa ch\u1EC9: ${options.address || "H\xE0 N\u1ED9i / TP.HCM"}
8290
+ ` }] },
8291
+ textHtml: `<p>\u0110\u1ECBa ch\u1EC9: ${options.address || "H\xE0 N\u1ED9i / TP.HCM"}</p>`
8292
+ },
8293
+ {
8294
+ image: {
8295
+ url: "https://adtima-media.zascdn.me/2023/10/d538811f-9232-4ef0-a130-ea2b1dda05d2.png",
8296
+ name: "phone.png"
8297
+ },
8298
+ textDelta: { ops: [{ insert: `Hotline: ${options.hotline || "1900 xxxx"}
8299
+ ` }] },
8300
+ textHtml: `<p>Hotline: ${options.hotline || "1900 xxxx"}</p>`
8301
+ }
8302
+ ]
8303
+ },
8304
+ "27": {
8305
+ id: "-1",
8306
+ type: 27,
8307
+ useCustomConsent: false
8308
+ }
8309
+ }
8310
+ };
8311
+ }
8312
+ }
8313
+ }
8314
+ };
8315
+
7615
8316
  // src/validators/automated-rules.validator.ts
7616
8317
  var AutomatedRuleScopeEnum = /* @__PURE__ */ ((AutomatedRuleScopeEnum2) => {
7617
8318
  AutomatedRuleScopeEnum2[AutomatedRuleScopeEnum2["Ads"] = 1] = "Ads";
@@ -8348,6 +9049,7 @@ var ZaloMediaValidator = {
8348
9049
  AutomatedRuleTimeRangeEnum,
8349
9050
  ConversionLabelEnum,
8350
9051
  ConversionUrlTypeEnum,
9052
+ InstantPageFactory,
8351
9053
  MAX_REPORT_RANGE_MS,
8352
9054
  MAX_REPORT_RANGE_SECONDS,
8353
9055
  MemoryZaloSessionStore,
@@ -8426,26 +9128,36 @@ var ZaloMediaValidator = {
8426
9128
  defaultSharedMemorySessionStore,
8427
9129
  deriveAccountKeyFromZpsid,
8428
9130
  parseZaloCookieInput,
9131
+ sanitizeCanvasKeys,
8429
9132
  validateChangeCampaignStatusParams,
8430
9133
  validateCloneInstantPageRequest,
9134
+ validateCreateArticleCampaign,
8431
9135
  validateCreateCampaignPayload,
9136
+ validateCreateCommerceCampaign,
8432
9137
  validateCreateCustomAudienceRequest,
9138
+ validateCreateDisplayCampaign,
8433
9139
  validateCreateFlowRequest,
9140
+ validateCreateFormCampaign,
8434
9141
  validateCreateFormEventAudienceRequest,
8435
9142
  validateCreateFormRequest,
8436
9143
  validateCreateInstantPageRequest,
8437
9144
  validateCreateLookalikeAudienceRequest,
9145
+ validateCreateMessageCampaign,
8438
9146
  validateCreateMessageOaEventAudienceRequest,
8439
9147
  validateCreateMessagePersonalEventAudienceRequest,
8440
9148
  validateCreateOaPageRequest,
9149
+ validateCreateOfficialAccountCampaign,
8441
9150
  validateCreatePhoneAudienceRequest,
8442
9151
  validateCreateSavedAudienceRequest,
9152
+ validateCreateVideoCampaign,
9153
+ validateCreateWebsiteCampaign,
8443
9154
  validateCropCoordinates,
8444
9155
  validateDateRangeReportRequest,
8445
9156
  validateDuplicateAdParams,
8446
9157
  validateEstimateAudienceRequest,
8447
9158
  validateGetInstantPageDetailRequest,
8448
9159
  validateGetInstantPageSharedUserRequest,
9160
+ validateInstantPageCanvas,
8449
9161
  validateListFlowsByOfficialAccountRequest,
8450
9162
  validateListFormLeadsRequest,
8451
9163
  validateListFormsByOfficialAccountRequest,
@@ -8461,10 +9173,18 @@ var ZaloMediaValidator = {
8461
9173
  validateSearchInstantPagesRequest,
8462
9174
  validateToggleLeadNotificationRequest,
8463
9175
  validateUpdateAdPayload,
9176
+ validateUpdateArticleAd,
9177
+ validateUpdateCommerceAd,
9178
+ validateUpdateDisplayAd,
8464
9179
  validateUpdateFlowRequest,
9180
+ validateUpdateFormAd,
8465
9181
  validateUpdateInstantPageRequest,
8466
9182
  validateUpdateInstantPageSharesRequest,
8467
9183
  validateUpdateLeadNotificationIntervalRequest,
9184
+ validateUpdateMessageAd,
9185
+ validateUpdateOfficialAccountAd,
9186
+ validateUpdateVideoAd,
9187
+ validateUpdateWebsiteAd,
8468
9188
  validateUploadCustomAudiencePhoneListRequest,
8469
9189
  validateUploadMediaRequest,
8470
9190
  validateUpsertCustomReportRequest,