from telegram import Update from telegram.constants import ParseMode, ChatType from telegram.ext import ContextTypes from telegram.error import BadRequest from app.bot.messages import ( ASK_ADD_GROUP, GROUP_BOUND, NEED_ADD_FIRST, NO_RIGHTS_CHANNEL, NO_RIGHTS_GROUP, ONLY_ADMINS_CAN_BIND, ALREADY_BOUND, ) from app.db.session import get_session from app.db.models import User, Chat from .utils import parse_chat_id, verify_and_fetch_chat STATE_KEY = "await_chat_id" def _get_forwarded_chat_id(message) -> int | None: fwd_chat = getattr(message, "forward_from_chat", None) if fwd_chat: return fwd_chat.id origin = getattr(message, "forward_origin", None) if origin: chat = getattr(origin, "chat", None) if chat: return chat.id return None async def add_group_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE): with get_session() as s: u = s.query(User).filter_by(tg_id=update.effective_user.id).first() if not u: u = User(tg_id=update.effective_user.id, name=update.effective_user.full_name) s.add(u); s.commit() ctx.user_data[STATE_KEY] = True await update.effective_message.reply_text(ASK_ADD_GROUP, parse_mode=ParseMode.MARKDOWN) async def add_group_capture(update: Update, ctx: ContextTypes.DEFAULT_TYPE): if update.effective_chat.type != ChatType.PRIVATE: return if not ctx.user_data.get(STATE_KEY): return msg = update.effective_message raw = _get_forwarded_chat_id(msg) if not raw: txt = (getattr(msg, "text", None) or getattr(msg, "caption", None) or "").strip() if not txt: await msg.reply_text("Вставьте chat_id или перешлите сообщение из группы/канала.") return if txt.startswith("@") or "t.me/" in txt: raw = txt else: cid = parse_chat_id(txt) if cid is None: await msg.reply_text("Не удалось распознать chat_id. Пример: -1001234567890 или @username.") return raw = cid # Проверяем наличие бота в чате и его право постить try: chat, member_bot, can_post = await verify_and_fetch_chat(ctx, raw) except BadRequest: await msg.reply_text("Такого чата не существует или у меня нет доступа. Проверьте chat_id/username.") return if member_bot is None: await msg.reply_text(NEED_ADD_FIRST.format(title_or_id=(chat.title or chat.id))) return # --- Новое: проверяем, что привязку делает АДМИН этого чата/канала --- try: user_member = await ctx.bot.get_chat_member(chat.id, update.effective_user.id) user_status = getattr(user_member, "status", "") is_admin = user_status in ("administrator", "creator") except Exception: is_admin = False if not is_admin: await msg.reply_text(ONLY_ADMINS_CAN_BIND) return with get_session() as s: me = s.query(User).filter_by(tg_id=update.effective_user.id).first() row = s.query(Chat).filter_by(chat_id=chat.id).first() # Если уже привязан к другому владельцу — запрещаем if row and row.owner_user_id and row.owner_user_id != me.id: await msg.reply_text(ALREADY_BOUND) ctx.user_data.pop(STATE_KEY, None) return if not row: row = Chat( chat_id=chat.id, type=chat.type, title=chat.title, owner_user_id=me.id, can_post=can_post, ) s.add(row) else: row.title = chat.title row.type = chat.type row.owner_user_id = row.owner_user_id or me.id row.can_post = can_post s.commit() ctx.user_data.pop(STATE_KEY, None) rights = ( "✅ У меня есть право публиковать." if can_post else (NO_RIGHTS_CHANNEL if chat.type == ChatType.CHANNEL else NO_RIGHTS_GROUP) ) await msg.reply_text(GROUP_BOUND.format(title_or_id=(chat.title or chat.id), rights=rights))