135 lines
4.7 KiB
Python
135 lines
4.7 KiB
Python
"""
|
||
Бот поддержки. Пользователи пишут боту — сообщения приходят админу.
|
||
Админ отвечает reply'ем — ответ уходит пользователю.
|
||
|
||
Запуск: python support_bot.py
|
||
Настройка в .env:
|
||
SUPPORT_BOT_TOKEN=...
|
||
SUPPORT_ADMIN_ID=... (ваш Telegram user_id)
|
||
"""
|
||
|
||
import asyncio
|
||
import logging
|
||
import os
|
||
from dotenv import load_dotenv
|
||
|
||
from aiogram import Bot, Dispatcher, F
|
||
from aiogram.types import Message
|
||
from aiogram.client.session.aiohttp import AiohttpSession
|
||
from aiogram.filters import CommandStart
|
||
|
||
load_dotenv()
|
||
|
||
TOKEN = os.getenv("SUPPORT_BOT_TOKEN", "")
|
||
ADMIN_ID = int(os.getenv("SUPPORT_ADMIN_ID", "0"))
|
||
|
||
logging.basicConfig(level=logging.INFO)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
bot = Bot(token=TOKEN)
|
||
dp = Dispatcher()
|
||
|
||
# user_id → message_id в чате с админом (для сопоставления ответов)
|
||
user_to_admin_msg: dict[int, int] = {}
|
||
# message_id в чате с админом → user_id
|
||
admin_msg_to_user: dict[int, int] = {}
|
||
|
||
|
||
@dp.message(CommandStart())
|
||
async def cmd_start(message: Message):
|
||
await message.answer(
|
||
"👋 Привет! Напишите своё сообщение — мы ответим как можно скорее."
|
||
)
|
||
|
||
|
||
@dp.message(F.chat.id == ADMIN_ID, F.reply_to_message)
|
||
async def admin_reply(message: Message):
|
||
"""Админ отвечает reply'ем — пересылаем пользователю."""
|
||
replied_id = message.reply_to_message.message_id
|
||
user_id = admin_msg_to_user.get(replied_id)
|
||
|
||
if not user_id:
|
||
await message.answer("⚠️ Не удалось найти пользователя для этого сообщения.")
|
||
return
|
||
|
||
try:
|
||
if message.text:
|
||
await bot.send_message(user_id, f"💬 Поддержка:\n\n{message.text}")
|
||
elif message.photo:
|
||
await bot.send_photo(user_id, message.photo[-1].file_id, caption=message.caption or "")
|
||
elif message.document:
|
||
await bot.send_document(user_id, message.document.file_id, caption=message.caption or "")
|
||
elif message.voice:
|
||
await bot.send_voice(user_id, message.voice.file_id)
|
||
elif message.sticker:
|
||
await bot.send_sticker(user_id, message.sticker.file_id)
|
||
else:
|
||
await bot.copy_message(user_id, message.chat.id, message.message_id)
|
||
|
||
await message.react([{"type": "emoji", "emoji": "✅"}])
|
||
except Exception as e:
|
||
await message.answer(f"❌ Не удалось отправить: {e}")
|
||
|
||
|
||
@dp.message(F.chat.id != ADMIN_ID)
|
||
async def user_message(message: Message):
|
||
"""Сообщение от пользователя — пересылаем админу."""
|
||
user = message.from_user
|
||
name = f"@{user.username}" if user.username else user.full_name
|
||
header = f"👤 {name} [<code>{user.id}</code>]:\n\n"
|
||
|
||
try:
|
||
if message.text:
|
||
sent = await bot.send_message(
|
||
ADMIN_ID,
|
||
header + message.text,
|
||
parse_mode="HTML"
|
||
)
|
||
elif message.photo:
|
||
sent = await bot.send_photo(
|
||
ADMIN_ID,
|
||
message.photo[-1].file_id,
|
||
caption=header + (message.caption or ""),
|
||
parse_mode="HTML"
|
||
)
|
||
elif message.document:
|
||
sent = await bot.send_document(
|
||
ADMIN_ID,
|
||
message.document.file_id,
|
||
caption=header + (message.caption or ""),
|
||
parse_mode="HTML"
|
||
)
|
||
elif message.voice:
|
||
sent = await bot.send_voice(
|
||
ADMIN_ID,
|
||
message.voice.file_id,
|
||
caption=header,
|
||
parse_mode="HTML"
|
||
)
|
||
else:
|
||
await bot.send_message(ADMIN_ID, header, parse_mode="HTML")
|
||
sent = await bot.copy_message(ADMIN_ID, message.chat.id, message.message_id)
|
||
|
||
# Запоминаем связку
|
||
admin_msg_to_user[sent.message_id] = user.id
|
||
user_to_admin_msg[user.id] = sent.message_id
|
||
|
||
await message.answer("✅ Сообщение отправлено. Ожидайте ответа.")
|
||
except Exception as e:
|
||
logger.error(f"Error forwarding message: {e}")
|
||
await message.answer("❌ Ошибка отправки. Попробуйте позже.")
|
||
|
||
|
||
async def main():
|
||
if not TOKEN:
|
||
raise ValueError("SUPPORT_BOT_TOKEN не задан в .env")
|
||
if not ADMIN_ID:
|
||
raise ValueError("SUPPORT_ADMIN_ID не задан в .env")
|
||
|
||
logger.info(f"Support bot started, admin: {ADMIN_ID}")
|
||
await dp.start_polling(bot)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(main())
|