Реализация чата в Aiogram через бота
Не работает пересылка сообщений между пользователями через бот, я новичок в питоне, помогите пожалуйста решить задачу.
import asyncio
import logging
import os
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import Command, StateFilter
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.fsm.state import State, StatesGroup
from aiogram.fsm.context import FSMContext
from aiogram.fsm.storage.memory import MemoryStorage
from dotenv import load_dotenv
load_dotenv()
API_TOKEN = os.getenv('API_TOKEN') # Токен вашего бота
CHANNEL_ID = os.getenv('CHANNEL_ID') # ID вашего канала (может быть отрицательным для приватного канала)
logging.basicConfig(level=logging.DEBUG)
bot = Bot(token=API_TOKEN)
dp = Dispatcher(storage=MemoryStorage())
class ChatStates(StatesGroup):
in_chat = State() # Состояние активного чата
# Словарь для хранения активных чатов
active_chats = {}
@dp.message(Command("start"))
async def start(message: types.Message):
logging.debug("Команда /start получена.")
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Да", callback_data="yes"), InlineKeyboardButton(text="Нет", callback_data="no")]
])
await message.answer("Хочешь пообщаться?", reply_markup=keyboard)
# Обработка ответа "Да"
@dp.callback_query(F.data == "yes")
async def process_callback(callback_query: types.CallbackQuery):
user_id = callback_query.from_user.id
logging.debug(f"Пользователь {user_id} нажал 'Да'")
chat_button = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Начать чат", callback_data=f"start_chat:{user_id}")]
])
# Отправка сообщения в канал с кнопкой для начала чата
await bot.send_message(CHANNEL_ID, "Знакомство в слепую. Нажмите, чтобы начать чат!", reply_markup=chat_button)
await callback_query.message.answer("Сообщение отправлено в канал. Ждем ответа от собеседника.")
await callback_query.answer()
# Обработка ответа "Нет"
@dp.callback_query(F.data == "no")
async def process_no(callback_query: types.CallbackQuery):
await callback_query.message.answer("Пока приходи еще!")
# Начало чата
@dp.callback_query(lambda c: c.data.startswith("start_chat"))
async def start_chat(callback_query: types.CallbackQuery, state: FSMContext):
user1_id = int(callback_query.data.split(":")[1]) # ID первого пользователя
user2_id = callback_query.from_user.id # ID второго пользователя
if user1_id == user2_id:
await callback_query.message.answer("Вы не можете начать чат с самим собой.")
return
# Устанавливаем активный чат
active_chats[user1_id] = user2_id
active_chats[user2_id] = user1_id
logging.debug(f"Чат начался между пользователями {user1_id} и {user2_id}")
# Устанавливаем состояние чата для обоих пользователей
await state.set_state(ChatStates.in_chat)
await state.update_data(partner_id=user2_id)
# Уведомляем пользователей о начале чата
await bot.send_message(user1_id, "Чат начался. Вы можете отправлять сообщения собеседнику.")
await bot.send_message(user2_id, "Чат начался. Вы можете отправлять сообщения собеседнику.")
# Логируем успешный переход в состояние
logging.debug(f"Пользователь {user1_id} и {user2_id} находятся в состоянии чата.")
@dp.message(StateFilter(ChatStates.in_chat))
async def chat_message_handler(message: types.Message, state: FSMContext):
sender_id = message.from_user.id
logging.debug(f"Получено сообщение от {sender_id}: {message.text}")
# Получаем ID собеседника
data = await state.get_data()
recipient_id = data.get('partner_id')
if recipient_id and recipient_id in active_chats: # Проверяем, что у собеседника активный чат
logging.debug(f"Отправка сообщения пользователю {recipient_id}")
await bot.send_message(recipient_id, f"Сообщение от собеседника: {message.text}")
else:
logging.warning(f"Пользователь {sender_id} попытался отправить сообщение, но чата нет.")
await message.answer("Ваш чат завершен или собеседник отключился.")
logging.debug(f"Получено сообщение от {sender_id} вне активного чата.")
# Для обработки всех других сообщений
@dp.message()
async def handle_unhandled_messages(message: types.Message):
logging.warning(f"Необработанное сообщение от {message.from_user.id}: {message.text}")
await message.answer("Ваше сообщение не было обработано, возможно, вы не находитесь в активном чате.")
# Завершение чата
@dp.message(Command("end_chat"), StateFilter(ChatStates.in_chat))
async def end_chat(message: types.Message, state: FSMContext):
user_id = message.from_user.id
partner_id = active_chats.get(user_id)
if partner_id:
await bot.send_message(partner_id, "Ваш собеседник завершил чат.")
await bot.send_message(user_id, "Вы завершили чат.")
# Удаляем участников из активных чатов и очищаем состояние
del active_chats[user_id]
del active_chats[partner_id]
await state.clear()
await dp.fsm.storage.get_context(bot=bot, user=partner_id).clear()
logging.debug(f"Чат завершен между {user_id} и {partner_id}.")
else:
await message.answer("У вас нет активного чата для завершения.")
logging.warning(f"Пользователь {user_id} попытался завершить несуществующий чат.")
async def main():
await bot.delete_webhook(drop_pending_updates=True)
await dp.start_polling(bot)
if __name__ == "__main__":
try:
logging.debug("Запуск бота...")
asyncio.run(main())
except Exception as e:
logging.error(f"Произошла ошибка: {e}")