Бот перестал реагировать на чужие группы и форвардить их сообщения
Сообщение в чате уведомлений оказалось форвардом из группы «Никитка играется с ботом», где тестовый бот был администратором: он видел сообщение прод-бота, считал отправителя посторонним и присылал access_denied с форвардом. Теперь чужие группы и каналы игнорируются полностью — и сообщения, и выходы, и callback-кнопки; личные чаты и основной чат работают как раньше.
This commit is contained in:
parent
e125d4bb0e
commit
0ae337711e
|
|
@ -158,7 +158,7 @@ make backup E=test # на домашнем сервере: ./scripts/clickho
|
|||
|
||||
## Версионирование
|
||||
|
||||
- Единый источник версии — `common/version.py` (`__version__`), текущая — `0.5.0`.
|
||||
- Единый источник версии — `common/version.py` (`__version__`), текущая — `0.5.1`.
|
||||
- Схема — SemVer-подобная (`MAJOR.MINOR.PATCH`); git-тег = `v` + версия (`v0.1`).
|
||||
- Docker-образы тегируются версией (Блок 2), события ClickHouse получают `bot_version` (Блок 3).
|
||||
- Выпуск: изменить `common/version.py` → коммит → аннотированный тег `vX.Y` → `git push --tags`.
|
||||
|
|
|
|||
|
|
@ -98,6 +98,9 @@ async def _send_fallback_welcome(event: ChatMemberUpdated, user: User) -> None:
|
|||
@router.chat_member(ChatMemberUpdatedFilter(member_status_changed=LEAVE_TRANSITION))
|
||||
async def goodbye_handler(event: ChatMemberUpdated) -> None:
|
||||
"""Пользователь вышел или был исключён — удалить данные именно его."""
|
||||
if event.chat.id != get_settings().chat_id:
|
||||
return
|
||||
|
||||
leaver = event.old_chat_member.user
|
||||
if leaver.is_bot:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from aiogram.types import CallbackQuery, Message
|
|||
from bot.keyboards import get_keyboard_donat, get_keyboard_main, get_keyboard_title
|
||||
from bot.services import access
|
||||
from bot.services import shop as shop_service
|
||||
from common.config import get_settings
|
||||
from common.texts import system
|
||||
from common.texts.render import render
|
||||
from common.texts.store import get_text
|
||||
|
|
@ -41,6 +42,15 @@ async def _render_chapter(chapter: str) -> tuple[str, object] | None:
|
|||
|
||||
@router.callback_query()
|
||||
async def callbacks_handler(callback: CallbackQuery) -> None:
|
||||
settings = get_settings()
|
||||
if (
|
||||
callback.message is not None
|
||||
and callback.message.chat.type != "private"
|
||||
and callback.message.chat.id != settings.chat_id
|
||||
):
|
||||
await callback.answer()
|
||||
return
|
||||
|
||||
answer_text = ""
|
||||
args = (callback.data or "").split("_")
|
||||
action = args[0] if args else ""
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ _ALLOWED_STATUSES = {
|
|||
ChatMemberStatus.RESTRICTED,
|
||||
}
|
||||
|
||||
|
||||
def is_allowed_chat(chat_id: int, chat_type: str, main_chat_id: int) -> bool:
|
||||
"""Личные чаты и основной чат; чужие группы/каналы игнорируются полностью."""
|
||||
return chat_type == "private" or chat_id == main_chat_id
|
||||
|
||||
|
||||
#: TTL-кеш членства, чтобы не дёргать get_chat_member на каждое сообщение.
|
||||
_MEMBERSHIP_TTL = 300.0
|
||||
_membership_cache: dict[int, tuple[float, bool]] = {}
|
||||
|
|
@ -50,6 +56,10 @@ async def check_user(message: Message) -> bool:
|
|||
if user is None:
|
||||
return False
|
||||
|
||||
# Сообщения из посторонних групп не обрабатываем и не шлём по ним уведомления.
|
||||
if not is_allowed_chat(message.chat.id, message.chat.type, settings.chat_id):
|
||||
return False
|
||||
|
||||
if user.id in settings.admin_ids or await _is_member(message.bot, user.id):
|
||||
await users_service.register_from_message(message)
|
||||
remember_user(user.id, user.username)
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
__version__ = "0.5.0"
|
||||
__version__ = "0.5.1"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
"""Тесты фильтра чатов: бот игнорирует чужие группы."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from bot.services.access import is_allowed_chat
|
||||
|
||||
|
||||
def test_private_chat_is_allowed() -> None:
|
||||
assert is_allowed_chat(123, "private", 100) is True
|
||||
|
||||
|
||||
def test_main_chat_is_allowed() -> None:
|
||||
assert is_allowed_chat(100, "supergroup", 100) is True
|
||||
assert is_allowed_chat(100, "group", 100) is True
|
||||
|
||||
|
||||
def test_foreign_group_is_ignored() -> None:
|
||||
assert is_allowed_chat(200, "supergroup", 100) is False
|
||||
assert is_allowed_chat(200, "group", 100) is False
|
||||
|
||||
|
||||
def test_foreign_channel_is_ignored() -> None:
|
||||
assert is_allowed_chat(200, "channel", 100) is False
|
||||
|
|
@ -7,4 +7,4 @@ from common import __version__
|
|||
|
||||
def test_version_is_set():
|
||||
assert __version__
|
||||
assert __version__ == "0.5.0"
|
||||
assert __version__ == "0.5.1"
|
||||
|
|
|
|||
Loading…
Reference in New Issue