This commit is contained in:
2024-06-17 10:40:49 +03:00
parent c50fc58257
commit c2255c2166
18 changed files with 1742 additions and 179 deletions

4
.gitignore vendored
View File

@@ -123,9 +123,9 @@ celerybeat.pid
# Environments # Environments
.env .env
.venv .venv
env/ .env/
venv/ venv/
ENV/ .env/
env.bak/ env.bak/
venv.bak/ venv.bak/

7
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/old/bot.log" charset="windows-1251" />
<file url="file://$PROJECT_DIR$/old/bot.log" charset="windows-1251" />
</component>
</project>

155
README.md
View File

@@ -1,2 +1,157 @@
# BOTKlining # BOTKlining
## Структура
1. `main.py`: основной файл для запуска бота.
2. `handlers.py`: обработчики команд и состояний.
3. `database.py`: взаимодействие с базой данных.
4. `logger.py`: логирование действий пользователей.
5. `.env`: файл для хранения конфиденциальных данных.
Для создания бота с указанной функциональностью и логикой, а также использования файла .env для хранения конфиденциальных данных, мы разобьем задачу на несколько шагов:
Настройка окружения и установка зависимостей
Создание базы данных
Разработка основных обработчиков команд и колбэков
Создание функций для работы с базой данных
Настройка логирования
Реализация основной логики бота
Вот подробное описание структуры и логики бота:
## Inline клавиатура бота:
1. Учетные данные
- Изменить ФИО: Пользователь может изменить свое ФИО.
- Изменить номер телефона: Позволяет изменить номер телефона.
- Добавить адрес: Пользователь может добавить новый адрес.
- Удалить адрес: Пользователь может удалить ранее добавленный адрес.
- Поделиться контактом: Позволяет поделиться контактными данными, для автоматического заполнения в базе данных.
2. Сделать заказ
- Добавить учетные данные: Если у пользователя нет учетных данных, он должен их добавить. Если данные есть они заполняются автоматически.
- Выбрать адрес: Пользователь выбирает адрес или добавляет новый.
- Выбрать время уборки: Предлагает утро, день, вечер.
- Выбрать тип уборки: Влажная, сухая, генеральная.
- Выбрать способ оплаты: Картой, наличными.
- Подтвердить заказ: Подтверждает заказ или позволяет изменить ответы. После подтверждения заказа автоматически отправлять уведомление в группу операторов, а также добавлять заказ в историю.
- Заказу присваивается ID номер
3. История заказов
- Просмотреть историю заказов: Позволяет пользователю просмотреть свою историю заказов.
- Добавить функцию повторного заказа на основе предыдущих заказов.
4. Заказать звонок
- Добавить учетные данные: Если у пользователя нет учетных данных, он должен их добавить. Если данные есть они заполняются автоматически.
- Заказать звонок: Отправляет учетные данные (ФИО, номер телефона) в группу операторов, с подписью об звонке. Пользователь видит сообщение "ожидайте звонок в течении 30 минут"
5. Начать разговор с оператором
- Добавить учетные данные: Если у пользователя нет учетных данных, он должен их добавить. Если данные есть они заполняются автоматически.
- Начать разговор: Отправляет учетные данные (ФИО, номер телефона, ID номер крайнего заказа) в группу операторов.
- Завершить разговор: Пользователь завершает разговор.
- После завершения разговора автоматически отправлять анкету о качестве обслуживания пользователю для обратной связи. Автоматически закрыть анкету в случае не ответа 2 часов.
6. Назад
- Возврат к предыдущему набору кнопок: Позволяет вернуться к предыдущему меню кнопок.
## Логика нажатия кнопок и сохранения данных:
- При первом использовании бота запросить у пользователя учетные данные (ФИО, номер телефона) и сохранить их для последующих заказов. Можно использовать личные данные из Telegram (если пользователь разрешил) для заполнения некоторых полей автоматически.
- При нажатии кнопок пользователем, бот запоминает предыдущий выбор и отображает следующий набор кнопок соответственно.
- Когда пользователь нажимает на любую из кнопок, предыдущий выбор автоматически скрывается, а вместо него появляется следующий набор кнопок. Кнопка "Назад" позволяет вернуться к предыдущему набору кнопок в случае необходимости. Это помогает сделать интерфейс более удобным и интуитивно понятным для пользователей.
- Данные пользователя (учетные данные, адреса, заказы и т.д.) сохраняются в базе данных SQLite3 для последующего использования.
- Логирование действий пользователей осуществляется путем записи информации о каждом действии в лог-файлы, включая дату, время, ID пользователя и другие параметры.
## Управление из группы и внутри бота:
- Группа для заказов управляется операторами и администраторами, которые имеют доступ к соответствующим функциям.
- Операторы могут просматривать историю заказов пользователей, отвечать на сообщения, завершать разговоры и управлять заказами.
- Администраторы имеют дополнительные функции, такие как выгрузка переписки в формате JSON.
- Бот на aiogram используется для более эффективной работы и реализации функций бота через асинхронные методы.
- Эта структура и логика позволят создать функционального бота для управления заказами и общения с операторами, обеспечивая удобство пользователей и контроль над данными.
- Данные токена id групп, id администраторов, операторов дложны храниться в файле env
## Автоматизация
- Добавить таймеры для отслеживания неактивности пользователя и предложения начать разговор с оператором или оформить заказ при необходимости.
- Использовать базу данных для хранения информации о пользователях, заказах и истории коммуникации с операторами.
- Реализовать механизм автоматического анализа данных о заказах для предложения персонализированных услуг или скидок.
- Создаем базу данных SQLite3 для хранения информации о пользователях, их учетных данных, заказах и истории сообщений с операторами.
- Создаем таблицы для каждой категории данных: пользователи, заказы, история сообщений и т.д.
- Связываем таблицы между собой по ключам (например, по ID пользователя).
- При каждом действии пользователя (нажатие кнопки, отправка сообщения) записываем соответствующую информацию в лог-файлы.
- Логируем дату, время действия, ID пользователя, текстовые данные (если есть) и другие необходимые параметры.
- Создаем специальную группу для приема заказов, где только операторы и администраторы имеют доступ.
- Назначаем операторов и администраторов, которые могут управлять заказами в этой группе.
1. Функционал операторов:
- Операторы могут просматривать историю заказов конкретного пользователя по его ID.
- Операторы могут отвечать пользователю из группы используя функцию ответа (replay).
- Операторы могут завершать разговор с пользователем с помощью соответствующей кнопки.
2. Функционал администраторов:
- Администраторы имеют все функции операторов.
- Дополнительно администраторы могут выгружать переписку операторов и пользователя в виде JSON файла.
Логика Бота
есть inline клавиотура со следующими кнопками:
Учетные данные
Изменить ФИО
Изменить номер телефона
Добавит адрес
Поделиться контактом
сделать заказ
Добавит учетные данные, если данные не введены, если введены то пропустить вопрос.
выбрать адрес или указать новый адрес. все веденные адреса сохраняються.
спросить время для уборки: утро/День/вечер
Спросить тип уборки: Влажная/Сухая/Генеральная
Спросить способ оплаты: Картой/Наличными
Подьвердить заказ, или предложить изменить ответ на вопрос. далее кнопки вопросов что бы изменить один ответ и после изменения повторно подтвердить.
После подтверждения, сообщения с ответами отправляеться группу операторов.
История заказов
Все отправленные ответы в группу сохраняются как заказ и храниться в базе данных.
Заказать звонок
Добавит учетные данные, если данные не введены, если введены то пропустить вопрос.
Кнопка заказать звонок, отправляет учетные данные (ФИО, номер телефона) в группу операторов.
Начать разговор с оератором
Добавит учетные данные, если данные не введены, если введены то пропустить вопрос.
Кнопка начать разговор, отправляет учетные данные (ФИО, номер телефона) в группу операторов.
Оператор из группы нажимает ответить(replay) и пишет сообщение, сообшение отправляеться пользователю
пользователь пишет сообщение и оно отправляеться в группу до дех под пока пользователь не нажмет завершить разговор.
Если кнопка завершить разговор не нажато, то через 1 час разговор с оператором завершаеться автоматически.
При заходе пользователя через 2 часа появляеться первоначальное меню кнопок.
Допиши логику, слелай её более автоматизированной.
ChatGPT
Ты создал очень хорошую базу для логики бота! Вот несколько дополнений и идей для автоматизации:
Учетные данные:
При первом использовании бота запросить у пользователя учетные данные (ФИО, номер телефона) и сохранить их для последующих заказов. Можно использовать личные данные из Telegram (если пользователь разрешил) для заполнения некоторых полей автоматически.
Добавить возможность изменения учетных данных через команду или кнопку "Изменить учетные данные".
Сделать заказ:
После выбора адреса показывать пользователю карту с указанным адресом для подтверждения или возможности изменения.
Автоматически предлагать время уборки в зависимости от текущего времени (например, если пользователь заходит в 9 утра, предложить утреннее время уборки).
После подтверждения заказа автоматически отправлять уведомление в группу операторов, а также добавлять заказ в историю.
История заказов:
Позволить пользователю просматривать историю своих заказов через бота.
Добавить функцию повторного заказа на основе предыдущих заказов.
Заказать звонок:
Позволить пользователю выбрать время для звонка (например, "Заказать звонок через 30 минут").
Автоматически отправлять уведомление о заказе звонка в группу операторов с указанием времени.
Начать разговор с оператором:
Добавить возможность выбора темы разговора (например, "Техническая поддержка", "Вопрос по заказу" и т. д.).
После завершения разговора автоматически отправлять анкету о качестве обслуживания пользователю для обратной связи.
Автоматизация:
Добавить таймеры для отслеживания неактивности пользователя и предложения начать разговор с оператором или оформить заказ при необходимости.
Использовать базу данных для хранения информации о пользователях, заказах и истории коммуникации с операторами.
Реализовать механизм автоматического анализа данных о заказах для предложения персонализированных услуг или скидок.
Эти функции помогут сделать бота более удобным и эффективным для пользователей и операторов.

