Add chat_id and username Parameters to ChatJoinRequestHandler (#3261)

This commit is contained in:
miles 2022-10-02 23:54:30 +08:00 committed by GitHub
parent 2eda63e9ae
commit 26e7cd2afb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 4 deletions

View file

@ -72,6 +72,7 @@ The following wonderful people contributed directly or indirectly to this projec
- `macrojames <https://github.com/macrojames>`_
- `Matheus Lemos <https://github.com/mlemosf>`_
- `Michael Elovskikh <https://github.com/wronglink>`_
- `miles <https://github.com/miles170>`_
- `Mischa Krüger <https://github.com/Makman2>`_
- `naveenvhegde <https://github.com/naveenvhegde>`_
- `neurrone <https://github.com/neurrone>`_

View file

@ -18,16 +18,27 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the ChatJoinRequestHandler class."""
from typing import FrozenSet, Optional
from telegram import Update
from telegram._utils.defaultvalue import DEFAULT_TRUE
from telegram._utils.types import RT, SCT, DVInput
from telegram.ext._handler import BaseHandler
from telegram.ext._utils.types import CCT
from telegram.ext._utils.types import CCT, HandlerCallback
class ChatJoinRequestHandler(BaseHandler[Update, CCT]):
"""BaseHandler class to handle Telegram updates that contain
:attr:`telegram.Update.chat_join_request`.
Note:
If neither of :paramref:`username` and the :paramref:`chat_id` are passed, this handler
accepts *any* join request. Otherwise, this handler accepts all requests to join chats
for which the chat ID is listed in :paramref:`chat_id` or the username is listed in
:paramref:`username`, or both.
.. versionadded:: 20.0
Warning:
When setting :paramref:`block` to :obj:`False`, you cannot rely on adding custom
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
@ -43,6 +54,14 @@ class ChatJoinRequestHandler(BaseHandler[Update, CCT]):
The return value of the callback is usually ignored except for the special case of
:class:`telegram.ext.ConversationHandler`.
chat_id (:obj:`int` | Collection[:obj:`int`], optional): Filters requests to allow only
those which are asking to join the specified chat ID(s).
.. versionadded:: 20.0
username (:obj:`str` | Collection[:obj:`str`], optional): Filters requests to allow only
those which are asking to join the specified username(s).
.. versionadded:: 20.0
block (:obj:`bool`, optional): Determines whether the return value of the callback should
be awaited before processing the next handler in
:meth:`telegram.ext.Application.process_update`. Defaults to :obj:`True`.
@ -53,7 +72,38 @@ class ChatJoinRequestHandler(BaseHandler[Update, CCT]):
"""
__slots__ = ()
__slots__ = (
"_chat_ids",
"_usernames",
)
def __init__(
self,
callback: HandlerCallback[Update, CCT, RT],
chat_id: SCT[int] = None,
username: SCT[str] = None,
block: DVInput[bool] = DEFAULT_TRUE,
):
super().__init__(callback, block=block)
self._chat_ids = self._parse_chat_id(chat_id)
self._usernames = self._parse_username(username)
@staticmethod
def _parse_chat_id(chat_id: Optional[SCT[int]]) -> FrozenSet[int]:
if chat_id is None:
return frozenset()
if isinstance(chat_id, int):
return frozenset({chat_id})
return frozenset(chat_id)
@staticmethod
def _parse_username(username: Optional[SCT[str]]) -> FrozenSet[str]:
if username is None:
return frozenset()
if isinstance(username, str):
return frozenset({username[1:] if username.startswith("@") else username})
return frozenset({usr[1:] if usr.startswith("@") else usr for usr in username})
def check_update(self, update: object) -> bool:
"""Determines whether an update should be passed to this handler's :attr:`callback`.
@ -65,4 +115,12 @@ class ChatJoinRequestHandler(BaseHandler[Update, CCT]):
:obj:`bool`
"""
return isinstance(update, Update) and bool(update.chat_join_request)
if isinstance(update, Update) and update.chat_join_request:
if not self._chat_ids and not self._usernames:
return True
if update.chat_join_request.chat.id in self._chat_ids:
return True
if update.chat_join_request.from_user.username in self._usernames:
return True
return False
return False

View file

@ -78,7 +78,7 @@ def time():
def chat_join_request(time, bot):
return ChatJoinRequest(
chat=Chat(1, Chat.SUPERGROUP),
from_user=User(2, "first_name", False),
from_user=User(2, "first_name", False, username="user_a"),
date=time,
bio="bio",
invite_link=ChatInviteLink(
@ -127,6 +127,43 @@ class TestChatJoinRequestHandler:
)
)
def test_with_chat_id(self, chat_join_request_update):
handler = ChatJoinRequestHandler(self.callback, chat_id=1)
assert handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, chat_id=[1])
assert handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, chat_id=2, username="@user_a")
assert handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, chat_id=2)
assert not handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, chat_id=[2])
assert not handler.check_update(chat_join_request_update)
def test_with_username(self, chat_join_request_update):
handler = ChatJoinRequestHandler(self.callback, username="user_a")
assert handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, username="@user_a")
assert handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, username=["user_a"])
assert handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, username=["@user_a"])
assert handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, chat_id=1, username="@user_b")
assert handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, username="user_b")
assert not handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, username="@user_b")
assert not handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, username=["user_b"])
assert not handler.check_update(chat_join_request_update)
handler = ChatJoinRequestHandler(self.callback, username=["@user_b"])
assert not handler.check_update(chat_join_request_update)
chat_join_request_update.chat_join_request.from_user.username = None
assert not handler.check_update(chat_join_request_update)
def test_other_update_types(self, false_update):
handler = ChatJoinRequestHandler(self.callback)
assert not handler.check_update(false_update)