diff --git a/backend/bots/mainBot.js b/backend/bots/mainBot.js index 7274b1b..7c528d5 100644 --- a/backend/bots/mainBot.js +++ b/backend/bots/mainBot.js @@ -106,13 +106,15 @@ const handleCommand = async (message) => { } } + // Использовать web_app с правильным URL миниаппа + const miniappUrl = 'https://nakama.glpshchn.ru/'; await sendMessage(chatId, startMessage, { reply_markup: { inline_keyboard: [[ { text: '🚀 Открыть Nakama', web_app: { - url: `https://t.me/${botUsername}` + url: miniappUrl } } ]] @@ -153,6 +155,28 @@ const pollUpdates = async () => { isPolling = true; log('info', 'Основной бот запущен, опрос обновлений...'); + // При первом запуске получить все обновления и установить offset на последний, + // чтобы не отвечать на старые команды + const initializeOffset = async () => { + try { + const response = await axios.get(`${TELEGRAM_API}/getUpdates`, { + params: { + timeout: 1, + allowed_updates: ['message'] + } + }); + + const updates = response.data.result || []; + if (updates.length > 0) { + // Установить offset на последний update_id + 1, чтобы пропустить все старые обновления + offset = updates[updates.length - 1].update_id + 1; + log('info', `Пропущено ${updates.length} старых обновлений, offset установлен на ${offset}`); + } + } catch (error) { + log('warn', 'Не удалось инициализировать offset, начнем с 0', { error: error.message }); + } + }; + const poll = async () => { try { const response = await axios.get(`${TELEGRAM_API}/getUpdates`, { @@ -179,7 +203,10 @@ const pollUpdates = async () => { } }; - poll(); + // Сначала инициализировать offset, затем начать опрос + initializeOffset().then(() => { + poll(); + }); }; const startMainBot = () => { diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index f0e1476..0793ccc 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -72,9 +72,21 @@ function AppContent() { // Запустить проверку initData только после успешной загрузки startInitDataChecker() - if (!startParamProcessed.current && tg?.startParam?.startsWith('post_')) { + // Обработка start_param для открытия конкретного поста + // startParam может быть в разных местах в зависимости от способа открытия + const startParam = tg?.startParam || tg?.initDataUnsafe?.start_param || tg?.initDataUnsafe?.startParam + + console.log('[App] Проверка start_param:', { + startParam: tg?.startParam, + initDataUnsafe_start_param: tg?.initDataUnsafe?.start_param, + initDataUnsafe_startParam: tg?.initDataUnsafe?.startParam, + final: startParam + }) + + if (!startParamProcessed.current && startParam?.startsWith('post_')) { startParamProcessed.current = true - const postId = tg.startParam.replace('post_', '') + const postId = startParam.replace('post_', '') + console.log('[App] Открытие поста из start_param:', postId) setTimeout(() => { navigate(`/feed?post=${postId}`, { replace: true }) }, 200) diff --git a/frontend/src/components/PostCard.jsx b/frontend/src/components/PostCard.jsx index 2591659..e93da1f 100644 --- a/frontend/src/components/PostCard.jsx +++ b/frontend/src/components/PostCard.jsx @@ -122,6 +122,7 @@ export default function PostCard({ post, currentUser, onUpdate }) { const botName = import.meta.env.VITE_TELEGRAM_BOT_NAME || 'NakamaSpaceBot' // Создать deeplink для открытия поста в миниапп + // Используем startapp для миниаппов - это правильный формат для передачи параметра в миниапп const deeplink = `https://t.me/${botName}?startapp=post_${post._id}` // Открыть нативное окно "Поделиться" в Telegram @@ -184,29 +185,15 @@ export default function PostCard({ post, currentUser, onUpdate }) { {`Image {images.length > 1 && ( - <> - {currentImageIndex > 0 && ( - - )} - - {currentImageIndex < images.length - 1 && ( - - )} - -
- {images.map((_, index) => ( - { e.stopPropagation(); setCurrentImageIndex(index); }} - /> - ))} -
- +
+ {images.map((_, index) => ( + { e.stopPropagation(); setCurrentImageIndex(index); }} + /> + ))} +
)} {/* Индикатор что можно открыть fullview */}