53
database.py Normal file
View File

@@ -0,0 +1,53 @@
import sqlite3
def create_tables():
conn = sqlite3.connect('bot_data.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
phone TEXT,
address TEXT,
cleaning_time TEXT,
cleaning_type TEXT,
payment_method TEXT
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY,
name TEXT,
phone TEXT,
address TEXT
)
''')
conn.commit()
conn.close()
def add_order(name, phone, address, cleaning_time, cleaning_type, payment_method):
conn = sqlite3.connect('bot_data.db')
cursor = conn.cursor()
cursor.execute('''
INSERT INTO orders (name, phone, address, cleaning_time, cleaning_type, payment_method)
VALUES (?, ?, ?, ?, ?, ?)
''', (name, phone, address, cleaning_time, cleaning_type, payment_method))
conn.commit()
conn.close()
def get_order_history(user_id):
conn = sqlite3.connect('bot_data.db')
cursor = conn.cursor()
cursor.execute('''
SELECT * FROM orders WHERE user_id = ?
''', (user_id,))
orders = cursor.fetchall()
conn.close()
return orders

158
handlers.py Normal file
View File

@@ -0,0 +1,158 @@
import logging
from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from database import add_order, get_order_history
from logger import log_action
logging.basicConfig(level=logging.INFO)
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()
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
def order_confirmation_keyboard():
keyboard = InlineKeyboardMarkup()
keyboard.add(InlineKeyboardButton('Подтвердить', callback_data='confirm_order'))
return keyboard
def register_handlers(dp, OPERATORS_GROUP_ID):
@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 callback_query.answer()
await callback_query.message.answer("Учетные данные:", 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 callback_query.answer()
await callback_query.message.answer("Начнем с ваших учетных данных. Введите ваше ФИО:")
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 callback_query.answer()
orders = get_order_history(callback_query.from_user.id)
if orders:
history_message = "\n\n".join([f"Заказ {order['id']}:\nФИО: {order['name']}\nАдрес: {order['address']}\nТип уборки: {order['cleaning_type']}" for order in orders])
await callback_query.message.answer(f"История заказов:\n{history_message}")
else:
await callback_query.message.answer("История заказов пуста.")
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 callback_query.answer()
await callback_query.message.answer("Заказ звонка оформлен. Ожидайте звонок в течение 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 callback_query.answer()
await callback_query.message.answer("Разговор с оператором начат.")
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 callback_query.answer()
await callback_query.message.answer("Главное меню:", 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=order_confirmation_keyboard())
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 callback_query.answer()
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)
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()

6
logger.py Normal file
View File

@@ -0,0 +1,6 @@
import logging
logging.basicConfig(level=logging.INFO)
def log_action(user_id, action):
logging.info(f"User {user_id} performed action: {action}")

197
main.py
View File

@@ -1,188 +1,31 @@
import logging import logging
import sqlite3
import asyncio
from aiogram import Bot, Dispatcher, types from aiogram import Bot, Dispatcher, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton from aiogram.utils import executor
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from dotenv import load_dotenv
import os
from handlers import register_handlers
from database import create_tables
# Загрузка переменных окружения из .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) logging.basicConfig(level=logging.INFO)
# Подключаемся к базе данных SQLite
conn = sqlite3.connect("answers.db")
cursor = conn.cursor()
# Создание таблицы для хранения ответов
cursor.execute("""
CREATE TABLE IF NOT EXISTS answers (
user_id INTEGER,
question_id INTEGER,
answer TEXT
)
""")
conn.commit()
# Заменить на свой токен
API_TOKEN = '7472030348:AAGI53nX-ON-WBmEhd_qBC6EnZsHOqp_2kE'
GROUP_ID = '-1001961537659'
# Инициализация бота и диспетчера
bot = Bot(token=API_TOKEN) bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot) dp = Dispatcher(bot)
dp.middleware.setup(LoggingMiddleware()) dp.middleware.setup(LoggingMiddleware())
# Клавиатура для подтверждения ответов # Основное приложение
confirm_keyboard = ReplyKeyboardMarkup(resize_keyboard=True).add(KeyboardButton('Подтвердить'))
# Словарь для хранения вопросов и ответов
questions = {
1: "Как вас зовут?",
2: "Укажите номер телефона дл связи",
3: "Укажите район, улицу дом",
4: "Какая уборка нужна, влажная ли сухая?",
5: "На какое время?",
6: "Оплата наличными или картой?"
}
# Обработчик команды /start
@dp.message_handler(commands=['start'])
async def start(message: types.Message):
await message.answer("Привет! Я задам тебе 6 вопросов. Давай начнем.")
await ask_question(message.chat.id, 1)
# Функция для задания вопроса
async def ask_question(user_id, question_id):
#question_text = questions[question_id]
#await bot.send_message(user_id, text=question_text, reply_markup=confirm_keyboard)
if question_id == 4:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[
InlineKeyboardButton(text="Влажная", callback_data="wet_cleaning"),
InlineKeyboardButton(text="Сухая", callback_data="dry_cleaning")
]
])
question_text = questions[question_id]
await bot.send_message(user_id, text=question_text, reply_markup=keyboard)
elif question_id == 5:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[
InlineKeyboardButton(text="Утро", callback_data="morning_time"),
InlineKeyboardButton(text="День", callback_data="day_time"),
InlineKeyboardButton(text="Вечер", callback_data="evening_time")
]
])
question_text = questions[question_id]
await bot.send_message(user_id, text=question_text, reply_markup=keyboard)
elif question_id == 6:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[
InlineKeyboardButton(text="Наличные", callback_data="cash_payment"),
InlineKeyboardButton(text="Карта", callback_data="card_payment")
]
])
question_text = questions[question_id]
await bot.send_message(user_id, text=question_text, reply_markup=keyboard)
else:
question_text = questions[question_id]
await bot.send_message(user_id, text=question_text, reply_markup=confirm_keyboard)
# Обработчик callback-кнопок
@dp.callback_query_handler(lambda query: query.data in ['wet_cleaning', 'dry_cleaning', 'morning_time', 'day_time', 'evening_time', 'cash_payment', 'card_payment'])
async def handle_callback_answer(query: types.CallbackQuery):
answer = {
'wet_cleaning': 'Влажная уборка',
'dry_cleaning': 'Сухая уборка',
'morning_time': 'Утро',
'day_time': 'День',
'evening_time': 'Вечер',
'cash_payment': 'Наличные',
'card_payment': 'Карта'
}
await save_answer(query.from_user.id, answer[query.data])
await ask_question(query.from_user.id, query.message.message_id + 1)
# Функция для сохранения ответа в базе данных
async def save_answer(user_id, answer):
cursor.execute("INSERT INTO answers (user_id, question_id, answer) VALUES (?, ?, ?)", (user_id, cursor.rowcount + 1, answer))
conn.commit()
# Обработчик ответов с текстовым полем
@dp.message_handler(lambda message: message.text != 'Подтвердить')
async def handle_text_answer(message: types.Message):
user_id = message.chat.id
cursor.execute("SELECT MAX(question_id) FROM answers WHERE user_id=?", (user_id,))
prev_question_id = cursor.fetchone()[0]
if prev_question_id is None:
question_id = 1
else:
question_id = prev_question_id + 1
answer = message.text
cursor.execute("INSERT INTO answers (user_id, question_id, answer) VALUES (?, ?, ?)",
(user_id, question_id, answer))
conn.commit()
if question_id < 6:
await ask_question(user_id, question_id + 1)
else:
await bot.send_message(user_id, "Ответы записаны. Подтверди перед отправкой.", reply_markup=confirm_keyboard)
# Обработчик ответов с inline кнопкой
@dp.callback_query_handler()
async def handle_callback_answer(query: types.CallbackQuery):
user_id = query.from_user.id
answer = query.data
cursor.execute("SELECT MAX(question_id) FROM answers WHERE user_id=?", (user_id,))
prev_question_id = cursor.fetchone()[0]
if prev_question_id is None:
question_id = 1
else:
question_id = prev_question_id + 1
cursor.execute("INSERT INTO answers (user_id, question_id, answer) VALUES (?, ?, ?)",
(user_id, question_id, answer))
conn.commit()
if question_id < 6:
await ask_question(user_id, question_id + 1)
else:
await bot.send_message(user_id, "Ответы записаны. Подтверди перед отправкой.", reply_markup=confirm_keyboard)
# Функция для подтверждения ответов и отправки в группу
@dp.message_handler(lambda message: message.text == 'Подтвердить')
async def confirm_answers(message: types.Message):
user_id = message.chat.id
cursor.execute("SELECT * FROM answers WHERE user_id=?", (user_id,))
answers = cursor.fetchall()
if answers:
group_id = GROUP_ID # Заменить на ID вашей группы
answer_text = '\n'.join([f"{questions[ans[1]]}: {ans[2]}" for ans in answers])
# Очищаем таблицу с ответами
cursor.execute("DELETE FROM answers WHERE user_id=?", (user_id,))
conn.commit()
# Отправляем ответы в группу с помощью реплая
sent_message = await bot.send_message(group_id, answer_text)
await bot.send_message(user_id,
f"Ответы отправлены в группу. Можете посмотреть их [здесь](https://t.me/{sent_message.chat.username}/{sent_message.message_id})",
parse_mode='Markdown')
else:
await bot.send_message(user_id, "Ответов нет")
if __name__ == '__main__': if __name__ == '__main__':
loop = asyncio.get_event_loop() create_tables()
try: register_handlers(dp, OPERATORS_GROUP_ID)
loop.create_task(dp.start_polling()) executor.start_polling(dp, skip_updates=True)
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
conn.close()

Binary file not shown.

103
old/bot(OLD).py Normal file
View File

@@ -0,0 +1,103 @@
import os
import logging
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.utils import executor
from aiogram.dispatcher.filters import Text
from database import create_tables
from logger import log_action
from dotenv import load_dotenv
# Загрузка переменных окружения из .env файла
load_dotenv()
API_TOKEN = os.getenv('BOT_API_TOKEN')
OPERATORS_GROUP_ID = os.getenv('OPERATORS_GROUP_ID')
ADMIN_GROUP_ID = os.getenv('ADMIN_GROUP_ID')
logging.basicConfig(level=logging.INFO)
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
dp.middleware.setup(LoggingMiddleware())
# 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
def order_keyboard():
keyboard = InlineKeyboardMarkup()
keyboard.add(InlineKeyboardButton('Добавить учетные данные', callback_data='add_account_data'))
keyboard.add(InlineKeyboardButton('Выбрать адрес', callback_data='select_address'))
keyboard.add(InlineKeyboardButton('Выбрать время для уборки', callback_data='select_time'))
keyboard.add(InlineKeyboardButton('Выбрать тип уборки', callback_data='select_cleaning_type'))
keyboard.add(InlineKeyboardButton('Выбрать способ оплаты', callback_data='select_payment_method'))
keyboard.add(InlineKeyboardButton('Подтвердить заказ', callback_data='confirm_order'))
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):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, "Сделать заказ:", reply_markup=order_keyboard())
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')
if __name__ == '__main__':
create_tables()
executor.start_polling(dp, skip_updates=True)

View File

254
old/bot.py Normal file
View File

@@ -0,0 +1,254 @@
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
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()
class CallRequest(StatesGroup):
waiting_for_name = State()
waiting_for_phone = State()
class OperatorChat(StatesGroup):
in_chat = 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
def order_keyboard():
keyboard = InlineKeyboardMarkup()
keyboard.add(InlineKeyboardButton('Добавить учетные данные', callback_data='add_account_data'))
keyboard.add(InlineKeyboardButton('Выбрать адрес', callback_data='select_address'))
keyboard.add(InlineKeyboardButton('Выбрать время для уборки', callback_data='select_time'))
keyboard.add(InlineKeyboardButton('Выбрать тип уборки', callback_data='select_cleaning_type'))
keyboard.add(InlineKeyboardButton('Выбрать способ оплаты', callback_data='select_payment_method'))
keyboard.add(InlineKeyboardButton('Подтвердить заказ', callback_data='confirm_order'))
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):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, "Сделать заказ:", reply_markup=order_keyboard())
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.callback_query_handler(lambda c: c.data == 'add_account_data')
async def process_add_account_data(callback_query: types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, "Введите ваше ФИО:")
await OrderForm.waiting_for_name.set()
@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
user_id = message.from_user.id
name = data['name']
phone = data['phone']
add_user(user_id, name, phone)
await message.answer("Ваши данные успешно сохранены!")
await state.finish()
# Изменение учетных данных
@dp.callback_query_handler(lambda c: c.data == 'change_name')
async def process_change_name(callback_query: types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, "Введите новое ФИО:")
await OrderForm.waiting_for_name.set()
@dp.callback_query_handler(lambda c: c.data == 'change_phone')
async def process_change_phone(callback_query: types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, "Введите новый номер телефона:")
await OrderForm.waiting_for_phone.set()
# Добавление адреса
@dp.callback_query_handler(lambda c: c.data == 'add_address')
async def process_add_address(callback_query: types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, "Введите адрес для добавления:")
await OrderForm.waiting_for_address.set()
@dp.message_handler(state=OrderForm.waiting_for_address, content_types=types.ContentTypes.TEXT)
async def process_add_address_step(message: types.Message, state: FSMContext):
user_id = message.from_user.id
address = message.text
add_address(user_id, address)
await message.answer("Адрес успешно добавлен!")
await state.finish()
# Удаление адреса
@dp.callback_query_handler(lambda c: c.data == 'delete_address')
async def process_delete_address(callback_query: types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, "Введите адрес для удаления:")
await OrderForm.waiting_for_address.set()
@dp.message_handler(state=OrderForm.waiting_for_address, content_types=types.ContentTypes.TEXT)
async def process_delete_address_step(message: types.Message, state: FSMContext):
user_id = message.from_user.id
address = message.text
delete_address(user_id, address)
await message.answer("Адрес успешно удален!")
await state.finish()
# Обработка заказа
@dp.callback_query_handler(lambda c: c.data == 'select_address')
async def process_select_address(callback_query: types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, "Введите адрес для уборки:")
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['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')
await bot.send_message(callback_query.from_user.id, "Ваш заказ был подтвержден и отправлен операторам.")
await state.finish()
# Основное приложение
if __name__ == '__main__':
create_tables()
executor.start_polling(dp, skip_updates=True)

89
old/database.py Normal file
View File

@@ -0,0 +1,89 @@
import sqlite3
def create_tables():
conn = sqlite3.connect('bot_klining.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
telegram_id INTEGER UNIQUE,
name TEXT,
phone TEXT
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS addresses (
id INTEGER PRIMARY KEY,
user_id INTEGER,
address TEXT,
FOREIGN KEY(user_id) REFERENCES users(id)
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
address TEXT,
cleaning_time TEXT,
cleaning_type TEXT,
payment_method TEXT,
order_id TEXT UNIQUE,
FOREIGN KEY(user_id) REFERENCES users(id)
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS logs (
id INTEGER PRIMARY KEY,
user_id INTEGER,
action TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(user_id) REFERENCES users(id)
)
''')
conn.commit()
conn.close()
def add_user(telegram_id, name, phone):
conn = sqlite3.connect('bot_klining.db')
cursor = conn.cursor()
cursor.execute('INSERT OR IGNORE INTO users (telegram_id, name, phone) VALUES (?, ?, ?)', (telegram_id, name, phone))
conn.commit()
conn.close()
def update_user_name(telegram_id, name):
conn = sqlite3.connect('bot_klining.db')
cursor = conn.cursor()
cursor.execute('UPDATE users SET name = ? WHERE telegram_id = ?', (name, telegram_id))
conn.commit()
conn.close()
def update_user_phone(telegram_id, phone):
conn = sqlite3.connect('bot_klining.db')
cursor = conn.cursor()
cursor.execute('UPDATE users SET phone = ? WHERE telegram_id = ?', (phone, telegram_id))
conn.commit()
conn.close()
def add_address(telegram_id, address):
conn = sqlite3.connect('bot_klining.db')
cursor = conn.cursor()
cursor.execute('SELECT id FROM users WHERE telegram_id = ?', (telegram_id,))
user_id = cursor.fetchone()[0]
cursor.execute('INSERT INTO addresses (user_id, address) VALUES (?, ?)', (user_id, address))
conn.commit()
conn.close()
def delete_address(telegram_id, address):
conn = sqlite3.connect('bot_klining.db')
cursor = conn.cursor()
cursor.execute('SELECT id FROM users WHERE telegram_id = ?', (telegram_id,))
user_id = cursor.fetchone()[0]
cursor.execute('DELETE FROM addresses WHERE user_id = ? AND address = ?', (user_id, address))
conn.commit()
conn.close()

