обавлена интеграция с аналитическим сервисом Graspil
This commit is contained in:
parent
a366be55c7
commit
c3e6a6b05d
@ -9,6 +9,12 @@
|
||||
<meta name="description" content="Создавайте уникальные стикеры для Telegram" />
|
||||
<title>Sticker Generator</title>
|
||||
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
||||
<script type="text/javascript">
|
||||
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({key:i});
|
||||
var f=d.getElementsByTagName(s)[0],j=d.createElement(s);
|
||||
j.async=true;j.src="https://w.graspil.com";f.parentNode.insertBefore(j,f);
|
||||
})(window,document,"script","graspil","3bb78a396b0aa436843d606d02abfe4c");
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
33
src/App.tsx
33
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 (
|
||||
<Routes>
|
||||
{/* Онбординг */}
|
||||
|
||||
105
src/services/analyticsService.ts
Normal file
105
src/services/analyticsService.ts
Normal file
@ -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);
|
||||
};
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
15
src/types/global.d.ts
vendored
Normal file
15
src/types/global.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
interface GraspilEvent {
|
||||
event: string;
|
||||
category?: string;
|
||||
value_num?: number;
|
||||
unit?: string;
|
||||
key?: string;
|
||||
}
|
||||
|
||||
interface GraspilInstance extends Array<GraspilEvent> {
|
||||
push: (event: GraspilEvent) => void;
|
||||
}
|
||||
|
||||
interface Window {
|
||||
graspil: GraspilInstance;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user