From 031d24344b408605bda71371ebfd7ec640d57fce Mon Sep 17 00:00:00 2001 From: "dev.daminik00" Date: Thu, 30 Oct 2025 02:43:16 +0100 Subject: [PATCH] add ym data --- src/components/funnel/FunnelRuntime.tsx | 13 +++- src/lib/funnel/unleash/useUnleashAnalytics.ts | 13 ++-- src/services/analytics/metricService.ts | 77 +++++++------------ 3 files changed, 46 insertions(+), 57 deletions(-) diff --git a/src/components/funnel/FunnelRuntime.tsx b/src/components/funnel/FunnelRuntime.tsx index 52b10ae..46bf8fc 100644 --- a/src/components/funnel/FunnelRuntime.tsx +++ b/src/components/funnel/FunnelRuntime.tsx @@ -164,16 +164,17 @@ export function FunnelRuntime({ funnel, initialScreenId }: FunnelRuntimeProps) { ); // ✅ Отправляем данные в userParams (параметры посетителя) - // Используем ту же структуру что и для сессии (через registrationFieldKey) - if (Object.keys(sessionData).length > 0) { - metricService.userParams(sessionData); - } + metricService.sendSessionDataToMetrics(sessionData); // ✅ Отправляем выбор пользователя в params (параметры визита) if (currentScreen.template === "list" && answers[currentScreen.id].length > 0) { metricService.sendVisitContext({ [`answer_${currentScreen.id}`]: answers[currentScreen.id].join(','), + ...sessionData, // Те же данные что и в userParams }); + } else if (Object.keys(sessionData).length > 0) { + // Для не-list экранов (например, date) отправляем только sessionData + metricService.sendVisitContext(sessionData); } // Для date экранов с registrationFieldKey НЕ отправляем answers @@ -289,7 +290,11 @@ export function FunnelRuntime({ funnel, initialScreenId }: FunnelRuntimeProps) { if (currentScreen.template === "list" && ids.length > 0) { metricService.sendVisitContext({ [`answer_${currentScreen.id}`]: ids.join(','), + ...sessionData, // Те же данные что и в userParams }); + } else if (Object.keys(sessionData).length > 0) { + // Для не-list экранов отправляем только sessionData + metricService.sendVisitContext(sessionData); } updateSession({ diff --git a/src/lib/funnel/unleash/useUnleashAnalytics.ts b/src/lib/funnel/unleash/useUnleashAnalytics.ts index 294c071..9ccb67a 100644 --- a/src/lib/funnel/unleash/useUnleashAnalytics.ts +++ b/src/lib/funnel/unleash/useUnleashAnalytics.ts @@ -32,8 +32,8 @@ export function useUnleashAnalytics() { useEffect(() => { console.log("🎯 [Unleash Analytics] Impression listener initialized"); - // Подписываемся на все impression события от Unleash (идентично aura-webapp) - unleashClient.on("impression", (impressionEvent: UnleashImpressionEvent) => { + // Сохраняем ссылку на handler для корректной отписки + const impressionHandler = (impressionEvent: UnleashImpressionEvent) => { console.log("📊 [Unleash Analytics] Impression event received:", { feature: impressionEvent.featureName, variant: impressionEvent.variant, @@ -101,12 +101,15 @@ export function useUnleashAnalytics() { } else { console.log("⏭️ [Unleash Analytics] Impression event skipped - flag not enabled"); } - }); + }; - // Отписываемся при unmount (идентично aura-webapp) + // Подписываемся на все impression события от Unleash + unleashClient.on("impression", impressionHandler); + + // Отписываемся при unmount, передавая ту же ссылку на handler return () => { console.log("🔌 [Unleash Analytics] Impression listener removed"); - unleashClient.off("impression"); + unleashClient.off("impression", impressionHandler); }; }, [unleashClient]); } diff --git a/src/services/analytics/metricService.ts b/src/services/analytics/metricService.ts index 1d601fd..58ff7f3 100644 --- a/src/services/analytics/metricService.ts +++ b/src/services/analytics/metricService.ts @@ -158,62 +158,43 @@ const reachGoal = (goal: string, params?: Record): void => { }; /** - * Извлекает данные для метрики из session data - * Отправляет только релевантные поля: gender, age, partnerGender, partnerAge + * Отправляет данные из sessionData в userParams + * Использует те же данные что собираются через registrationFieldKey + * Дополнительно вычисляет age из birthdate полей */ const sendSessionDataToMetrics = (sessionData: Record): void => { - const metrics: Partial = {}; + if (Object.keys(sessionData).length === 0) return; - // Извлекаем gender (может быть в profile.gender или просто gender) - if (typeof sessionData.gender === 'string') { - metrics.gender = sessionData.gender; - } else if (sessionData.profile && typeof sessionData.profile === 'object') { - const profile = sessionData.profile as Record; - if (typeof profile.gender === 'string') { - metrics.gender = profile.gender; - } - if (typeof profile.partnerGender === 'string') { - metrics.partnerGender = profile.partnerGender; - } - } + const metrics: Record = {}; - // Извлекаем partner gender (может быть в partner.gender или partnerGender) - if (typeof sessionData.partnerGender === 'string') { - metrics.partnerGender = sessionData.partnerGender; - } else if (sessionData.partner && typeof sessionData.partner === 'object') { - const partner = sessionData.partner as Record; - if (typeof partner.gender === 'string') { - metrics.partnerGender = partner.gender; - } - } + // Рекурсивная функция для извлечения всех полей + const extractFields = (obj: Record, prefix = ''): void => { + Object.entries(obj).forEach(([key, value]) => { + const fieldKey = prefix ? `${prefix}.${key}` : key; + + if (value && typeof value === 'object' && !Array.isArray(value)) { + // Рекурсивно обрабатываем вложенные объекты + extractFields(value as Record, fieldKey); + } else if (typeof value === 'string' || typeof value === 'number') { + // Для birthdate полей вычисляем age + if (key === 'birthdate' && typeof value === 'string') { + const age = calculateAge(value); + if (age) { + const ageKey = prefix ? `${prefix.split('.').pop()}Age` : 'age'; + metrics[ageKey] = age; + } + } + // Добавляем все остальные поля как есть + metrics[key] = value; + } + }); + }; - // Вычисляем age из birthdate если есть - if (typeof sessionData.birthdate === 'string') { - const age = calculateAge(sessionData.birthdate); - if (age) metrics.age = age; - } else if (sessionData.profile && typeof sessionData.profile === 'object') { - const profile = sessionData.profile as Record; - if (typeof profile.birthdate === 'string') { - const age = calculateAge(profile.birthdate); - if (age) metrics.age = age; - } - } - - // Вычисляем partner age если есть - if (typeof sessionData.partnerBirthdate === 'string') { - const age = calculateAge(sessionData.partnerBirthdate); - if (age) metrics.partnerAge = age; - } else if (sessionData.partner && typeof sessionData.partner === 'object') { - const partner = sessionData.partner as Record; - if (typeof partner.birthdate === 'string') { - const age = calculateAge(partner.birthdate); - if (age) metrics.partnerAge = age; - } - } + extractFields(sessionData); // Отправляем только если есть данные if (Object.keys(metrics).length > 0) { - userParams(metrics); + userParams(metrics as Partial); } };