1
0
mirror of https://github.com/eternnoir/pyTelegramBotAPI.git synced 2023-08-10 21:12:57 +03:00

Merge pull request #1353 from coder2020official/master

Bot API 5.4 features
This commit is contained in:
Badiboy 2021-11-06 18:02:01 +03:00 committed by GitHub
commit 695c699893
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 188 additions and 35 deletions

View File

@ -31,6 +31,7 @@
* [Poll Answer Handler](#poll-answer-handler) * [Poll Answer Handler](#poll-answer-handler)
* [My Chat Member Handler](#my-chat-member-handler) * [My Chat Member Handler](#my-chat-member-handler)
* [Chat Member Handler](#chat-member-handler) * [Chat Member Handler](#chat-member-handler)
* [Chat Join request handler](#chat-join-request-handler)
* [Inline Mode](#inline-mode) * [Inline Mode](#inline-mode)
* [Inline handler](#inline-handler) * [Inline handler](#inline-handler)
* [Chosen Inline handler](#chosen-inline-handler) * [Chosen Inline handler](#chosen-inline-handler)
@ -272,6 +273,10 @@ Handle updates of a chat member's status in a chat
`@bot.chat_member_handler() # <- passes a ChatMemberUpdated type object to your function` `@bot.chat_member_handler() # <- passes a ChatMemberUpdated type object to your function`
*Note: "chat_member" updates are not requested by default. If you want to allow all update types, set `allowed_updates` in `bot.polling()` / `bot.infinity_polling()` to `util.update_types`* *Note: "chat_member" updates are not requested by default. If you want to allow all update types, set `allowed_updates` in `bot.polling()` / `bot.infinity_polling()` to `util.update_types`*
#### Chat Join Request Handler
Handle chat join requests using:
`@bot.chat_join_request_handler() # <- passes ChatInviteLink type object to your function`
### Inline Mode ### Inline Mode
More information about [Inline mode](https://core.telegram.org/bots/inline). More information about [Inline mode](https://core.telegram.org/bots/inline).

View File

@ -0,0 +1,11 @@
import telebot
bot = telebot.TeleBot('TOKEN')
@bot.chat_join_request_handler()
def make_some(message: telebot.types.ChatJoinRequest):
bot.send_message(message.chat.id, 'I accepted a new user!')
bot.approve_chat_join_request(message.chat.id, message.from_user.id)
bot.infinity_polling(allowed_updates=telebot.util.update_types)

View File

@ -5,13 +5,19 @@ from telebot import custom_filters
bot = telebot.TeleBot("") bot = telebot.TeleBot("")
class MyStates:
name = 1
surname = 2
age = 3
@bot.message_handler(commands=['start']) @bot.message_handler(commands=['start'])
def start_ex(message): def start_ex(message):
""" """
Start command. Here we are starting state Start command. Here we are starting state
""" """
bot.set_state(message.chat.id, 1) bot.set_state(message.from_user.id, MyStates.name)
bot.send_message(message.chat.id, 'Hi, write me a name') bot.send_message(message.chat.id, 'Hi, write me a name')
@ -22,38 +28,38 @@ def any_state(message):
Cancel state Cancel state
""" """
bot.send_message(message.chat.id, "Your state was cancelled.") bot.send_message(message.chat.id, "Your state was cancelled.")
bot.delete_state(message.chat.id) bot.delete_state(message.from_user.id)
@bot.message_handler(state=1) @bot.message_handler(state=MyStates.name)
def name_get(message): def name_get(message):
""" """
State 1. Will process when user's state is 1. State 1. Will process when user's state is 1.
""" """
bot.send_message(message.chat.id, f'Now write me a surname') bot.send_message(message.chat.id, f'Now write me a surname')
bot.set_state(message.chat.id, 2) bot.set_state(message.from_user.id, MyStates.surname)
with bot.retrieve_data(message.chat.id) as data: with bot.retrieve_data(message.from_user.id) as data:
data['name'] = message.text data['name'] = message.text
@bot.message_handler(state=2) @bot.message_handler(state=MyStates.surname)
def ask_age(message): def ask_age(message):
""" """
State 2. Will process when user's state is 2. State 2. Will process when user's state is 2.
""" """
bot.send_message(message.chat.id, "What is your age?") bot.send_message(message.chat.id, "What is your age?")
bot.set_state(message.chat.id, 3) bot.set_state(message.from_user.id, MyStates.age)
with bot.retrieve_data(message.chat.id) as data: with bot.retrieve_data(message.from_user.id) as data:
data['surname'] = message.text data['surname'] = message.text
# result # result
@bot.message_handler(state=3, is_digit=True) @bot.message_handler(state=MyStates.age, is_digit=True)
def ready_for_answer(message): def ready_for_answer(message):
with bot.retrieve_data(message.chat.id) as data: with bot.retrieve_data(message.from_user.id) as data:
bot.send_message(message.chat.id, "Ready, take a look:\n<b>Name: {name}\nSurname: {surname}\nAge: {age}</b>".format(name=data['name'], surname=data['surname'], age=message.text), parse_mode="html") bot.send_message(message.chat.id, "Ready, take a look:\n<b>Name: {name}\nSurname: {surname}\nAge: {age}</b>".format(name=data['name'], surname=data['surname'], age=message.text), parse_mode="html")
bot.delete_state(message.chat.id) bot.delete_state(message.from_user.id)
#incorrect number #incorrect number
@bot.message_handler(state=3, is_digit=False) @bot.message_handler(state=MyStates.age, is_digit=False)
def age_incorrect(message): def age_incorrect(message):
bot.send_message(message.chat.id, 'Looks like you are submitting a string in the field age. Please enter a number') bot.send_message(message.chat.id, 'Looks like you are submitting a string in the field age. Please enter a number')

View File

@ -185,6 +185,7 @@ class TeleBot:
self.poll_answer_handlers = [] self.poll_answer_handlers = []
self.my_chat_member_handlers = [] self.my_chat_member_handlers = []
self.chat_member_handlers = [] self.chat_member_handlers = []
self.chat_join_request_handlers = []
self.custom_filters = {} self.custom_filters = {}
self.state_handlers = [] self.state_handlers = []
@ -205,7 +206,8 @@ class TeleBot:
'poll': [], 'poll': [],
'poll_answer': [], 'poll_answer': [],
'my_chat_member': [], 'my_chat_member': [],
'chat_member': [] 'chat_member': [],
'chat_join_request': []
} }
self.default_middleware_handlers = [] self.default_middleware_handlers = []
@ -426,6 +428,7 @@ class TeleBot:
new_poll_answers = None new_poll_answers = None
new_my_chat_members = None new_my_chat_members = None
new_chat_members = None new_chat_members = None
chat_join_request = None
for update in updates: for update in updates:
if apihelper.ENABLE_MIDDLEWARE: if apihelper.ENABLE_MIDDLEWARE:
@ -480,6 +483,9 @@ class TeleBot:
if update.chat_member: if update.chat_member:
if new_chat_members is None: new_chat_members = [] if new_chat_members is None: new_chat_members = []
new_chat_members.append(update.chat_member) new_chat_members.append(update.chat_member)
if update.chat_join_request:
if chat_join_request is None: chat_join_request = []
chat_join_request.append(update.chat_join_request)
if new_messages: if new_messages:
self.process_new_messages(new_messages) self.process_new_messages(new_messages)
@ -507,6 +513,9 @@ class TeleBot:
self.process_new_my_chat_member(new_my_chat_members) self.process_new_my_chat_member(new_my_chat_members)
if new_chat_members: if new_chat_members:
self.process_new_chat_member(new_chat_members) self.process_new_chat_member(new_chat_members)
if chat_join_request:
self.process_new_chat_join_request(chat_join_request)
def process_new_messages(self, new_messages): def process_new_messages(self, new_messages):
self._notify_next_handlers(new_messages) self._notify_next_handlers(new_messages)
@ -550,6 +559,9 @@ class TeleBot:
def process_new_chat_member(self, chat_members): def process_new_chat_member(self, chat_members):
self._notify_command_handlers(self.chat_member_handlers, chat_members) self._notify_command_handlers(self.chat_member_handlers, chat_members)
def process_new_chat_join_request(self, chat_join_request):
self._notify_command_handlers(self.chat_join_request_handlers, chat_join_request)
def process_middlewares(self, update): def process_middlewares(self, update):
for update_type, middlewares in self.typed_middleware_handlers.items(): for update_type, middlewares in self.typed_middleware_handlers.items():
if getattr(update, update_type) is not None: if getattr(update, update_type) is not None:
@ -1668,8 +1680,10 @@ class TeleBot:
def create_chat_invite_link( def create_chat_invite_link(
self, chat_id: Union[int, str], self, chat_id: Union[int, str],
name: Optional[str]=None,
expire_date: Optional[Union[int, datetime]]=None, expire_date: Optional[Union[int, datetime]]=None,
member_limit: Optional[int]=None) -> types.ChatInviteLink: member_limit: Optional[int]=None,
creates_join_request: Optional[bool]=None) -> types.ChatInviteLink:
""" """
Use this method to create an additional invite link for a chat. Use this method to create an additional invite link for a chat.
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
@ -1681,13 +1695,15 @@ class TeleBot:
:return: :return:
""" """
return types.ChatInviteLink.de_json( return types.ChatInviteLink.de_json(
apihelper.create_chat_invite_link(self.token, chat_id, expire_date, member_limit) apihelper.create_chat_invite_link(self.token, chat_id, name, expire_date, member_limit, creates_join_request)
) )
def edit_chat_invite_link( def edit_chat_invite_link(
self, chat_id: Union[int, str], invite_link: str, self, chat_id: Union[int, str], name: Optional[str]=None,
invite_link: Optional[str] = None,
expire_date: Optional[Union[int, datetime]]=None, expire_date: Optional[Union[int, datetime]]=None,
member_limit: Optional[int]=None) -> types.ChatInviteLink: member_limit: Optional[int]=None ,
creates_join_request: Optional[bool]=None) -> types.ChatInviteLink:
""" """
Use this method to edit a non-primary invite link created by the bot. Use this method to edit a non-primary invite link created by the bot.
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
@ -1701,7 +1717,7 @@ class TeleBot:
:return: :return:
""" """
return types.ChatInviteLink.de_json( return types.ChatInviteLink.de_json(
apihelper.edit_chat_invite_link(self.token, chat_id, invite_link, expire_date, member_limit) apihelper.edit_chat_invite_link(self.token, chat_id, name, invite_link, expire_date, member_limit, creates_join_request)
) )
def revoke_chat_invite_link( def revoke_chat_invite_link(
@ -1731,6 +1747,32 @@ class TeleBot:
""" """
return apihelper.export_chat_invite_link(self.token, chat_id) return apihelper.export_chat_invite_link(self.token, chat_id)
def approve_chat_join_request(self, chat_id: Union[str, int], user_id: Union[int, str]) -> bool:
"""
Use this method to approve a chat join request.
The bot must be an administrator in the chat for this to work and must have
the can_invite_users administrator right. Returns True on success.
:param chat_id: Unique identifier for the target chat or username of the target supergroup
(in the format @supergroupusername)
:param user_id: Unique identifier of the target user
:return: True on success.
"""
return apihelper.approve_chat_join_request(self.token, chat_id, user_id)
def decline_chat_join_request(self, chat_id: Union[str, int], user_id: Union[int, str]) -> bool:
"""
Use this method to decline a chat join request.
The bot must be an administrator in the chat for this to work and must have
the can_invite_users administrator right. Returns True on success.
:param chat_id: Unique identifier for the target chat or username of the target supergroup
(in the format @supergroupusername)
:param user_id: Unique identifier of the target user
:return: True on success.
"""
return apihelper.decline_chat_join_request(self.token, chat_id, user_id)
def set_chat_photo(self, chat_id: Union[int, str], photo: Any) -> bool: def set_chat_photo(self, chat_id: Union[int, str], photo: Any) -> bool:
""" """
Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. Use this method to set a new profile photo for the chat. Photos can't be changed for private chats.
@ -3148,6 +3190,39 @@ class TeleBot:
handler_dict = self._build_handler_dict(callback, func=func, **kwargs) handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
self.add_chat_member_handler(handler_dict) self.add_chat_member_handler(handler_dict)
def chat_join_request_handler(self, func=None, **kwargs):
"""
chat_join_request handler
:param func:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_chat_join_request_handler(handler_dict)
return handler
return decorator
def add_chat_join_request_handler(self, handler_dict):
"""
Adds a chat_join_request handler
:param handler_dict:
:return:
"""
self.chat_join_request_handlers.append(handler_dict)
def register_chat_join_request_handler(self, callback, func=None, **kwargs):
"""
Registers chat join request handler.
:param callback: function to be called
:param func:
:return: decorated function
"""
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
self.add_chat_join_request_handler(handler_dict)
def _test_message_handler(self, message_handler, message): def _test_message_handler(self, message_handler, message):
""" """
Test message handler Test message handler

View File

@ -973,7 +973,7 @@ def set_chat_permissions(token, chat_id, permissions):
return _make_request(token, method_url, params=payload, method='post') return _make_request(token, method_url, params=payload, method='post')
def create_chat_invite_link(token, chat_id, expire_date, member_limit): def create_chat_invite_link(token, chat_id, name, expire_date, member_limit, creates_join_request):
method_url = 'createChatInviteLink' method_url = 'createChatInviteLink'
payload = { payload = {
'chat_id': chat_id 'chat_id': chat_id
@ -986,11 +986,15 @@ def create_chat_invite_link(token, chat_id, expire_date, member_limit):
payload['expire_date'] = expire_date payload['expire_date'] = expire_date
if member_limit: if member_limit:
payload['member_limit'] = member_limit payload['member_limit'] = member_limit
if creates_join_request is not None:
payload['creates_join_request'] = creates_join_request
if name:
payload['name'] = name
return _make_request(token, method_url, params=payload, method='post') return _make_request(token, method_url, params=payload, method='post')
def edit_chat_invite_link(token, chat_id, invite_link, expire_date, member_limit): def edit_chat_invite_link(token, chat_id, invite_link, name, expire_date, member_limit, creates_join_request):
method_url = 'editChatInviteLink' method_url = 'editChatInviteLink'
payload = { payload = {
'chat_id': chat_id, 'chat_id': chat_id,
@ -1005,6 +1009,10 @@ def edit_chat_invite_link(token, chat_id, invite_link, expire_date, member_limit
if member_limit is not None: if member_limit is not None:
payload['member_limit'] = member_limit payload['member_limit'] = member_limit
if name:
payload['name'] = name
if creates_join_request:
payload['creates_join_request'] = creates_join_request
return _make_request(token, method_url, params=payload, method='post') return _make_request(token, method_url, params=payload, method='post')
@ -1023,7 +1031,20 @@ def export_chat_invite_link(token, chat_id):
payload = {'chat_id': chat_id} payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload, method='post') return _make_request(token, method_url, params=payload, method='post')
def approve_chat_join_request(token, chat_id, user_id):
method_url = 'approveChatJoinRequest'
payload = {
'chat_id': chat_id,
'user_id': user_id
}
return _make_request(token, method_url, params=payload, method='post')
def decline_chat_join_request(token, chat_id, user_id):
method_url = 'declineChatJoinRequest'
payload = {
'chat_id': chat_id,
'user_id': user_id
}
return _make_request(token, method_url, params=payload, method='post')
def set_chat_photo(token, chat_id, photo): def set_chat_photo(token, chat_id, photo):
method_url = 'setChatPhoto' method_url = 'setChatPhoto'
payload = {'chat_id': chat_id} payload = {'chat_id': chat_id}

View File

@ -107,13 +107,14 @@ class Update(JsonDeserializable):
poll_answer = PollAnswer.de_json(obj.get('poll_answer')) poll_answer = PollAnswer.de_json(obj.get('poll_answer'))
my_chat_member = ChatMemberUpdated.de_json(obj.get('my_chat_member')) my_chat_member = ChatMemberUpdated.de_json(obj.get('my_chat_member'))
chat_member = ChatMemberUpdated.de_json(obj.get('chat_member')) chat_member = ChatMemberUpdated.de_json(obj.get('chat_member'))
chat_join_request = ChatJoinRequest.de_json(obj.get('chat_join_request'))
return cls(update_id, message, edited_message, channel_post, edited_channel_post, inline_query, return cls(update_id, message, edited_message, channel_post, edited_channel_post, inline_query,
chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer, chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer,
my_chat_member, chat_member) my_chat_member, chat_member, chat_join_request)
def __init__(self, update_id, message, edited_message, channel_post, edited_channel_post, inline_query, def __init__(self, update_id, message, edited_message, channel_post, edited_channel_post, inline_query,
chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer, chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer,
my_chat_member, chat_member): my_chat_member, chat_member, chat_join_request):
self.update_id = update_id self.update_id = update_id
self.message = message self.message = message
self.edited_message = edited_message self.edited_message = edited_message
@ -128,6 +129,7 @@ class Update(JsonDeserializable):
self.poll_answer = poll_answer self.poll_answer = poll_answer
self.my_chat_member = my_chat_member self.my_chat_member = my_chat_member
self.chat_member = chat_member self.chat_member = chat_member
self.chat_join_request = chat_join_request
class ChatMemberUpdated(JsonDeserializable): class ChatMemberUpdated(JsonDeserializable):
@ -166,6 +168,23 @@ class ChatMemberUpdated(JsonDeserializable):
dif[key] = [old[key], new[key]] dif[key] = [old[key], new[key]]
return dif return dif
class ChatJoinRequest(JsonDeserializable):
@classmethod
def de_json(cls, json_string):
if json_string is None: return None
obj = cls.check_json(json_string)
obj['chat'] = Chat.de_json(obj['chat'])
obj['from_user'] = User.de_json(obj['from'])
obj['invite_link'] = ChatInviteLink.de_json(obj['invite_link'])
return cls(**obj)
def __init__(self, chat, from_user, date, bio=None, invite_link=None, **kwargs):
self.chat = Chat = chat
self.from_user: User = from_user
self.date: int = date
self.bio: Optional[str] = bio
self.invite_link: Optional[ChatInviteLink] = invite_link
class WebhookInfo(JsonDeserializable): class WebhookInfo(JsonDeserializable):
@classmethod @classmethod
@ -2752,14 +2771,17 @@ class ChatInviteLink(JsonSerializable, JsonDeserializable, Dictionaryable):
obj['creator'] = User.de_json(obj['creator']) obj['creator'] = User.de_json(obj['creator'])
return cls(**obj) return cls(**obj)
def __init__(self, invite_link, creator, is_primary, is_revoked, def __init__(self, invite_link, creator, creates_join_request , is_primary, is_revoked,
expire_date=None, member_limit=None, **kwargs): name=None, expire_date=None, member_limit=None, pending_join_request_count=None, **kwargs):
self.invite_link: str = invite_link self.invite_link: str = invite_link
self.creator: User = creator self.creator: User = creator
self.creates_join_request: bool = creates_join_request
self.is_primary: bool = is_primary self.is_primary: bool = is_primary
self.is_revoked: bool = is_revoked self.is_revoked: bool = is_revoked
self.name: str = name
self.expire_date: int = expire_date self.expire_date: int = expire_date
self.member_limit: int = member_limit self.member_limit: int = member_limit
self.pending_join_request_count: int = pending_join_request_count
def to_json(self): def to_json(self):
return json.dumps(self.to_dict()) return json.dumps(self.to_dict())
@ -2769,12 +2791,17 @@ class ChatInviteLink(JsonSerializable, JsonDeserializable, Dictionaryable):
"invite_link": self.invite_link, "invite_link": self.invite_link,
"creator": self.creator.to_dict(), "creator": self.creator.to_dict(),
"is_primary": self.is_primary, "is_primary": self.is_primary,
"is_revoked": self.is_revoked "is_revoked": self.is_revoked,
"creates_join_request": self.creates_join_request
} }
if self.expire_date: if self.expire_date:
json_dict["expire_date"] = self.expire_date json_dict["expire_date"] = self.expire_date
if self.member_limit: if self.member_limit:
json_dict["member_limit"] = self.member_limit json_dict["member_limit"] = self.member_limit
if self.pending_join_request_count:
json_dict["pending_join_request_count"] = self.pending_join_request_count
if self.name:
json_dict["name"] = self.name
return json_dict return json_dict

View File

@ -46,7 +46,7 @@ content_type_service = [
update_types = [ update_types = [
"update_id", "message", "edited_message", "channel_post", "edited_channel_post", "inline_query", "update_id", "message", "edited_message", "channel_post", "edited_channel_post", "inline_query",
"chosen_inline_result", "callback_query", "shipping_query", "pre_checkout_query", "poll", "poll_answer", "chosen_inline_result", "callback_query", "shipping_query", "pre_checkout_query", "poll", "poll_answer",
"my_chat_member", "chat_member" "my_chat_member", "chat_member", "chat_join_request"
] ]
class WorkerThread(threading.Thread): class WorkerThread(threading.Thread):

View File

@ -64,9 +64,10 @@ def update_type(message):
poll_answer = None poll_answer = None
my_chat_member = None my_chat_member = None
chat_member = None chat_member = None
chat_join_request = None
return types.Update(1001234038283, message, edited_message, channel_post, edited_channel_post, inline_query, return types.Update(1001234038283, message, edited_message, channel_post, edited_channel_post, inline_query,
chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer, chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer,
my_chat_member, chat_member) my_chat_member, chat_member, chat_join_request)
@pytest.fixture() @pytest.fixture()
@ -83,9 +84,10 @@ def reply_to_message_update_type(reply_to_message):
poll_answer = None poll_answer = None
my_chat_member = None my_chat_member = None
chat_member = None chat_member = None
chat_join_request = None
return types.Update(1001234038284, reply_to_message, edited_message, channel_post, edited_channel_post, return types.Update(1001234038284, reply_to_message, edited_message, channel_post, edited_channel_post,
inline_query, chosen_inline_result, callback_query, shipping_query, pre_checkout_query, inline_query, chosen_inline_result, callback_query, shipping_query, pre_checkout_query,
poll, poll_answer, my_chat_member, chat_member) poll, poll_answer, my_chat_member, chat_member, chat_join_request)
def next_handler(message): def next_handler(message):

View File

@ -485,9 +485,10 @@ class TestTeleBot:
poll_answer = None poll_answer = None
my_chat_member = None my_chat_member = None
chat_member = None chat_member = None
chat_join_request = None
return types.Update(-1001234038283, message, edited_message, channel_post, edited_channel_post, inline_query, return types.Update(-1001234038283, message, edited_message, channel_post, edited_channel_post, inline_query,
chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer, chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer,
my_chat_member, chat_member) my_chat_member, chat_member, chat_join_request)
def test_is_string_unicode(self): def test_is_string_unicode(self):
s1 = u'string' s1 = u'string'

View File

@ -222,14 +222,19 @@ def test_KeyboardButtonPollType():
def test_json_chat_invite_link(): def test_json_chat_invite_link():
json_string = r'{"invite_link": "https://t.me/joinchat/z-abCdEFghijKlMn", "creator": {"id": 329343347, "is_bot": false, "first_name": "Test", "username": "test_user", "last_name": "User", "language_code": "en"}, "is_primary": false, "is_revoked": false, "expire_date": 1624119999, "member_limit": 10}' json_string = r'{"invite_link":"https://t.me/joinchat/MeASP-Wi...","creator":{"id":927266710,"is_bot":false,"first_name":">_run","username":"coder2020","language_code":"ru"},"pending_join_request_count":1,"creates_join_request":true,"is_primary":false,"is_revoked":false}'
invite_link = types.ChatInviteLink.de_json(json_string) invite_link = types.ChatInviteLink.de_json(json_string)
assert invite_link.invite_link == 'https://t.me/joinchat/z-abCdEFghijKlMn' assert invite_link.invite_link == 'https://t.me/joinchat/MeASP-Wi...'
assert isinstance(invite_link.creator, types.User) assert isinstance(invite_link.creator, types.User)
assert not invite_link.is_primary assert not invite_link.is_primary
assert not invite_link.is_revoked assert not invite_link.is_revoked
assert invite_link.expire_date == 1624119999 assert invite_link.expire_date is None
assert invite_link.member_limit == 10 assert invite_link.member_limit is None
assert invite_link.name is None
assert invite_link.creator.id == 927266710
assert invite_link.pending_join_request_count == 1
assert invite_link.creates_join_request
def test_chat_member_updated(): def test_chat_member_updated():
json_string = r'{"chat": {"id": -1234567890123, "type": "supergroup", "title": "No Real Group", "username": "NoRealGroup"}, "from": {"id": 133869498, "is_bot": false, "first_name": "Vincent"}, "date": 1624119999, "old_chat_member": {"user": {"id": 77777777, "is_bot": false, "first_name": "Pepe"}, "status": "member"}, "new_chat_member": {"user": {"id": 77777777, "is_bot": false, "first_name": "Pepe"}, "status": "administrator"}}' json_string = r'{"chat": {"id": -1234567890123, "type": "supergroup", "title": "No Real Group", "username": "NoRealGroup"}, "from": {"id": 133869498, "is_bot": false, "first_name": "Vincent"}, "date": 1624119999, "old_chat_member": {"user": {"id": 77777777, "is_bot": false, "first_name": "Pepe"}, "status": "member"}, "new_chat_member": {"user": {"id": 77777777, "is_bot": false, "first_name": "Pepe"}, "status": "administrator"}}'