183
old/handlers.py Normal file
View File

@@ -0,0 +1,183 @@
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)

185
old/klining_order.py Normal file
View File

@@ -0,0 +1,185 @@
import logging
import sqlite3
import asyncio
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
# Устанавливаем уровень логов
logging.basicConfig(level=logging.INFO)
# Подключаемся к базе данных SQLite
conn = sqlite3.connect("answers.db")
cursor = conn.cursor()
# Создание таблицы для хранения ответов
cursor.execute("""
CREATE TABLE IF NOT EXISTS answers (
user_id INTEGER,
question_id INTEGER,
answer TEXT
)
""")
conn.commit()
# Заменить на свой токен
API_TOKEN = '7472030348:AAGI53nX-ON-WBmEhd_qBC6EnZsHOqp_2kE'
GROUP_ID = '-1001961537659'
# Инициализация бота и диспетчера
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
dp.middleware.setup(LoggingMiddleware())
# Словарь для хранения вопросов и ответов
questions = {
1: "Как вас зовут?",
2: "Укажите номер телефона для связи",
3: "Укажите район, улицу, дом",
4: "Какая уборка нужна, влажная или сухая?",
5: "На какое время?",
6: "Оплата наличными или картой?"
}
answer_map = {
'wet_cleaning': 'Влажная уборка',
'dry_cleaning': 'Сухая уборка',
'morning_time': 'Утро',
'day_time': 'День',
'evening_time': 'Вечер',
'cash_payment': 'Наличные',
'card_payment': 'Карта'
}
# Обработчик команды /start
@dp.message_handler(commands=['start'])
async def start(message: types.Message):
await message.answer("Привет! Я задам тебе 6 вопросов. Давай начнем.")
await ask_question(message.chat.id, 1)
# Функция для задания вопроса
async def ask_question(user_id, question_id):
if question_id in [4, 5, 6]:
if question_id == 4:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Влажная", callback_data="wet_cleaning")],
[InlineKeyboardButton(text="Сухая", callback_data="dry_cleaning")]
])
elif question_id == 5:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Утро", callback_data="morning_time")],
[InlineKeyboardButton(text="День", callback_data="day_time")],
[InlineKeyboardButton(text="Вечер", callback_data="evening_time")]
])
elif question_id == 6:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Наличные", callback_data="cash_payment")],
[InlineKeyboardButton(text="Карта", callback_data="card_payment")]
])
await bot.send_message(user_id, text=questions[question_id], reply_markup=keyboard)
else:
await bot.send_message(user_id, text=questions[question_id])
# Обработчик текстовых ответов на первые три вопроса
@dp.message_handler(lambda message: message.text not in ["Переписать", "Отправить"])
async def handle_text_answer(message: types.Message):
user_id = message.chat.id
cursor.execute("SELECT MAX(question_id) FROM answers WHERE user_id=?", (user_id,))
prev_question_id = cursor.fetchone()[0]
if prev_question_id is None:
question_id = 1
else:
question_id = prev_question_id + 1
answer = message.text
await save_answer(user_id, question_id, answer)
if question_id < 6:
await ask_question(user_id, question_id + 1)
else:
await show_confirmation_options(user_id)
# Обработчик inline-кнопок
@dp.callback_query_handler(lambda query: query.data in answer_map.keys())
async def handle_callback_answer(query: types.CallbackQuery):
user_id = query.from_user.id
cursor.execute("SELECT MAX(question_id) FROM answers WHERE user_id=?", (user_id,))
prev_question_id = cursor.fetchone()[0]
if prev_question_id is None:
question_id = 1
else:
question_id = prev_question_id + 1
await save_answer(user_id, question_id, answer_map[query.data])
await query.answer()
if question_id < 6:
await ask_question(user_id, question_id + 1)
else:
await show_confirmation_options(user_id)
# Функция для сохранения ответа в базе данных
async def save_answer(user_id, question_id, answer):
cursor.execute("INSERT INTO answers (user_id, question_id, answer) VALUES (?, ?, ?)", (user_id, question_id, answer))
conn.commit()
# Функция для отображения опций подтверждения
async def show_confirmation_options(user_id):
cursor.execute("SELECT answer FROM answers WHERE user_id=? ORDER BY question_id", (user_id,))
answers = cursor.fetchall()
answer_text = "\n".join([f"{questions[i+1]}: {answers[i][0]}" for i in range(6)])
await bot.send_message(user_id, text=f"Ваши ответы:\n\n{answer_text}")
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Отправить", callback_data="send_answers")],
[InlineKeyboardButton(text="Переписать", callback_data="rewrite_answers")]
])
await bot.send_message(user_id, "Проверьте свои ответы. Выберите действие:", reply_markup=keyboard)
# Обработчик выбора действия подтверждения
@dp.callback_query_handler(lambda query: query.data in ['send_answers', 'rewrite_answers'])
async def handle_confirmation(query: types.CallbackQuery):
user_id = query.from_user.id
if query.data == "send_answers":
await send_answers_to_group(user_id)
elif query.data == "rewrite_answers":
await rewrite_answers(user_id)
# Функция для отправки ответов в группу
async def send_answers_to_group(user_id):
cursor.execute("SELECT * FROM answers WHERE user_id=?", (user_id,))
answers = cursor.fetchall()
if answers:
answer_text = '\n'.join([f"{questions[ans[1]]}: {ans[2]}" for ans in answers])
# Очищаем таблицу с ответами
cursor.execute("DELETE FROM answers WHERE user_id=?", (user_id,))
conn.commit()
# Отправляем ответы в группу
await bot.send_message(GROUP_ID, answer_text)
await bot.send_message(user_id, "Ваши ответы отправлены.")
else:
await bot.send_message(user_id, "Ответов нет")
# Функция для переписывания ответов
async def rewrite_answers(user_id):
# Очищаем таблицу с ответами
cursor.execute("DELETE FROM answers WHERE user_id=?", (user_id,))
conn.commit()
await bot.send_message(user_id, "Ваши ответы удалены. Начнем сначала.")
await ask_question(user_id, 1)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
loop.create_task(dp.start_polling())
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
conn.close()

