Created
February 25, 2026 13:33
-
-
Save mendelB/5702e99aad8f420a8d904cba1971204e to your computer and use it in GitHub Desktop.
Zendesk Messaging conversationFields diagnostic script — 21Casino/WHG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Zendesk Messaging Diagnostic Script — 21Casino | |
| * ================================================ | |
| * | |
| * PURPOSE: Diagnose why conversationFields may not be flowing through | |
| * to Zendesk tickets on 21Casino (branders.koek.link). | |
| * | |
| * USAGE: | |
| * 1. Open the 21Casino site in Chrome | |
| * 2. Open DevTools (F12 → Console) | |
| * 3. Paste this ENTIRE script and press Enter | |
| * 4. Click the chat button on the site | |
| * 5. Review the diagnostic output in the console | |
| * | |
| * WHAT IT DOES: | |
| * - Intercepts ALL zE() calls with precise timestamps | |
| * - Tracks widget lifecycle: load → conversationFields → open | |
| * - Detects race conditions (fields set after conversation starts) | |
| * - Monitors Zendesk network requests for field delivery | |
| * - Checks conversation state (new vs existing) | |
| * - Validates field IDs against known WHG configuration | |
| * - Prints a diagnostic summary when you send a message | |
| * | |
| * SAFE: Uses Object.defineProperty to wrap zE without breaking it. | |
| * All original zE behavior is preserved. | |
| * | |
| * Author: Cevro Engineering (for WHG/Branders debugging) | |
| * Date: 2026-02-25 | |
| */ | |
| (function() { | |
| 'use strict'; | |
| // ─── Configuration ─────────────────────────────────────────────── | |
| // Known WHG custom field IDs (for validation) | |
| var KNOWN_FIELDS = { | |
| '29575162993042': 'Player ID', | |
| '30809643209618': 'Full Name', | |
| '30809684417554': 'Email Address', | |
| '33311874639250': 'Country', | |
| '33311899437330': 'VIP', | |
| '33311891744018': 'Flags' | |
| }; | |
| // ─── State Tracking ────────────────────────────────────────────── | |
| var state = { | |
| scriptInstalledAt: Date.now(), | |
| widgetLoadedAt: null, | |
| conversationFieldsCalls: [], // every call to conversationFields | |
| messengerOpenCalls: [], // every call to messenger open | |
| messengerCloseCalls: [], // every call to messenger close | |
| allZeCalls: [], // every zE() call | |
| networkRequests: [], // Zendesk API requests | |
| errors: [], // any errors caught | |
| widgetState: 'not-loaded', // not-loaded | loaded | open | closed | |
| existingConversation: null, // true/false/null (unknown) | |
| callbacksReceived: [] // callbacks from conversationFields | |
| }; | |
| var T0 = state.scriptInstalledAt; | |
| function ts() { | |
| return '+' + (Date.now() - T0) + 'ms'; | |
| } | |
| function log(tag, msg, data) { | |
| var prefix = '[ZE-DIAG ' + ts() + ']'; | |
| var color = { | |
| 'LOAD': 'color: #00aa00; font-weight: bold', | |
| 'FIELDS': 'color: #ff8800; font-weight: bold', | |
| 'OPEN': 'color: #0088ff; font-weight: bold', | |
| 'CLOSE': 'color: #888888; font-weight: bold', | |
| 'CALL': 'color: #666666', | |
| 'NET': 'color: #aa00aa; font-weight: bold', | |
| 'WARN': 'color: #ff0000; font-weight: bold', | |
| 'INFO': 'color: #0066cc', | |
| 'OK': 'color: #00aa00; font-weight: bold', | |
| 'RACE': 'background: #ff0000; color: white; font-weight: bold; padding: 2px 6px', | |
| 'SUMMARY':'background: #0066cc; color: white; font-weight: bold; padding: 2px 8px' | |
| }[tag] || 'color: #333'; | |
| if (data !== undefined) { | |
| console.log('%c' + prefix + ' [' + tag + '] ' + msg, color, data); | |
| } else { | |
| console.log('%c' + prefix + ' [' + tag + '] ' + msg, color); | |
| } | |
| } | |
| // ─── Network Monitoring ────────────────────────────────────────── | |
| // | |
| // Intercept fetch() and XMLHttpRequest to capture Zendesk API calls. | |
| // This shows whether conversationFields data actually leaves the browser. | |
| // Wrap fetch | |
| var _origFetch = window.fetch; | |
| window.fetch = function() { | |
| var url = (arguments[0] && arguments[0].url) ? arguments[0].url : String(arguments[0]); | |
| var method = 'GET'; | |
| var body = null; | |
| if (arguments[1]) { | |
| method = arguments[1].method || 'GET'; | |
| body = arguments[1].body || null; | |
| } | |
| if (url.indexOf('zendesk') !== -1 || url.indexOf('zdassets') !== -1) { | |
| var entry = { | |
| timestamp: Date.now(), | |
| elapsed: ts(), | |
| method: method, | |
| url: url, | |
| bodySnippet: null | |
| }; | |
| // Try to extract field-related data from request body | |
| if (body) { | |
| try { | |
| var bodyStr = typeof body === 'string' ? body : JSON.stringify(body); | |
| if (bodyStr.indexOf('field') !== -1 || bodyStr.indexOf('metadata') !== -1) { | |
| entry.bodySnippet = bodyStr.substring(0, 500); | |
| log('NET', 'Zendesk request with field/metadata data: ' + method + ' ' + url); | |
| log('NET', 'Body snippet:', entry.bodySnippet); | |
| } | |
| } catch(e) { /* ignore */ } | |
| } | |
| state.networkRequests.push(entry); | |
| // Flag conversation-starting requests | |
| if (url.indexOf('/conversations') !== -1 || url.indexOf('/messages') !== -1) { | |
| log('NET', 'Conversation/message request: ' + method + ' ' + url); | |
| } | |
| } | |
| return _origFetch.apply(this, arguments); | |
| }; | |
| // Wrap XMLHttpRequest | |
| var _origXHROpen = XMLHttpRequest.prototype.open; | |
| var _origXHRSend = XMLHttpRequest.prototype.send; | |
| XMLHttpRequest.prototype.open = function(method, url) { | |
| this._zeMethod = method; | |
| this._zeUrl = url; | |
| return _origXHROpen.apply(this, arguments); | |
| }; | |
| XMLHttpRequest.prototype.send = function(body) { | |
| if (this._zeUrl && (this._zeUrl.indexOf('zendesk') !== -1 || this._zeUrl.indexOf('zdassets') !== -1)) { | |
| var entry = { | |
| timestamp: Date.now(), | |
| elapsed: ts(), | |
| method: this._zeMethod, | |
| url: this._zeUrl, | |
| bodySnippet: null | |
| }; | |
| if (body) { | |
| try { | |
| var bodyStr = typeof body === 'string' ? body : JSON.stringify(body); | |
| if (bodyStr.indexOf('field') !== -1 || bodyStr.indexOf('metadata') !== -1) { | |
| entry.bodySnippet = bodyStr.substring(0, 500); | |
| log('NET', 'XHR to Zendesk with field data: ' + this._zeMethod + ' ' + this._zeUrl); | |
| } | |
| } catch(e) { /* ignore */ } | |
| } | |
| state.networkRequests.push(entry); | |
| } | |
| return _origXHRSend.apply(this, arguments); | |
| }; | |
| // ─── zE Interceptor ────────────────────────────────────────────── | |
| // | |
| // Uses Object.defineProperty to catch the moment Zendesk creates | |
| // window.zE, then wraps it to log all calls. | |
| var _origZE = null; | |
| var _installed = false; | |
| function wrapZE(realZE) { | |
| return function wrappedZE() { | |
| var args = Array.prototype.slice.call(arguments); | |
| var cmd = args[0] || ''; | |
| var sub = args[1] || ''; | |
| var now = Date.now(); | |
| // Record every call | |
| state.allZeCalls.push({ | |
| timestamp: now, | |
| elapsed: ts(), | |
| command: cmd, | |
| subcommand: sub, | |
| args: args | |
| }); | |
| // ── conversationFields ── | |
| if (cmd === 'messenger:set' && sub === 'conversationFields') { | |
| var fields = args[2]; | |
| var callback = args[3]; | |
| var hasCallback = typeof callback === 'function'; | |
| log('FIELDS', 'conversationFields called' + (hasCallback ? ' (WITH callback)' : ' (NO callback)')); | |
| var callEntry = { | |
| timestamp: now, | |
| elapsed: ts(), | |
| fields: [], | |
| hasCallback: hasCallback, | |
| widgetStateAtCall: state.widgetState, | |
| messengerAlreadyOpened: state.messengerOpenCalls.length > 0 | |
| }; | |
| // Validate each field | |
| if (Array.isArray(fields)) { | |
| fields.forEach(function(f) { | |
| var knownName = KNOWN_FIELDS[String(f.id)] || 'UNKNOWN FIELD'; | |
| var valuePreview = String(f.value).substring(0, 50); | |
| var valid = f.id && f.value !== undefined && f.value !== null && f.value !== ''; | |
| callEntry.fields.push({ | |
| id: String(f.id), | |
| name: knownName, | |
| value: valuePreview, | |
| valid: valid, | |
| type: typeof f.value | |
| }); | |
| var statusIcon = valid ? 'OK' : 'WARN'; | |
| log(statusIcon, ' Field ' + f.id + ' (' + knownName + ') = "' + valuePreview + '"' + | |
| ' [type: ' + typeof f.value + ']' + (valid ? '' : ' — EMPTY OR MISSING VALUE')); | |
| }); | |
| } else { | |
| log('WARN', ' fields argument is NOT an array:', fields); | |
| } | |
| // ── RACE CONDITION DETECTION ── | |
| if (callEntry.messengerAlreadyOpened) { | |
| log('RACE', 'TIMING ISSUE: conversationFields called AFTER messenger was already opened!'); | |
| log('RACE', 'Messenger opened at ' + state.messengerOpenCalls[0].elapsed + | |
| ', fields set at ' + ts()); | |
| log('RACE', 'Zendesk docs say fields are applied when "end users start a conversation ' + | |
| 'or send a message". If the conversation already started, these fields may NOT apply.'); | |
| } else { | |
| log('OK', 'Good: conversationFields set BEFORE messenger open'); | |
| } | |
| // If there IS a callback, wrap it to track when Zendesk confirms | |
| if (hasCallback) { | |
| args[3] = function() { | |
| log('OK', 'conversationFields CALLBACK fired — Zendesk confirmed fields are stored'); | |
| state.callbacksReceived.push({ timestamp: Date.now(), elapsed: ts() }); | |
| return callback.apply(this, arguments); | |
| }; | |
| } else { | |
| log('WARN', 'No callback provided. Zendesk recommends using a callback to confirm ' + | |
| 'fields are stored. This is a potential reliability issue.'); | |
| } | |
| state.conversationFieldsCalls.push(callEntry); | |
| } | |
| // ── messenger open ── | |
| else if (cmd === 'messenger' && sub === 'open') { | |
| log('OPEN', 'messenger OPEN called'); | |
| state.messengerOpenCalls.push({ timestamp: now, elapsed: ts() }); | |
| state.widgetState = 'open'; | |
| // Check if fields were set before this | |
| if (state.conversationFieldsCalls.length === 0) { | |
| log('WARN', 'Messenger opened but NO conversationFields have been set yet'); | |
| } else { | |
| var lastFieldsCall = state.conversationFieldsCalls[state.conversationFieldsCalls.length - 1]; | |
| var timeSinceFields = now - lastFieldsCall.timestamp; | |
| log('INFO', 'conversationFields were set ' + timeSinceFields + 'ms before open — ' + | |
| (timeSinceFields > 50 ? 'good gap' : 'very tight, could race')); | |
| } | |
| } | |
| // ── messenger close ── | |
| else if (cmd === 'messenger' && sub === 'close') { | |
| log('CLOSE', 'messenger CLOSE called'); | |
| state.messengerCloseCalls.push({ timestamp: now, elapsed: ts() }); | |
| state.widgetState = 'closed'; | |
| } | |
| // ── locale ── | |
| else if (cmd === 'messenger:set' && sub === 'locale') { | |
| log('INFO', 'Locale set to: ' + args[2]); | |
| } | |
| // ── loginUser (JWT auth) ── | |
| else if (cmd === 'messenger' && sub === 'loginUser') { | |
| log('INFO', 'loginUser called — JWT authentication active'); | |
| } | |
| // ── logoutUser ── | |
| else if (cmd === 'messenger' && sub === 'logoutUser') { | |
| log('INFO', 'logoutUser called'); | |
| } | |
| // ── anything else ── | |
| else { | |
| log('CALL', cmd + ' ' + sub, args.length > 2 ? args.slice(2) : ''); | |
| } | |
| // Pass through to real zE | |
| if (realZE) { | |
| try { | |
| return realZE.apply(this, args); | |
| } catch(e) { | |
| log('WARN', 'zE() threw an error: ' + e.message); | |
| state.errors.push({ timestamp: now, error: e.message, command: cmd + ' ' + sub }); | |
| throw e; | |
| } | |
| } | |
| }; | |
| } | |
| // Check if zE is already defined (widget already loaded) | |
| if (typeof window.zE !== 'undefined') { | |
| log('INFO', 'Zendesk widget already loaded — wrapping existing zE'); | |
| _origZE = window.zE; | |
| window.zE = wrapZE(_origZE); | |
| state.widgetLoadedAt = 'before-script'; | |
| state.widgetState = 'loaded'; | |
| _installed = true; | |
| } else { | |
| // Widget not loaded yet — use defineProperty to intercept when it gets created | |
| log('INFO', 'Zendesk widget not loaded yet — installing property trap'); | |
| Object.defineProperty(window, 'zE', { | |
| configurable: true, | |
| enumerable: true, | |
| get: function() { | |
| if (_origZE && !_installed) { | |
| _installed = true; | |
| // Return the wrapper | |
| var wrapped = wrapZE(_origZE); | |
| // Replace ourselves with a normal property now | |
| Object.defineProperty(window, 'zE', { | |
| configurable: true, | |
| enumerable: true, | |
| writable: true, | |
| value: wrapped | |
| }); | |
| return wrapped; | |
| } | |
| return _origZE ? wrapZE(_origZE) : undefined; | |
| }, | |
| set: function(val) { | |
| if (val && !_origZE) { | |
| state.widgetLoadedAt = Date.now(); | |
| state.widgetState = 'loaded'; | |
| log('LOAD', 'Zendesk widget loaded! (took ' + (state.widgetLoadedAt - T0) + 'ms from script install)'); | |
| } | |
| _origZE = val; | |
| // Process any queued commands (Zendesk queues calls made before load) | |
| if (val && val.q && Array.isArray(val.q)) { | |
| log('INFO', 'Found ' + val.q.length + ' queued zE commands from before widget load'); | |
| val.q.forEach(function(queuedArgs, i) { | |
| if (queuedArgs[0] === 'messenger:set' && queuedArgs[1] === 'conversationFields') { | |
| log('FIELDS', 'Queued command #' + i + ' is a conversationFields call — will be processed on load'); | |
| } | |
| }); | |
| } | |
| } | |
| }); | |
| } | |
| // ─── Conversation State Detection ───────────────────────────────── | |
| // | |
| // After widget loads, check if there is an existing conversation. | |
| // An existing conversation means conversationFields may not apply | |
| // (they only apply at ticket creation or when a new message is sent). | |
| function checkConversationState() { | |
| try { | |
| // Look for Zendesk's internal conversation storage | |
| var iframes = document.querySelectorAll('iframe[title*="messaging"], iframe[title*="Messaging"], iframe[data-product="messaging"]'); | |
| if (iframes.length > 0) { | |
| log('INFO', 'Found ' + iframes.length + ' Zendesk messaging iframe(s)'); | |
| } | |
| // Check localStorage for existing conversation markers | |
| var conversationKeys = []; | |
| for (var i = 0; i < localStorage.length; i++) { | |
| var key = localStorage.key(i); | |
| if (key && (key.indexOf('zendesk') !== -1 || key.indexOf('zE') !== -1 || key.indexOf('messaging') !== -1)) { | |
| conversationKeys.push(key); | |
| } | |
| } | |
| if (conversationKeys.length > 0) { | |
| log('INFO', 'Zendesk localStorage keys found: ' + conversationKeys.join(', ')); | |
| state.existingConversation = true; | |
| log('WARN', 'Existing conversation data found in localStorage. If the player has ' + | |
| 'chatted before, conversationFields may only apply to the NEXT message, not retroactively.'); | |
| } else { | |
| state.existingConversation = false; | |
| log('OK', 'No existing conversation data found — this looks like a fresh session'); | |
| } | |
| } catch(e) { | |
| log('WARN', 'Could not check conversation state: ' + e.message); | |
| } | |
| } | |
| // Run the check after a delay (widget needs time to initialize) | |
| setTimeout(checkConversationState, 2000); | |
| // ─── Diagnostic Summary ────────────────────────────────────────── | |
| // | |
| // Call window.zeDiagSummary() at any time to get the full report. | |
| // Also auto-prints 10 seconds after messenger opens. | |
| function printSummary() { | |
| var now = Date.now(); | |
| console.log(''); | |
| log('SUMMARY', '═══════════════════════════════════════════════════'); | |
| log('SUMMARY', ' ZENDESK DIAGNOSTIC SUMMARY'); | |
| log('SUMMARY', '═══════════════════════════════════════════════════'); | |
| console.log(''); | |
| // 1. Widget Load | |
| console.log('%c1. Widget Load', 'font-weight: bold; font-size: 13px'); | |
| if (state.widgetLoadedAt === 'before-script') { | |
| console.log(' Widget was already loaded when script was installed'); | |
| } else if (state.widgetLoadedAt) { | |
| console.log(' Loaded at ' + (state.widgetLoadedAt - T0) + 'ms after script install'); | |
| } else { | |
| console.log(' %cWidget has NOT loaded yet', 'color: red'); | |
| } | |
| console.log(' Current state: ' + state.widgetState); | |
| console.log(''); | |
| // 2. conversationFields Calls | |
| console.log('%c2. conversationFields Calls (' + state.conversationFieldsCalls.length + ' total)', | |
| 'font-weight: bold; font-size: 13px'); | |
| if (state.conversationFieldsCalls.length === 0) { | |
| console.log(' %cNO conversationFields calls detected!', 'color: red; font-weight: bold'); | |
| console.log(' This means branders.chat.setUser() either did not run,'); | |
| console.log(' or zE was not defined when it ran.'); | |
| } else { | |
| state.conversationFieldsCalls.forEach(function(call, i) { | |
| console.log(' Call #' + (i + 1) + ' at ' + call.elapsed); | |
| console.log(' Widget state: ' + call.widgetStateAtCall); | |
| console.log(' Messenger already opened: ' + call.messengerAlreadyOpened); | |
| console.log(' Has callback: ' + call.hasCallback); | |
| console.log(' Fields:'); | |
| call.fields.forEach(function(f) { | |
| var status = f.valid ? 'OK' : 'EMPTY'; | |
| console.log(' [' + status + '] ' + f.id + ' (' + f.name + ') = "' + f.value + '"'); | |
| }); | |
| }); | |
| } | |
| console.log(''); | |
| // 3. Timing Analysis | |
| console.log('%c3. Timing Analysis', 'font-weight: bold; font-size: 13px'); | |
| if (state.conversationFieldsCalls.length > 0 && state.messengerOpenCalls.length > 0) { | |
| var firstFields = state.conversationFieldsCalls[0].timestamp; | |
| var firstOpen = state.messengerOpenCalls[0].timestamp; | |
| var delta = firstFields - firstOpen; | |
| if (delta < 0) { | |
| // Fields were set BEFORE open — correct order | |
| console.log(' %cFields set ' + Math.abs(delta) + 'ms BEFORE messenger open — CORRECT ORDER', | |
| 'color: green; font-weight: bold'); | |
| } else if (delta === 0) { | |
| console.log(' %cFields set at SAME TIME as messenger open — RISKY (race condition possible)', | |
| 'color: orange; font-weight: bold'); | |
| } else { | |
| console.log(' %cFields set ' + delta + 'ms AFTER messenger open — WRONG ORDER!', | |
| 'color: red; font-weight: bold'); | |
| console.log(' Zendesk docs: fields are "only applied when end users start a conversation'); | |
| console.log(' or send a message in an existing conversation." If the conversation starts'); | |
| console.log(' before fields are set, they may be lost.'); | |
| } | |
| if (!state.conversationFieldsCalls[0].hasCallback) { | |
| console.log(' %cNo callback used — Zendesk recommends callbacks for reliable delivery', | |
| 'color: orange'); | |
| console.log(' Recommended pattern:'); | |
| console.log(' zE("messenger:set", "conversationFields", fields, function() {'); | |
| console.log(' zE("messenger", "open");'); | |
| console.log(' });'); | |
| } | |
| } else { | |
| if (state.conversationFieldsCalls.length === 0) { | |
| console.log(' Cannot analyze — no conversationFields calls detected'); | |
| } | |
| if (state.messengerOpenCalls.length === 0) { | |
| console.log(' Cannot analyze — messenger has not been opened'); | |
| } | |
| } | |
| console.log(''); | |
| // 4. Existing Conversation Check | |
| console.log('%c4. Conversation State', 'font-weight: bold; font-size: 13px'); | |
| if (state.existingConversation === true) { | |
| console.log(' %cExisting conversation detected in localStorage', 'color: orange'); | |
| console.log(' conversationFields apply at ticket CREATION time or on next MESSAGE.'); | |
| console.log(' If the player already has an open conversation, the widget may resume it'); | |
| console.log(' and fields set via the API would only appear on the next Support ticket.'); | |
| } else if (state.existingConversation === false) { | |
| console.log(' %cNo existing conversation — fresh session (good)', 'color: green'); | |
| } else { | |
| console.log(' Could not determine conversation state'); | |
| } | |
| console.log(''); | |
| // 5. All zE Calls (timeline) | |
| console.log('%c5. Full zE Call Timeline (' + state.allZeCalls.length + ' calls)', | |
| 'font-weight: bold; font-size: 13px'); | |
| state.allZeCalls.forEach(function(call) { | |
| console.log(' ' + call.elapsed + ' ' + call.command + ' ' + call.subcommand); | |
| }); | |
| console.log(''); | |
| // 6. Network Requests | |
| console.log('%c6. Zendesk Network Requests (' + state.networkRequests.length + ' captured)', | |
| 'font-weight: bold; font-size: 13px'); | |
| var fieldRequests = state.networkRequests.filter(function(r) { return r.bodySnippet; }); | |
| if (fieldRequests.length > 0) { | |
| console.log(' Requests containing field/metadata data:'); | |
| fieldRequests.forEach(function(r) { | |
| console.log(' ' + r.elapsed + ' ' + r.method + ' ' + r.url); | |
| console.log(' Body: ' + r.bodySnippet); | |
| }); | |
| } else { | |
| console.log(' No requests with field/metadata data captured'); | |
| console.log(' (Fields may be queued client-side and sent with the first message)'); | |
| } | |
| console.log(''); | |
| // 7. Errors | |
| if (state.errors.length > 0) { | |
| console.log('%c7. Errors (' + state.errors.length + ')', 'font-weight: bold; font-size: 13px; color: red'); | |
| state.errors.forEach(function(e) { | |
| console.log(' ' + e.command + ': ' + e.error); | |
| }); | |
| } else { | |
| console.log('%c7. No errors detected', 'font-weight: bold; font-size: 13px; color: green'); | |
| } | |
| console.log(''); | |
| // 8. Verdict | |
| console.log('%c8. VERDICT', 'font-weight: bold; font-size: 14px'); | |
| var issues = []; | |
| if (state.conversationFieldsCalls.length === 0) { | |
| issues.push('conversationFields was NEVER called — check if branders.account.user is populated'); | |
| } | |
| state.conversationFieldsCalls.forEach(function(call) { | |
| if (call.messengerAlreadyOpened) { | |
| issues.push('RACE CONDITION: conversationFields called after messenger open'); | |
| } | |
| if (!call.hasCallback) { | |
| issues.push('No callback used — async delivery not confirmed'); | |
| } | |
| call.fields.forEach(function(f) { | |
| if (!f.valid) { | |
| issues.push('Empty/missing value for field ' + f.id + ' (' + f.name + ')'); | |
| } | |
| if (f.name === 'UNKNOWN FIELD') { | |
| issues.push('Unknown field ID: ' + f.id + ' — verify this exists in Zendesk Admin Center'); | |
| } | |
| }); | |
| }); | |
| if (state.existingConversation) { | |
| issues.push('Existing conversation found — fields may not apply to resumed conversation'); | |
| } | |
| if (issues.length === 0) { | |
| console.log(' %cNo issues detected from client-side. If fields still missing on tickets,', | |
| 'color: green; font-weight: bold'); | |
| console.log(' %ccheck Zendesk Admin Center: field must be "editable in portal" and not hidden.', | |
| 'color: green'); | |
| } else { | |
| console.log(' %cIssues found:', 'color: red; font-weight: bold'); | |
| issues.forEach(function(issue, i) { | |
| console.log(' ' + (i + 1) + '. %c' + issue, 'color: red'); | |
| }); | |
| } | |
| console.log(''); | |
| log('SUMMARY', '═══════════════════════════════════════════════════'); | |
| console.log(''); | |
| console.log('Raw state object available at: window._zeDiagState'); | |
| console.log('Run again anytime: window.zeDiagSummary()'); | |
| } | |
| // Export for manual invocation | |
| window._zeDiagState = state; | |
| window.zeDiagSummary = printSummary; | |
| // Auto-print summary 10 seconds after messenger opens | |
| var _autoSummaryScheduled = false; | |
| var _origSetInterval = setInterval; | |
| _origSetInterval(function() { | |
| if (state.messengerOpenCalls.length > 0 && !_autoSummaryScheduled) { | |
| _autoSummaryScheduled = true; | |
| log('INFO', 'Messenger opened — diagnostic summary will print in 10 seconds...'); | |
| log('INFO', 'Send a message in the chat, then check the summary.'); | |
| log('INFO', 'Or run window.zeDiagSummary() at any time.'); | |
| setTimeout(printSummary, 10000); | |
| } | |
| }, 1000); | |
| // ─── Ready ─────────────────────────────────────────────────────── | |
| console.log(''); | |
| console.log('%c╔══════════════════════════════════════════════════════════╗', 'color: #0066cc'); | |
| console.log('%c║ Zendesk Diagnostic Script Installed ║', 'color: #0066cc; font-weight: bold'); | |
| console.log('%c║ ║', 'color: #0066cc'); | |
| console.log('%c║ 1. Click the chat button on the site ║', 'color: #0066cc'); | |
| console.log('%c║ 2. Watch the console for intercepted zE calls ║', 'color: #0066cc'); | |
| console.log('%c║ 3. Send a test message in the chat ║', 'color: #0066cc'); | |
| console.log('%c║ 4. Summary prints automatically after 10 seconds ║', 'color: #0066cc'); | |
| console.log('%c║ — or run window.zeDiagSummary() anytime ║', 'color: #0066cc'); | |
| console.log('%c║ ║', 'color: #0066cc'); | |
| console.log('%c║ State: window._zeDiagState ║', 'color: #0066cc'); | |
| console.log('%c╚══════════════════════════════════════════════════════════╝', 'color: #0066cc'); | |
| console.log(''); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment