Skip to content

Commit 80553b8

Browse files
authored
Merge pull request #2566 from KimmyXYC/master
Add support for Bot API version 9.5
2 parents 9435ddd + f83c3de commit 80553b8

14 files changed

+353
-19
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.</p>
1111
<p align="center">Both synchronous and asynchronous.</p>
1212

13-
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#february-9-2026"><img src="https://img.shields.io/badge/Bot%20API-9.4-blue?logo=telegram" alt="Supported Bot API version"></a>
13+
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#march-1-2026"><img src="https://img.shields.io/badge/Bot%20API-9.5-blue?logo=telegram" alt="Supported Bot API version"></a>
1414

1515
<h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>
1616
<h2><a href='https://pytba.readthedocs.io/ru/latest/index.html'>Official ru documentation</a></h2>

examples/asynchronous_telebot/chat_member_example.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,17 @@ async def my_chat_m(message: types.ChatMemberUpdated):
3030
@bot.message_handler(content_types=util.content_type_service)
3131
async def delall(message: types.Message):
3232
await bot.delete_message(message.chat.id,message.message_id)
33+
34+
35+
@bot.message_handler(commands=['set_tag'])
36+
async def set_tag(message: types.Message):
37+
tag = util.extract_arguments(message.text)
38+
if not tag:
39+
await bot.reply_to(message, "Usage: /set_tag your_tag")
40+
return
41+
await bot.set_chat_member_tag(message.chat.id, message.from_user.id, tag=tag)
42+
await bot.reply_to(message, f"Tag updated: {tag}")
43+
44+
3345
import asyncio
3446
asyncio.run(bot.polling(allowed_updates=util.update_types))

examples/asynchronous_telebot/formatting_example.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from telebot.async_telebot import AsyncTeleBot
2-
from telebot import formatting
2+
from telebot import formatting, types
33

44
bot = AsyncTeleBot('token')
55

@@ -50,5 +50,22 @@ async def start_message(message):
5050
parse_mode='HTML'
5151
)
5252

53+
# Bot API 9.5: date_time entity example
54+
date_text = "2026-03-01 12:00:00"
55+
text = f"Local time: {date_text}"
56+
await bot.send_message(
57+
message.chat.id,
58+
text,
59+
entities=[
60+
types.MessageEntity(
61+
type='date_time',
62+
offset=len("Local time: "),
63+
length=len(date_text),
64+
unix_time=1772366400,
65+
date_time_format='short'
66+
)
67+
]
68+
)
69+
5370
import asyncio
54-
asyncio.run(bot.polling())
71+
asyncio.run(bot.polling())
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import asyncio
2+
3+
from telebot.async_telebot import AsyncTeleBot
4+
5+
bot = AsyncTeleBot("TOKEN")
6+
7+
8+
@bot.message_handler(commands=['draft'])
9+
async def send_draft(message):
10+
if message.chat.type != 'private':
11+
await bot.reply_to(message, "This example works in private chats.")
12+
return
13+
14+
draft_id = message.from_user.id
15+
await bot.send_message_draft(message.chat.id, draft_id, "Generating response...")
16+
await asyncio.sleep(1)
17+
await bot.send_message_draft(message.chat.id, draft_id, "Still working...")
18+
await asyncio.sleep(1)
19+
await bot.send_message(message.chat.id, "Done.")
20+
21+
22+
asyncio.run(bot.polling())

examples/chat_member_example.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,16 @@ def my_chat_m(message: types.ChatMemberUpdated):
3030
@bot.message_handler(content_types=util.content_type_service)
3131
def delall(message: types.Message):
3232
bot.delete_message(message.chat.id,message.message_id)
33+
34+
35+
@bot.message_handler(commands=['set_tag'])
36+
def set_tag(message: types.Message):
37+
tag = util.extract_arguments(message.text)
38+
if not tag:
39+
bot.reply_to(message, "Usage: /set_tag your_tag")
40+
return
41+
bot.set_chat_member_tag(message.chat.id, message.from_user.id, tag=tag)
42+
bot.reply_to(message, f"Tag updated: {tag}")
43+
44+
3345
bot.infinity_polling(allowed_updates=util.update_types)

examples/formatting_example.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from telebot import TeleBot
2-
from telebot import formatting
2+
from telebot import formatting, types
33

44
bot = TeleBot('TOKEN')
55

@@ -50,4 +50,21 @@ def start_message(message):
5050
parse_mode='HTML'
5151
)
5252