17
old/logger.py Normal file
View File

@@ -0,0 +1,17 @@
import logging
import sqlite3
# Настройка логирования
logging.basicConfig(filename='bot.log', level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
def log_action(user_id, action, details=""):
logging.info(f"User ID: {user_id} - Action: {action} - Details: {details}")
def log_action(user_id, action):
conn = sqlite3.connect('bot_klining.db')
cursor = conn.cursor()
cursor.execute('INSERT INTO logs (user_id, action) VALUES ((SELECT id FROM users WHERE telegram_id = ?), ?)', (user_id, action))
conn.commit()
conn.close()

213
old/main(OLD).py Normal file
View File

@@ -0,0 +1,213 @@
import logging
import sqlite3
import asyncio
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
# Устанавливаем уровень логов
logging.basicConfig(level=logging.INFO)
# Подключаемся к базе данных SQLite
conn = sqlite3.connect("answers.db")
cursor = conn.cursor()
# Создание таблицы для хранения ответов
cursor.execute("""
CREATE TABLE IF NOT EXISTS answers (
user_id INTEGER,
question_id INTEGER,
answer TEXT
)
""")
conn.commit()
# Заменить на свой токен
API_TOKEN = '7472030348:AAGI53nX-ON-WBmEhd_qBC6EnZsHOqp_2kE'
GROUP_ID = '-1001961537659'
# Инициализация бота и диспетчера
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
dp.middleware.setup(LoggingMiddleware())
# Словарь для хранения вопросов и ответов
questions = {
1: "Как вас зовут?",
2: "Укажите номер телефона для связи",
3: "Укажите район, улицу, дом",
4: "Какая уборка нужна, влажная или сухая?",
5: "На какое время?",
6: "Оплата наличными или картой?"
}
answer_map = {
'wet_cleaning': 'Влажная уборка',
'dry_cleaning': 'Сухая уборка',
'morning_time': 'Утро',
'day_time': 'День',
'evening_time': 'Вечер',
'cash_payment': 'Наличные',
'card_payment': 'Карта'
}
# Обработчик команды /start
@dp.message_handler(commands=['start'])
async def start(message: types.Message):
if message.chat.id != int(GROUP_ID):
await message.answer("Привет! Я задам тебе 6 вопросов. Давай начнем.")
await ask_question(message.chat.id, 1)
# Функция для задания вопроса
async def ask_question(user_id, question_id):
if question_id in [4, 5, 6]:
if question_id == 4:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Влажная", callback_data="wet_cleaning")],
[InlineKeyboardButton(text="Сухая", callback_data="dry_cleaning")]
])
elif question_id == 5:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Утро", callback_data="morning_time")],
[InlineKeyboardButton(text="День", callback_data="day_time")],
[InlineKeyboardButton(text="Вечер", callback_data="evening_time")]
])
elif question_id == 6:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Наличные", callback_data="cash_payment")],
[InlineKeyboardButton(text="Карта", callback_data="card_payment")]
])
await bot.send_message(user_id, text=questions[question_id], reply_markup=keyboard)
else:
await bot.send_message(user_id, text=questions[question_id])
# Обработчик текстовых ответов на первые три вопроса
@dp.message_handler(lambda message: message.text not in ["Переписать", "Отправить"])
async def handle_text_answer(message: types.Message):
if message.chat.id != int(GROUP_ID):
user_id = message.chat.id
cursor.execute("SELECT MAX(question_id) FROM answers WHERE user_id=?", (user_id,))
prev_question_id = cursor.fetchone()[0]
if prev_question_id is None:
question_id = 1
else:
question_id = prev_question_id + 1
answer = message.text
await save_answer(user_id, question_id, answer)
if question_id < 6:
await ask_question(user_id, question_id + 1)
else:
await show_confirmation_options(user_id)
# Обработчик inline-кнопок
@dp.callback_query_handler(lambda query: query.data in answer_map.keys())
async def handle_callback_answer(query: types.CallbackQuery):
user_id = query.from_user.id
cursor.execute("SELECT MAX(question_id) FROM answers WHERE user_id=?", (user_id,))
prev_question_id = cursor.fetchone()[0]
if prev_question_id is None:
question_id = 1
else:
question_id = prev_question_id + 1
await save_answer(user_id, question_id, answer_map[query.data])
await query.answer()
if question_id < 6:
await ask_question(user_id, question_id + 1)
else:
await show_confirmation_options(user_id)
# Функция для сохранения ответа в базе данных
async def save_answer(user_id, question_id, answer):
cursor.execute("INSERT INTO answers (user_id, question_id, answer) VALUES (?, ?, ?)", (user_id, question_id, answer))
conn.commit()
# Функция для отображения опций подтверждения
async def show_confirmation_options(user_id):
cursor.execute("SELECT answer FROM answers WHERE user_id=? ORDER BY question_id", (user_id,))
answers = cursor.fetchall()
answer_text = "\n".join([f"{questions[i+1]}: {answers[i][0]}" for i in range(6)])
await bot.send_message(user_id, text=f"Ваши ответы:\n\n{answer_text}")
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Отправить", callback_data="send_answers")],
[InlineKeyboardButton(text="Переписать", callback_data="rewrite_answers")]
])
await bot.send_message(user_id, "Проверьте свои ответы. Выберите действие:", reply_markup=keyboard)
# Обработчик выбора действия подтверждения
@dp.callback_query_handler(lambda query: query.data in ['send_answers', 'rewrite_answers'])
async def handle_confirmation(query: types.CallbackQuery):
user_id = query.from_user.id
if query.data == "send_answers":
await send_answers_to_group(user_id)
elif query.data == "rewrite_answers":
await rewrite_answers(user_id)
# Функция для отправки ответов в группу
async def send_answers_to_group(user_id):
cursor.execute("SELECT * FROM answers WHERE user_id=?", (user_id,))
answers = cursor.fetchall()
if answers:
answer_text = '\n'.join([f"{questions[ans[1]]}: {ans[2]}" for ans in answers])
# Очищаем таблицу с ответами
cursor.execute("DELETE FROM answers WHERE user_id=?", (user_id,))
conn.commit()
# Отправляем ответы в группу и добавляем ID пользователя
sent_message = await bot.send_message(GROUP_ID, f"Ответы от пользователя {user_id}:\n\n{answer_text}")
await bot.send_message(user_id, f"Ваши ответы отправлены. Можете посмотреть их [здесь](https://t.me/{sent_message.chat.username}/{sent_message.message_id})",
parse_mode='Markdown')
else:
await bot.send_message(user_id, "Ответов нет")
# Функция для переписывания ответов
async def rewrite_answers(user_id):
# Очищаем таблицу с ответами
cursor.execute("DELETE FROM answers WHERE user_id=?", (user_id,))
conn.commit()
await bot.send_message(user_id, "Ваши ответы удалены. Начнем сначала.")
await ask_question(user_id, 1)
# Функция для обработки сообщений из группы и пересылки их пользователю
@dp.message_handler(lambda message: message.chat.id == int(GROUP_ID) and message.reply_to_message)
async def handle_group_reply(message: types.Message):
# Проверяем, что сообщение является ответом на сообщение бота
if message.reply_to_message.from_user.id == bot.id:
# Извлекаем ID пользователя из текста сообщения
try:
user_id = int(message.reply_to_message.text.split()[2].strip(':'))
await bot.send_message(user_id, f"Сообщение от администратора:\n\n{message.text}")
# Сохраняем ответ пользователя для пересылки обратно в группу
cursor.execute("INSERT INTO admin_user_conversation (user_id, admin_message_id) VALUES (?, ?)",
(user_id, message.message_id))
conn.commit()
except (IndexError, ValueError):
await message.reply("Не удалось определить ID пользователя для ответа.")
# Обработчик сообщений от пользователя в ответ на администратора
@dp.message_handler(lambda message: message.chat.id != int(GROUP_ID))
async def handle_user_reply(message: types.Message):
user_id = message.chat.id
cursor.execute("SELECT admin_message_id FROM admin_user_conversation WHERE user_id=? ORDER BY admin_message_id DESC LIMIT 1", (user_id,))
admin_message_id = cursor.fetchone()
if admin_message_id:
await bot.send_message(GROUP_ID, f"Сообщение от пользователя {user_id}:\n\n{message.text}", reply_to_message_id=admin_message_id[0])
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
loop.create_task(dp.start_polling())
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
conn.close()

