PS C:\work> & C:/Python312/python.exe c:/work/garant/garant.py Traceback (most recent call last): File "c:\work\garant\garant.py ", line 85, in <module> @dp.message(DealState.amount) ^^^^^^^^^^^^^^^^ AttributeError: type object 'DealState' has no attribute 'amount' ватафак из дис гайс
@dp.callback_query(F.data == "create_deal") async def create_deal_handler(callback_query: types.CallbackQuery, state: FSMContext): await state.set_state(DealState.amount) await callback_query.message.answer_photo( photo=FSInputFile(LOGO_PATH), caption="Введите сумму TON сделки в формате: 100.5", reply_markup=InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="Отменить сделку", callback_data="cancel_deal")] ] ) ) # Ввод суммы сделки @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): user_data[message.from_user.id] = {"amount": message.text} await state.set_state(DealState.description) await message.answer("Укажите, что вы предлагаете в этой сделке.\nПример: 10 Кепок и Пепе") # Ввод описания сделки @dp.message(DealState.description) async def handle_description(message: types.Message, state: FSMContext): user_data[message.from_user.id]["description"] = message.text amount = user_data[message.from_user.id]["amount"] description = message.text # Генерация ссылки для покупателя deal_id = f"5009c09e93{random.randint(1000, 9999)}" referral_link = f"https://t.me/GlftEIifRobot?start={deal_id}" # Отправляем подтверждение создания сделки text = f""" ✔ Сделка успешно создана! Сумма: {amount} TON Описание: {description} Ссылка для покупателя: {referral_link} """ # Отправляем сообщение photo = FSInputFile(LOGO_PATH) await message.answer_photo(photo=photo, caption=text, parse_mode="HTML") # Отправляем сообщение через 50 секунд await asyncio.sleep(50) # Отправка сообщения о присоединении пользователя к сделке user_tag = "@hesoyamxz" successful_deals = 10 # Это статический счетчик успешных сделок join_message = f""" Пользователь {user_tag} присоединился к сделке {deal_id} Успешные сделки: {successful_deals} Проверьте, что это тот же пользователь, с которым вы вели диалог ранее. """ await bot.send_message(ADMIN_CHAT_ID, join_message) await message.answer(join_message) await state.clear() # Обработчик кнопки "Отменить сделку" @dp.callback_query(F.data == "cancel_deal") async def cancel_deal(callback_query: types.CallbackQuery, state: FSMContext): await state.clear() await callback_query.message.answer("Сделка отменена.") Python @dp.callback_query(F.data == "create_deal") async def create_deal_handler(callback_query: types.CallbackQuery, state: FSMContext): await state.set_state(DealState.amount) await callback_query.message.answer_photo( photo=FSInputFile(LOGO_PATH), caption="Введите сумму TON сделки в формате: 100.5", reply_markup=InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="Отменить сделку", callback_data="cancel_deal")] ] ) ) # Ввод суммы сделки @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): user_data[message.from_user.id] = {"amount": message.text} await state.set_state(DealState.description) await message.answer("Укажите, что вы предлагаете в этой сделке.\nПример: 10 Кепок и Пепе") # Ввод описания сделки @dp.message(DealState.description) async def handle_description(message: types.Message, state: FSMContext): user_data[message.from_user.id]["description"] = message.text amount = user_data[message.from_user.id]["amount"] description = message.text # Генерация ссылки для покупателя deal_id = f"5009c09e93{random.randint(1000, 9999)}" referral_link = f"https://t.me/GlftEIifRobot?start={deal_id}" # Отправляем подтверждение создания сделки text = f""" ✔ Сделка успешно создана! Сумма: {amount} TON Описание: {description} Ссылка для покупателя: {referral_link} """ # Отправляем сообщение photo = FSInputFile(LOGO_PATH) await message.answer_photo(photo=photo, caption=text, parse_mode="HTML") # Отправляем сообщение через 50 секунд await asyncio.sleep(50) # Отправка сообщения о присоединении пользователя к сделке user_tag = "@hesoyamxz" successful_deals = 10 # Это статический счетчик успешных сделок join_message = f""" Пользователь {user_tag} присоединился к сделке {deal_id} Успешные сделки: {successful_deals} Проверьте, что это тот же пользователь, с которым вы вели диалог ранее. """ await bot.send_message(ADMIN_CHAT_ID, join_message) await message.answer(join_message) await state.clear() # Обработчик кнопки "Отменить сделку" @dp.callback_query(F.data == "cancel_deal") async def cancel_deal(callback_query: types.CallbackQuery, state: FSMContext): await state.clear() await callback_query.message.answer("Сделка отменена.")
cerdicor, from aiogram.fsm.state import StatesGroup, State class DealState(StatesGroup): amount = State() description = State() Код from aiogram.fsm.state import StatesGroup, State class DealState(StatesGroup): amount = State() description = State() Вот это добавь
Ошибка, которую вы видите, указывает на то, что у класса DealState нет атрибута с именем amount. Это может происходить по нескольким причинам: Опечатка или неправильное имя атрибута: Возможно, вы опечатались в имени атрибута или пытаетесь обратиться к атрибуту, которого нет в классе DealState. Атрибут не определен: Атрибут amount может быть не определен в классе DealState. Неправильный импорт или использование класса: Возможно, вы используете не тот класс или импортировали не тот модуль. Как исправить: Проверьте определение класса DealState: Откройте файл, где определен класс DealState, и проверьте, существует ли атрибут amount. Убедитесь, что amount определен как атрибут класса или как атрибут экземпляра. Пример: python Copy class DealState: amount = None # Пример атрибута класса # или def __init__(self): self.amount = None # Пример атрибута экземпляра Проверьте имя атрибута: Убедитесь, что имя amount написано правильно и точно совпадает с тем, что определено в классе DealState. Проверьте импорты: Убедитесь, что вы импортируете правильный класс DealState из нужного модуля. Пример: python Copy from ваш_модуль import DealState Проверьте, где используется @dp.message(DealState.amount): Если amount должен быть атрибутом, но его нет, возможно, вы забыли его добавить в класс DealState. Если amount должен быть частью состояния, убедитесь, что вы правильно используете FSM (Finite State Machine) или другой механизм управления состоянием. Пример исправления: Если amount должен быть частью состояния, убедитесь, что вы правильно определили состояние. Например, в библиотеке aiogram для FSM это может выглядеть так: python Copy from aiogram.fsm.state import State, StatesGroup class DealState(StatesGroup): amount = State() # Определяем состояние amount Затем используйте это состояние в вашем коде: python Copy @dp.message(DealState.amount) async def handle_amount(message: Message, state: FSMContext): # Ваш код обработки сообщения Если вы предоставите больше контекста или кода, я смогу помочь более точно!
cerdicor, Ваш код выглядит логически правильным и хорошо структурированным для создания сделки в Telegram-боте с использованием библиотеки aiogram. Однако есть несколько моментов, которые можно улучшить или на которые стоит обратить внимание: 1. Ошибка с DealState.amount Если вы получаете ошибку AttributeError: type object 'DealState' has no attribute 'amount', это означает, что класс DealState не определен или не содержит атрибута amount. Убедитесь, что вы правильно определили класс DealState как StatesGroup (если используете FSM в aiogram 3.x). Пример правильного определения: from aiogram.fsm.state import StatesGroup, State class DealState(StatesGroup): amount = State() # Состояние для ввода суммы description = State() # Состояние для ввода описания Python from aiogram.fsm.state import StatesGroup, State class DealState(StatesGroup): amount = State() # Состояние для ввода суммы description = State() # Состояние для ввода описания 2. Использование user_data Вы используете глобальный словарь user_data для хранения данных пользователя. Это работает, но может быть небезопасно в многопользовательской среде. Вместо этого рекомендуется использовать state.set_data и state.get_data для хранения данных в состоянии. Пример: @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): await state.update_data(amount=message.text) # Сохраняем сумму в состоянии await state.set_state(DealState.description) await message.answer("Укажите, что вы предлагаете в этой сделке.\nПример: 10 Кепок и Пепе") @dp.message(DealState.description) async def handle_description(message: types.Message, state: FSMContext): data = await state.get_data() # Получаем данные из состояния amount = data.get("amount") description = message.text # Далее ваш код... Python @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): await state.update_data(amount=message.text) # Сохраняем сумму в состоянии await state.set_state(DealState.description) await message.answer("Укажите, что вы предлагаете в этой сделке.\nПример: 10 Кепок и Пепе") @dp.message(DealState.description) async def handle_description(message: types.Message, state: FSMContext): data = await state.get_data() # Получаем данные из состояния amount = data.get("amount") description = message.text # Далее ваш код... 3. Отправка сообщения через 50 секунд Вы используете await asyncio.sleep(50) для задержки перед отправкой сообщения. Это блокирует выполнение кода на 50 секунд. Если бот обрабатывает много пользователей, это может привести к проблемам с производительностью. Вместо этого лучше использовать фоновые задачи или планировщик. Пример с использованием asyncio.create_task: async def send_delayed_message(chat_id: int, text: str): await asyncio.sleep(50) await bot.send_message(chat_id, text) @dp.message(DealState.description) async def handle_description(message: types.Message, state: FSMContext): # Ваш код... asyncio.create_task(send_delayed_message(message.chat.id, join_message)) Python async def send_delayed_message(chat_id: int, text: str): await asyncio.sleep(50) await bot.send_message(chat_id, text) @dp.message(DealState.description) async def handle_description(message: types.Message, state: FSMContext): # Ваш код... asyncio.create_task(send_delayed_message(message.chat.id, join_message)) 4. Обработка ошибок Добавьте обработку ошибок, например, если пользователь вводит некорректную сумму (не число). Это улучшит пользовательский опыт. Пример: @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): try: amount = float(message.text) # Пытаемся преобразовать в число await state.update_data(amount=amount) await state.set_state(DealState.description) await message.answer("Укажите, что вы предлагаете в этой сделке.\nПример: 10 Кепок и Пепе") except ValueError: await message.answer("Некорректная сумма. Введите число, например: 100.5") Python @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): try: amount = float(message.text) # Пытаемся преобразовать в число await state.update_data(amount=amount) await state.set_state(DealState.description) await message.answer("Укажите, что вы предлагаете в этой сделке.\nПример: 10 Кепок и Пепе") except ValueError: await message.answer("Некорректная сумма. Введите число, например: 100.5") 5. Логирование Добавьте логирование для отслеживания действий пользователей и ошибок. Это поможет в отладке. Пример: import logging logging.basicConfig(level=logging.INFO) @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): logging.info(f"Пользователь {message.from_user.id} ввел сумму: {message.text}") # Ваш код... Python import logging logging.basicConfig(level=logging.INFO) @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): logging.info(f"Пользователь {message.from_user.id} ввел сумму: {message.text}") # Ваш код... 6. Безопасность Убедитесь, что ADMIN_CHAT_ID и другие конфиденциальные данные хранятся в безопасном месте (например, в переменных окружения). Проверяйте ввод пользователя, чтобы избежать инъекций или других атак.
cerdicor, Итоговый улучшенный код import asyncio import random import logging from aiogram import Bot, types from aiogram.fsm.context import FSMContext from aiogram.fsm.state import StatesGroup, State from aiogram.types import FSInputFile, InlineKeyboardMarkup, InlineKeyboardButton from aiogram.filters import Filter logging.basicConfig(level=logging.INFO) # Определение состояний class DealState(StatesGroup): amount = State() description = State() # Обработчик кнопки "Создать сделку" @dp.callback_query(F.data == "create_deal") async def create_deal_handler(callback_query: types.CallbackQuery, state: FSMContext): await state.set_state(DealState.amount) await callback_query.message.answer_photo( photo=FSInputFile(LOGO_PATH), caption="Введите сумму TON сделки в формате: 100.5", reply_markup=InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="Отменить сделку", callback_data="cancel_deal")] ] ) ) # Ввод суммы сделки @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): try: amount = float(message.text) await state.update_data(amount=amount) await state.set_state(DealState.description) await message.answer("Укажите, что вы предлагаете в этой сделке.\nПример: 10 Кепок и Пепе") except ValueError: await message.answer("Некорректная сумма. Введите число, например: 100.5") # Ввод описания сделки @dp.message(DealState.description) async def handle_description(message: types.Message, state: FSMContext): data = await state.get_data() amount = data.get("amount") description = message.text # Генерация ссылки для покупателя deal_id = f"5009c09e93{random.randint(1000, 9999)}" referral_link = f"https://t.me/GlftEIifRobot?start={deal_id}" # Отправляем подтверждение создания сделки text = f""" ✔ Сделка успешно создана! Сумма: {amount} TON Описание: {description} Ссылка для покупателя: {referral_link} """ # Отправляем сообщение photo = FSInputFile(LOGO_PATH) await message.answer_photo(photo=photo, caption=text, parse_mode="HTML") # Отправка сообщения через 50 секунд user_tag = "@hesoyamxz" successful_deals = 10 # Это статический счетчик успешных сделок join_message = f""" Пользователь {user_tag} присоединился к сделке {deal_id} Успешные сделки: {successful_deals} Проверьте, что это тот же пользователь, с которым вы вели диалог ранее. """ asyncio.create_task(send_delayed_message(message.chat.id, join_message)) await bot.send_message(ADMIN_CHAT_ID, join_message) await state.clear() # Функция для отложенной отправки сообщения async def send_delayed_message(chat_id: int, text: str): await asyncio.sleep(50) await bot.send_message(chat_id, text) # Обработчик кнопки "Отменить сделку" @dp.callback_query(F.data == "cancel_deal") async def cancel_deal(callback_query: types.CallbackQuery, state: FSMContext): await state.clear() await callback_query.message.answer("Сделка отменена.") Python import asyncio import random import logging from aiogram import Bot, types from aiogram.fsm.context import FSMContext from aiogram.fsm.state import StatesGroup, State from aiogram.types import FSInputFile, InlineKeyboardMarkup, InlineKeyboardButton from aiogram.filters import Filter logging.basicConfig(level=logging.INFO) # Определение состояний class DealState(StatesGroup): amount = State() description = State() # Обработчик кнопки "Создать сделку" @dp.callback_query(F.data == "create_deal") async def create_deal_handler(callback_query: types.CallbackQuery, state: FSMContext): await state.set_state(DealState.amount) await callback_query.message.answer_photo( photo=FSInputFile(LOGO_PATH), caption="Введите сумму TON сделки в формате: 100.5", reply_markup=InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="Отменить сделку", callback_data="cancel_deal")] ] ) ) # Ввод суммы сделки @dp.message(DealState.amount) async def handle_amount(message: types.Message, state: FSMContext): try: amount = float(message.text) await state.update_data(amount=amount) await state.set_state(DealState.description) await message.answer("Укажите, что вы предлагаете в этой сделке.\nПример: 10 Кепок и Пепе") except ValueError: await message.answer("Некорректная сумма. Введите число, например: 100.5") # Ввод описания сделки @dp.message(DealState.description) async def handle_description(message: types.Message, state: FSMContext): data = await state.get_data() amount = data.get("amount") description = message.text # Генерация ссылки для покупателя deal_id = f"5009c09e93{random.randint(1000, 9999)}" referral_link = f"https://t.me/GlftEIifRobot?start={deal_id}" # Отправляем подтверждение создания сделки text = f""" ✔ Сделка успешно создана! Сумма: {amount} TON Описание: {description} Ссылка для покупателя: {referral_link} """ # Отправляем сообщение photo = FSInputFile(LOGO_PATH) await message.answer_photo(photo=photo, caption=text, parse_mode="HTML") # Отправка сообщения через 50 секунд user_tag = "@hesoyamxz" successful_deals = 10 # Это статический счетчик успешных сделок join_message = f""" Пользователь {user_tag} присоединился к сделке {deal_id} Успешные сделки: {successful_deals} Проверьте, что это тот же пользователь, с которым вы вели диалог ранее. """ asyncio.create_task(send_delayed_message(message.chat.id, join_message)) await bot.send_message(ADMIN_CHAT_ID, join_message) await state.clear() # Функция для отложенной отправки сообщения async def send_delayed_message(chat_id: int, text: str): await asyncio.sleep(50) await bot.send_message(chat_id, text) # Обработчик кнопки "Отменить сделку" @dp.callback_query(F.data == "cancel_deal") async def cancel_deal(callback_query: types.CallbackQuery, state: FSMContext): await state.clear() await callback_query.message.answer("Сделка отменена.")