53-
bot.infinity_polling()
53+
# Bot API 9.5: date_time entity example
54+
date_text = "2026-03-01 12:00:00"
55+
text = f"Local time: {date_text}"
56+
bot.send_message(
57+
message.chat.id,
58+
text,
59+
entities=[
60+
types.MessageEntity(
61+
type='date_time',
62+
offset=len("Local time: "),
63+
length=len(date_text),
64+
unix_time=1772366400,
65+
date_time_format='short'
66+
)
67+
]
68+
)
69+
70+
bot.infinity_polling()
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import time
2+
3+
import telebot
4+
5+
bot = telebot.TeleBot("TOKEN")
6+
7+
8+
@bot.message_handler(commands=['draft'])
9+
def send_draft(message):
10+
if message.chat.type != 'private':
11+
bot.reply_to(message, "This example works in private chats.")
12+
return
13+
14+
draft_id = message.from_user.id
15+
bot.send_message_draft(message.chat.id, draft_id, "Generating response...")
16+
time.sleep(1)
17+
bot.send_message_draft(message.chat.id, draft_id, "Still working...")
18+
time.sleep(1)
19+
bot.send_message(message.chat.id, "Done.")
20+
21+
22+
bot.infinity_polling()

telebot/__init__.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4237,7 +4237,7 @@ def send_message_draft(
42374237
entities: Optional[List[types.MessageEntity]]=None):
42384238
"""
42394239
Use this method to stream a partial message to a user while the message is being generated;
4240-
supported only for bots with forum topic mode enabled. Returns True on success.
4240+
available for all bots. Returns True on success.
42414241
42424242
Telegram documentation: https://core.telegram.org/bots/api#sendmessagedraft
42434243
@@ -4487,7 +4487,8 @@ def promote_chat_member(
44874487
can_post_stories: Optional[bool]=None,
44884488
can_edit_stories: Optional[bool]=None,
44894489
can_delete_stories: Optional[bool]=None,
4490-
can_manage_direct_messages: Optional[bool]=None) -> bool:
4490+
can_manage_direct_messages: Optional[bool]=None,
4491+
can_manage_tags: Optional[bool]=None) -> bool:
44914492
"""
44924493
Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator
44934494
in the chat for this to work and must have the appropriate admin rights.
@@ -4561,6 +4562,9 @@ def promote_chat_member(
45614562
within the channel and decline suggested posts; for channels only
45624563
:type can_manage_direct_messages: :obj:`bool`
45634564
4565+
:param can_manage_tags: Pass True if the administrator can manage tags in the chat
4566+
:type can_manage_tags: :obj:`bool`
4567+
45644568
:return: True on success.
45654569
:rtype: :obj:`bool`
45664570
"""
@@ -4578,6 +4582,7 @@ def promote_chat_member(
45784582
can_manage_video_chats=can_manage_video_chats, can_manage_topics=can_manage_topics,
45794583
can_post_stories=can_post_stories, can_edit_stories=can_edit_stories,
45804584
can_delete_stories=can_delete_stories, can_manage_direct_messages=can_manage_direct_messages,
4585+
can_manage_tags=can_manage_tags,
45814586
)
45824587

45834588

@@ -4606,6 +4611,30 @@ def set_chat_administrator_custom_title(
46064611
return apihelper.set_chat_administrator_custom_title(self.token, chat_id, user_id, custom_title)
46074612

46084613

4614+
def set_chat_member_tag(
4615+
self, chat_id: Union[int, str], user_id: int, tag: Optional[str]=None) -> bool:
4616+
"""
4617+
Use this method to set a new tag for a member in a chat.
4618+
Returns True on success.
4619+
4620+
Telegram documentation: https://core.telegram.org/bots/api#setchatmembertag
4621+
4622+
:param chat_id: Unique identifier for the target chat or username of the target supergroup
4623+
(in the format @supergroupusername)
4624+
:type chat_id: :obj:`int` or :obj:`str`
4625+
4626+
:param user_id: Unique identifier of the target user
4627+
:type user_id: :obj:`int`
4628+
4629+
:param tag: New tag for the member; pass an empty string to remove the tag
4630+
:type tag: :obj:`str`
4631+
4632+
:return: True on success.
4633+
:rtype: :obj:`bool`
4634+
"""
4635+
return apihelper.set_chat_member_tag(self.token, chat_id, user_id, tag=tag)
4636+
4637+
46094638
def ban_chat_sender_chat(self, chat_id: Union[int, str], sender_chat_id: Union[int, str]) -> bool:
46104639
"""
46114640
Use this method to ban a channel chat in a supergroup or a channel.

telebot/apihelper.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,7 @@ def promote_chat_member(
12871287
can_restrict_members=None, can_pin_messages=None, can_promote_members=None,
12881288
is_anonymous=None, can_manage_chat=None, can_manage_video_chats=None,
12891289
can_manage_topics=None, can_post_stories=None, can_edit_stories=None,
1290-
can_delete_stories=None, can_manage_direct_messages=None):
1290+
can_delete_stories=None, can_manage_direct_messages=None, can_manage_tags=None):
12911291
method_url = 'promoteChatMember'
12921292
payload = {'chat_id': chat_id, 'user_id': user_id}
12931293
if can_change_info is not None:
@@ -1322,6 +1322,8 @@ def promote_chat_member(
13221322
payload['can_delete_stories'] = can_delete_stories
13231323
if can_manage_direct_messages is not None:
13241324
payload['can_manage_direct_messages'] = can_manage_direct_messages
1325+
if can_manage_tags is not None:
1326+
payload['can_manage_tags'] = can_manage_tags
13251327
return _make_request(token, method_url, params=payload, method='post')
13261328

13271329

@@ -1333,6 +1335,14 @@ def set_chat_administrator_custom_title(token, chat_id, user_id, custom_title):
13331335
return _make_request(token, method_url, params=payload, method='post')
13341336

13351337

1338+
def set_chat_member_tag(token, chat_id, user_id, tag=None):
1339+
method_url = 'setChatMemberTag'
1340+
payload = {'chat_id': chat_id, 'user_id': user_id}
1341+
if tag is not None:
1342+
payload['tag'] = tag
1343+
return _make_request(token, method_url, params=payload, method='post')
1344+
1345+
13361346
def ban_chat_sender_chat(token, chat_id, sender_chat_id):
13371347
method_url = 'banChatSenderChat'
13381348
payload = {'chat_id': chat_id, 'sender_chat_id': sender_chat_id}

telebot/async_telebot.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5757,7 +5757,7 @@ async def send_message_draft(
57575757
entities: Optional[List[types.MessageEntity]]=None):
57585758
"""
57595759
Use this method to stream a partial message to a user while the message is being generated;
5760-
supported only for bots with forum topic mode enabled. Returns True on success.
5760+
available for all bots. Returns True on success.
57615761
57625762
Telegram documentation: https://core.telegram.org/bots/api#sendmessagedraft
57635763
@@ -5996,7 +5996,8 @@ async def promote_chat_member(
59965996
can_post_stories: Optional[bool]=None,
59975997
can_edit_stories: Optional[bool]=None,
59985998
can_delete_stories: Optional[bool]=None,
5999-
can_manage_direct_messages: Optional[bool]=None) -> bool:
5999+
can_manage_direct_messages: Optional[bool]=None,
6000+
can_manage_tags: Optional[bool]=None) -> bool:
60006001
"""
60016002
Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator
60026003
in the chat for this to work and must have the appropriate admin rights.
@@ -6070,6 +6071,9 @@ async def promote_chat_member(
60706071
within the channel and decline suggested posts; for channels only
60716072
:type can_manage_direct_messages: :obj:`bool`
60726073
6074+
:param can_manage_tags: Pass True if the administrator can manage tags in the chat
6075+
:type can_manage_tags: :obj:`bool`
6076+
60736077
:return: True on success.
60746078
:rtype: :obj:`bool`
60756079
"""
@@ -6084,7 +6088,8 @@ async def promote_chat_member(
60846088
can_edit_messages, can_delete_messages, can_invite_users,
60856089
can_restrict_members, can_pin_messages, can_promote_members,
60866090
is_anonymous, can_manage_chat, can_manage_video_chats, can_manage_topics,
6087-
can_post_stories, can_edit_stories, can_delete_stories, can_manage_direct_messages=can_manage_direct_messages
6091+
can_post_stories, can_edit_stories, can_delete_stories,
6092+
can_manage_direct_messages=can_manage_direct_messages, can_manage_tags=can_manage_tags
60886093
)
60896094

60906095
async def set_chat_administrator_custom_title(
@@ -6112,6 +6117,30 @@ async def set_chat_administrator_custom_title(
61126117
return await asyncio_helper.set_chat_administrator_custom_title(self.token, chat_id, user_id, custom_title)
61136118

61146119

6120+
async def set_chat_member_tag(
6121+
self, chat_id: Union[int, str], user_id: int, tag: Optional[str]=None) -> bool:
6122+
"""
6123+
Use this method to set a new tag for a member in a chat.
6124+
Returns True on success.
6125+
6126+
Telegram documentation: https://core.telegram.org/bots/api#setchatmembertag
6127+
6128+
:param chat_id: Unique identifier for the target chat or username of the target supergroup
6129+
(in the format @supergroupusername)
6130+
:type chat_id: :obj:`int` or :obj:`str`
6131+
6132+
:param user_id: Unique identifier of the target user
6133+
:type user_id: :obj:`int`
6134+
6135+
:param tag: New tag for the member; pass an empty string to remove the tag
6136+
:type tag: :obj:`str`
6137+
6138+
:return: True on success.
6139+
:rtype: :obj:`bool`
6140+
"""
6141+
return await asyncio_helper.set_chat_member_tag(self.token, chat_id, user_id, tag=tag)
6142+
6143+
61156144
async def ban_chat_sender_chat(self, chat_id: Union[int, str], sender_chat_id: Union[int, str]) -> bool:
61166145
"""
61176146
Use this method to ban a channel chat in a supergroup or a channel.

0 commit comments

Comments
 (0)