diff --git a/index.html b/index.html index cb404c7..fa4d437 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,12 @@ Sticker Generator +
diff --git a/src/App.tsx b/src/App.tsx index bb83775..043fc06 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,6 +3,7 @@ import { BrowserRouter, Routes, Route, Navigate, Outlet, useNavigate, useLocatio import Layout from './components/layout/Layout'; import Home from './screens/Home'; import { initializeUserId } from './constants/user'; +import { trackScreenView } from './services/analyticsService'; // Ленивая загрузка компонентов const OnboardingWelcome = lazy(() => import('./screens/onboarding/OnboardingWelcome')); @@ -64,6 +65,38 @@ const AppContent: React.FC = () => { } }, [navigate, location.pathname]); + // Отслеживаем изменение маршрута для аналитики + useEffect(() => { + // Получаем название экрана из пути + let screenName = location.pathname; + if (screenName === '/') { + screenName = 'Главная'; + } else { + // Преобразуем путь в более читаемое название + screenName = screenName + .replace('/onboarding/welcome', 'Онбординг: Приветствие') + .replace('/onboarding/how-to', 'Онбординг: Как использовать') + .replace('/onboarding/sticker-packs', 'Онбординг: Стикер-паки') + .replace('/onboarding/terms', 'Условия использования') + .replace('/create', 'Создание стикера') + .replace('/gallery', 'Галерея') + .replace('/packs', 'Стикер-паки') + .replace('/create-sticker-pack', 'Создание стикер-пака') + .replace('/profile', 'Профиль') + .replace('/history', 'История') + .replace('/crop-photo', 'Обрезка фото'); + + // Если это добавление стикера в пак, извлекаем название пака + if (screenName.includes('/add-sticker/')) { + const packName = screenName.split('/add-sticker/')[1]; + screenName = `Добавление стикера в пак: ${packName}`; + } + } + + // Отправляем событие просмотра экрана + trackScreenView(screenName); + }, [location.pathname]); + return ( {/* Онбординг */} diff --git a/src/services/analyticsService.ts b/src/services/analyticsService.ts new file mode 100644 index 0000000..e36c889 --- /dev/null +++ b/src/services/analyticsService.ts @@ -0,0 +1,105 @@ +/** + * Сервис для работы с аналитикой Graspil + */ + +/** + * Отслеживает пользовательское событие + * @param eventName - Название события + * @param category - Категория события (опционально) + * @param valueNum - Числовое значение (опционально) + * @param unit - Код валюты, максимальная длина 3 символа (опционально, обязательно если указан valueNum) + */ +export const trackEvent = ( + eventName: string, + category?: string, + valueNum?: number, + unit?: string +): void => { + if (typeof window !== 'undefined' && window.graspil) { + const eventData: { + event: string; + category?: string; + value_num?: number; + unit?: string; + } = { + event: eventName, + }; + + if (category) { + eventData.category = category; + } + + if (valueNum !== undefined) { + eventData.value_num = valueNum; + + // Если есть числовое значение, но нет единицы измерения, используем 'unit' по умолчанию + if (unit) { + eventData.unit = unit; + } + } + + window.graspil.push(eventData); + } +}; + +/** + * Отслеживает просмотр экрана + * @param screenName - Название экрана + */ +export const trackScreenView = (screenName: string): void => { + trackEvent(`Просмотр экрана: ${screenName}`, 'navigation'); +}; + +/** + * Отслеживает клик по кнопке + * @param buttonName - Название кнопки + */ +export const trackButtonClick = (buttonName: string): void => { + trackEvent(`Клик: ${buttonName}`, 'interaction'); +}; + +/** + * Отслеживает генерацию стикера + * @param prompt - Промпт для генерации + */ +export const trackStickerGeneration = (prompt: string): void => { + // Создаем объект события с дополнительными данными + const eventData: { + event: string; + category: string; + value_num: number; + prompt?: string; + } = { + event: 'Генерация стикера', + category: 'generation', + value_num: 1 + }; + + // Добавляем промпт в данные события, если он предоставлен + if (prompt) { + eventData.prompt = prompt; + } + + // Отправляем событие напрямую, чтобы включить дополнительные данные + if (typeof window !== 'undefined' && window.graspil) { + window.graspil.push(eventData); + } +}; + +/** + * Отслеживает создание стикер-пака + * @param packName - Название пака + */ +export const trackStickerPackCreation = (packName: string): void => { + trackEvent('Создание стикер-пака', 'creation', 1); +}; + +/** + * Отслеживает покупку токенов + * @param amount - Количество токенов + * @param price - Цена в валюте + * @param currency - Код валюты (максимум 3 символа) + */ +export const trackTokenPurchase = (amount: number, price: number, currency: string): void => { + trackEvent('Покупка токенов', 'purchase', price, currency); +}; diff --git a/src/services/api.ts b/src/services/api.ts index 3c6ae8b..ab978e9 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -3,6 +3,7 @@ import { baseWorkflow } from '../constants/baseWorkflow'; import { prompts } from '../assets/prompts'; import translateService from './translateService'; import { getCurrentUserId, isTelegramWebAppAvailable } from '../constants/user'; +import { trackStickerGeneration } from './analyticsService'; const API_BASE_URL = 'https://stickerserver.gymnasticstuff.uk'; @@ -276,6 +277,9 @@ const apiService = { const result = await response.json() as GenerationResponse; + // Отслеживаем событие генерации стикера + trackStickerGeneration(usedPrompt); + // Возвращаем результат и использованный промпт return { result, diff --git a/src/services/stickerService.ts b/src/services/stickerService.ts index d9a883f..d68a6db 100644 --- a/src/services/stickerService.ts +++ b/src/services/stickerService.ts @@ -1,6 +1,7 @@ import { getCurrentUserId } from '../constants/user'; import { StickerPack, StickerSetResponse } from '../types/api'; import { normalizeImageUrl } from './api'; +import { trackStickerPackCreation } from './analyticsService'; /** * Сервис для работы со стикерпаками через Sticker API. @@ -125,6 +126,9 @@ export class StickerService { } } + // Отслеживаем событие создания стикер-пака + trackStickerPackCreation(title); + return createResult; } catch (error) { console.error('Ошибка при создании стикерпака:', error); diff --git a/src/types/global.d.ts b/src/types/global.d.ts new file mode 100644 index 0000000..a8f0099 --- /dev/null +++ b/src/types/global.d.ts @@ -0,0 +1,15 @@ +interface GraspilEvent { + event: string; + category?: string; + value_num?: number; + unit?: string; + key?: string; +} + +interface GraspilInstance extends Array { + push: (event: GraspilEvent) => void; +} + +interface Window { + graspil: GraspilInstance; +}