diff --git a/bot/main.py b/bot/main.py
index bc62a4e..fe0fddf 100644
--- a/bot/main.py
+++ b/bot/main.py
@@ -32,15 +32,24 @@ def main_keyboard() -> ReplyKeyboardMarkup:
)
+def webapp_inline_keyboard() -> InlineKeyboardMarkup:
+ return InlineKeyboardMarkup(
+ inline_keyboard=[
+ [InlineKeyboardButton(text="Открыть CarPass", web_app=WebAppInfo(url=settings.effective_webapp_url))],
+ ]
+ )
+
+
@dp.message(Command("start"))
async def start(message: Message) -> None:
user = await api.upsert_user(message.from_user)
text = (
f"Готово, {user.get('first_name') or 'водитель'}.\n\n"
- "Здесь можно вести заправки, обслуживание, ремонты и смотреть стоимость владения. "
- "Основная работа идет в mini app, а бот остается быстрым входом."
+ "CarPass — цифровой паспорт автомобиля: заправки, обслуживание, напоминания, подтвержденная история и стоимость владения.\n\n"
+ "Нажми «Открыть CarPass», чтобы перейти в приложение."
)
- await message.answer(text, reply_markup=main_keyboard())
+ await message.answer(text, reply_markup=webapp_inline_keyboard())
+ await message.answer("Быстрый вход также закреплен на клавиатуре ниже.", reply_markup=main_keyboard())
@dp.message(Command("add_car"))
diff --git a/web/index.html b/web/index.html
index 1197543..45fb100 100644
--- a/web/index.html
+++ b/web/index.html
@@ -14,11 +14,15 @@
-
Drivers
-
Гараж
-
Это приложение открывается через Telegram-бота. Откройте Mini App из Telegram.
+
CarPass
+
Цифровой паспорт авто
+
Откройте приложение через Telegram-бота, чтобы безопасно привязать гараж к вашему аккаунту.
+
-
Открыть бота
+
Если Telegram уже открыт, нажмите «Открыть гараж» в боте.
diff --git a/web/static/app.js b/web/static/app.js
index 595a862..65320ad 100644
--- a/web/static/app.js
+++ b/web/static/app.js
@@ -513,7 +513,7 @@ async function ensureUser() {
hideAuthOverlay();
return;
}
- showTelegramOpenHint();
+ await showTelegramLogin();
throw new Error("Требуется вход через Telegram");
}
@@ -527,18 +527,27 @@ function showTelegramOpenHint() {
const slot = document.querySelector("#telegramLoginSlot");
const link = document.querySelector("#telegramLoginLink");
const message = document.querySelector("#authMessage");
+ const note = document.querySelector("#authNote");
overlay?.classList.remove("hidden");
document.body.classList.add("auth-required");
const botUsername = state.authConfig?.bot_username;
if (message) {
- message.textContent = "Это приложение открывается через Telegram-бота. Откройте Mini App из Telegram.";
+ message.textContent = botUsername
+ ? "Откройте CarPass через Telegram. Бот привяжет гараж к вашему аккаунту и покажет кнопку Mini App."
+ : "Это приложение открывается через Telegram-бота. Настройте BOT_USERNAME на сервере.";
+ }
+ if (slot && !slot.dataset.ready) slot.textContent = "";
+ if (note) {
+ note.textContent = isMobileBrowser()
+ ? "После перехода в Telegram нажмите в боте кнопку «Открыть гараж»."
+ : "На компьютере можно войти кнопкой Telegram ниже или открыть бота.";
}
- if (slot) slot.textContent = "";
if (!botUsername) {
return;
}
if (link) {
- link.href = `https://t.me/${botUsername}`;
+ link.href = telegramBotUrl(botUsername);
+ link.target = isMobileBrowser() ? "_self" : "_blank";
link.classList.remove("hidden");
}
}
@@ -549,6 +558,11 @@ async function showTelegramLogin() {
if (!slot || slot.dataset.ready) return;
const botUsername = state.authConfig?.bot_username;
if (!botUsername) return;
+ if (isMobileBrowser()) {
+ slot.innerHTML = `В мобильном браузере авторизация проходит через Telegram-бота.`;
+ slot.dataset.ready = "true";
+ return;
+ }
window.onTelegramAuth = async (user) => {
state.user = await api("/users/telegram-login", {
method: "POST",
@@ -573,6 +587,14 @@ async function showTelegramLogin() {
slot.appendChild(script);
}
+function isMobileBrowser() {
+ return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);
+}
+
+function telegramBotUrl(botUsername) {
+ return `https://t.me/${botUsername}?start=garage`;
+}
+
async function savePushSubscription(subscription) {
if (!state.user || !subscription) return;
await api(`/users/${state.user.id}/push-subscriptions`, {
@@ -750,7 +772,7 @@ function renderCars() {
(car) => `