Skip to content

Instantly share code, notes, and snippets.

@Jonghakseo
Created January 13, 2025 02:11
Show Gist options
  • Save Jonghakseo/019864751290ce43663d325b026083a4 to your computer and use it in GitHub Desktop.
Save Jonghakseo/019864751290ce43663d325b026083a4 to your computer and use it in GitHub Desktop.
Zendesk chatbot sdk AI로 난독화 제거
(() => {
// Module definitions
var moduleCache,
moduleExports,
moduleDefinitions = {
271: (module) => {
function getQueryParamsString(url) {
const link = document.createElement('a');
link.href = url;
return link.search.split('?').at(1) || '';
}
module.exports = {
getQueryParamsString: getQueryParamsString,
parseUrlParams: function (url) {
const queryString = getQueryParamsString(url);
return queryString === ''
? {}
: queryString.split('&').reduce((params, paramString) => {
const paramParts = paramString.split('=');
params[paramParts.at(0)] = decodeURIComponent(paramParts.at(1));
return params;
}, {});
},
loadScript: function (src, callback = () => {}) {
const script = document.createElement('script');
script.type = 'text/javascript';
script.onerror = function () {
callback(new Error('Script failed to load'));
};
script.readyState
? (script.onreadystatechange = function () {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
callback();
}
})
: (script.onload = function () {
callback();
});
script.src = src;
document.getElementsByTagName('head').at(0)?.appendChild(script);
},
};
},
},
moduleContainer = {};
function requireModule(moduleId) {
var cachedModule = moduleContainer[moduleId];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
var newModule = (moduleContainer[moduleId] = { id: moduleId, loaded: false, exports: {} });
moduleDefinitions[moduleId](newModule, newModule.exports, requireModule);
newModule.loaded = true;
return newModule.exports;
}
// Webpack bootstrap
requireModule.m = moduleDefinitions;
requireModule.d = (module, exports) => {
for (var key in exports) {
if (requireModule.o(exports, key) && !requireModule.o(module, key)) {
Object.defineProperty(module, key, { enumerable: true, get: exports[key] });
}
}
};
requireModule.f = {};
requireModule.e = (chunkId) =>
Promise.all(
Object.keys(requireModule.f).reduce((promises, key) => {
requireModule.f[key](chunkId, promises);
return promises;
}, []),
);
requireModule.u = (chunkId) => 'sentry-browser.min.js';
requireModule.hmd = (module) => {
module = Object.create(module);
if (!module.children) {
module.children = [];
}
Object.defineProperty(module, 'exports', {
enumerable: true,
set: () => {
throw new Error(
'ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' +
module.id,
);
},
});
return module;
};
requireModule.o = (object, property) => Object.prototype.hasOwnProperty.call(object, property);
// Chunk loading
var chunkLoadingGlobal = (globalThis.zEWebpackACJsonp = globalThis.zEWebpackACJsonp || []);
function webpackJsonpCallback(parentChunkLoadingFunction, data) {
var [chunkIds, moreModules, runtime] = data;
var moduleId,
chunkId,
i = 0;
if (chunkIds.some((id) => ((moduleId = id), 0 !== moduleCache[moduleId]))) {
for (moduleId in moreModules) {
if (requireModule.o(moreModules, moduleId)) {
requireModule.m[moduleId] = moreModules[moduleId];
}
}
if (runtime) {
var result = runtime(requireModule);
}
}
if (parentChunkLoadingFunction) {
parentChunkLoadingFunction(data);
}
for (; i < chunkIds.length; i++) {
chunkId = chunkIds.at(i);
if (requireModule.o(moduleCache, chunkId) && moduleCache[chunkId]) {
moduleCache[chunkId].at(0)();
}
moduleCache[chunkId] = 0;
}
}
chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
chunkLoadingGlobal.push = webpackJsonpCallback.bind(
null,
chunkLoadingGlobal.push.bind(chunkLoadingGlobal),
);
// Zendesk Embeddable Product Loader
class EmbeddableProductError extends Error {
constructor(message = '', properties = {}, isUserError = false) {
super(message);
this.props = properties;
this.isUserError = isUserError;
this.fingerprint = message;
}
}
const productAssets = {},
zopimAssets = {},
productLoaders = {};
class ProductIframe {
constructor(product, window) {
this.name = product.name;
this.id = product.id;
this.features = product.features;
this.bootstrap = product.bootstrap;
this.win = window;
this.doc = window.document;
}
ready() {
return new Promise((resolve, reject) => {
this.createIframeElement().then((iframe) => {
iframe.addEventListener('load', () => {
const { contentWindow } = iframe;
if (contentWindow && contentWindow.document) {
resolve(contentWindow.document);
} else {
reject(this.error());
}
});
iframe.src = 'about:blank';
this.doc.body.appendChild(iframe);
});
});
}
injectMetadata(document, queue) {
if (document) {
document.zendesk = {
[this.name]: {
id: this.id,
features: this.features,
bootstrap: this.bootstrap,
},
};
Object.freeze(document.zendesk);
document.zEQueue = queue;
}
}
injectAssets(document, assets) {
if (!document) {
return;
}
const head = document.getElementsByTagName('head').at(0);
assets.scripts.forEach((script) => {
head.appendChild(this.createScriptElement(document, script.src));
});
}
parentDocumentReady() {
return new Promise((resolve, reject) => {
if (this.doc.readyState !== 'loading' && this.doc.body) {
resolve();
} else {
this.doc.addEventListener('DOMContentLoaded', () => {
const { body } = this.doc;
body
? resolve()
: reject(new EmbeddableProductError('host page document.body not available'));
});
}
});
}
createIframeElement() {
return this.parentDocumentReady().then(() => {
const iframe = this.doc.createElement('iframe');
iframe.dataset.product = this.name;
iframe.title = 'No content';
iframe.role = 'presentation';
iframe.tabIndex = -1;
iframe.allow = 'microphone *';
iframe.setAttribute('aria-hidden', true);
iframe.style.cssText = 'width: 0; height: 0; border: 0; position: absolute; top: -9999px';
return iframe;
});
}
createScriptElement(document, src) {
if (!document) {
return null;
}
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
return script;
}
error() {
const properties = { product: this.name, id: this.id, features: this.features };
return new EmbeddableProductError(
'iframe document not available to load product',
properties,
);
}
}
class ProductLoader {
constructor(product, window) {
this.product = product;
this.productIframe = new ProductIframe(this.product, window);
}
getProductAssets(forceReload = false) {
return forceReload ? zopimAssets[this.product.name].assets : this.product.assets;
}
load(assets, queue) {
return this.productIframe
.ready()
.then((document) => {
this.productIframe.injectMetadata(document, queue);
this.productIframe.injectAssets(document, assets);
})
.catch(() => Promise.reject(this.loadProductError()));
}
loadProductError() {
const { name, id, features } = this.product;
return new EmbeddableProductError('failed to load product', {
product: name,
id: id,
features: features,
});
}
}
var scriptUtils = requireModule(271);
class ZopimLoader {
constructor(zopimKey, window) {
this.zopimKey = zopimKey;
this.win = window;
this.doc = window.document;
}
getProductAssets() {
return { zopimSrc: `https://v2.zopim.com/w?${this.zopimKey}` };
}
load(assets) {
return new Promise((resolve, reject) => {
try {
scriptUtils.loadScript(assets.zopimSrc);
resolve();
} catch (error) {
reject(error);
}
});
}
}
const versionStorageKey = '__zE_ac_version';
class VersionManager {
constructor(window, snippetKey) {
this.version = this.getVersion(window);
this.baseUrl = `https://ekr.zdassets.com/compose/${snippetKey}`;
this.snippetKey = snippetKey;
}
resolveComposeUrl(forceReload = false) {
let url = this.baseUrl;
if (this.version) {
url += `?${this.getSerializedVersionQueryParam()}`;
this.displayWarning();
}
return decodeURI(url);
}
displayWarning() {
console.warn(`You are loading ${this.version.name} version ${this.version.string}`);
}
getSerializedVersionQueryParam() {
return `${versionStorageKey}=${this.version.name}/${this.version.string}`;
}
getVersion(window) {
let versionString;
try {
versionString = window.localStorage.getItem('ZD-ac-version');
} catch {}
const versionQuery =
scriptUtils.parseUrlParams(window.location.href)[versionStorageKey] || versionString;
if (versionQuery) {
const versionParts = versionQuery.split('/');
if (this.validVersion(versionParts.at(1))) {
return { name: versionParts.at(0), string: versionParts.at(1) };
}
}
return null;
}
validVersion(version) {
return version && /^\w+$/.test(version);
}
}
class ProductManager {
constructor(snippet) {
this.snippet = snippet;
}
getProducts(snippetKey, forceReload = false) {
return new Promise((resolve, reject) => {
const parentWindow = this.snippet.getParentWindow();
if (forceReload) {
parentWindow.zEACLoaded = true;
parentWindow.$zopim ? resolve(zopimAssets.products) : resolve(productAssets.products);
} else {
const handleResponse = (response) => {
if (response.status === 200) {
response
.json()
.then(({ products }) => {
parentWindow.zEACLoaded = true;
resolve(products);
})
.catch(() => reject(this.error(snippetKey)));
} else {
reject(this.error(snippetKey));
}
};
const composeUrl = new VersionManager(parentWindow, snippetKey).resolveComposeUrl();
fetch(composeUrl)
.then(handleResponse)
.catch(() => reject(this.error(snippetKey)));
}
});
}
loadProducts(products, forceReload = false) {
return products.map((productLoader) => {
const assets = productLoader.getProductAssets(forceReload);
return productLoader
.load(assets, this.snippet.getZEQueue())
.catch((error) => Promise.reject(error));
});
}
getProductLoaders(products) {
const parentWindow = this.snippet.getParentWindow();
return products.map((product) =>
'zopim_chat' === product.name
? new ZopimLoader(product.id, parentWindow)
: new ProductLoader(product, parentWindow),
);
}
error(snippetKey) {
return new EmbeddableProductError('compose request failed', { key: snippetKey });
}
}
class Snippet {
constructor(window) {
this.win = window;
this.doc = window.document;
}
getKey() {
return new Promise((resolve, reject) =>
reject(new EmbeddableProductError('Key is missing from snippet', {}, true)),
);
}
getZEQueue() {
return null;
}
getParentWindow() {
return this.win;
}
}
class WebWidgetSnippet extends Snippet {
getKey() {
return new Promise((resolve, reject) => {
const { zendeskHost } = this.doc;
if (zendeskHost) {
if (this._isHostMapped(zendeskHost)) {
fetch(`https://${zendeskHost}/embeddable/zendesk_host`)
.then((response) => {
if (response.status === 200) {
response
.json()
.then(({ zendesk_host }) => {
resolve(`web_widget/${zendesk_host}`);
})
.catch((error) => reject(new EmbeddableProductError(error.message)));
} else {
reject(new EmbeddableProductError('zendesk_host request failed'));
}
})
.catch((error) => reject(new EmbeddableProductError(error.message)));
} else {
resolve(`web_widget/${zendeskHost}`);
}
} else {
reject(Error('Zendesk host is not defined'));
}
});
}
getZEQueue() {
return this.doc.zEQueue;
}
getParentWindow() {
return this.win.parent;
}
_isHostMapped(host) {
return host.indexOf('.zendesk.com') === -1 && host.indexOf('.zendesk-staging.com') === -1;
}
}
class SnippetUtil {
static isSnippetPresent(window) {
return window.document.getElementById('ze-snippet');
}
getKey() {
return new Promise((resolve, reject) => {
const script = this._getScript(this.win.zE);
if (script) {
const params = scriptUtils.parseUrlParams(script.src);
if (params && params.key) {
return resolve(params.key);
}
}
return reject(new EmbeddableProductError('Key is missing from snippet', {}, true));
});
}
getZEQueue() {
return this.win.zE._;
}
_getScript(zE) {
return SnippetUtil.isSnippetPresent(this.win) || (zE && zE.s ? zE.s : undefined);
}
}
class ZopimSnippet extends Snippet {
getKey() {
return new Promise((resolve) =>
resolve(
`zopim_chat/${scriptUtils.getQueryParamsString(ZopimSnippet.getScriptSrc(this.win))}`,
),
);
}
static getScriptSrc(win) {
if (win.$zopim && win.$zopim.s) {
return win.$zopim.s.src;
}
const scripts = document.getElementsByTagName('script');
const zopimRegex = /.*zopim.(com|net|org)\//;
let src;
for (let i = 0, len = scripts.length; i < len; i++) {
src = scripts.at(i)?.src || '';
if (zopimRegex.test(src)) {
return src;
}
}
}
static isSnippetPresent(win) {
return !!ZopimSnippet.getScriptSrc(win);
}
}
let sentryClient = null;
const sentryConfig = {
autoSessionTracking: false,
enabled:
!window.zESettings || window.zESettings.errorReporting !== undefined
? Boolean(window.zESettings.errorReporting)
: true,
dsn: 'https://aba337625608d678c785a8649566e231@o4507427284123728.ingest.de.sentry.io/4507427362963540',
environment: 'production',
release: 'asset-composer@v79',
sampleRate: 0.001,
defaultIntegrations: false,
};
const initSentryClient = () =>
new Promise((resolve) => {
if (sentryClient) {
resolve(sentryClient);
} else {
requireModule
.e(996)
.then(requireModule.bind(null, 858))
.then((sentry) => {
const { BrowserClient, makeFetchTransport, defaultStackParser, Hub, Integrations } =
sentry;
const client = new BrowserClient({
...sentryConfig,
integrations: [
new Integrations.InboundFilters(),
new Integrations.FunctionToString(),
new Integrations.HttpContext(),
],
transport: makeFetchTransport,
stackParser: defaultStackParser,
});
sentryClient = new Hub(client);
resolve(sentryClient);
});
}
});
function reportError(error) {
if (error && error instanceof EmbeddableProductError) {
initSentryClient().then((client) => {
client.withScope((scope) => {
if (error.fingerprint) {
scope.setFingerprint(error.fingerprint);
}
scope.setLevel('warning');
client.captureException(error.error);
});
if (window.console && error.isUserError) {
window.console.error(error.message);
}
});
} else {
initSentryClient().then((client) => {
client.captureException(error);
});
}
}
(function () {
try {
if (typeof window.zE !== 'function') {
const zEStub = function () {
const callQueue = [];
const stubFn = function () {
callQueue.push(arguments);
};
stubFn._ = callQueue;
stubFn.t = Date.now();
return stubFn;
};
window.zE = zEStub();
window.zEmbed = window.zE;
}
if (window.zEACLoaded) {
return;
}
const snippet = (function (win) {
if (SnippetUtil.isSnippetPresent(win)) {
return new SnippetUtil(win);
} else if (win.document.zendeskHost && win.document.zEQueue) {
return new WebWidgetSnippet(win);
} else if (ZopimSnippet.isSnippetPresent(win)) {
return new ZopimSnippet(win);
} else {
return new SnippetUtil(win);
}
})(window);
const productManager = new ProductManager(snippet);
const forceReload = false;
snippet
.getKey()
.then((key) => productManager.getProducts(key, forceReload))
.then((products) => {
if (products && products.length) {
return Promise.all(
productManager.loadProducts(productManager.getProductLoaders(products), forceReload),
);
}
})
.catch((error) => reportError(error));
} catch (error) {
reportError(error);
}
})();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment