/* eslint-disable eqeqeq -- This legacy tracker intentionally accepts string, number, null and undefined inputs. */ var pixels = []; // 初始化状态表 var fbcalllist = { fbinited: null, gginited: null, kkinited: null, ttinited: null, baseLeftInitCount: 4, isInited: function () { return fbcalllist.baseLeftInitCount == 0; }, initEndCallback: [], addInitEndCallback: function (callback) { fbcalllist.initEndCallback.push(callback); }, noticeInitEnd: function (isTimeout = false) { if (isTimeout == true) { console.log('timeout'); } if (fbcalllist.baseLeftInitCount == 0 || isTimeout == true) { for (var i = 0; i < fbcalllist.initEndCallback.length; i++) { fbcalllist.initEndCallback[i](); } // 去除监听回调 fbcalllist.initEndCallback = []; } }, // 模块回调 fbInitEnd: function () { if (!fbcalllist.fbinited) { fbcalllist.baseLeftInitCount = fbcalllist.baseLeftInitCount - 1; fbcalllist.fbinited = true; fbcalllist.noticeInitEnd(); } }, ggInitEnd: function () { if (!fbcalllist.gginited) { fbcalllist.baseLeftInitCount = fbcalllist.baseLeftInitCount - 1; fbcalllist.gginited = true; fbcalllist.noticeInitEnd(); } }, kkInitEnd: function () { if (!fbcalllist.kkinited) { fbcalllist.baseLeftInitCount = fbcalllist.baseLeftInitCount - 1; fbcalllist.kkinited = true; fbcalllist.noticeInitEnd(); } }, ttInitEnd: function () { if (fbcalllist.ttinited != true) { fbcalllist.baseLeftInitCount = fbcalllist.baseLeftInitCount - 1; fbcalllist.ttinited = true; fbcalllist.noticeInitEnd(); } } }; fbcalllist.kkInitEnd(); fbcalllist.ttInitEnd(); //记录 pixcel 值 function load_pixel(pixel) { } function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); } var evapi = ''; var dualstackApi = ''; evapi = window.themeConfig.api; dualstackApi = window.themeConfig.api; evapi = evapi + '/api/weblog'; //qilinid 预加载(下载的时候有用) var preloadqilinid = localStorage.getItem('qilinid'); if (preloadqilinid != null && preloadqilinid != '') { window.qilinid = preloadqilinid; } // 如果有链接变化, 则保存到 localstorage 里面 function checkAdUrlChange() { // 如果当前的链接里面有 pixel , gcode 参数, 则保存到 localstorage 里面 var url = window.location.href; var urlParams = new URLSearchParams(window.location.search); var pixel = urlParams.get('pixel'); var gcode = urlParams.get('gcode'); if ((pixel != null && pixel != '') || (gcode != null && gcode != '')) { localStorage.setItem('lastFbUrl', url); } } checkAdUrlChange(); // 封装的目的 因为前端框架的路由变化的原因, 会导致页面的 url 变化, 但是页面的 fbclid 参数不变 function getURLSearchParams() { // 如果 local storage 里面有, 则生成返回 var lastFbUrl = localStorage.getItem('lastFbUrl'); if (lastFbUrl != null && (lastFbUrl.indexOf('fbclid') >= 0 || lastFbUrl.indexOf('gcode') >= 0)) { // 先使用 ? 分割 var url = lastFbUrl.split('?'); if (url.length >= 2) { return new URLSearchParams(url[1]); } else { return new URLSearchParams(lastFbUrl); } } // 如果没有, 则从当前 url 里面获取 return new URLSearchParams(window.location.search); } var hasGGSendPageView = false; var hasSendPageView = false; var fbCookieCheckAttempts = 0; function checkFbcAndFbp(conditionname) { // console.log('check ...', conditionname); if (hasSendPageView) { console.log('hasSendPageView'); return; } var fbp = getCookie('_fbp'); var fbc = getCookie('_fbc'); if (fbp == undefined) { if (fbCookieCheckAttempts >= 500) { fbcalllist.fbInitEnd(); return; } fbCookieCheckAttempts += 1; // console.log("fbp is null", fbc, fbp); setTimeout(function () { checkFbcAndFbp('timer check'); }, 10); return; } fbcalllist.fbInitEnd(); // 取到参数就是加载结束 // 如果 url 里面没有 fbclid, 则不做提取拦截 var url = window.location.href; if (url.indexOf('fbclid') >= 0) { if (fbc == undefined) { // console.log("fbc is null", fbc, fbp); return; } } else { // 检查 localstorage 里面是否有上次的 fbclid var lastFbUrl = localStorage.getItem('lastFbUrl'); if (lastFbUrl != null && lastFbUrl.indexOf('fbclid') >= 0) { return; } } submitFBEvent('PageView'); hasSendPageView = true; } //多个像素初始化 function initPixels(pixels_array, useOfficialOnly) { console.log('old call'); } function init_facebook_pixels(pixels) { console.log('old call 2'); } function loadpixel() { const urlParams = getURLSearchParams(); var pixel = urlParams.get('pixel'); if (pixel == undefined || pixel == null || pixel == '') { fbcalllist.fbInitEnd(); return; } (function (f, b, e, v, n, t, s) { if (f.fbq) return; n = f.fbq = function () { n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments); }; if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = '2.0'; n.queue = []; t = b.createElement(e); t.addEventListener('load', function () { window.fbq('init', pixel); var u = navigator.userAgent; console.log('userAgent = ', u); var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); var isMac = u.indexOf('Macintosh') >= 0; if (isiOS || isMac) { console.log('is ios or mac'); //fbq('init', '767609381614056'); // fbq('init', '307708915641269');// 备用 //fbq('init', '1214268193069234'); // fbq('init', '430357023093521');// 备用1 // fbq('init', '3348497502121560');// 备用2 } else { //fbq('init', '410150778670828'); // fbq('init', '950445440166110'); // 备用1 // fbq('init', '1710862789652432'); // 备用2 } window.fbq('track', 'PageView'); checkFbcAndFbp('after laod node'); }); t.async = !0; t.src = v; s = b.getElementsByTagName(e)[0]; s.parentNode.insertBefore(t, s); })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js'); } try { loadpixel(); } catch (e) { console.log('load pixel error:', e); } // 复制 qilinid 到剪切板 function copyQilinid() { if (!(window.qilinid == undefined || window.qilinid == null || window.qilinid == '')) { console.log('qilinid is copyed'); if (copyText(window.qilinid)) { window.qilinid = ''; //就拷贝一次就行 } } else { // alert('qilin id is null'); } } function copyText(text) { var input = document.createElement('textarea'); document.body.appendChild(input); // 将文本赋值给输入框 input.value = text; // 聚焦并选中 input.focus(); input.select(); var result = false; try { if (document.queryCommandEnabled('copy')) { // 执行 copy 命令 var success = document.execCommand('copy'); // 移除输入框节点 console.log('Copy Ok'); result = success; // alert('success copy'); } else { console.log('queryCommandEnabled is false'); result = false; // alert('failed copy'); } } catch (e) { // alert('failed copy catch exception'); console.log(e); } input.remove(); return result; } function requestEvApi(requsetUrl, callback) { var url = requsetUrl; var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.send(); xhr.onload = function (data) { if (callback) { callback(this.responseText); } if (this.responseText.indexOf('Error No Access Token Find') >= 0) { console.error(this.responseText); // alert("Please config access token : " + this.responseText); } else { console.log(this.responseText); // console.log('request success'); } }; } //提交 FB 事件 function submitFBEvent(eventName) { // 获取 cookie 里面的 fbp 参数 var fbp = getCookie('_fbp'); if (fbp == null) { fbp = ''; console.log('fbp is null'); } else { console.log('fbp is ' + fbp); } var fbc = getCookie('_fbc'); // 从 url 里面获取 material 参数 const urlParams = getURLSearchParams(); var pixel = urlParams.get('pixel'); // fb 像素 var material = urlParams.get('campaign'); // 取广告系列名 var adgroup = urlParams.get('adgroup'); // 取广告系组名 if (material == null) { material = ''; } if (adgroup == null) { adgroup = ''; } var apkch = urlParams.get('apkch') || ''; if (apkch == '') { apkch = window.apkch || ''; } if (window.apkchforce != undefined && window.apkchforce != null && window.apkchforce != '') { apkch = window.apkchforce || ''; } // 查找 url 里面正则提取 ch_ 开头的协议 if (apkch == '') { var lourl = window.location.href; var reg = /ch_([^/]*)/g; var match = reg.exec(lourl); if (match != null && match.length >= 2) { apkch = match[1]; } } var paste = ''; // 上报一次到服务器. 只要 fbc 不变化, 那就只上传一次. 因为 h5 里面访问会很高频。 var reportfbc = localStorage.getItem('reportfbc'); var oldqilinid = localStorage.getItem('qilinid'); if (reportfbc == null || reportfbc != fbc || oldqilinid == null || oldqilinid == '') { var url = dualstackApi + '/api/sendfbevent?pixel=' + pixel + '&apkch=' + apkch + '_APK' + '&event=' + eventName + '&fbp=' + fbp + '&fbc=' + fbc + '&paste=' + paste + '&material=' + material + '&adgroup=' + adgroup + '&dualstack=1'; requestEvApi(url, function (data) { //从 data 解析 qilinid var qilinid = ''; if (data != undefined && data != null) { // 正则匹配 qilinid(?) 括号里面的内容 var reg = /qilinid\((.*?)\)/g; var match = reg.exec(data); if (match != null && match.length >= 2) { qilinid = match[1]; } window.qilinid = qilinid; // 保存到 localstorage 里面 localStorage.setItem('qilinid', qilinid); localStorage.setItem('reportfbc', fbc); } }); } else { window.qilinid = oldqilinid; } //fb 的事件提交 if (typeof window.fbq === 'function') window.fbq('track', eventName); //'SubmitApplication' } // 页面统计事件 function pageEventSubmit(event_name, during = 0, mark = '') { // 请求 evapi 接口 // alert(url); // XMLHttpRequest post application/json var xhr = new XMLHttpRequest(); var urlParams = getURLSearchParams(); var click_id = urlParams.get('fbclid') || ''; var apkch = urlParams.get('apkch') || ''; if (apkch == '') { apkch = window.apkch || ''; } if (window.apkchforce != undefined && window.apkchforce != null && window.apkchforce != '') { apkch = window.apkchforce || ''; } // 查找 url 里面正则提取 ch_ 开头的协议 if (apkch == '') { var lourl = window.location.href; var reg = /ch_([^/]*)/g; var match = reg.exec(lourl); if (match != null && match.length >= 2) { apkch = match[1]; } } xhr.open('POST', evapi, true); // xhr.setRequestHeader("Content-Type","application/json"); var data = JSON.stringify({ click_id: click_id, event_name: event_name, apkch: apkch, during: during, mark: mark }); xhr.send(data); xhr.onload = function (data) { console.log(this.responseText); // console.log('request success'); }; } var downloadIframe; // 页面下载 function pageDownload(download_url) { // 取到 fbp 之后就去下载 var retryDownTime = 0; function autoDownload() { retryDownTime = retryDownTime + 1; if (retryDownTime > 2 * 10) { //超过 2 秒, 就直接请求 pageEventSubmit(window.down_type_name || 'download', 0, download_url); // window.location.href = download_url todoownload(download_url); return; } if (hasSendPageView == false && hasGGSendPageView == false) { setTimeout(() => { autoDownload(); }, 100); // 过100毫秒再检查 } else { todoownload(download_url); } } autoDownload(); return; } // 使用 iframe 来 做 url apk 下载 function todoownload(download_url) { if (download_url == undefined || download_url == null || download_url == '') { return; } downloadIframe = document.createElement('iframe'); downloadIframe.style.display = 'none'; document.body.appendChild(downloadIframe); downloadIframe.src = download_url; } // -- google var ggClientCheckAttempts = 0; function checkGGClientEvent(conditionname) { if (hasGGSendPageView) { console.log('hasGGSendPageView'); return; } if (window.gg_client_id == undefined) { if (ggClientCheckAttempts >= 500) { fbcalllist.ggInitEnd(); return; } ggClientCheckAttempts += 1; setTimeout(function () { checkGGClientEvent('timer check'); }, 10); return; } submitGGEvent('page_view'); hasGGSendPageView = true; } // 谷歌加载 (function () { const urlParams = getURLSearchParams(); var gcode = urlParams.get('gcode'); if (gcode == undefined || gcode == null || gcode == '') { fbcalllist.ggInitEnd(); return; } var script = document.createElement('script'); script.async = true; script.src = 'https://www.googletagmanager.com/gtag/js?id=' + gcode; document.head.appendChild(script); window.dataLayer = window.dataLayer || []; function gtag() { window.dataLayer.push(arguments); } script.onload = function () { gtag('js', new Date()); gtag('config', gcode); gtag('get', gcode, 'client_id', clientID => { console.log('this client id is: ' + clientID); window.gg_client_id = clientID; fbcalllist.ggInitEnd(); }); checkGGClientEvent('script.onload'); }; })(); //提交 GG 事件 function submitGGEvent(eventName) { // 从 url 里面获取 material 参数 const urlParams = new URLSearchParams(window.location.search); var gcode = urlParams.get('gcode'); // 谷歌代码 if (gcode == null || gcode == '') { return false; } var gclid = urlParams.get('gclid') || ''; // 点击id var material = urlParams.get('campaign'); // 取广告系列名 var adgroup = urlParams.get('adgroup'); // 取广告系组名 if (material == null) { material = ''; } if (adgroup == null) { adgroup = ''; } var apkch = urlParams.get('apkch') || ''; if (apkch == '') { apkch = window.apkch || ''; } if (window.apkchforce != undefined && window.apkchforce != null && window.apkchforce != '') { apkch = window.apkchforce || ''; } // 查找 url 里面正则提取 ch_ 开头的协议 if (apkch == '') { var lourl = window.location.href; var reg = /ch_([^/]*)/g; var match = reg.exec(lourl); if (match != null && match.length >= 2) { apkch = match[1]; } } var paste = ''; var fbp = 'gg.' + (window.gg_client_id || ''); var fbc = 'gg.' + (gclid || ''); var url = dualstackApi + '/api/sendggevent?gcode=' + gcode + '&apkch=' + apkch + '_APK' + '&event=' + eventName + '&fbp=' + fbp + '&fbc=' + fbc + '&paste=' + paste + '&material=' + material + '&adgroup=' + adgroup; var reportgclid = localStorage.getItem('reportgclid'); var oldqilinid = localStorage.getItem('qilinid'); if (reportgclid == null || reportgclid != gclid || oldqilinid == null || oldqilinid == '') { requestEvApi(url, function (data) { //从 data 解析 qilinid var qilinid = ''; if (data != undefined && data != null) { // 正则匹配 qilinid(?) 括号里面的内容 var reg = /qilinid\((.*?)\)/g; var match = reg.exec(data); if (match != null && match.length >= 2) { qilinid = match[1]; } window.qilinid = qilinid; localStorage.setItem('qilinid', qilinid); localStorage.setItem('reportgclid', gclid); } if (window.callLoadGtag != undefined) { try { window.callLoadGtag(); } catch (e) { console.log(e); } window.callLoadGtag = undefined; } }); } else { window.qilinid = oldqilinid; } return true; } function sureCheck() { if (fbcalllist.isInited()) { // 通知回调 fbcalllist.noticeInitEnd(); } else if (new Date().getTime() - fbcalllist.startCheckTime > fbcalllist.timeOutSeconds * 1000) { // 已超时, 直接通知掉 fbcalllist.noticeInitEnd(true); } else { // 100 毫秒后再次检查 setTimeout(function () { sureCheck(); }, 100); } } // * 在网页内启动的时候, 调用这个方法来获得 fbp , fbc , gclid , material , adgroup, apkch function getFbcAndFbp(bccallback, timeOutSeconds = 5) { fbcalllist.startCheckTime = new Date().getTime(); fbcalllist.timeOutSeconds = timeOutSeconds; // 加入监听 fbcalllist.addInitEndCallback(function () { var fbinfo = {}; try { // 从 url 里面获取 material 参数 const urlParams = getURLSearchParams(); //new URLSearchParams(location.search); fbinfo = { fbp: undefined, fbc: undefined, ready: false, gclid: undefined, pixel: undefined, gcode: undefined, material: undefined, adgroup: undefined, apkch: undefined, paste: undefined, creative: urlParams.get('creative') }; // 遍历打印 urlParams // for (var pair of urlParams.entries()) { // console.log(pair[0]+ ', ' + pair[1]); // } fbinfo.gcode = urlParams.get('gcode'); // 谷歌代码 fbinfo.gclid = urlParams.get('gclid') || ''; // 点击id fbinfo.fbclid = urlParams.get('fbclid') || ''; // 点击id fbinfo.material = urlParams.get('campaign'); // 取广告系列名 fbinfo.adgroup = urlParams.get('adgroup'); // 取广告系组名 if (fbinfo.material == null) { fbinfo.material = ''; } if (fbinfo.adgroup == null) { fbinfo.adgroup = ''; } var apkch = urlParams.get('apkch') || ''; if (apkch == '') { apkch = window.apkch || ''; } if (window.apkchforce != undefined && window.apkchforce != null && window.apkchforce != '') { apkch = window.apkchforce || ''; } // 查找 url 里面正则提取 ch_ 开头的协议 if (apkch == '') { var lourl = window.location.href; var channelPattern = /ch_([^/]*)/g; var channelMatch = channelPattern.exec(lourl); if (channelMatch != null && channelMatch.length >= 2) { apkch = channelMatch[1]; } } fbinfo.apkch = apkch; fbinfo.paste = ''; // fb 点击进来的 if (fbinfo.fbclid != undefined && fbinfo.fbclid != null && fbinfo.fbclid != '') { fbinfo.fbp = getCookie('_fbp'); fbinfo.fbc = getCookie('_fbc'); fbinfo.pixel = urlParams.get('pixel'); // fb 像素 } // if (fbinfo.gcode != undefined && fbinfo.gcode != null && fbinfo.gcode != '') { fbinfo.fbp = 'gg.' + (window.gg_client_id || ''); fbinfo.fbc = 'gg.' + (fbinfo.gclid || ''); fbinfo.pixel = fbinfo.gcode; } fbinfo.ready = false; if ( fbinfo.fbp != undefined && fbinfo.fbp != null && fbinfo.fbp != '' && fbinfo.fbc != undefined && fbinfo.fbc != null && fbinfo.fbc != '' ) { fbinfo.ready = true; } // campaign , campaign_id 的提取 if (fbinfo.material != undefined && fbinfo.material != null && fbinfo.material != '') { // fb if (fbinfo.fbp != undefined && fbinfo.fbp != null && fbinfo.fbp != '' && fbinfo.fbp.indexOf('fb.') >= 0) { // "{{campaign.name}} ({{campaign.id}})" 解析出 campaign.name 和 campaign.id var campaignPattern = /(.*)\((.*)\)/g; var campaignMatch = campaignPattern.exec(fbinfo.material); if (campaignMatch != null && campaignMatch.length >= 3) { fbinfo.campaign = campaignMatch[1]; fbinfo.campaign_id = campaignMatch[2]; } } // gg if (fbinfo.fbp != undefined && fbinfo.fbp != null && fbinfo.fbp != '' && fbinfo.fbp.indexOf('gg.') >= 0) { fbinfo.campaign = fbinfo.material; fbinfo.campaign_id = fbinfo.material; } } // ad , adset , adset_id if (fbinfo.adgroup != undefined && fbinfo.adgroup != null && fbinfo.adgroup != '') { // fb if (fbinfo.fbp != undefined && fbinfo.fbp != null && fbinfo.fbp != '' && fbinfo.fbp.indexOf('fb.') >= 0) { // "{{adset.name}} ({{adset.id}})" 解析出 , adset.name , adset.id var adGroupPattern = /(.*)\((.*)\)/g; var adGroupMatch = adGroupPattern.exec(fbinfo.adgroup); if (adGroupMatch != null && adGroupMatch.length >= 3) { fbinfo.adset = adGroupMatch[1]; fbinfo.adset_id = adGroupMatch[2]; } // 从 creative 里面提取 ad ad_id var creativePattern = /(.*)\((.*)\)/g; var creativeMatch = creativePattern.exec(fbinfo.creative); if (creativeMatch != null && creativeMatch.length >= 3) { fbinfo.ad = creativeMatch[1]; fbinfo.ad_id = creativeMatch[2]; } } // gg. if (fbinfo.fbp != undefined && fbinfo.fbp != null && fbinfo.fbp != '' && fbinfo.fbp.indexOf('gg.') >= 0) { fbinfo.ad = fbinfo.creative; fbinfo.ad_id = fbinfo.creative; fbinfo.adset = fbinfo.adgroup; fbinfo.adset_id = fbinfo.adgroup; } } fbinfo._fbp = fbinfo.fbp; fbinfo._fbc = fbinfo.fbc; // if (isNaN(fbinfo.ad_id)){ // fbinfo.ad_id = ''; // } // if(isNaN(fbinfo.adset_id)){ // fbinfo.adset_id = ''; // } } catch (e) { console.log('parse error:', e); } if (typeof bccallback === 'function') bccallback(fbinfo); }); sureCheck(); } // 在 fbqreq 事件后面调用 function tryFbBind(userid, uuid, channel, fbclid) { if (fbclid && fbclid.length > 0) { return; } setTimeout(function () { var initUrl = dualstackApi + '/api/init-h5-client'; var xhr = new XMLHttpRequest(); xhr.open('POST', initUrl, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); var data = 'machine_serial=' + uuid + '&channel=' + channel + '&userid=' + userid; xhr.send(data); xhr.onload = function (data) { }; }, 10); } // Public API consumed by legacy landing pages and native shells. Object.assign(window, { pixels, load_pixel, initPixels, init_facebook_pixels, copyQilinid, pageDownload, getFbcAndFbp, tryFbBind });