1/** 2 * Chatway è®¿å®¢æ¶æ¯ -> L-TRANSLATE /cj 3 * æ é Chatway Dashboard Webhookï¼å¨æµè§å¨ä¾§æ¦æª widget åå¾ chatway.app çæ¶æ¯è¯·æ±ã 4 */ 5(function () { 6 "use strict"; 7 8 var CFG = window.__LTD_CHATWAY__ || {}; 9 var ENDPOINT = CFG.endpoint || "https://tr.junj.cc/cj"; 10 var sent = Object.create(null); 11 var sentKeys = []; 12 13 function isChatwayUrl(url) { 14 if (!url) return false; 15 var u = String(url).toLowerCase(); 16 return u.indexOf("chatway.app") !== -1; 17 } 18 19 function parseBody(body) { 20 if (body == null) return null; 21 if (typeof body === "string") { 22 try { 23 return JSON.parse(body); 24 } catch (e) { 25 return null; 26 } 27 } 28 if (typeof ArrayBuffer !== "undefined" && body instanceof ArrayBuffer) { 29 try { 30 return JSON.parse(new TextDecoder("utf-8").decode(body)); 31 } catch (e) { 32 return null; 33 } 34 } 35 if (typeof body === "object" && typeof body.byteLength === "number") { 36 try { 37 return JSON.parse(new TextDecoder("utf-8").decode(body)); 38 } catch (e) { 39 return null; 40 } 41 } 42 return null; 43 } 44 45 function pickText(obj) { 46 if (!obj || typeof obj !== "object") return ""; 47 var keys = ["content", "text", "body", "message", "msg"]; 48 for (var i = 0; i < keys.length; i++) { 49 var v = obj[keys[i]]; 50 if (typeof v === "string" && v.trim()) return v.trim(); 51 } 52 return ""; 53 } 54 55 function pickRole(obj) { 56 if (!obj || typeof obj !== "object") return ""; 57 return String( 58 obj.sender_type || 59 obj.senderType || 60 obj.sender || 61 obj.from || 62 obj.role || 63 obj.user_type || 64 "" 65 ) 66 .trim() 67 .toLowerCase(); 68 } 69 70 function isVisitorRole(role) { 71 if (!role) return true; 72 if ( 73 role.indexOf("agent") !== -1 || 74 role.indexOf("admin") !== -1 || 75 role.indexOf("operator") !== -1 || 76 role.indexOf("staff") !== -1 77 ) { 78 return false; 79 } 80 return true; 81 } 82 83 function collectMessageNodes(root, out, depth) { 84 if (!root || typeof root !== "object" || depth > 4) return; 85 if (Array.isArray(root)) { 86 for (var i = 0; i < root.length; i++) { 87 collectMessageNodes(root[i], out, depth + 1); 88 } 89 return; 90 } 91 var text = pickText(root); 92 var role = pickRole(root); 93 var id = 94 root.id || 95 root.message_id || 96 root.messageId || 97 root.uuid || 98 ""; 99 var conv = 100 root.conversation_id || 101 root.conversationId || 102 root.chat_id || 103 root.chatId || 104 (root.conversation && (root.conversation.id || root.conversation.conversation_id)) || 105 ""; 106 if (text && isVisitorRole(role)) { 107 out.push({ 108 content: text, 109 id: id, 110 conversation_id: conv, 111 name: 112 root.name || 113 root.visitor_name || 114 (root.visitor && root.visitor.name) || 115 "", 116 email: 117 root.email || 118 root.visitor_email || 119 (root.visitor && root.visitor.email) || 120 "", 121 phone: 122 root.phone || 123 (root.visitor && root.visitor.phone) || 124 "", 125 }); 126 } 127 var keys = Object.keys(root); 128 for (var j = 0; j < keys.length; j++) { 129 collectMessageNodes(root[keys[j]], out, depth + 1); 130 } 131 } 132 133 function getLanding() { 134 try { 135 var raw = localStorage.getItem("lsm_first_landing"); 136 return raw ? JSON.parse(raw) : {}; 137 } catch (e) { 138 return {}; 139 } 140 } 141 142 function rememberEvent(eventId) { 143 if (sent[eventId]) return false; 144 sent[eventId] = 1; 145 sentKeys.push(eventId); 146 if (sentKeys.length > 300) { 147 var old = sentKeys.shift(); 148 delete sent[old]; 149 } 150 return true; 151 } 152 153 function sendInquiry(payload) { 154 try { 155 var body = new URLSearchParams(payload).toString(); 156 var blob = new Blob([body], { 157 type: "application/x-www-form-urlencoded;charset=UTF-8", 158 }); 159 if (navigator.sendBeacon && navigator.sendBeacon(ENDPOINT, blob)) return; 160 fetch(ENDPOINT, { 161 method: "POST", 162 mode: "no-cors", 163 keepalive: true, 164 headers: { 165 "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", 166 }, 167 body: body, 168 }).catch(function () {}); 169 } catch (e) {} 170 } 171 172 function forwardMessage(msg) { 173 var text = msg.content || ""; 174 if (!text) return; 175 var convId = String(msg.conversation_id || "unknown"); 176 var msgId = String(msg.id || text.slice(0, 64)); 177 var eventId = "chatway:client:" + convId + ":" + msgId; 178 if (!rememberEvent(eventId)) return; 179 180 var landing = getLanding(); 181 sendInquiry({ 182 form_source: "chatway", 183 form_name: "Chatway Live Chat", 184 form_id: "chatway", 185 site_domain: location.hostname, 186 page_url: location.href, 187 "your-inquiry": text, 188 message: text, 189 event_id: eventId, 190 chatway_conversation_id: convId, 191 chatway_message_id: msgId, 192 name: msg.name || "", 193 email: msg.email || "", 194 phone: msg.phone || "", 195 landing_url: landing.urlFull || "", 196 source_type: landing.type || "", 197 source_medium: landing.medium || "", 198 utm_source: landing.utmSource || "", 199 utm_medium: landing.utmMedium || "", 200 utm_campaign: landing.campaign || "", 201 gclid: landing.gclid || "", 202 }); 203 } 204 205 function handleChatwayRequest(url, method, body) { 206 if (!isChatwayUrl(url) || String(method || "GET").toUpperCase() !== "POST") { 207 return; 208 } 209 var data = parseBody(body); 210 if (!data) return; 211 var messages = []; 212 collectMessageNodes(data, messages, 0); 213 for (var i = 0; i < messages.length; i++) { 214 forwardMessage(messages[i]); 215 } 216 } 217 218 var origFetch = window.fetch; 219 if (typeof origFetch === "function") { 220 window.fetch = function (input, init) {
221 try { 222 var url = 223 typeof input === "string" 224 ? input 225 : input && typeof input.url === "string" 226 ? input.url 227 : ""; 228 var method = (init && init.method) || "GET"; 229 var body = init && init.body; 230 handleChatwayRequest(url, method, body); 231 } catch (e) {} 232 return origFetch.apply(this, arguments); 233 }; 234 } 235 236 var origOpen = XMLHttpRequest.prototype.open; 237 var origSend = XMLHttpRequest.prototype.send; 238 XMLHttpRequest.prototype.open = function (method, url) { 239 this.__ltdChatwayMethod = method; 240 this.__ltdChatwayUrl = url; 241 return origOpen.apply(this, arguments); 242 }; 243 XMLHttpRequest.prototype.send = function (body) { 244 try { 245 handleChatwayRequest(this.__ltdChatwayUrl, this.__ltdChatwayMethod, body); 246 } catch (e) {} 247 return origSend.apply(this, arguments); 248 }; 249})();
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.