221
old/main.py Normal file
View File

@@ -0,0 +1,221 @@
import logging
import sqlite3
import asyncio
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.dispatcher.filters import Command
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
# Устанавливаем уровень логов
logging.basicConfig(level=logging.INFO)
# Подключаемся к базе данных SQLite
conn = sqlite3.connect("answers.db")
cursor = conn.cursor()
# Создание таблицы для хранения ответов
cursor.execute("""
CREATE TABLE IF NOT EXISTS answers (
user_id INTEGER,
question_id INTEGER,
answer TEXT
)
""")
conn.commit()
# Заменить на свой токен
API_TOKEN = '7472030348:AAGI53nX-ON-WBmEhd_qBC6EnZsHOqp_2kE'
GROUP_ID = '-1001961537659'
# Инициализация бота и диспетчера
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
dp.middleware.setup(LoggingMiddleware())
# Словарь для хранения вопросов и ответов
questions = {
1: "Как вас зовут?",
2: "Укажите номер телефона для связи",
3: "Укажите район, улицу, дом",
4: "Какая уборка нужна, влажная или сухая?",
5: "На какое время?",
6: "Оплата наличными или картой?"
}
answer_map = {
'wet_cleaning': 'Влажная уборка',
'dry_cleaning': 'Сухая уборка',
'morning_time': 'Утро',
'day_time': 'День',
'evening_time': 'Вечер',
'cash_payment': 'Наличные',
'card_payment': 'Карта'
}
# Обработчик команды /start
@dp.message_handler(commands=['start'])
async def start(message: types.Message):
if message.chat.id != int(GROUP_ID):
await message.answer("Привет! Я задам тебе 6 вопросов Чтобы создать заказ. Давай начнем.")
await ask_question(message.chat.id, 1)
@dp.message_handler(Command("start"))
async def show_menu(message: types.Message):
await message.reply("Выбери действие:", reply_markup=ReplyKeyboardMarkup(
resize_keyboard=True).add(KeyboardButton("Создать заказ")))
# Функция для задания вопроса
async def ask_question(user_id, question_id):
if question_id in [4, 5, 6]:
if question_id == 4:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Влажная", callback_data="wet_cleaning")],
[InlineKeyboardButton(text="Сухая", callback_data="dry_cleaning")]
])
elif question_id == 5:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Утро", callback_data="morning_time")],
[InlineKeyboardButton(text="День", callback_data="day_time")],
[InlineKeyboardButton(text="Вечер", callback_data="evening_time")]
])
elif question_id == 6:
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Наличные", callback_data="cash_payment")],
[InlineKeyboardButton(text="Карта", callback_data="card_payment")]
])
await bot.send_message(user_id, text=questions[question_id], reply_markup=keyboard)
else:
await bot.send_message(user_id, text=questions[question_id])
# Обработчик текстовых ответов на первые три вопроса
@dp.message_handler(lambda message: message.text not in ["Переписать", "Отправить"])
async def handle_text_answer(message: types.Message):
if message.chat.id != int(GROUP_ID):
user_id = message.chat.id
cursor.execute("SELECT MAX(question_id) FROM answers WHERE user_id=?", (user_id,))
prev_question_id = cursor.fetchone()[0]
if prev_question_id is None:
question_id = 1
else:
question_id = prev_question_id + 1
answer = message.text
await save_answer(user_id, question_id, answer)
if question_id < 6:
await ask_question(user_id, question_id + 1)
else:
await show_confirmation_options(user_id)
# Обработчик inline-кнопок
@dp.callback_query_handler(lambda query: query.data in answer_map.keys())
async def handle_callback_answer(query: types.CallbackQuery):
user_id = query.from_user.id
cursor.execute("SELECT MAX(question_id) FROM answers WHERE user_id=?", (user_id,))
prev_question_id = cursor.fetchone()[0]
if prev_question_id is None:
question_id = 1
else:
question_id = prev_question_id + 1
await save_answer(user_id, question_id, answer_map[query.data])
await query.answer()
if question_id < 6:
await ask_question(user_id, question_id + 1)
else:
await show_confirmation_options(user_id)
# Функция для сохранения ответа в базе данных
async def save_answer(user_id, question_id, answer):
cursor.execute("INSERT INTO answers (user_id, question_id, answer) VALUES (?, ?, ?)", (user_id, question_id, answer))
conn.commit()
# Функция для отображения опций подтверждения
async def show_confirmation_options(user_id):
cursor.execute("SELECT answer FROM answers WHERE user_id=? ORDER BY question_id", (user_id,))
answers = cursor.fetchall()
answer_text = "\n".join([f"{questions[i+1]}: {answers[i][0]}" for i in range(6)])
await bot.send_message(user_id, text=f"Ваши ответы:\n\n{answer_text}")
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Отправить", callback_data="send_answers")],
[InlineKeyboardButton(text="Переписать", callback_data="rewrite_answers")]
])
await bot.send_message(user_id, "Проверьте свои ответы. Выберите действие:", reply_markup=keyboard)
# Обработчик выбора действия подтверждения
@dp.callback_query_handler(lambda query: query.data in ['send_answers', 'rewrite_answers'])
async def handle_confirmation(query: types.CallbackQuery):
user_id = query.from_user.id
if query.data == "send_answers":
await send_answers_to_group(user_id)
elif query.data == "rewrite_answers":
await rewrite_answers(user_id)
# Функция для отправки ответов в группу
async def send_answers_to_group(user_id):
cursor.execute("SELECT * FROM answers WHERE user_id=?", (user_id,))
answers = cursor.fetchall()
if answers:
answer_text = '\n'.join([f"{questions[ans[1]]}: {ans[2]}" for ans in answers])
# Очищаем таблицу с ответами
cursor.execute("DELETE FROM answers WHERE user_id=?", (user_id,))
conn.commit()
# Отправляем ответы в группу и добавляем ID пользователя
sent_message = await bot.send_message(GROUP_ID, f"Ответы от пользователя {user_id}:\n\n{answer_text}")
await bot.send_message(user_id, f"Ваши ответы отправлены. Оператор с вами свяжится)",
parse_mode='Markdown')
else:
await bot.send_message(user_id, "Ответов нет")
# Функция для переписывания ответов
async def rewrite_answers(user_id):
# Очищаем таблицу с ответами
cursor.execute("DELETE FROM answers WHERE user_id=?", (user_id,))
conn.commit()
await bot.send_message(user_id, "Ваши ответы удалены. Начнем сначала.")
await ask_question(user_id, 1)
# Функция для обработки сообщений из группы и пересылки их пользователю
@dp.message_handler(lambda message: message.chat.id == int(GROUP_ID) and message.reply_to_message)
async def handle_group_reply(message: types.Message):
# Проверяем, что сообщение является ответом на сообщение бота
if message.reply_to_message.from_user.id == bot.id:
# Извлекаем ID пользователя из текста сообщения
try:
user_id = int(message.reply_to_message.text.split()[2].strip(':'))
await bot.send_message(user_id, f"Сообщение от администратора:\n\n{message.text}")
# Сохраняем ответ пользователя для пересылки обратно в группу
cursor.execute("INSERT INTO admin_user_conversation (user_id, admin_message_id) VALUES (?, ?)",
(user_id, message.message_id))
conn.commit()
except (IndexError, ValueError):
await message.reply("Не удалось определить ID пользователя для ответа.")
# Обработчик сообщений от пользователя в ответ на администратора
@dp.message_handler(lambda message: message.chat.id != int(GROUP_ID))
async def handle_user_reply(message: types.Message):
user_id = message.chat.id
cursor.execute("SELECT admin_message_id FROM admin_user_conversation WHERE user_id=? ORDER BY admin_message_id DESC LIMIT 1", (user_id,))
admin_message_id = cursor.fetchone()
if admin_message_id:
await bot.send_message(GROUP_ID, f"Сообщение от пользователя {user_id}:\n\n{message.text}", reply_to_message_id=admin_message_id[0])
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
loop.create_task(dp.start_polling())
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
conn.close()

