mirror of
https://github.com/olegvodyanov/docbot.git
synced 2025-12-19 23:57:05 +03:00
update register logic
This commit is contained in:
parent
44d04256a2
commit
4492c03590
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,4 +6,4 @@ alembic.ini
|
||||
alembic/
|
||||
db/
|
||||
__pycache__
|
||||
conversations.pkl
|
||||
src/docbot/conversations.pkl
|
||||
11
src/core/enums/dialog_helpers.py
Normal file
11
src/core/enums/dialog_helpers.py
Normal file
@ -0,0 +1,11 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class ConfirmationMessage(str, Enum):
|
||||
PROCEED = "Продолжаем 😊"
|
||||
DECLINE = "Отмена 😔"
|
||||
|
||||
|
||||
class Acknowledgement(str, Enum):
|
||||
OK = "Понятно 😊"
|
||||
DECLINE = "Отмена 😔"
|
||||
Binary file not shown.
@ -10,15 +10,45 @@ from telegram.ext import (
|
||||
from docbot.handlers.utils.cancel_handler import get_cancel_handler
|
||||
from docbot.services.referral_service import validate_referral_code, mark_referral_code_as_used
|
||||
from core.enums.consultation_types import Consultation
|
||||
from core.enums.dialog_helpers import ConfirmationMessage, Acknowledgement
|
||||
|
||||
ASK_REFERRAL_CODE = 1
|
||||
ASK_NAME = 2
|
||||
ASK_CONSULTATION_TYPE = 3
|
||||
SEND_ACKNOWLEDGEMENT_INFO = 2
|
||||
ASK_NAME = 3
|
||||
ASK_SPECIALITY = 4
|
||||
SEND_DIPLOMA_ACK_INFO = 5
|
||||
SEND_CONSULTATION_TYPE_ACK_INFO = 6
|
||||
|
||||
SEND_ME_REFERRAL_CODE_TEXT = (
|
||||
"📝 Пожалуйста, пришлите реферальный код, чтобы начать процесс регистрации."
|
||||
)
|
||||
ACCEPT_OFFER_TEXT = (
|
||||
"📝 Продолжая работу с ботом, вы соглашаетесь с условиями оферты и на обработку персональных данных! \n"
|
||||
"Оферта и согласие - это гиперссылки на Яндекс документ, которые ведут на страничку с текстом"
|
||||
)
|
||||
SEND_ME_YOUR_FULL_NAME_TEXT = (
|
||||
"📝 Пожалуйста, введите ФИО."
|
||||
)
|
||||
SEND_ME_YOUR_SPECIALITY_TEXT = (
|
||||
"📝 Пожалуйста, введите вашу специальность, в соответствии с которой планируете проводить консультации."
|
||||
)
|
||||
WAIT_FOR_ACTIVATION_TEXT = (
|
||||
"📝 Заявка принята, направьте диплом и аккредитацию с указанием кода в теме письма на адрес электронной почты:____\n"
|
||||
"В этом шаге нужно встроить подсказку: в каком формате направлять диплом, как скачать с госуслуг\n"
|
||||
"выписку об аккредитации. Верификация займет 24 часа."
|
||||
)
|
||||
VERIFICATION_IN_PROGRESS_TEXT = (
|
||||
"📝 Пока идет верификация, вы можете ознакомиться с форматами работы и условиями сервиса\n"
|
||||
"Формат: название форматов + пакеты."
|
||||
)
|
||||
ALL_INFORMATION_RECEIVED_TEXT = (
|
||||
"✅ Спасибо за информацию, мы с вами свяжемся. До свидания. 👋"
|
||||
)
|
||||
|
||||
|
||||
async def ask_doctor_referral_code(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
await update.message.reply_text(
|
||||
"📝 Пожалуйста, пришлите реферальный код.",
|
||||
SEND_ME_REFERRAL_CODE_TEXT,
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
return ASK_REFERRAL_CODE
|
||||
@ -27,6 +57,12 @@ async def ask_doctor_referral_code(update: Update, context: ContextTypes.DEFAULT
|
||||
async def receive_doctor_referral_code(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
doctor_referral_code = update.message.text.strip()
|
||||
ref_obj = await validate_referral_code(doctor_referral_code)
|
||||
reply_keyboard = [
|
||||
[
|
||||
ConfirmationMessage.PROCEED.value,
|
||||
ConfirmationMessage.DECLINE.value
|
||||
]
|
||||
]
|
||||
|
||||
if not ref_obj:
|
||||
return ConversationHandler.END
|
||||
@ -35,8 +71,25 @@ async def receive_doctor_referral_code(update: Update, context: ContextTypes.DEF
|
||||
context.user_data["doctor_telegram_id"] = doctor_telegram_id
|
||||
context.user_data["ref_obj"] = ref_obj
|
||||
await update.message.reply_text(
|
||||
"📝 Пожалуйста, пришлите своё имя или псевдоним.",
|
||||
parse_mode="Markdown"
|
||||
ACCEPT_OFFER_TEXT,
|
||||
parse_mode="Markdown",
|
||||
reply_markup=ReplyKeyboardMarkup(
|
||||
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Оферта и согласие"
|
||||
),
|
||||
)
|
||||
return SEND_ACKNOWLEDGEMENT_INFO
|
||||
|
||||
|
||||
async def receive_doctor_info_confirmation(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
doctor_info_confirmation = update.message.text.strip()
|
||||
|
||||
if doctor_info_confirmation == ConfirmationMessage.DECLINE.value:
|
||||
return ConversationHandler.END
|
||||
|
||||
await update.message.reply_text(
|
||||
SEND_ME_YOUR_FULL_NAME_TEXT,
|
||||
parse_mode="Markdown",
|
||||
reply_markup=ReplyKeyboardRemove()
|
||||
)
|
||||
return ASK_NAME
|
||||
|
||||
@ -44,37 +97,72 @@ async def receive_doctor_referral_code(update: Update, context: ContextTypes.DEF
|
||||
async def receive_doctor_name(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
doctor_name = update.message.text.strip()
|
||||
context.user_data["doctor_name"] = doctor_name
|
||||
|
||||
await update.message.reply_text(
|
||||
SEND_ME_YOUR_SPECIALITY_TEXT,
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
return ASK_SPECIALITY
|
||||
|
||||
|
||||
async def receive_doctor_speciality(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
doctor_speciality = update.message.text.strip()
|
||||
context.user_data["doctor_speciality"] = doctor_speciality
|
||||
reply_keyboard = [
|
||||
[
|
||||
Consultation.ASYNC_TEXT.value,
|
||||
Consultation.ASYNC_TEXT_WITH_DIALOG.value,
|
||||
Consultation.ONLINE_CHAT.value,
|
||||
Consultation.AUDION_CALL.value,
|
||||
Consultation.VIDEO_CALL.value
|
||||
Acknowledgement.OK,
|
||||
Acknowledgement.DECLINE
|
||||
]
|
||||
]
|
||||
|
||||
await update.message.reply_text(
|
||||
f"Пожалуйста, выберите тип консультации.",
|
||||
WAIT_FOR_ACTIVATION_TEXT,
|
||||
parse_mode="Markdown",
|
||||
reply_markup=ReplyKeyboardMarkup(
|
||||
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Тип консультации"
|
||||
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Отправка пакета документов"
|
||||
),
|
||||
)
|
||||
return ASK_CONSULTATION_TYPE
|
||||
return SEND_DIPLOMA_ACK_INFO
|
||||
|
||||
|
||||
async def receive_doctor_consultation_type(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
doctor_consultation_type = update.message.text.strip()
|
||||
async def receive_doctor_diploma_acknowledgement_status(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
doctor_info_confirmation = update.message.text.strip()
|
||||
|
||||
reply_keyboard = [
|
||||
[
|
||||
Acknowledgement.OK,
|
||||
Acknowledgement.DECLINE
|
||||
]
|
||||
]
|
||||
|
||||
if doctor_info_confirmation == Acknowledgement.DECLINE.value:
|
||||
return ConversationHandler.END
|
||||
|
||||
await update.message.reply_text(
|
||||
"📝 Спасибо, сохраняю информацию.",
|
||||
VERIFICATION_IN_PROGRESS_TEXT,
|
||||
parse_mode="Markdown",
|
||||
reply_markup=ReplyKeyboardRemove()
|
||||
reply_markup=ReplyKeyboardMarkup(
|
||||
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Ознакомление с форматами работы"
|
||||
),
|
||||
)
|
||||
|
||||
return SEND_CONSULTATION_TYPE_ACK_INFO
|
||||
|
||||
|
||||
async def receive_doctor_consultation_packages_acknowledgement_status(update: Update,
|
||||
context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
doctor_info_confirmation = update.message.text.strip()
|
||||
|
||||
if doctor_info_confirmation == Acknowledgement.DECLINE.value:
|
||||
return ConversationHandler.END
|
||||
|
||||
await update.message.reply_text(
|
||||
ALL_INFORMATION_RECEIVED_TEXT,
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
|
||||
await mark_referral_code_as_used(context.user_data["ref_obj"], context.user_data["doctor_telegram_id"],
|
||||
context.user_data["doctor_name"], Consultation(doctor_consultation_type))
|
||||
context.user_data["doctor_name"])
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
@ -83,21 +171,30 @@ def ask_doctor_info_handler() -> CommandHandler:
|
||||
return CommandHandler("register", ask_doctor_referral_code)
|
||||
|
||||
|
||||
def get_register_doctor_handler() -> ConversationHandler:
|
||||
def get_register_doctor_first_stage_handler() -> ConversationHandler:
|
||||
return ConversationHandler(
|
||||
entry_points=[ask_doctor_info_handler()],
|
||||
states={
|
||||
ASK_REFERRAL_CODE: [
|
||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_referral_code)
|
||||
],
|
||||
SEND_ACKNOWLEDGEMENT_INFO: [
|
||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_info_confirmation)
|
||||
],
|
||||
ASK_NAME: [
|
||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_name)
|
||||
],
|
||||
ASK_CONSULTATION_TYPE: [
|
||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_consultation_type)
|
||||
ASK_SPECIALITY: [
|
||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_speciality)
|
||||
],
|
||||
SEND_DIPLOMA_ACK_INFO: [
|
||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_diploma_acknowledgement_status)
|
||||
],
|
||||
SEND_CONSULTATION_TYPE_ACK_INFO: [
|
||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_consultation_packages_acknowledgement_status)
|
||||
],
|
||||
},
|
||||
fallbacks=[get_cancel_handler()],
|
||||
name="register_doctor_conversation", # для тестов/логирования
|
||||
name="register_doctor_conversation_first_stage", # для тестов/логирования
|
||||
persistent=True, # если используете хранение состояний
|
||||
)
|
||||
|
||||
@ -5,7 +5,7 @@ from core.config import settings
|
||||
from docbot.handlers.start_handler import get_start_handler
|
||||
from docbot.handlers.patients.send_form_handler import get_send_form_handler
|
||||
from docbot.handlers.admins.doctors_handler import get_doctors_handler
|
||||
from docbot.handlers.doctors.register_handler import get_register_doctor_handler
|
||||
from docbot.handlers.doctors.register_handler import get_register_doctor_first_stage_handler
|
||||
from docbot.handlers.admins.generate_ref import get_referral_handlers
|
||||
from docbot.handlers.utils.unknown import get_unknown_handler
|
||||
|
||||
@ -24,7 +24,7 @@ def main():
|
||||
app.add_handler(get_start_handler())
|
||||
app.add_handler(get_send_form_handler())
|
||||
app.add_handler(get_doctors_handler())
|
||||
app.add_handler(get_register_doctor_handler())
|
||||
app.add_handler(get_register_doctor_first_stage_handler())
|
||||
app.add_handler(get_referral_handlers())
|
||||
app.add_handler(get_unknown_handler())
|
||||
logger.debug("Все хэндлеры зарегистрированы, запускаем polling")
|
||||
|
||||
@ -9,7 +9,7 @@ async def get_admin_info(telegram_id: int) -> Admins | None:
|
||||
async with AsyncSessionLocal() as session:
|
||||
result = await session.execute(
|
||||
select(Admins.telegram_id)
|
||||
.where(Admins.telegram_id.match(str(telegram_id)))
|
||||
.where(Admins.telegram_id.match(telegram_id))
|
||||
)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@ -18,6 +18,6 @@ async def mark_doctor_inactive(telegram_id: int) -> Admins | None:
|
||||
async with AsyncSessionLocal() as session:
|
||||
result = await session.execute(
|
||||
select(Admins.telegram_id)
|
||||
.where(Admins.telegram_id.match(str(telegram_id)))
|
||||
.where(Admins.telegram_id.match(telegram_id))
|
||||
)
|
||||
return result.scalar_one_or_none()
|
||||
@ -27,11 +27,11 @@ async def get_doctors_names() -> Doctors | None:
|
||||
return result.all()
|
||||
|
||||
|
||||
async def add_doctor(telegram_id: str, name: str, available_formats: Consultation, is_active: bool):
|
||||
async def add_doctor(telegram_id: int, name: str, available_formats: Consultation, is_active: bool):
|
||||
async with AsyncSessionLocal() as session:
|
||||
async with session.begin():
|
||||
session.add(Doctors(
|
||||
telegram_id=str(telegram_id),
|
||||
telegram_id=telegram_id,
|
||||
name=name,
|
||||
available_formats=available_formats,
|
||||
is_active=is_active,
|
||||
|
||||
@ -6,7 +6,6 @@ from sqlalchemy import select
|
||||
|
||||
from db.session import AsyncSessionLocal
|
||||
from db.models import ReferralCode, Doctors
|
||||
from core.enums.consultation_types import Consultation
|
||||
|
||||
|
||||
async def generate_referral_code(length: int = 12) -> str:
|
||||
@ -46,8 +45,7 @@ async def validate_referral_code(referral_code: str) -> ReferralCode | None:
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def mark_referral_code_as_used(referral_obj: ReferralCode, telegram_id: str, name: str,
|
||||
available_formats: Consultation) -> Doctors:
|
||||
async def mark_referral_code_as_used(referral_obj: ReferralCode, telegram_id: int, name: str) -> Doctors:
|
||||
"""
|
||||
Помечает referral_obj как использованный, создаёт запись в таблице Doctors
|
||||
с привязкой к telegram_id и возвращает объект Doctor.
|
||||
@ -60,10 +58,9 @@ async def mark_referral_code_as_used(referral_obj: ReferralCode, telegram_id: st
|
||||
|
||||
# создаём врача
|
||||
new_doc = Doctors(
|
||||
telegram_id=str(telegram_id),
|
||||
telegram_id=telegram_id,
|
||||
name=name,
|
||||
available_formats=[Consultation(available_formats)],
|
||||
is_active=True,
|
||||
is_active=False,
|
||||
created_at=datetime.utcnow(),
|
||||
referral=referral_obj
|
||||
)
|
||||
|
||||
@ -19,7 +19,7 @@ async def create_session_code(telegram_id: int, form_link: str) -> str:
|
||||
async with session.begin():
|
||||
session.add(SessionCode(
|
||||
code=code,
|
||||
telegram_id=str(telegram_id), # храним как строку
|
||||
telegram_id=telegram_id, # храним как строку
|
||||
form_link=form_link,
|
||||
sent_at=datetime.utcnow()
|
||||
))
|
||||
@ -51,7 +51,7 @@ async def get_pending_session(telegram_id: int) -> SessionCode | None:
|
||||
async with AsyncSessionLocal() as session:
|
||||
result = await session.execute(
|
||||
select(SessionCode)
|
||||
.where(SessionCode.telegram_id.match(str(telegram_id)))
|
||||
.where(SessionCode.telegram_id.match(telegram_id))
|
||||
.where(SessionCode.consulted_at.is_(None))
|
||||
.order_by(SessionCode.sent_at.desc())
|
||||
.limit(1)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user