HEX
Server: Apache
System: Linux 244.240.109.208.host.secureserver.net 5.14.0-611.11.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Dec 3 09:47:37 EST 2025 x86_64
User: icsla (1002)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: /home/icsla/public_html/wp-content/plugins/link-whisper/js/wpil_telemetry.js
/**
 * LinkWhisper Telemetry Service
 * Handles logging of user interactions for analytics
 */

class WpilTelemetryLogger {
    constructor() {
        this.nonce = wpil_ajax?.nonce || '';
        this.ajaxUrl = wpil_ajax?.ajax_url || '';
        this.isEnabled = wpil_ajax?.telemetry_active || '';
        this.debounceDelay = 100; // Prevent duplicate events
        this.recentEvents = new Set();
    }

    /**
     * Generic event logging method
     * @param {string} eventName - The event name to log
     * @param {object} eventData - Additional data to log with the event
     * @returns {Promise}
     */
    async logEvent(eventName, eventData = {}) {
        if (!this.isEnabled || !eventName || !this.ajaxUrl) {
            return Promise.resolve();
        }

        // Prevent duplicate events in quick succession
        const eventKey = `${eventName}_${JSON.stringify(eventData)}`;
        if (this.recentEvents.has(eventKey)) {
            return Promise.resolve();
        }

        // Add to debounce set
        this.recentEvents.add(eventKey);
        setTimeout(() => {
            this.recentEvents.delete(eventKey);
        }, this.debounceDelay);

        const data = {
            action: 'wpil_log_event',
            event_name: eventName,
            event_data: JSON.stringify(eventData),
            nonce: wpil_ajax.telemetry_nonce
        };

        return new Promise((resolve) => {
            jQuery.post(this.ajaxUrl, data)
                .done(() => {
                    console.log(`LinkWhisper Telemetry: Logged event '${eventName}'`);
                })
                .fail((xhr, status, error) => {
                    console.warn(`LinkWhisper Telemetry: Failed to log event '${eventName}':`, error);
                })
                .always(resolve);
        });
    }

    /**
     * Log notification hub events
     * @param {string} action - The action performed (loaded, notification_impression, notification_clicked)
     * @param {object} extraData - Additional data specific to the action
     */
    logNotificationHubEvent(action, extraData = {}) {
        const eventName = `notification_hub_${action}`;
        return this.logEvent(eventName, {
            timestamp: Math.round(Date.now()/1000),
            ...extraData
        });
    }

    /**
     * Log popup notification events  
     * @param {string} action - The action performed (impression, cta_clicked, dismissed, auto_dismissed)
     * @param {string|number} notificationId - The notification identifier
     * @param {object} extraData - Additional data specific to the action
     */
    logPopupNotificationEvent(action, notificationId = null, extraData = {}) {
        const eventName = `popup_notification_${action}`;
        return this.logEvent(eventName, {
            notification_id: notificationId,
            timestamp: Math.round(Date.now()/1000),
            ...extraData
        });
    }

    /**
     * Log tour events
     * @param {string} action - The action performed (started, step_viewed, completed, etc.)
     * @param {string|number} tourId - The tour identifier
     * @param {string|number} stepId - The step identifier (optional)
     * @param {object} extraData - Additional data specific to the action
     */
    logTourEvent(action, tourId = null, stepId = null, extraData = {}) {
        const eventName = `tour_${action}`;
        return this.logEvent(eventName, {
            tour_id: tourId,
            step_id: stepId,
            timestamp: Math.round(Date.now()/1000),
            ...extraData
        });
    }

    /**
     * Convenience methods for specific notification hub events
     */
    logNotificationHubLoaded(notificationCount = 0, unreadCount = 0) {
        return this.logNotificationHubEvent('loaded', {
            notification_count: notificationCount,
            unread_count: unreadCount
        });
    }

    logNotificationHubNotificationImpression(notificationId, positionInList = null) {
        return this.logNotificationHubEvent('notification_impression', {
            notification_id: notificationId,
            position_in_list: positionInList
        });
    }

    logNotificationHubNotificationClicked(notificationId) {
        return this.logNotificationHubEvent('notification_clicked', {
            notification_id: notificationId
        });
    }

    /**
     * Convenience methods for specific popup notification events
     */
    logPopupNotificationImpression(notificationId, priority = null, displayFrequency = null) {
        return this.logPopupNotificationEvent('impression', notificationId, {
            priority: priority,
            display_frequency: displayFrequency
        });
    }

    logPopupNotificationCtaClicked(notificationId, ctaText = null) {
        return this.logPopupNotificationEvent('cta_clicked', notificationId, {
            cta_text: ctaText
        });
    }

    logPopupNotificationDismissed(notificationId, dismissMethod = 'user_action') {
        return this.logPopupNotificationEvent('dismissed', notificationId, {
            dismiss_method: dismissMethod
        });
    }

    logPopupNotificationAutoDismissed(notificationId, displayDuration = null) {
        return this.logPopupNotificationEvent('auto_dismissed', notificationId, {
            display_duration: displayDuration
        });
    }

    /**
     * Convenience methods for specific tour events
     */
    logTourStarted(tourId, isAutoStart = false) {
        return this.logTourEvent('started', tourId, null, {
            auto_start: isAutoStart
        });
    }

    logTourAutoStarted(tourId) {
        return this.logTourEvent('auto_started', tourId);
    }

    logTourStepViewed(tourId, stepId, stepNumber = null, totalSteps = null) {
        return this.logTourEvent('step_viewed', tourId, stepId, {
            step_number: stepNumber,
            total_steps: totalSteps
        });
    }

    logTourStepCompleted(tourId, stepId, stepNumber = null) {
        return this.logTourEvent('step_completed', tourId, stepId, {
            step_number: stepNumber
        });
    }

    logTourNavigationClicked(tourId, stepId, action = null) {
        return this.logTourEvent('navigation_clicked', tourId, stepId, {
            navigation_action: action // 'next', 'previous', 'done'
        });
    }

    logTourCompleted(tourId, totalSteps = null, timeSpent = null) {
        return this.logTourEvent('completed', tourId, null, {
            total_steps: totalSteps,
            time_spent: timeSpent
        });
    }

    logTourDismissed(tourId, stepId = null, reason = null) {
        return this.logTourEvent('dismissed', tourId, stepId, {
            dismiss_reason: reason
        });
    }

    logTourWidgetExpanded(tourId) {
        return this.logTourEvent('widget_expanded', tourId);
    }

    logTourWidgetMinimized(tourId) {
        return this.logTourEvent('widget_minimized', tourId);
    }

    logTourReset(tourId) {
        return this.logTourEvent('reset', tourId);
    }

    /**
     * Utility method to check if telemetry is enabled
     */
    isLoggingEnabled() {
        return this.isEnabled;
    }
}

// Initialize the global telemetry logger
window.wpilTelemetry = new WpilTelemetryLogger();

// Expose for debugging in development
if (window.wpil_ajax?.debug) {
    console.log('LinkWhisper Telemetry Logger initialized:', window.wpilTelemetry);
}