src/hooks/analytics/initialize.js

/**
 * Start Third Party Tools
 * Fragmented initilization logic for third party analytical tools
 */

import {hotjar} from "react-hotjar";
import {constants} from "utils";
import {enabledToolsHash} from "./tools";

const {
  ANALYTICS: {
    APPSFLYER,
    FACEBOOK_PIXEL,
    GOOGLE_ANALYTICS,
    GOOGLE_TAG_MANAGER,
    HOTJAR,
    SEGMENT,
    SMARTLOOK,
  },
} = constants;

const {DEBUG_TOOLS} = process.env;

// Retry initilizing failed tools for a maximum of 60 seconds
const timeoutSeconds = 60;

// Dispatch the Lunchbox Tools Initialized Window Event
const startLbxTools = () => {
  const event = new Event("lbxInit");
  window.dispatchEvent(event);
};

/**
 * @todo When webpack v5 is merged in, we can use AVAILABLE_ENVS as constants.
 * @todo Consolidate console logs into logger fn with optional condition to make code easier to read.
 */

const toolInitializers = (retryTools) => {
  const appsFlyerInit = typeof window !== "undefined" && !!window.AF;
  const facebookInit = typeof window !== "undefined" && !!window.fbq;
  const hotjarInit = typeof window !== "undefined" && !!window.hotjar;
  const segmentInit = typeof window !== "undefined" && !!window.analytics;

  const toolsToCheck = retryTools ?? Object.keys(enabledToolsHash);

  return (
    toolsToCheck.reduce((accu, tool) => {
      const apiKey = enabledToolsHash[tool];

      switch (tool) {
        case APPSFLYER:
          if (!appsFlyerInit) return [...accu, tool];

          if (DEBUG_TOOLS) {
            console.log(
              "[lbx-tools]",
              "AppsFlyer was successfully initialized.",
            );
          }
          break;
        case FACEBOOK_PIXEL:
          if (!facebookInit) return [...accu, tool];

          window.fbq("init", apiKey);
          window.fbq("track", "PageView");
          if (DEBUG_TOOLS) {
            console.log(
              "[lbx-tools]",
              "Facebook pixel was successfully initialized.",
            );
          }
          break;
        case GOOGLE_ANALYTICS:
        case GOOGLE_TAG_MANAGER:
          if (!window.dataLayer) return [...accu, tool];

          if (DEBUG_TOOLS) {
            console.info(
              "[lbx-tools]",
              "Google tag manager was successfully initialized.",
            );
          }
          break;
        case HOTJAR:
          if (!hotjarInit) return [...accu, tool];

          hotjar.initialize(apiKey, 6);
          if (DEBUG_TOOLS) {
            console.info("[lbx-tools]", "Hotjar was successfully initialized.");
          }
          break;
        case SEGMENT:
          if (!segmentInit) return [...accu, tool];

          window.analytics.load(apiKey);
          window.analytics.page();
          if (DEBUG_TOOLS) {
            console.info(
              "[lbx-tools]",
              "Segment.io was successfully initialized.",
            );
          }
          break;
        case SMARTLOOK:
        default:
      }

      return accu;
    }, []) || []
  );
};

// Start each tool respectively, some tools may require additional logic
const initialize = (failedTools = null, counter = 0) => {
  if (counter > timeoutSeconds) {
    if (failedTools?.length > 0) {
      console.error("[lbx-tools]", failedTools, "failed to initialize");
    }

    // Start the Local Lunchbox Tools Event Queue
    // for tools that did not fail...
    startLbxTools();

    return;
  }

  // Successful completed initialization
  if (failedTools?.length === 0 && counter > 0) {
    // Start the Local Lunchbox Tools Event Queue
    startLbxTools();

    return;
  }

  // Retry initilizing failed tools every 1000ms (1s)
  setTimeout(() => {
    initialize(toolInitializers(failedTools), counter + 1);
  }, 1000);
};

export default initialize;