import logging import sqlite3 from aiogram import types from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton from aiogram.dispatcher import FSMContext from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.contrib.middlewares.logging import LoggingMiddleware from aiogram.utils import executor from aiogram import Bot, Dispatcher from aiogram.dispatcher.filters import Text from database import create_tables, add_user, update_user_name, update_user_phone, add_address, delete_address, add_order from logger import log_action from dotenv import load_dotenv import os # Загрузка переменных окружения из .env файла load_dotenv() API_TOKEN = os.getenv('BOT_API_TOKEN') OPERATORS_GROUP_ID = int(os.getenv('OPERATORS_GROUP_ID')) ADMIN_GROUP_ID = int(os.getenv('ADMIN_GROUP_ID')) logging.basicConfig(level=logging.INFO) bot = Bot(token=API_TOKEN) dp = Dispatcher(bot) dp.middleware.setup(LoggingMiddleware()) # Состояния для заказа class OrderForm(StatesGroup): waiting_for_name = State() waiting_for_phone = State() waiting_for_address = State() waiting_for_cleaning_time = State() waiting_for_cleaning_type = State() waiting_for_payment_method = State() confirmation = State() # Inline клавиатуры def main_menu_keyboard(): keyboard = InlineKeyboardMarkup() keyboard.add(InlineKeyboardButton('Учетные данные', callback_data='account_data')) keyboard.add(InlineKeyboardButton('Сделать заказ', callback_data='make_order')) keyboard.add(InlineKeyboardButton('История заказов', callback_data='order_history')) keyboard.add(InlineKeyboardButton('Заказать звонок', callback_data='request_call')) keyboard.add(InlineKeyboardButton('Начать разговор с оператором', callback_data='talk_operator')) return keyboard def account_data_keyboard(): keyboard = InlineKeyboardMarkup() keyboard.add(InlineKeyboardButton('Изменить ФИО', callback_data='change_name')) keyboard.add(InlineKeyboardButton('Изменить номер телефона', callback_data='change_phone')) keyboard.add(InlineKeyboardButton('Добавить адрес', callback_data='add_address')) keyboard.add(InlineKeyboardButton('Удалить адрес', callback_data='delete_address')) keyboard.add(InlineKeyboardButton('Поделиться контактом', callback_data='share_contact')) keyboard.add(InlineKeyboardButton('Назад', callback_data='back_to_main')) return keyboard # Основные команды @dp.message_handler(commands=['start']) async def send_welcome(message: types.Message): await message.answer("Добро пожаловать в BOTKlining!", reply_markup=main_menu_keyboard()) log_action(message.from_user.id, 'start') @dp.callback_query_handler(lambda c: c.data == 'account_data') async def process_account_data(callback_query: types.CallbackQuery): await bot.answer_callback_query(callback_query.id) await bot.send_message(callback_query.from_user.id, "Учетные данные:", reply_markup=account_data_keyboard()) log_action(callback_query.from_user.id, 'account_data') @dp.callback_query_handler(lambda c: c.data == 'make_order') async def process_make_order(callback_query: types.CallbackQuery, state: FSMContext): await bot.answer_callback_query(callback_query.id) await bot.send_message(callback_query.from_user.id, "Начнем с ваших учетных данных. Введите ваше ФИО:") await OrderForm.waiting_for_name.set() log_action(callback_query.from_user.id, 'make_order') @dp.callback_query_handler(lambda c: c.data == 'order_history') async def process_order_history(callback_query: types.CallbackQuery): await bot.answer_callback_query(callback_query.id) # Добавьте логику для просмотра истории заказов await bot.send_message(callback_query.from_user.id, "История заказов:") log_action(callback_query.from_user.id, 'order_history') @dp.callback_query_handler(lambda c: c.data == 'request_call') async def process_request_call(callback_query: types.CallbackQuery): await bot.answer_callback_query(callback_query.id) # Добавьте логику для заказа звонка await bot.send_message(callback_query.from_user.id, "Заказ звонка оформлен. Ожидайте звонок в течение 30 минут.") log_action(callback_query.from_user.id, 'request_call') @dp.callback_query_handler(lambda c: c.data == 'talk_operator') async def process_talk_operator(callback_query: types.CallbackQuery): await bot.answer_callback_query(callback_query.id) # Добавьте логику для начала разговора с оператором await bot.send_message(callback_query.from_user.id, "Разговор с оператором начат.") log_action(callback_query.from_user.id, 'talk_operator') @dp.callback_query_handler(lambda c: c.data == 'back_to_main') async def process_back_to_main(callback_query: types.CallbackQuery): await bot.answer_callback_query(callback_query.id) await bot.send_message(callback_query.from_user.id, "Главное меню:", reply_markup=main_menu_keyboard()) log_action(callback_query.from_user.id, 'back_to_main') # Обработка шагов заказа @dp.message_handler(state=OrderForm.waiting_for_name, content_types=types.ContentTypes.TEXT) async def process_name(message: types.Message, state: FSMContext): async with state.proxy() as data: data['name'] = message.text await message.answer("Введите ваш номер телефона:") await OrderForm.waiting_for_phone.set() @dp.message_handler(state=OrderForm.waiting_for_phone, content_types=types.ContentTypes.TEXT) async def process_phone(message: types.Message, state: FSMContext): async with state.proxy() as data: data['phone'] = message.text await message.answer("Введите адрес для уборки:") await OrderForm.waiting_for_address.set() @dp.message_handler(state=OrderForm.waiting_for_address, content_types=types.ContentTypes.TEXT) async def process_order_address(message: types.Message, state: FSMContext): async with state.proxy() as data: data['address'] = message.text await message.answer("Выберите время для уборки (утро/день/вечер):") await OrderForm.waiting_for_cleaning_time.set() @dp.message_handler(state=OrderForm.waiting_for_cleaning_time, content_types=types.ContentTypes.TEXT) async def process_cleaning_time(message: types.Message, state: FSMContext): async with state.proxy() as data: data['cleaning_time'] = message.text await message.answer("Выберите тип уборки (влажная/сухая/генеральная):") await OrderForm.waiting_for_cleaning_type.set() @dp.message_handler(state=OrderForm.waiting_for_cleaning_type, content_types=types.ContentTypes.TEXT) async def process_cleaning_type(message: types.Message, state: FSMContext): async with state.proxy() as data: data['cleaning_type'] = message.text await message.answer("Выберите способ оплаты (картой/наличными):") await OrderForm.waiting_for_payment_method.set() @dp.message_handler(state=OrderForm.waiting_for_payment_method, content_types=types.ContentTypes.TEXT) async def process_payment_method(message: types.Message, state: FSMContext): async with state.proxy() as data: data['payment_method'] = message.text # Отправка подтверждения заказа await message.answer("Подтвердите заказ:\n" f"ФИО: {data['name']}\n" f"Номер телефона: {data['phone']}\n" f"Адрес: {data['address']}\n" f"Время уборки: {data['cleaning_time']}\n" f"Тип уборки: {data['cleaning_type']}\n" f"Способ оплаты: {data['payment_method']}\n" "Если все верно, нажмите 'Подтвердить'. В противном случае, измените нужные данные.", reply_markup=InlineKeyboardMarkup().add(InlineKeyboardButton('Подтвердить', callback_data='confirm_order'))) await OrderForm.confirmation.set() @dp.callback_query_handler(lambda c: c.data == 'confirm_order', state=OrderForm.confirmation) async def process_confirm_order(callback_query: types.CallbackQuery, state: FSMContext): await bot.answer_callback_query(callback_query.id) async with state.proxy() as data: order_details = (f"Новый заказ:\n" f"ФИО: {data['name']}\n" f"Номер телефона: {data['phone']}\n" f"Адрес: {data['address']}\n" f"Время уборки: {data['cleaning_time']}\n" f"Тип уборки: {data['cleaning_type']}\n" f"Способ оплаты: {data['payment_method']}") # Отправка заказа операторам await bot.send_message(OPERATORS_GROUP_ID, order_details) log_action(callback_query.from_user.id, 'confirm_order') # Сохранение заказа в базе данных add_order(data['name'], data['phone'], data['address'], data['cleaning_time'], data['cleaning_type'], data['payment_method']) await bot.send_message(callback_query.from_user.id, "Ваш заказ был подтвержден и отправлен операторам.") await state.finish() # Основное приложение if __name__ == '__main__': create_tables() executor.start_polling(dp, skip_updates=True)