add ym data

This commit is contained in:
dev.daminik00 2025-10-30 02:43:16 +01:00
parent fcd3e0da3f
commit 031d24344b
3 changed files with 46 additions and 57 deletions

View File

@ -164,16 +164,17 @@ export function FunnelRuntime({ funnel, initialScreenId }: FunnelRuntimeProps) {
); );
// ✅ Отправляем данные в userParams (параметры посетителя) // ✅ Отправляем данные в userParams (параметры посетителя)
// Используем ту же структуру что и для сессии (через registrationFieldKey) metricService.sendSessionDataToMetrics(sessionData);
if (Object.keys(sessionData).length > 0) {
metricService.userParams(sessionData);
}
// ✅ Отправляем выбор пользователя в params (параметры визита) // ✅ Отправляем выбор пользователя в params (параметры визита)
if (currentScreen.template === "list" && answers[currentScreen.id].length > 0) { if (currentScreen.template === "list" && answers[currentScreen.id].length > 0) {
metricService.sendVisitContext({ metricService.sendVisitContext({
[`answer_${currentScreen.id}`]: answers[currentScreen.id].join(','), [`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 // Для date экранов с registrationFieldKey НЕ отправляем answers
@ -289,7 +290,11 @@ export function FunnelRuntime({ funnel, initialScreenId }: FunnelRuntimeProps) {
if (currentScreen.template === "list" && ids.length > 0) { if (currentScreen.template === "list" && ids.length > 0) {
metricService.sendVisitContext({ metricService.sendVisitContext({
[`answer_${currentScreen.id}`]: ids.join(','), [`answer_${currentScreen.id}`]: ids.join(','),
...sessionData, // Те же данные что и в userParams
}); });
} else if (Object.keys(sessionData).length > 0) {
// Для не-list экранов отправляем только sessionData
metricService.sendVisitContext(sessionData);
} }
updateSession({ updateSession({

View File

@ -32,8 +32,8 @@ export function useUnleashAnalytics() {
useEffect(() => { useEffect(() => {
console.log("🎯 [Unleash Analytics] Impression listener initialized"); console.log("🎯 [Unleash Analytics] Impression listener initialized");
// Подписываемся на все impression события от Unleash (идентично aura-webapp) // Сохраняем ссылку на handler для корректной отписки
unleashClient.on("impression", (impressionEvent: UnleashImpressionEvent) => { const impressionHandler = (impressionEvent: UnleashImpressionEvent) => {
console.log("📊 [Unleash Analytics] Impression event received:", { console.log("📊 [Unleash Analytics] Impression event received:", {
feature: impressionEvent.featureName, feature: impressionEvent.featureName,
variant: impressionEvent.variant, variant: impressionEvent.variant,
@ -101,12 +101,15 @@ export function useUnleashAnalytics() {
} else { } else {
console.log("⏭️ [Unleash Analytics] Impression event skipped - flag not enabled"); console.log("⏭️ [Unleash Analytics] Impression event skipped - flag not enabled");
} }
}); };
// Отписываемся при unmount (идентично aura-webapp) // Подписываемся на все impression события от Unleash
unleashClient.on("impression", impressionHandler);
// Отписываемся при unmount, передавая ту же ссылку на handler
return () => { return () => {
console.log("🔌 [Unleash Analytics] Impression listener removed"); console.log("🔌 [Unleash Analytics] Impression listener removed");
unleashClient.off("impression"); unleashClient.off("impression", impressionHandler);
}; };
}, [unleashClient]); }, [unleashClient]);
} }

View File

@ -158,62 +158,43 @@ const reachGoal = (goal: string, params?: Record<string, unknown>): void => {
}; };
/** /**
* Извлекает данные для метрики из session data * Отправляет данные из sessionData в userParams
* Отправляет только релевантные поля: gender, age, partnerGender, partnerAge * Использует те же данные что собираются через registrationFieldKey
* Дополнительно вычисляет age из birthdate полей
*/ */
const sendSessionDataToMetrics = (sessionData: Record<string, unknown>): void => { const sendSessionDataToMetrics = (sessionData: Record<string, unknown>): void => {
const metrics: Partial<IUserParams> = {}; if (Object.keys(sessionData).length === 0) return;
// Извлекаем gender (может быть в profile.gender или просто gender) const metrics: Record<string, string | number> = {};
if (typeof sessionData.gender === 'string') {
metrics.gender = sessionData.gender;
} else if (sessionData.profile && typeof sessionData.profile === 'object') {
const profile = sessionData.profile as Record<string, unknown>;
if (typeof profile.gender === 'string') {
metrics.gender = profile.gender;
}
if (typeof profile.partnerGender === 'string') {
metrics.partnerGender = profile.partnerGender;
}
}
// Извлекаем partner gender (может быть в partner.gender или partnerGender) // Рекурсивная функция для извлечения всех полей
if (typeof sessionData.partnerGender === 'string') { const extractFields = (obj: Record<string, unknown>, prefix = ''): void => {
metrics.partnerGender = sessionData.partnerGender; Object.entries(obj).forEach(([key, value]) => {
} else if (sessionData.partner && typeof sessionData.partner === 'object') { const fieldKey = prefix ? `${prefix}.${key}` : key;
const partner = sessionData.partner as Record<string, unknown>;
if (typeof partner.gender === 'string') { if (value && typeof value === 'object' && !Array.isArray(value)) {
metrics.partnerGender = partner.gender; // Рекурсивно обрабатываем вложенные объекты
} extractFields(value as Record<string, unknown>, 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 если есть extractFields(sessionData);
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<string, unknown>;
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<string, unknown>;
if (typeof partner.birthdate === 'string') {
const age = calculateAge(partner.birthdate);
if (age) metrics.partnerAge = age;
}
}
// Отправляем только если есть данные // Отправляем только если есть данные
if (Object.keys(metrics).length > 0) { if (Object.keys(metrics).length > 0) {
userParams(metrics); userParams(metrics as Partial<IUserParams>);
} }
}; };