import logging
import telebot
bot = telebot.TeleBot('%5318516291:AAFFqooEY6NuOTCBJjrr86JfLD-6n9XsKg8%');
from telegram import Bot
from telegram import InlineKeyboardButton
from telegram import InlineKeyboardMarkup
from telegram import Update
from telegram.ext import CallbackContext
from telegram.ext import CallbackQueryHandler
from telegram.ext import Updater
from telegram.ext import MessageHandler
from telegram.ext import CommandHandler
from telegram.ext import ConversationHandler
from telegram.ext import Filters
from telegram.utils.request import Request
from echo.config import load_config
from echo.utils import logger_factory
from anketa.validators import GENDER_MAP
from anketa.validators import gender_hru
from anketa.validators import validate_age
config = load_config()
logger = logging.getLogger(__name__)
debug_requests = logger_factory(logger=logger)
NAME, GENDER, AGE = range(3)
CALLBACK_BEGIN = 'x1'
@debug_requests
def start_buttons_handler(update: Update, context: CallbackContext):
""" Не относится к сценарию диалога, но создаёт начальные inline-кнопки
"""
inline_buttons = InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(text='Начать', callback_data=CALLBACK_BEGIN),
],
],
)
update.message.reply_text(
'Нажми на кнопку:',
reply_markup=inline_buttons,
)
@debug_requests
def start_handler(update: Update, context: CallbackContext):
""" Начало взаимодействия по клику на inline-кнопку
"""
init = update.callback_query.data
chat_id = update.callback_query.message.chat.id
if init != CALLBACK_BEGIN:
logger.debug('bad init: %s', init)
update.callback_query.bot.send_message(
chat_id=chat_id,
text='Что-то пошло не так, обратитесь к администратору бота',
)
return ConversationHandler.END
update.callback_query.answer()
# Спросить имя
update.callback_query.bot.send_message(
chat_id=chat_id,
text='Введи своё имя чтобы продолжить:',
)
return NAME
@debug_requests
def name_handler(update: Update, context: CallbackContext):
# Получить имя
context.user_data[NAME] = update.message.text
logger.info('user_data: %s', context.user_data)
# Спросить пол
inline_buttons = InlineKeyboardMarkup(
inline_keyboard=[
[InlineKeyboardButton(text=value, callback_data=key) for key, value in GENDER_MAP.items()],
],
)
update.message.reply_text(
text='Выберите свой пол чтобы продолжить',
reply_markup=inline_buttons,
)
return GENDER
@debug_requests
def age_handler(update: Update, context: CallbackContext):
# Получить пол
gender = update.callback_query.data
gender = int(gender)
if gender not in GENDER_MAP:
# Этой ситуации не должно быть для пользователя! То есть какое-то значение
# в кнопках есть, но оно не включено в список гендеров
update.effective_message.reply_text('Что-то пошло не так, обратитесь к администратору бота')
return GENDER
context.user_data[GENDER] = gender
logger.info('user_data: %s', context.user_data)
# Спросить возраст
update.effective_message.reply_text(
text='Введите свой возраст:',
)
return AGE
@debug_requests
def finish_handler(update: Update, context: CallbackContext):
# Получить возраст
age = validate_age(text=update.message.text)
if age is None:
update.message.reply_text('Пожалуйста, введите корректный возраст!')
return AGE
context.user_data[AGE] = age
logger.info('user_data: %s', context.user_data)
# TODO: вот тут запись в базу финала
# TODO 2: очистить `user_data`
# Завершить диалог
update.message.reply_text(f'''
Все данные успешно сохранены!
Вы: {context.user_data[NAME]}, пол: {gender_hru(context.user_data[GENDER])}, возраст: {context.user_data[AGE]}
''')
return ConversationHandler.END
@debug_requests
def cancel_handler(update: Update, context: CallbackContext):
""" Отменить весь процесс диалога. Данные будут утеряны
"""
update.message.reply_text('Отмена. Для начала с нуля нажмите /start')
return ConversationHandler.END
@debug_requests
def echo_handler(update: Update, context: CallbackContext):
update.message.reply_text(
'Нажмите /start для заполнения анкеты!',
)
def main():
logger.info('Started Anketa-bot')
req = Request(
connect_timeout=0.5,
read_timeout=1.0,
)
bot = Bot(
token=config.TG_TOKEN,
request=req,
base_url=config.TG_API_URL,
)
updater = Updater(
bot=bot,
use_context=True,
)
# Проверить что бот корректно подключился к Telegram API
info = bot.get_me()
logger.info(f'Bot info: {info}')
# Навесить обработчики команд
conv_handler = ConversationHandler(
entry_points=[
CallbackQueryHandler(start_handler, pass_user_data=True),
],
states={
NAME: [
MessageHandler(Filters.all, name_handler, pass_user_data=True),
],
GENDER: [
CallbackQueryHandler(age_handler, pass_user_data=True),
],
AGE: [
MessageHandler(Filters.all, finish_handler, pass_user_data=True),
],
},
fallbacks=[
CommandHandler('cancel', cancel_handler),
],
)
updater.dispatcher.add_handler(conv_handler)
updater.dispatcher.add_handler(CommandHandler('start', start_buttons_handler))
updater.dispatcher.add_handler(MessageHandler(Filters.all, echo_handler))
# Начать бесконечную обработку входящих сообщений
updater.start_polling()
updater.idle()
logger.info('Stopped Anketa-bot')
if __name__ == '__main__':
main()