UNPKG

top-analyze-sdk

Version:

SDK for TOP analytics

4 lines 12.8 kB
/* Top Analyze SDK - автоматическая аналитика для TON Mini Apps */ function h(){let i=window.Telegram?.WebApp;if(i?.initDataUnsafe?.user){let e=i.initDataUnsafe.user;return {telegramId:e.id,locale:e.language_code,premium:e.is_premium||false,telegramUsername:e.username,telegramFirstname:e.first_name,telegramLastname:e.last_name,telegramPlatform:i.platform,startapp:i.initDataUnsafe.start_param,userProperties:{}}}throw new Error("Telegram WebApp API \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D")}function d(){return !!window.Telegram?.WebApp}var C="https://analyze.playdeck.io",g=`${C}/v1/e`,m=1e5,p=1e3,T=100,f=["button","input","textarea","select","a","img"],u=["invoiceClosed","settingsButtonClicked","backButtonClicked","mainButtonClicked","secondaryButtonClicked","popupClosed","qrTextReceived","clipboardTextReceived","writeAccessRequested","contactRequested","scanQrPopupClosed","activated","deactivated","fullscreenChanged","fullscreenFailed","homeScreenAdded","homeScreenChecked","locationManagerUpdated","locationRequested","shareMessageSent","shareMessageFailed","emojiStatusSet","emojiStatusFailed","emojiStatusAccessRequested","fileDownloadRequested"];var o=class{constructor(e,t,n){this.appName=e,this.userData=t,this.debug=n;}normalizeSchema(e){let t=e.type==="custom"?"CUSTOM":"AUTO",n=e.type==="custom"?e.data.eventName:e.type,a=e.type==="custom"?e.data.payload:this.extractEventProperties(e.data);return {type:t,source:this.appName,ts:new Date(e.timestamp).toISOString(),pagePath:e.data.pageUrl||window.location.href,pageReferrer:document.referrer||"",name:n,telegramId:this.userData?.telegramId||null,locale:this.userData?.locale||"unknown",premium:this.userData?.premium||false,userAgent:e.data.userAgent||navigator.userAgent,sessionId:e.sessionId,startapp:this.userData?.startapp||null,telegramUsername:this.userData?.telegramUsername||null,telegramFirstname:this.userData?.telegramFirstname||null,telegramLastname:this.userData?.telegramLastname||null,telegramPlatform:this.userData?.telegramPlatform||null,eventCategory:e.eventCategory,eventProperties:a,userProperties:{}}}extractEventProperties(e){let{pageUrl:t,userAgent:n,...a}=e;return a}validatePayloadSize(e){try{return JSON.stringify(e).length<=m}catch(t){return this.debug&&console.log("Error validating payload size:",t),false}}sanitizeData(e){if(e==null)return e;if(typeof e=="string")return e.length>p?e.slice(0,p):e;if(Array.isArray(e))return e.slice(0,T).map(n=>this.sanitizeData(n));if(typeof e=="object"){let t={};for(let[n,a]of Object.entries(e)){let s=n.length>100?n.slice(0,100):n;t[s]=this.sanitizeData(a);}return t}return e}};var l=class{constructor(e,t,n){this.tonConnectInstance=null;this.tonConnectUIOriginal=null;this.lastWalletInfo=null;this.userData=e,this.debug=t,this.tonConnectInstance=null,this.tonConnectUIOriginal=null,this.lastWalletInfo=null,this.sendEvent=n,t&&console.log("\u{1F680} TonConnectAdapter initialized");}attachTonConnect(e){"connector"in e?(this.tonConnectUIOriginal=e,this.tonConnectInstance={sendTransaction:e.sendTransaction.bind(e),connect:e.connector.connect.bind(e.connector),disconnect:e.disconnect.bind(e),onStatusChange:e.onStatusChange.bind(e),get wallet(){return e.wallet}}):(this.tonConnectInstance=e,this.tonConnectUIOriginal=null),this.setupTonConnectProxies(),this.setupTonConnectStatusListener(),this.tonConnectInstance.wallet&&this.updateWalletInfo(),this.debug&&console.log("\u{1F680} TonConnectAdapter attached",{tonConnectInstance:this.tonConnectInstance,tonConnectUIOriginal:this.tonConnectUIOriginal});}setupTonConnectProxies(){if(this.tonConnectInstance)if(this.tonConnectUIOriginal){let e=this.tonConnectUIOriginal;if(e.openModal){let n=e.openModal.bind(e);e.openModal=()=>{this.debug&&console.log("\u{1F535} [TON CONNECT] openModal() called");let{address:a,client:s}=this.buildWalletConnectStartInfo();this.sendTonWalletEvent("wallet_connect_start",{ton_wallet_address:a,ton_wallet_client:s});try{let r=n();return this.debug&&console.log("\u{1F7E2} [TON CONNECT] openModal() completed"),r}catch(r){throw this.debug&&console.error("\u{1F534} [TON CONNECT] openModal() error:",r),r}};}let t=e.sendTransaction.bind(e);e.sendTransaction=async n=>{this.debug&&console.log("\u{1F535} [TON CONNECT] sendTransaction() called:",n);try{this.sendTonWalletEvent("transaction_sent_for_signature",{transaction:n});let a=await t(n);return this.debug&&console.log("\u{1F7E2} [TON CONNECT] sendTransaction() completed:",a),this.sendTonWalletEvent("transaction_signed",{transaction:n,result:a}),a}catch(a){throw this.debug&&console.error("\u{1F534} [TON CONNECT] sendTransaction() error:",a),this.sendTonWalletEvent("transaction_signing_failed",{transaction:n,error:String(a)}),a}};}else {let e=this.tonConnectInstance.connect;this.tonConnectInstance.connect=n=>{let{address:a,client:s}=this.buildWalletConnectStartInfo(n);this.sendTonWalletEvent("wallet_connect_start",{ton_wallet_address:a,ton_wallet_client:s});try{return e.call(this.tonConnectInstance,n)}catch(r){throw this.sendTonWalletEvent("wallet_connect_error",{error:String(r),error_code:r?.code||r?.message||"unknown"}),r}};let t=this.tonConnectInstance.sendTransaction;this.tonConnectInstance.sendTransaction=async n=>{try{this.sendTonWalletEvent("transaction_sent_for_signature",{transaction:n});let a=await t.call(this.tonConnectInstance,n);return this.sendTonWalletEvent("transaction_signed",{transaction:n,result:a}),a}catch(a){throw this.sendTonWalletEvent("transaction_signing_failed",{transaction:n,error:String(a)}),a}};}}setupTonConnectStatusListener(){this.tonConnectInstance?.onStatusChange&&this.tonConnectInstance.onStatusChange(e=>{e?(this.updateWalletInfo(),this.sendTonWalletEvent("wallet_connected")):(this.sendTonWalletEvent("wallet_disconnected"),this.lastWalletInfo=null);});}updateWalletInfo(){this.lastWalletInfo=this.getTonWalletInfo();}detectWalletTransport(e){let t=e??this.tonConnectInstance?.wallet;if(!t)return "unknown";try{return (t.connectItems?.tonProof||t.provider)&&(t.provider||t.device?.features?.includes("SendTransaction"))?"http":t.embedded||t.injected?"js":t.device?.features?.includes("SSE")?"sse":"http"}catch(n){return this.debug&&console.log("Error detecting transport:",n),"unknown"}}formatWalletClientFromWallet(e,t){let n=t||"unknown";if(!e)return `unknown/${n}/unknown/unknown`;try{let a=e.device||{},s=a.appName||a.name||"unknown",r=t||a.platform||"unknown",E=this.detectWalletTransport(e),v=a.appVersion||"unknown";return `${s}/${r}/${E}/${v}`}catch(a){return this.debug&&console.log("Error formatting wallet client:",a),`unknown/${n}/unknown/unknown`}}formatWalletClient(){return this.formatWalletClientFromWallet(this.tonConnectInstance?.wallet)}buildWalletConnectStartInfo(e){let t=e??this.tonConnectInstance?.wallet,n=this.userData?.telegramPlatform||"unknown";return {address:t?.account?.address??null,client:this.formatWalletClientFromWallet(t,n)}}getTonWalletInfo(){if(!this.tonConnectInstance?.wallet)return null;try{return {client:this.formatWalletClient(),address:this.tonConnectInstance.wallet.account?.address}}catch(e){return this.debug&&console.log("Error getting wallet info:",e),null}}sendTonWalletEvent(e,t={}){let n={...t,ton_wallet_address:t?.ton_wallet_address??this.lastWalletInfo?.address??null,ton_wallet_client:t?.ton_wallet_client??this.lastWalletInfo?.client??null};this.sendEvent(e,n,"WALLET");}isAttached(){return this.tonConnectInstance!==null}};var c=class{constructor(e){this.maxBatchSize=10;this.batchInterval=5e3;this.isStarted=false;this.events=[];this.batchTimer=null;this.appName=e.appName,this.userData=this.initUserData(),this.debug=e.debug??false,this.sessionId=this.generateSessionId(),this.sessionStartTime=Date.now(),this.onlyImportantClicks=e.onlyImportantClicks??false,this.apiToken=e.apiToken,this.eventTransformer=new o(this.appName,this.userData,this.debug),this.tonConnectAdapter=new l(this.userData,this.debug,this.sendEvent.bind(this)),this.setupPageUnloadHandlers();}start(){this.isStarted||(this.isStarted=true,this.setupEventListeners(),this.setupTelegramEventListeners(),this.sendEvent("session_start",{pageUrl:window.location.href,userAgent:navigator.userAgent},"WEB"),this.sendEvent("page_view",{pageUrl:window.location.href,userAgent:navigator.userAgent},"WEB"),this.debug&&console.log("\u{1F680} Top Analyze SDK started",{sessionId:this.sessionId,appName:this.appName}));}stop(){this.isStarted&&(this.isStarted=false,this.removeEventListeners(),this.flushEvents(),this.debug&&console.log("\u{1F680} Top Analyze SDK stopped",{sessionId:this.sessionId,appName:this.appName}));}attachTonConnect(e){this.tonConnectAdapter.attachTonConnect(e),this.debug&&console.log("\u{1F680} Top Analyze SDK attached TON Connect",{sessionId:this.sessionId,appName:this.appName});}track(e,t={}){this.sendEvent("custom",{eventName:e,payload:t??{}},"CUSTOM");}getTonWalletInfo(){return this.tonConnectAdapter.getTonWalletInfo()}getSessionInfo(){return {sessionId:this.sessionId,duration:Date.now()-this.sessionStartTime,isActive:this.isStarted}}getStatus(){return {isInitialized:true,isStarted:this.isStarted,isTonConnectAttached:this.tonConnectAdapter.isAttached(),appName:this.appName}}initUserData(){try{if(d())return h()}catch(e){this.debug&&console.log("Error getting Telegram user data:",e);}return null}generateSessionId(){let e=Date.now().toString(36),t=Math.random().toString(36).substr(2,9);return `session_${e}_${t}`}setupEventListeners(){typeof window>"u"||(document.addEventListener("click",this.handleClick.bind(this),true),window.addEventListener("popstate",this.handlePageView.bind(this)),this.setupHistoryTracking());}removeEventListeners(){typeof window>"u"||(document.removeEventListener("click",this.handleClick.bind(this),true),window.removeEventListener("popstate",this.handlePageView.bind(this)));}handleClick(e){if(this.onlyImportantClicks&&!f.includes(e.target.tagName.toLowerCase()))return;let t=e.target;if(!t)return;let n={element_tag:t.tagName.toLowerCase(),element_text:t.textContent?.trim()?.slice(0,100),element_slug:t.getAttribute("data-analytics-slug")||t.id||(typeof t.className=="string"?t.className.split(" ")[0]:t.className?.[0]),coordinates:{clientX:e.clientX,clientY:e.clientY,pageX:e.pageX,pageY:e.pageY},pageUrl:window.location.href};this.sendEvent("click",n,"WEB");}handlePageView(){this.sendEvent("page_view",{pageUrl:window.location.href,userAgent:navigator.userAgent},"WEB");}setupHistoryTracking(){if(typeof window>"u")return;let e=history.pushState,t=history.replaceState;history.pushState=function(n,a,s){e.call(history,n,a,s),window.dispatchEvent(new PopStateEvent("popstate",{state:n}));},history.replaceState=function(n,a,s){t.call(history,n,a,s),window.dispatchEvent(new PopStateEvent("popstate",{state:n}));};}sendEvent(e,t,n){if(!this.isStarted)return;let a={type:e,timestamp:Date.now(),sessionId:this.sessionId,appName:this.appName,data:t,eventCategory:n};this.events.push(a),this.events.length>=this.maxBatchSize?this.flushEvents():this.startBatchTimer();}startBatchTimer(){this.batchTimer||(this.batchTimer=setTimeout(()=>{this.flushEvents();},this.batchInterval));}flushEvents(){if(this.events.length===0)return;let e=[...this.events];this.events=[],this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.sendBatchToAPI(e);}async sendBatchToAPI(e){try{let t=e.map(a=>this.eventTransformer.normalizeSchema(a));if(!this.eventTransformer?.validatePayloadSize(t)){this.debug&&console.warn("\u26A0\uFE0F Top Analyze: payload is too large, skipping send");return}let n=this.eventTransformer?.sanitizeData(t);this.debug&&(console.group(`\u{1F4CA} Top Analyze: sending ${n.length} events`),n.forEach(a=>console.log(`${a.type} [${a.ts}]`,a)),console.groupEnd()),await fetch(g,{method:"POST",headers:{"Content-Type":"application/json","X-Auth-TAS":this.apiToken},body:JSON.stringify(n)});}catch(t){console.error("\u274C Top Analyze: error sending batch:",t);}}setupTelegramEventListeners(){if(typeof window>"u"||!d())return;let e=window.Telegram?.WebApp;e?.onEvent&&(u.forEach(t=>{e.onEvent(t,n=>{this.handleTelegramEvent(t,n);});}),this.debug&&console.log("\u{1F680} Top Analyze SDK: Telegram event listeners setup completed",{eventsCount:u.length}));}handleTelegramEvent(e,t){this.isStarted&&(this.sendEvent(e,{telegram_event_data:t,pageUrl:window.location.href},"TELEGRAM"),this.debug&&console.log("\u{1F4F1} Telegram Event:",e,t));}setupPageUnloadHandlers(){if(typeof window>"u")return;let e=()=>this.flushEvents();window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flushEvents();});}};var z=c; export{c as TopAnalyzeSDK,z as default};//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map