feat: ask about previous mobile email access before showing instructions
This commit is contained in:
+44
-13
@@ -19,6 +19,7 @@ from utils.texts import (
|
|||||||
INSTRUCT_TRUECONF_WITH_AD,
|
INSTRUCT_TRUECONF_WITH_AD,
|
||||||
INSTRUCT_TRUECONF_PENDING_TEXT,
|
INSTRUCT_TRUECONF_PENDING_TEXT,
|
||||||
INSTRUCT_EMAIL_AVAILABLE,
|
INSTRUCT_EMAIL_AVAILABLE,
|
||||||
|
INSTRUCT_EMAIL_HISTORY_ASK,
|
||||||
INSTRUCT_EMAIL_UNAVAILABLE,
|
INSTRUCT_EMAIL_UNAVAILABLE,
|
||||||
INSTRUCT_ERROR_MSG,
|
INSTRUCT_ERROR_MSG,
|
||||||
)
|
)
|
||||||
@@ -446,19 +447,10 @@ async def instruct_router_handler(msg: Message):
|
|||||||
ad_info = get_ad_user_info(user_id)
|
ad_info = get_ad_user_info(user_id)
|
||||||
raw_mail = ad_info.get("raw_mail") if ad_info else None
|
raw_mail = ad_info.get("raw_mail") if ad_info else None
|
||||||
if raw_mail:
|
if raw_mail:
|
||||||
text = INSTRUCT_EMAIL_AVAILABLE(EMOJI_DIGITS, cn, raw_mail)
|
# Пользователь с доступом к почте — спрашиваем про прошлый доступ
|
||||||
# Отправляем текст сообщения
|
set_state(user_id, "INSTRUCT_EMAIL_HISTORY")
|
||||||
|
text = INSTRUCT_EMAIL_HISTORY_ASK(EMOJI_DIGITS, cn)
|
||||||
await msg.answer(text, parse_mode="html")
|
await msg.answer(text, parse_mode="html")
|
||||||
# Затем отправляем оба документа отдельно
|
|
||||||
for instruct_path, file_name in [
|
|
||||||
(GMAIL_ANDROID_INSTRUCT_PATH, "Инструкция Android.docx"),
|
|
||||||
(APPLE_INSTRUCT_PATH, "Инструкция Apple.docx"),
|
|
||||||
]:
|
|
||||||
if os.path.isfile(instruct_path):
|
|
||||||
await msg.bot.send_document(
|
|
||||||
chat_id=msg.chat_id,
|
|
||||||
file=FSInputFile(instruct_path, file_name=file_name),
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
text = INSTRUCT_EMAIL_UNAVAILABLE(EMOJI_DIGITS, cn)
|
text = INSTRUCT_EMAIL_UNAVAILABLE(EMOJI_DIGITS, cn)
|
||||||
await msg.answer(text, parse_mode="html")
|
await msg.answer(text, parse_mode="html")
|
||||||
@@ -489,6 +481,45 @@ async def instruct_router_handler(msg: Message):
|
|||||||
else:
|
else:
|
||||||
await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")
|
await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")
|
||||||
|
|
||||||
|
elif current_state == "INSTRUCT_EMAIL_HISTORY":
|
||||||
|
msg.handled = True
|
||||||
|
if cmd == "0":
|
||||||
|
clear_state(user_id)
|
||||||
|
from utils.menu import MENU_TEXT
|
||||||
|
await msg.answer(MENU_TEXT, parse_mode="html")
|
||||||
|
elif cmd == "9":
|
||||||
|
set_state(user_id, "INSTRUCT_MODE")
|
||||||
|
await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html")
|
||||||
|
elif cmd == "1":
|
||||||
|
# Да, был доступ — показываем инструкции
|
||||||
|
log_menu_stats(user_id, "Инструкции", "Почта (был доступ)")
|
||||||
|
cn = get_user_cn(user_id)
|
||||||
|
if cn is None:
|
||||||
|
cn = user_id
|
||||||
|
set_state(user_id, "INSTRUCT_EMAIL_VIEW")
|
||||||
|
text = INSTRUCT_EMAIL_AVAILABLE(EMOJI_DIGITS, cn, "")
|
||||||
|
await msg.answer(text, parse_mode="html")
|
||||||
|
for instruct_path, file_name in [
|
||||||
|
(GMAIL_ANDROID_INSTRUCT_PATH, "Инструкция Android.docx"),
|
||||||
|
(APPLE_INSTRUCT_PATH, "Инструкция Apple.docx"),
|
||||||
|
]:
|
||||||
|
if os.path.isfile(instruct_path):
|
||||||
|
await msg.bot.send_document(
|
||||||
|
chat_id=msg.chat_id,
|
||||||
|
file=FSInputFile(instruct_path, file_name=file_name),
|
||||||
|
)
|
||||||
|
elif cmd == "2":
|
||||||
|
# Нет, не было доступа — показываем текст про заявку
|
||||||
|
log_menu_stats(user_id, "Инструкции", "Почта (не было доступа)")
|
||||||
|
cn = get_user_cn(user_id)
|
||||||
|
if cn is None:
|
||||||
|
cn = user_id
|
||||||
|
set_state(user_id, "INSTRUCT_EMAIL_VIEW")
|
||||||
|
text = INSTRUCT_EMAIL_UNAVAILABLE(EMOJI_DIGITS, cn)
|
||||||
|
await msg.answer(text, parse_mode="html")
|
||||||
|
else:
|
||||||
|
await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")
|
||||||
|
|
||||||
elif current_state in ["INSTRUCT_TRUECONF_VIEW", "INSTRUCT_EMAIL_VIEW"]:
|
elif current_state in ["INSTRUCT_TRUECONF_VIEW", "INSTRUCT_EMAIL_VIEW"]:
|
||||||
msg.handled = True
|
msg.handled = True
|
||||||
if cmd == "0":
|
if cmd == "0":
|
||||||
@@ -499,4 +530,4 @@ async def instruct_router_handler(msg: Message):
|
|||||||
set_state(user_id, "INSTRUCT_MODE")
|
set_state(user_id, "INSTRUCT_MODE")
|
||||||
await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html")
|
await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html")
|
||||||
else:
|
else:
|
||||||
await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")
|
await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")
|
||||||
|
|||||||
+48
-47
@@ -1,47 +1,48 @@
|
|||||||
# /opt/trueconf_bot/utils/states.py
|
# /opt/trueconf_bot/utils/states.py
|
||||||
import time
|
import time
|
||||||
import config.config as config
|
import config.config as config
|
||||||
|
|
||||||
user_states = {}
|
user_states = {}
|
||||||
tc_bot = None # Общая переменная для экземпляра бота
|
tc_bot = None # Общая переменная для экземпляра бота
|
||||||
|
|
||||||
# --- Константы состояний ---
|
# --- Константы состояний ---
|
||||||
PHOTO_MODE = "PHOTO_MODE"
|
PHOTO_MODE = "PHOTO_MODE"
|
||||||
SD_MODE = "SD_MODE"
|
SD_MODE = "SD_MODE"
|
||||||
TRANSCRIPTION_MODE = "TRANSCRIPTION_MODE"
|
TRANSCRIPTION_MODE = "TRANSCRIPTION_MODE"
|
||||||
SEARCH_MODE = "SEARCH_MODE"
|
SEARCH_MODE = "SEARCH_MODE"
|
||||||
|
INSTRUCT_EMAIL_HISTORY = "INSTRUCT_EMAIL_HISTORY"
|
||||||
def set_state(user_id, state):
|
|
||||||
"""Фиксирует новое состояние пользователя и обновляет метку времени активности"""
|
def set_state(user_id, state):
|
||||||
user_states[user_id] = {
|
"""Фиксирует новое состояние пользователя и обновляет метку времени активности"""
|
||||||
"state": state,
|
user_states[user_id] = {
|
||||||
"last_active": time.time()
|
"state": state,
|
||||||
}
|
"last_active": time.time()
|
||||||
|
}
|
||||||
def get_state(user_id):
|
|
||||||
"""
|
def get_state(user_id):
|
||||||
Возвращает текущее состояние пользователя.
|
"""
|
||||||
Если время неактивности превысило лимит из config.py, сессия сбрасывается.
|
Возвращает текущее состояние пользователя.
|
||||||
"""
|
Если время неактивности превысило лимит из config.py, сессия сбрасывается.
|
||||||
if user_id in user_states:
|
"""
|
||||||
session = user_states[user_id]
|
if user_id in user_states:
|
||||||
|
session = user_states[user_id]
|
||||||
# Динамически забираем значение таймаута из конфига (дефолт — 1800 сек / 30 мин)
|
|
||||||
session_timeout = getattr(config, 'SESSION_TIMEOUT', 1800)
|
# Динамически забираем значение таймаута из конфига (дефолт — 1800 сек / 30 мин)
|
||||||
|
session_timeout = getattr(config, 'SESSION_TIMEOUT', 1800)
|
||||||
# Проверяем, сколько секунд прошло с момента последнего сообщения
|
|
||||||
if time.time() - session["last_active"] > session_timeout:
|
# Проверяем, сколько секунд прошло с момента последнего сообщения
|
||||||
# Время вышло! Аппаратно сносим сессию навигации
|
if time.time() - session["last_active"] > session_timeout:
|
||||||
del user_states[user_id]
|
# Время вышло! Аппаратно сносим сессию навигации
|
||||||
return None
|
del user_states[user_id]
|
||||||
|
return None
|
||||||
# Если время не вышло, обновляем таймер (пользователь проявил активность)
|
|
||||||
session["last_active"] = time.time()
|
# Если время не вышло, обновляем таймер (пользователь проявил активность)
|
||||||
return session["state"]
|
session["last_active"] = time.time()
|
||||||
|
return session["state"]
|
||||||
return None
|
|
||||||
|
return None
|
||||||
def clear_state(user_id):
|
|
||||||
"""Принудительно очищает состояние пользователя (выход в корень)"""
|
def clear_state(user_id):
|
||||||
if user_id in user_states:
|
"""Принудительно очищает состояние пользователя (выход в корень)"""
|
||||||
del user_states[user_id]
|
if user_id in user_states:
|
||||||
|
del user_states[user_id]
|
||||||
|
|||||||
+11
-1
@@ -633,6 +633,15 @@ def _instruct_email_available(emojis: dict, cn: str, mail: str) -> str:
|
|||||||
f"<i>{emojis['9']} — Назад\n{emojis['0']} — В главное меню</i>"
|
f"<i>{emojis['9']} — Назад\n{emojis['0']} — В главное меню</i>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _instruct_email_history_ask(emojis: dict, cn: str) -> str:
|
||||||
|
"""Вопрос о наличии ранее доступа к мобильной почте."""
|
||||||
|
return (
|
||||||
|
f"📧 <b>Был ли у Вас ранее доступ к мобильной почте?</b>\n\n"
|
||||||
|
f"Нажмите {emojis['1']} — да, был / {emojis['2']} — нет, не было\n\n"
|
||||||
|
f"<i>{emojis['0']} — В главное меню</i>"
|
||||||
|
)
|
||||||
|
|
||||||
def _instruct_email_unavailable(emojis: dict, cn: str) -> str:
|
def _instruct_email_unavailable(emojis: dict, cn: str) -> str:
|
||||||
"""Текст когда почта недоступна."""
|
"""Текст когда почта недоступна."""
|
||||||
return (
|
return (
|
||||||
@@ -649,7 +658,8 @@ INSTRUCT_TRUECONF_WITH_AD = _instruct_trueconf_with_ad
|
|||||||
INSTRUCT_TRUECONF_PENDING_TEXT = _instruct_trueconf_pending
|
INSTRUCT_TRUECONF_PENDING_TEXT = _instruct_trueconf_pending
|
||||||
INSTRUCT_TRUECONF_NO_TICKET_TEXT = _instruct_trueconf_no_ticket
|
INSTRUCT_TRUECONF_NO_TICKET_TEXT = _instruct_trueconf_no_ticket
|
||||||
INSTRUCT_EMAIL_AVAILABLE = _instruct_email_available
|
INSTRUCT_EMAIL_AVAILABLE = _instruct_email_available
|
||||||
|
INSTRUCT_EMAIL_HISTORY_ASK = _instruct_email_history_ask
|
||||||
INSTRUCT_EMAIL_UNAVAILABLE = _instruct_email_unavailable
|
INSTRUCT_EMAIL_UNAVAILABLE = _instruct_email_unavailable
|
||||||
|
|
||||||
# Единая стандартная заглушка системной ошибки для модуля инструкций
|
# Единая стандартная заглушка системной ошибки для модуля инструкций
|
||||||
INSTRUCT_ERROR_MSG = system_error_text(EMOJI_DIGITS, show_back=True)
|
INSTRUCT_ERROR_MSG = system_error_text(EMOJI_DIGITS, show_back=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user