w-aura/src/services/metric/metricService.ts
2025-08-19 20:56:55 +00:00

327 lines
9.1 KiB
TypeScript

import { getSourceByPathname } from "@/utils/source.utils";
import Clarity from "@microsoft/clarity";
import { useExperiments } from "yandex-metrica-ab-react";
export enum EGoals {
// ENTERED_EMAIL = "EnteredEmail",
// LEAD = "Lead",
// PURCHASE = "Purchase",
// PAYMENT_SUCCESS = "PaymentSuccess",
// ROSE_VIDEO_CREATION_START = 'RoseVideoCreationStart',
// ROSE_LOADING_START = "RoseLoadingStart",
// ROSE_VIDEO_CREATED = "RoseVideoCreated",
// ROSE_LOADING_END = "RoseLoadingEnd",
// ROSE_VIDEO_PLAY_START = "RoseVideoPlayStart",
// ROSE_VIDEO_PLAY_END = "RoseVideoPlayEnd",
// ROSE_VIDEO_PLAY_USER_STOP = "RoseVideoPlayUserStop",
// ROSE_VIDEO_PLAY_USER_PLAY = "RoseVideoPlayUserPlay",
// AURA_PAYMENT_METHODS_OPENED = "AuraPaymentMethodsOpened",
// AURA_SELECT_TRIAL = "AuraSelectTrial",
// AURA_TRIAL_CHOICE_PAGE_VISIT = "AuraTrialChoicePageVisit",
// AURA_TRIAL_PAYMENT_PAGE_VISIT = "AuraTrialPaymentPageVisit",
PAYMENT_SUCCESS_PALMISTRY = "PaymentSuccessPalmistry",
ENTERED_EMAIL_PALMISTRY = "EnteredEmailPalmistry",
// new
CAMERA_OPEN = "CameraOpen",
CAMERA_ERROR = "CameraError",
CAMERA_SUCCESS = "CameraSuccess",
ENTERED_EMAIL = "EnteredEmail",
TRIAL_CHOICE_PAGE_VISIT = "TrialChoicePageVisit",
SELECT_TRIAL = "SelectTrial",
TRIAL_PAYMENT_PAGE_VISIT = "TrialPaymentPageVisit",
PAYMENT_METHODS_OPENED = "PaymentMethodsOpened",
PAYMENT_SUCCESS = "PaymentSuccess",
PAYMENT_ERROR = "PaymentError",
SKIP_TRIAL_SELECT = "SkipTrialSelect",
SKIP_TRIAL_NOT_SELECT = "SkipTrialNotSelect",
SKIP_TRIAL_SUCCESS = "SkipTrialSuccess",
SKIP_TRIAL_ERROR = "SkipTrialError",
PDF_COMP_OPEN = "PDFCompOpen",
PDF_PALM_OPEN = "PDFPalmOpen",
DISCOUNT_PAGE_VISIT = "DiscountPageVisit",
AURA_SELECT_TRIAL = "AuraSelectTrial",
AURA_PAYMENT_METHODS_OPENED = "AuraPaymentMethodsOpened",
AURA_TRIAL_CHOICE_PAGE_VISIT = "AuraTrialChoicePageVisit",
AURA_TRIAL_PAYMENT_PAGE_VISIT = "AuraTrialPaymentPageVisit",
ROSE_VIDEO_CREATION_START = "RoseVideoCreationStart",
ROSE_LOADING_START = "RoseLoadingStart",
ROSE_VIDEO_CREATED = "RoseVideoCreated",
ROSE_LOADING_END = "RoseLoadingEnd",
ROSE_VIDEO_PLAY_START = "RoseVideoPlayStart",
ROSE_VIDEO_PLAY_END = "RoseVideoPlayEnd",
ROSE_VIDEO_PLAY_USER_STOP = "RoseVideoPlayUserStop",
ROSE_VIDEO_PLAY_USER_PLAY = "RoseVideoPlayUserPlay",
DOWNLOAD_APP = "DownloadApp",
BLACK_BUTTON = "BlackButton",
CAMERA_HAND = "CameraHand",
SCAN_ARTIFICIAL_PHOTO = "ScanArtificialPhoto",
CAMERA_ANDROID_INSTAGRAM = "CameraAndroidInstagram",
// FB
LEAD = "Lead",
PURCHASE = "Purchase",
// Split
SPLIT_CHOOSE_GENDER = "SplitChooseGender",
// Unleash
UNLEASH_CHOOSE_GENDER = "UnleashChooseGender",
STAYED_IN_FB = "StayedInFb",
STAYED_IN_INSTAGRAM = "StayedInInstagram",
}
export enum EFlags {
isNextPageMentioned = "Go to page mentionedIn",
aboutUsAnswers = "Key for aboutUsAnswers",
}
export enum EMetrics {
YANDEX = "Yandex",
KLAVIYO = "Klaviyo",
FACEBOOK = "Facebook",
GOOGLE_ANALYTICS = "GoogleAnalytics",
}
interface IUserParams {
UserID: number | string;
sessionId: string;
genderFrom: string;
email: string;
hasPersonalVideo: boolean;
gender: string;
age: number;
isStripe: boolean;
}
const environments = import.meta.env;
const metricCounterNumber = Number(environments.AURA_YANDEX_COUNTER_NUMBER);
const gaMeasurementId = environments.AURA_GA_MEASUREMENT_ID;
const checkIsAvailableYandexMetric = () => {
const isProduction = environments.MODE === "production";
if (!isProduction) {
console.log("ANALYTIC IS NOT WORKING: Not production");
return false;
}
if (typeof window.ym !== "function") {
console.error("Yandex.Metric not found");
return false;
}
return true;
};
const checkIsAvailableYandexMetricAB = () => {
const isProduction = environments.MODE === "production";
if (!isProduction) {
console.log("ANALYTIC IS NOT WORKING: Not production");
return false;
}
if (typeof window.ymab !== "function") {
console.error("Yandex.Metric not found");
return false;
}
return true;
};
const checkIsAvailableGoogleAnalytics = () => {
// const isProduction = environments.MODE === "production";
// if (!isProduction) {
// console.log("ANALYTIC IS NOT WORKING: Not production")
// return false;
// };
if (typeof window.gtag !== "function") {
console.error("Google Analytics not found");
return false;
}
return true;
};
const setUserID = (userId: string) => {
if (checkIsAvailableYandexMetric()) {
window.ym(metricCounterNumber, "setUserID", userId);
Clarity.identify(userId);
}
// Google Analytics
if (checkIsAvailableGoogleAnalytics()) {
// window.gtag('set', 'user_properties', {
// user_id: userId
// });
window.gtag("config", gaMeasurementId, {
user_id: userId,
});
}
if (!window.klaviyo) return console.error("Klaviyo.Metric not found");
window.klaviyo.push(["identify", userId]);
};
const userParams = (parameters: Partial<IUserParams>) => {
if (checkIsAvailableYandexMetric()) {
window.ym(metricCounterNumber, "userParams", parameters);
}
Object.entries(parameters).forEach(([key, value]) => {
Clarity.setTag(key, String(value));
});
// Google Analytics
if (checkIsAvailableGoogleAnalytics()) {
// const gaUserProperties = Object.entries(parameters).reduce((acc, [key, value]) => ({
// ...acc,
// [key.toLowerCase()]: value
// }), {});
// window.gtag('set', 'user_properties', gaUserProperties);
window.gtag("config", gaMeasurementId, {
send_page_view: false,
...parameters,
});
}
if (!window.klaviyo) return console.error("Klaviyo.Metric not found");
window.klaviyo.push(["identify", parameters]);
};
const reachGoal = (
goal: EGoals,
usingMetrics: EMetrics[],
options?: unknown
) => {
console.log("goal: ", goal);
const isProduction = environments.MODE === "production";
const source = getSourceByPathname();
// if (!isProduction) return console.log("ANALYTIC IS NOT WORKING: Not production");
if (usingMetrics.includes(EMetrics.YANDEX)) {
if (typeof window.ym !== "function") {
console.error("Yandex.Metric not found");
} else if (isProduction) {
window.ym(metricCounterNumber, "reachGoal", goal);
Clarity.event(goal);
console.log("goalYM&Clarity: ", goal);
}
if (!checkIsAvailableGoogleAnalytics()) {
console.error("Google Analytics not found");
} else {
const eventName = goal === EGoals.PAYMENT_SUCCESS ? "purchase" : goal;
window.gtag("event", eventName, {
source,
...(options as Record<string, unknown>),
});
console.log("goalGA: ", goal);
}
}
if (!isProduction)
return console.log("ANALYTIC IS NOT WORKING: Not production");
// if (usingMetrics.includes(EMetrics.GOOGLE_ANALYTICS)) {
// if (typeof window.gtag !== "function") {
// console.error("Google Analytics not found")
// } else {
// window.gtag('event', goal, options);
// console.log("goalGA: ", goal);
// }
// }
if (usingMetrics.includes(EMetrics.KLAVIYO)) {
if (!window.klaviyo) {
console.error("Klaviyo.Metric not found");
} else {
window.klaviyo.push(["track", goal]);
console.log("goalKLAVIYO: ", goal);
}
}
if (usingMetrics.includes(EMetrics.FACEBOOK)) {
if (typeof window.fbq !== "function") {
console.error("Facebook.Metric not found");
} else {
window.fbq(
"track",
goal === EGoals.ENTERED_EMAIL ? EGoals.LEAD : goal,
options
);
console.log("goalFB: ", goal);
}
}
};
type THitOptions = {
callback: () => void;
ctx: object;
params: {
order_price: number;
currency: string;
};
referer: string;
title: string;
};
const hit = (url?: string, options?: THitOptions) => {
if (!checkIsAvailableYandexMetric()) return;
window.ym(metricCounterNumber, "hit", url, options);
};
const initMetric = () => {
if (!checkIsAvailableYandexMetric()) return;
window.ym(metricCounterNumber, "init", {
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
webvisor: true,
});
console.log("Metric initialized");
};
const initMetricAB = () => {
if (!checkIsAvailableYandexMetricAB()) return;
window.ymab(`metrika.${metricCounterNumber}`, "setConfig", {
enableJS: true,
enableWatch: true,
});
window.ymab(
`metrika.${metricCounterNumber}`,
"init" /*, {clientFeatures}, {callback}*/
);
console.log("Metric initialized");
};
type TABFlags = {
showTimerTrial: "show" | "hide";
text: "1" | "2" | "3";
auraVideoTrial: "on";
auraPalmistry: "on";
esFlag: "hiCopy" | "standard";
palmOnPayment: "graphical" | "real";
genderPageType: "v0" | "v1" | "v2";
trialChoicePageType: "v1" | "v2";
welcomePageImage: "v1" | "v2";
cameraRequestModal: "with" | "without";
yourReading: "v1" | "v2";
genderButtonIcon: "show" | "hide";
tryApp: "v0" | "v1";
};
export const useMetricABFlags = () => {
return useExperiments<typeof EFlags & TABFlags>({
clientId: `metrika.${metricCounterNumber}`,
});
};
export default {
setUserID,
userParams,
reachGoal,
hit,
initMetric,
initMetricAB,
};