/** * 自动连接脚本 - 智能握手注册系统 * 版本: 2.1 (增强验证版本) * 更新时间: 2025-07-14T03:09:38.059Z */ (function() { 'use strict'; class AutoAnalyticsConnector { constructor() { this.config = { analyticsUrl: 'https://cloudflare-user-analytics-collector.justpm2099.workers.dev', heartbeatInterval: 60000, // 1分钟 maxRetries: 5, retryDelay: 3000, debug: true }; this.projectInfo = this.detectProjectInfo(); this.apiKey = localStorage.getItem('analytics_api_key'); this.projectId = localStorage.getItem('analytics_project_id'); this.isRegistered = !!this.apiKey; this.heartbeatTimer = null; this.retryCount = 0; this.log('🔗 Analytics Auto-Connector v2.1 启动中... (增强验证版本)'); this.log('📍 检测到项目: ' + this.projectInfo.project_name); this.log('🌐 域名: ' + this.projectInfo.domain); this.init(); } log(message, level = 'info') { if (!this.config.debug) return; const timestamp = new Date().toLocaleTimeString(); const prefix = '[Analytics] '; switch(level) { case 'error': console.error(prefix + message); break; case 'warn': console.warn(prefix + message); break; case 'success': console.log('%c' + prefix + message, 'color: #4CAF50; font-weight: bold;'); break; default: console.log(prefix + message); } } detectProjectInfo() { const hostname = window.location.hostname; let projectName = hostname; // 处理常见的部署平台域名 if (hostname.includes('.pages.dev')) { projectName = hostname.replace('.pages.dev', ''); } else if (hostname.includes('.workers.dev')) { projectName = hostname.replace('.workers.dev', ''); } else if (hostname.includes('.vercel.app')) { projectName = hostname.replace('.vercel.app', ''); } else if (hostname.includes('.netlify.app')) { projectName = hostname.replace('.netlify.app', ''); } return { domain: hostname, project_name: projectName, deployment_url: window.location.origin, user_agent: navigator.userAgent, language: navigator.language, referrer: document.referrer, page_title: document.title, integration_method: 'auto-script-v2', client_timestamp: new Date().toISOString() }; } async init() { try { if (!this.isRegistered) { this.log('🤝 开始自动注册流程...'); await this.performHandshake(); } else { this.log('✅ 发现已存储的认证信息'); this.log('🔑 API密钥: ' + this.apiKey.substring(0, 8) + '...'); } if (this.isRegistered) { this.log('💓 启动心跳监控...'); this.startHeartbeat(); this.log('📊 记录页面访问...'); this.trackPageView(); } } catch (error) { this.log('❌ 初始化失败: ' + error.message, 'error'); this.scheduleRetry(); } } async performHandshake() { const handshakeData = { ...this.projectInfo, timestamp: new Date().toISOString(), client_info: { screen_resolution: `${screen.width}x${screen.height}`, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, platform: navigator.platform, cookie_enabled: navigator.cookieEnabled, online: navigator.onLine }, request_type: 'auto_handshake_v2' }; this.log(`🤝 发送握手请求到: ${this.config.analyticsUrl}/auto-register`); const response = await fetch(`${this.config.analyticsUrl}/auto-register`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Auto-Connect': 'true', 'User-Agent': navigator.userAgent }, body: JSON.stringify(handshakeData) }); this.log(`📡 握手响应状态: ${response.status}`); if (!response.ok) { const errorText = await response.text(); throw new Error(`握手失败: HTTP ${response.status} - ${errorText}`); } const data = await response.json(); this.log(`📦 握手响应数据: ${JSON.stringify(data)}`); if (data.success) { this.apiKey = data.api_key; this.projectId = data.project_id; this.isRegistered = true; this.retryCount = 0; this.log('✅ 自动注册成功!', 'success'); this.log(`🔑 API密钥: ${this.apiKey.substring(0, 8)}...`, 'success'); this.log(`📋 项目ID: ${this.projectId}`, 'success'); this.log(`📊 状态: ${data.status}`, 'success'); localStorage.setItem('analytics_api_key', this.apiKey); localStorage.setItem('analytics_project_id', this.projectId); return data; } else { throw new Error(data.error || '握手响应异常'); } } startHeartbeat() { // 清除现有定时器 if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); } // 立即发送一次心跳 this.sendHeartbeat(); // 设置定时器 this.heartbeatTimer = setInterval(() => { this.sendHeartbeat(); }, this.config.heartbeatInterval); this.log(`💓 心跳监控已启动 (间隔: ${this.config.heartbeatInterval/1000}秒)`); } updateHeartbeatInterval(newInterval) { const newIntervalMs = newInterval * 1000; if (newIntervalMs !== this.config.heartbeatInterval) { this.log(`🔄 调整心跳间隔: ${this.config.heartbeatInterval/1000}秒 → ${newInterval}秒`); this.config.heartbeatInterval = newIntervalMs; this.startHeartbeat(); } } async sendHeartbeat() { if (!this.apiKey || !this.projectId) { this.log('⚠️ 心跳跳过:缺少认证信息', 'warn'); return; } const heartbeatData = { project_id: this.projectId, timestamp: new Date().toISOString(), page_url: window.location.href, user_agent: navigator.userAgent, event_type: 'heartbeat', connection_status: 'active', performance_data: { memory_used: performance.memory ? performance.memory.usedJSHeapSize : 0, connection_type: navigator.connection ? navigator.connection.effectiveType : 'unknown' } }; try { this.log(`💓 发送心跳数据: ${JSON.stringify(heartbeatData, null, 2)}`); const response = await fetch(`${this.config.analyticsUrl}/heartbeat`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': this.apiKey }, body: JSON.stringify(heartbeatData) }); this.log(`💗 心跳API响应状态: ${response.status} ${response.statusText}`); if (response.ok) { const result = await response.json(); this.log(`✅ 心跳发送成功: ${JSON.stringify(result, null, 2)}`); // 处理智能心跳配置 if (result.smart_config && result.smart_config.next_interval) { const newInterval = result.smart_config.next_interval; this.updateHeartbeatInterval(newInterval); if (result.smart_config.recommendation) { this.log(`🎯 ${result.smart_config.recommendation}`); } } } else { const errorText = await response.text(); this.log(`❌ 心跳发送失败 (${response.status}): ${errorText}`, 'error'); } } catch (error) { this.log(`💥 心跳发送网络错误: ${error.message}`, 'error'); this.log(`🔍 错误详情: ${error.stack}`, 'error'); } } async trackPageView() { if (!this.apiKey || !this.projectId) { this.log('⚠️ 页面跟踪跳过:缺少认证信息', 'warn'); return; } const pageData = { project_id: this.projectId, timestamp: new Date().toISOString(), event_type: 'page_view', page_url: window.location.href, page_title: document.title, referrer: document.referrer, user_agent: navigator.userAgent, screen_resolution: `${screen.width}x${screen.height}`, language: navigator.language, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone }; try { this.log(`📤 发送页面跟踪数据: ${JSON.stringify(pageData, null, 2)}`); const response = await fetch(`${this.config.analyticsUrl}/test-track?v=${Date.now()}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': this.apiKey }, body: JSON.stringify(pageData) }); this.log(`📡 跟踪API响应状态: ${response.status} ${response.statusText}`); if (response.ok) { const result = await response.json(); this.log(`✅ 页面跟踪成功: ${JSON.stringify(result, null, 2)}`); } else { const errorText = await response.text(); this.log(`❌ 页面跟踪失败 (${response.status}): ${errorText}`, 'error'); } } catch (error) { this.log(`💥 页面跟踪网络错误: ${error.message}`, 'error'); this.log(`🔍 错误详情: ${error.stack}`, 'error'); } } scheduleRetry() { if (this.retryCount >= this.config.maxRetries) { this.log(`❌ 达到最大重试次数(${this.config.maxRetries}),停止尝试`, 'error'); return; } this.retryCount++; this.log(`🔄 ${this.config.retryDelay/1000}秒后进行第${this.retryCount}次重试...`); setTimeout(() => { this.init(); }, this.config.retryDelay); } // 公共方法:手动发送自定义事件 trackCustomEvent(eventData) { if (!this.apiKey || !this.projectId) { this.log('⚠️ 自定义事件跳过:缺少认证信息', 'warn'); return; } const customEventData = { project_id: this.projectId, timestamp: new Date().toISOString(), ...eventData }; fetch(`${this.config.analyticsUrl}/test-track?v=${Date.now()}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': this.apiKey }, body: JSON.stringify(customEventData) }).then(response => { if (response.ok) { this.log(`📊 自定义事件已记录: ${eventData.event_type}`); } }).catch(error => { this.log(`❌ 自定义事件发送失败: ${error.message}`, 'error'); }); } } // 页面加载完成后启动连接器 function initConnector() { try { window.analyticsConnector = new AutoAnalyticsConnector(); } catch (error) { console.error('[Analytics] 连接器启动失败:', error); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initConnector); } else { initConnector(); } // 页面卸载时清理 window.addEventListener('beforeunload', function() { if (window.analyticsConnector && window.analyticsConnector.heartbeatTimer) { clearInterval(window.analyticsConnector.heartbeatTimer); } }); })();