76
old/remain.py Normal file
View File

@@ -0,0 +1,76 @@
import logging
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Command
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
API_TOKEN = '7472030348:AAGI53nX-ON-WBmEhd_qBC6EnZsHOqp_2kE'
GROUP_ID = '-1001961537659'
logging.basicConfig(level=logging.INFO)
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
dp.middleware.setup(LoggingMiddleware())
# Define states
class OrderForm(StatesGroup):
question_1 = State()
question_2 = State()
question_3 = State()
question_4 = State()
question_5 = State()
question_6 = State()
@dp.message_handler(Command("start"))
async def cmd_start(message: types.Message):
await message.reply("Привет! Чтобы создать заказ, нажми на кнопку 'Создать заказ' внизу.", reply_markup=ReplyKeyboardMarkup(
resize_keyboard=True).add(KeyboardButton("Создать заказ")))
@dp.message_handler(Command("menu"))
async def show_menu(message: types.Message):
await message.reply("Выбери действие:", reply_markup=ReplyKeyboardMarkup(
resize_keyboard=True).add(KeyboardButton("Создать заказ")))
@dp.message_handler(Command("create_order"))
async def cmd_create_order(message: types.Message):
await OrderForm.question_1.set()
await message.reply("Ответьте на первый вопрос:")
@dp.message_handler(state=OrderForm.question_1)
async def process_question_1(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['question_1'] = message.text
await OrderForm.next()
await message.reply("Ответьте на второй вопрос:")
# Аналогично для остальных вопросов
@dp.message_handler(state=OrderForm.question_6)
async def process_question_6(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['question_6'] = message.text
await message.reply("Отлично! Ваши ответы:")
async with state.proxy() as data:
for key, value in data.items():
await message.reply(f"{key}: {value}")
# Предложить отправить или переписать ответы
keyboard = InlineKeyboardMarkup().add(InlineKeyboardButton("Отправить", callback_data="send_order")).add(InlineKeyboardButton("Переписать", callback_data="rewrite_order"))
await message.reply("Хотите отправить эти ответы или переписать?", reply_markup=keyboard)
@dp.callback_query_handler(text="send_order", state="*")
async def send_order(callback_query: types.CallbackQuery, state: FSMContext):
async with state.proxy() as data:
for key, value in data.items():
await bot.send_message(callback_query.from_user.id, f"{key}: {value}")
@dp.callback_query_handler(text="rewrite_order", state="*")
async def rewrite_order(callback_query: types.CallbackQuery):
await cmd_create_order(callback_query.message)
if __name__ == '__main__':
from aiogram import executor
executor.start_polling(dp, skip_updates=True)