Files
tg_post_min/app/bot/handlers/add_group.py
2025-08-20 21:53:40 +09:00

120 lines
4.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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))