1(function () { 2 // ========================= 3 // CHAT FORM STATE (GLOBAL TRONG IIFE) 4 // ========================= 5 let chatFormState = { 6 fullname: "", 7 phone: "", 8 email: "", 9 service: "" 10 }; 11 12 // â FLAG: chá» track chat_form 1 lần / 1 phiên chat 13 let hasTrackedChatForm = false; 14 15 // ========================= 16 // INIT 17 // ========================= 18 document.addEventListener("DOMContentLoaded", function () { 19 // DOM ready 20 }); 21 22 // ========================= 23 // MESSAGE SOP HOOK LISTENER 24 // ========================= 25 window.addEventListener("message", (event) => { 26 if (event.data?.type !== "SOP_EVENT") return; 27 28 const { action, ...payload } = event.data.payload || {}; 29 30 switch (action) { 31 // Click và o bóng 32 case "click_chat": 33 // console.log("Chat Clicked. Is Open:", payload.isOpen); 34 35 // ð RESET STATE KHI CHAT ÄÃNG 36 if (payload.isOpen === false) { 37 resetChatFormState(); 38 resetChatFormTracking(); 39 return; 40 } 41 42 // â CHá» TRACK KHI CHAT Má» 43 if (payload.isOpen === true) { 44 fireFtracking({ 45 eventName: "click_form", 46 eventCustom: "click_chat", 47 event_description: "Click bóng chat SOP", 48 area: "sop_fchat_icon", 49 area_position: "1", 50 item_position: "1", 51 label: "Bóng chat SOP" 52 }); 53 } 54 break; 55 56 // Change field là gá»i 57 case "chat_form": 58 handleChatForm(payload); 59 break; 60 61 // Click button chat 62 case "start_chat": 63 64 const userInfo = payload.user_info || {}; 65 const fullname = userInfo.fullname || userInfo["HoÌ£ vaÌ tên"] || ""; 66 const phone = userInfo.phone || userInfo["SÃ´Ì Äiện thoaÌ£i"] || ""; 67 const email = userInfo.email || ""; 68 const rawService = userInfo.service || userInfo["Dá»ch vụ cần tư vấn"] || ""; 69 const normalizedService = normalizeService(rawService); 70 71 // Äá»ng bá» lại state 72 chatFormState.fullname = fullname; 73 chatFormState.phone = phone; 74 chatFormState.email = email; 75 chatFormState.service = normalizedService; 76 77 // â CHá» TRACK KHI ÄỦ NAME + PHONE 78 if (!isChatFormReady()) return; 79 80 fireFtracking({ 81 eventName: "submit_form", 82 eventCustom: "start_chat", 83 event_description: "Bắt Äầu chat bóng SOP", 84 area: "sop_fchat_start", 85 area_position: "1", 86 item_position: "1", 87 label: "Chat vá»i FPT Telecom", 88 fullname, 89 phone, 90 email, 91 service: normalizedService 92 }); 93 break; 94 95 default: 96 console.log("Unknown Action:", action); 97 } 98 }); 99 100 // ---------------------------------------- 101 // HANDLERS 102 // ---------------------------------------- 103 function handleChatForm(payload) { 104 const { type, value } = payload.data || {}; 105 106 switch (type) { 107 case "valid_name": 108 chatFormState.fullname = value || ""; 109 console.log("Valid Name Entered:", chatFormState.fullname); 110 break; 111 112 case "valid_phone": 113 chatFormState.phone = value || ""; 114 console.log("Valid Phone Entered:", chatFormState.phone); 115 break; 116 117 case "valid_email": 118 chatFormState.email = value || ""; 119 console.log("Valid Email Entered:", chatFormState.email); 120 break; 121 122 case "select_service": 123 chatFormState.service = normalizeService(value); 124 console.log("Service Selected:", chatFormState.service); 125 break; 126 127 default: 128 return; 129 } 130 131 // â Äà TRACK â KHÃNG TRACK LẠI 132 if (hasTrackedChatForm) return; 133 134 // â CHá» TRACK KHI ÄỦ NAME + PHONE 135 if (!isChatFormReady()) return; 136 137 fireFtracking({ 138 eventName: "change_form", 139 eventCustom: "chat_form", 140 event_description: "Click bóng chat SOP", 141 area: "sop_fchat_form", 142 area_position: "1", 143 item_position: "1", 144 label: "", 145 fullname: chatFormState.fullname, 146 phone: chatFormState.phone, 147 email: chatFormState.email, 148 service: chatFormState.service 149 }); 150 151 hasTrackedChatForm = true; 152 } 153 154 // ---------------------------------------- 155 // COMMON TRACKING FUNCTION 156 // ---------------------------------------- 157 function fireFtracking(payload) { 158 159 const { 160 eventName, 161 eventCustom, 162 area,
163 label, 164 ...data 165 } = payload; 166 167 trackingCustomEventIsc(eventName, { 168 event_custom: eventCustom, 169 area, 170 parent_id: normalizeUrl(window.location.href), 171 ...(label && { label }), 172 ...data 173 }); 174 } 175 176 // ---------------------------------------- 177 // HELPERS 178 // ---------------------------------------- 179 function normalizeService(service) { 180 if (Array.isArray(service)) { 181 return service 182 .map(v => typeof v === "string" ? v.trim() : "") 183 .filter(Boolean) 184 .join(" | "); 185 } 186 return typeof service === "string" ? service.trim() : ""; 187 } 188 189 function normalizeUrl(url) { 190 try { 191 const u = new URL(url); 192 return ( 193 u.host.replace(/^www\./, "") + 194 (u.pathname === "/" ? "" : u.pathname) + 195 u.search + 196 u.hash 197 ); 198 } catch { 199 return url; 200 } 201 } 202 203 function isChatFormReady() { 204 return ( 205 chatFormState.fullname.trim() !== "" && chatFormState.phone.trim() !== "" 206 ); 207 } 208 209 function resetChatFormState() { 210 chatFormState.fullname = ""; 211 chatFormState.phone = ""; 212 chatFormState.email = ""; 213 chatFormState.service = ""; 214 // console.log("Chat form state reset"); 215 } 216 217 function resetChatFormTracking() { 218 hasTrackedChatForm = false; 219 } 220 221})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.