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

Compare commits

...

182 Commits
4.7.0 ... 4.9.0

Author SHA1 Message Date
6f86382e33 Merge pull request #1860 from Badiboy/master
Bump version to 4.9/0
2023-01-02 18:00:39 +03:00
43cc203654 Bump version to 4.9/0 2023-01-02 18:00:20 +03:00
3b62ad4765 Merge pull request #1855 from coder2020official/botapi6.4
Bot API 6.4
2023-01-02 17:55:32 +03:00
3be5015f9e Update telebot/types.py 2023-01-02 17:55:30 +04:00
267a33c329 Update telebot/types.py 2023-01-02 17:55:14 +04:00
667e82d073 Update telebot/types.py 2023-01-02 17:54:35 +04:00
79bc869143 Merge pull request #1856 from Cub11k/master
Copied translations from sync_version.po to async_version.po
2022-12-30 23:56:32 +04:00
68edb4990c Fix async_version.po 2022-12-30 21:42:50 +02:00
19544ecc58 Copied translations from sync_version.po to async_version.po
Minor fixes in sync_version.po, found while copying
2022-12-30 21:24:13 +02:00
eed56be596 Added fields has_hidden_members and has_aggressive_anti_spam_enabled to class Chat 2022-12-30 20:38:26 +04:00
9f8256607a Added the parameter message_thread_id to the method sendChatAction for sending chat actions to a specific message thread or a forum topic.
Added the parameter message_thread_id to the method sendChatAction for sending chat actions to a specific message thread or a forum topic.
2022-12-30 20:23:53 +04:00
f297ad23c7 Added methods for topic management
Added the methods editGeneralForumTopic, closeGeneralForumTopic, reopenGeneralForumTopic, hideGeneralForumTopic, unhideGeneralForumTopic for managing the General topic in forums.
2022-12-30 20:19:50 +04:00
a20a3ae321 topic events and write_access_allowed
Added the classes ForumTopicEdited, GeneralForumTopicHidden, GeneralForumTopicUnhidden, and WriteAccessAllowed and the fields forum_topic_edited, general_forum_topic_hidden, general_forum_topic_unhidden, and write_access_allowed to the class Message.
2022-12-30 20:07:38 +04:00
107f92314b icon_custom_emoji_id and name parameters made optional for edit_forum_topic
The parameters name and icon_custom_emoji_id of the method editForumTopic are now optional. If they are omitted, the existing values are kept.
2022-12-30 19:50:14 +04:00
9f5d9861a4 Added the field has_media_spoiler to the class Message.
Added the field has_media_spoiler to the class Message.
2022-12-30 19:41:46 +04:00
4537b237c8 has_spoiler for types.py
Added the field has_spoiler to the classes InputMediaPhoto, InputMediaVideo, and InputMediaAnimation.
2022-12-30 19:27:38 +04:00
4d11e97c25 has_spoiler parameter
Added the parameter has_spoiler to the methods sendPhoto, sendVideo, and sendAnimation.
2022-12-30 19:20:23 +04:00
f0a1cefdda Added the field is_persistent to the class ReplyKeyboardMarkup
Added the field is_persistent to the class ReplyKeyboardMarkup, allowing to control when the keyboard is shown.
2022-12-30 19:08:37 +04:00
24cd014410 Update README.md 2022-12-30 18:52:00 +04:00
ba64180b5f Merge pull request #1854 from Cub11k/master
Fixed typehints for reply markup in editing methods
2022-12-30 16:44:31 +03:00
3812fd05e3 Fixed typehints for reply markup in editing methods (async) 2022-12-30 14:04:12 +02:00
69afd7232e Fixed typehints for reply markup in editing methods 2022-12-30 14:02:02 +02:00
81600cf27e Merge pull request #1849 from eternnoir/dependabot/pip/wheel-0.38.1
Bump wheel from 0.24.0 to 0.38.1
2022-12-30 00:02:27 +03:00
bb8023ecc6 Merge pull request #1852 from Cub11k/master
Fixed typehints for register_<any>_handler()
2022-12-28 22:14:50 +04:00
a50a6e2e54 Fixed typehints for register_<any>_handler() 2022-12-28 20:00:06 +02:00
0329e5adb8 Merge pull request #1850 from ayitinya/patch-1
Update README.md
2022-12-27 09:17:26 +03:00
2f25b56659 Update README.md
Adds a bot to Bots using this library list
2022-12-27 02:46:07 +00:00
2aaab08517 Bump wheel from 0.24.0 to 0.38.1
Bumps [wheel](https://github.com/pypa/wheel) from 0.24.0 to 0.38.1.
- [Release notes](https://github.com/pypa/wheel/releases)
- [Changelog](https://github.com/pypa/wheel/blob/main/docs/news.rst)
- [Commits](https://github.com/pypa/wheel/compare/0.24.0...0.38.1)

---
updated-dependencies:
- dependency-name: wheel
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 19:49:24 +00:00
a6a22c351a Merge pull request #1845 from Cub11k/master
Partly translated files: sync_version.po
2022-12-21 17:14:55 +04:00
d211db90cf Update sync_version.po 2022-12-21 15:04:43 +02:00
f2c211616c Merge pull request #1844 from coder2020official/master
✉️ Fixed escape_markdown: now it should escape { and } characters in a string as well.
2022-12-21 16:59:03 +04:00
c5e733a4c1 Escape both metachars 2022-12-20 23:47:12 +04:00
925f7012f1 Update formatting.py 2022-12-20 23:44:32 +04:00
625ae09573 Merge pull request #1839 from coder2020official/master
Fix bug with asyncwebhooks
2022-12-19 17:35:23 +04:00
5b279b7ad9 (A)SyncWebhookListener changes 2022-12-19 17:28:05 +04:00
247cddf23d Merge pull request #1831 from coder2020official/reloader_fix
Update reloader.py
2022-12-19 17:17:11 +04:00
171172d12e Update async_telebot.py 2022-12-19 17:12:15 +04:00
c3c12b93dd Merge pull request #1832 from coder2020official/master
Fix bug related to get_user_profile_photos
2022-12-14 14:18:18 +04:00
add240adfd Update asyncio_helper.py 2022-12-14 12:41:30 +04:00
45fe2ea319 Update reloader.py 2022-12-13 18:44:41 +04:00
6373af78f3 Merge pull request #1824 from reddere/patch-3
fixing escape()
2022-12-03 16:48:16 +03:00
4ed460b137 Update util.py 2022-12-03 14:23:10 +01:00
ae20cb9f31 Update util.py 2022-12-03 14:21:31 +01:00
669c18fdc0 update
updated "== None" to "is None" and adjusted the else statement
2022-12-03 14:11:07 +01:00
34acae9a59 fixing escape()
fixing escape() as replacing a None would throw an exception 'NoneType' object has no attribute 'replace'. useful in case of escaping a None string given from message.from_user.last_name as you dont know wether the user has a last name or not
2022-12-03 13:33:22 +01:00
109ae69f27 Merge pull request #1823 from Badiboy/master
Fixed register_next_step_handler_by_chat_id chat_id description
2022-12-03 00:01:57 +03:00
43abedbff7 Fixed register_next_step_handler_by_chat_id chat_id description 2022-12-02 23:59:59 +03:00
42d162f732 Merge pull request #1822 from Badiboy/master
Fix caption_entities miss in InputMediaXXX
2022-12-02 23:52:54 +03:00
cd4dc899a1 Fix caption_entities miss in InputMediaXXX 2022-12-02 23:46:26 +03:00
5066626692 Merge pull request #1818 from Cub11k/master
Translated to russian file: util.po
2022-12-01 12:46:16 +04:00
e255d9cbab Update docs/source/locales/ru/LC_MESSAGES/util.po
Co-authored-by: _run <khumogo1@gmail.com>
2022-11-30 23:12:33 +02:00
8e1c8a2742 Update docs/source/locales/ru/LC_MESSAGES/util.po
Co-authored-by: _run <khumogo1@gmail.com>
2022-11-30 23:12:25 +02:00
e358abc1bd Update util.po 2022-11-30 21:07:46 +02:00
42da2d1794 Merge pull request #1816 from Cub11k/master
Translated into russian file: formatting.po
2022-11-30 19:44:24 +04:00
feaef2b2b8 Merge remote-tracking branch 'origin/master' 2022-11-30 17:33:28 +02:00
6cf60a3dcb Update formatting.po according to comments 2022-11-30 17:33:06 +02:00
91ff06eeba Update docs/source/locales/ru/LC_MESSAGES/formatting.po
Co-authored-by: _run <khumogo1@gmail.com>
2022-11-30 16:49:46 +02:00
1c2111d689 Update formatting.po 2022-11-29 20:19:25 +02:00
bf039df122 Merge pull request #1815 from coder2020official/master
Update install.po
2022-11-29 19:25:40 +04:00
44309797d1 Update install.po 2022-11-29 19:21:05 +04:00
8489383eb4 Merge pull request #1814 from abdullaev388/master
Translated into russian files:  install.po, quick_start.po
2022-11-29 19:12:54 +04:00
848a2cc7ec Update docs/source/locales/ru/LC_MESSAGES/install.po
Co-authored-by: _run <khumogo1@gmail.com>
2022-11-29 10:11:27 -05:00
cc87dbce50 Update docs/source/locales/ru/LC_MESSAGES/install.po
Co-authored-by: _run <khumogo1@gmail.com>
2022-11-29 10:11:21 -05:00
15f6bbeacb Update docs/source/locales/ru/LC_MESSAGES/install.po
Co-authored-by: _run <khumogo1@gmail.com>
2022-11-29 10:09:48 -05:00
29befa4d0c Update install.po
translated into russian
2022-11-29 09:25:10 -05:00
cce03dab78 Update quick_start.po
translated into russian
2022-11-29 09:21:24 -05:00
7702d63fd7 Merge pull request #1813 from coder2020official/docs
Base of ru documentation added.
2022-11-29 17:39:30 +04:00
d636cdf88b Update doc_req.txt 2022-11-29 17:37:16 +04:00
06a28380d7 Update doc_req.txt 2022-11-29 17:33:42 +04:00
d7e9d3accc Update conf.py 2022-11-29 14:59:17 +04:00
736c03fe84 Update conf.py 2022-11-29 14:49:32 +04:00
7502d26b1a Added locales 2022-11-29 14:45:51 +04:00
b4d59fdf0a Merge pull request #1812 from Badiboy/master
Bump version to 4.8.0 and update Python versions
2022-11-28 19:24:46 +03:00
8d723bdcb3 Python 3.6 removed, Python 3.11 added 2022-11-28 19:17:23 +03:00
a169404a7c Bump version to 4.8.0 2022-11-28 19:14:07 +03:00
7a20017dfb Merge pull request #1811 from coder2020official/continuehandling-fix
Continuehandling fix
2022-11-27 11:30:37 +03:00
8d82b3d56b Update async_telebot.py 2022-11-26 20:08:00 +04:00
0759c8e081 Update __init__.py 2022-11-26 20:07:08 +04:00
8992db1d24 Merge pull request #1808 from coder2020official/master
Fix #1804
2022-11-26 20:05:00 +04:00
deb2099396 Update types.py 2022-11-22 18:36:15 +04:00
8a74198276 Merge pull request #1801 from coder2020official/master
Fixed bot api bug
2022-11-18 23:22:39 +04:00
15bd5f991a Update types.py 2022-11-18 23:21:06 +04:00
25571b581c Update types.py 2022-11-18 23:12:03 +04:00
bf617ab8da Merge pull request #1799 from Badiboy/master
content_type_media and content_type_service reviewed
2022-11-13 13:21:45 +03:00
74732f2eda content_type_media and content_type_service reviewed 2022-11-13 13:20:26 +03:00
0a79f7e4f3 Merge pull request #1783 from coder2020official/botapi-63
Bot API 6.3 Update
2022-11-13 12:39:38 +03:00
8b735aa114 Update __init__.py 2022-11-13 13:34:54 +04:00
ae1845f285 Added active_usernames and emoji_status_custom_emoji_id 2022-11-06 17:38:01 +04:00
0846852ea1 Added all necessary parameters
Added the parameter message_thread_id to the methods sendMessage, sendPhoto, sendVideo, sendAnimation, sendAudio, sendDocument, sendSticker, sendVideoNote, sendVoice, sendLocation, sendVenue, sendContact, sendPoll, sendDice, sendInvoice, sendGame, sendMediaGroup, copyMessage, forwardMessage to support sending of messages to a forum topic.
2022-11-06 17:31:49 +04:00
4825624d48 Added docs to types, added new methods
Added the methods createForumTopic, editForumTopic, closeForumTopic, reopenForumTopic, deleteForumTopic, unpinAllForumTopicMessages, and getForumTopicIconStickers for forum topic management.
2022-11-06 15:43:16 +04:00
876d679765 Added ForumTopic class and fixed previous classes by fixing de_json method. 2022-11-06 15:14:19 +04:00
7958d0dca7 Added can_manage_topics for promotechatmember
Added the parameter can_manage_topics to the method promoteChatMember.
2022-11-06 15:04:41 +04:00
4e2ea90db3 Added field can_manage_topics
Added the field can_manage_topics to the classes ChatAdministratorRights, ChatPermissions, ChatMemberAdministrator, and ChatMemberRestricted.
2022-11-06 15:00:20 +04:00
566aef1679 Fix wrong typehint for previous commit 2022-11-06 14:49:13 +04:00
2dad99ad95 Merge pull request #1761 from coder2020official/master
Extended exception handler behaviour for async
2022-11-06 09:23:02 +03:00
f288470b43 Added the classes ForumTopicCreated, ForumTopicClosed, and ForumTopicReopened and the fields forum_topic_created, forum_topic_closed, and forum_topic_reopened to the class Message. Note that service messages about forum topic creation can't be deleted with the deleteMessage method.
Added the classes ForumTopicCreated, ForumTopicClosed, and ForumTopicReopened and the fields forum_topic_created, forum_topic_closed, and forum_topic_reopened to the class Message. Note that service messages about forum topic creation can't be deleted with the deleteMessage method.
2022-11-06 01:04:33 +04:00
475394d241 Added message_thread_id & is_topic_message 2022-11-05 23:23:00 +04:00
76f06cacfe Fix typo 2022-11-05 23:15:10 +04:00
77738b2537 Added is_forum 2022-11-05 23:14:37 +04:00
070479f7af Update async_telebot.py 2022-11-05 23:06:28 +04:00
f1f18c6df2 Fix error description 2022-11-05 22:49:07 +04:00
81c8ee5820 Update README.md 2022-11-05 22:20:11 +04:00
76a689d939 Merge pull request #1774 from batmanscode/master
fixes: `debug` removed from uvicorn #1767
2022-11-02 13:29:45 +03:00
92ecfdec48 fixes: debug removed from uvicorn #1767 2022-10-30 17:21:53 +00:00
20376168c1 Merge pull request #1772 from sijokun/master
Added example of running serverless on AWS Lambda
2022-10-29 12:02:31 +03:00
507d53efbd Rename lambda_function.py to aws_lambda_function.py 2022-10-29 11:57:53 +03:00
1d8dc78c87 Added example of running serverless on AWS Lambda
Example of using of PyTelegramBotAPI in Amazon AWS Lambda
2022-10-29 01:18:52 +03:00
ebec3bf5c1 Merge pull request #1762 from reddere/patch-1
Fixed InlineQueryResultVideo params in example.
2022-10-24 19:25:15 +03:00
d11b9802da Fixed InlineQueryResultVideo params in example.
Fixed InlineQueryResultVideo params in example. String "Video" was passed in stead of the thumbnail url, making the example not work, This has been tested working.
2022-10-24 16:02:59 +02:00
572f103db7 Extended exception handler behaviour for async 2022-10-22 21:48:29 +04:00
231371f1f8 Merge pull request #1759 from Badiboy/master
Bump version to 4.7.1
2022-10-21 10:58:23 +03:00
623d8b27ec Bump version to 4.7.1 2022-10-21 10:18:47 +03:00
31c3a2b2a3 Merge pull request #1742 from byehack/ContinueHandling
Support ContinueHandling
2022-10-11 19:03:44 +03:00
c45af810f9 Updated docstrings for ContinueHandling 2022-10-11 19:15:38 +04:00
81f090cce6 Update asyncio_handler_backends.py 2022-10-11 19:15:01 +04:00
5d16b8bd4a Create continue_handling.py 2022-10-11 19:13:10 +04:00
0fecf46201 Create continue_handling.py 2022-10-11 19:09:59 +04:00
982e642c73 Update telebot/handler_backends.py 2022-10-11 19:05:55 +04:00
97bca49c00 ContinueHandling on asyncio_handler_backends 2022-10-09 02:28:05 +03:30
e0ee087162 Merge pull request #1749 from Badiboy/master
Check CUSTOM_REQUEST_SENDER before RETRY_xxx.
2022-10-08 23:43:44 +03:00
620b1364a6 Check CUSTOM_REQUEST_SENDER before RETRY_xxx. 2022-10-08 23:41:41 +03:00
c561cf3076 Merge pull request #1748 from coder2020official/master
Added warning for non_stop=False
2022-10-08 23:24:58 +03:00
b3953d6249 ℹ️ Better description 2022-10-08 23:03:04 +04:00
2d7170feee Added warning for non_stop=False 2022-10-08 22:35:22 +04:00
0ca8007633 Merge pull request #1747 from coder2020official/master
Update __init__.py
2022-10-07 20:57:49 +03:00
c541533762 Update __init__.py 2022-10-07 21:50:51 +04:00
4798c26188 improve code quality 2022-10-02 12:05:20 +03:30
30aaf8d0f1 Support ContinueHandling 2022-10-02 03:27:06 +03:30
82ad37fed8 Merge pull request #1693 from coder2020official/conflicts
Logging improvements(still not 100%), file restarts on file changes(needs tests), and more
2022-10-01 22:30:49 +03:00
2d1f39085d Improved code readability x 2 2022-10-01 22:34:49 +04:00
b523cec22f Improved code readability 2022-10-01 22:32:41 +04:00
27e0197855 Added examples and made it possible to specify --path path for path 2022-10-01 21:28:53 +04:00
ea69b8093d Added some notes 2022-10-01 21:15:24 +04:00
04ff428bba Added option to specify path to watch 2022-10-01 21:02:40 +04:00
eb576d83fb Fixed a bug, made improvements in reload system
Didn't test that much, there is still some stuff to do
2022-09-30 23:22:21 +04:00
d3080b6d4e Merge branch 'master' into conflicts 2022-09-30 22:53:19 +04:00
7c9b01b10a Merge pull request #1722 from Badiboy/master
Handlers and Middlewares processing union
2022-09-24 22:16:33 +03:00
b3993bb019 Merge remote-tracking branch 'upstream/master' 2022-09-24 22:14:45 +03:00
36b889feab Merge pull request #1736 from AntonGlyzin/antonglyzin-shopbotlist
Added a new bot to the list
2022-09-24 16:06:33 +03:00
d943f40643 Added a new bot to the list 2022-09-24 15:33:11 +03:00
dafafd2ad2 Merge pull request #1735 from coder2020official/class_params
⚙️ Added some frequent parameters to classes(see full list)
2022-09-23 22:06:09 +04:00
e002484a9b ⚙️ Added some frequent parameters to classes(see full list)
Added:
- disable_web_page_preview
- disable_notification
- protect_content
- allow_sending_without_reply
2022-09-23 21:52:40 +04:00
52e09637c2 Fix: do not call handler in one more task 2022-09-17 23:17:07 +03:00
e7a96ec2ed Rename also in Async 2022-09-17 14:09:05 +03:00
598de25b6d Rename _check_middlewares to _get_middlewares 2022-09-17 12:55:55 +03:00
b841fc10ed Merge pull request #1723 from byehack/patch-1
don't block loop
2022-09-17 13:42:57 +04:00
c14760d81c don't block loop 2022-09-17 13:58:28 +04:30
da639dd1f6 Handlers and Middlewares processing union
Call for handlers now union in a single function for future extension.

Plus minor fixes in storages.
2022-09-17 11:57:12 +03:00
96e137f5e6 Update setup.py 2022-09-16 22:39:40 +04:00
8d9dfcfac8 Merge pull request #1707 from S1RANN/master
raise other exceptions in antiflood function
2022-09-13 17:59:30 +03:00
a1c77db236 Merge pull request #1710 from coder2020official/bugfixes
Fixed difference between request_timeout and timeout.
2022-09-10 20:48:30 +04:00
4f97b26e81 Update asyncio_helper.py 2022-09-10 20:37:13 +04:00
0028feb4c5 Update asyncio_helper.py 2022-09-10 20:14:48 +04:00
a06b4a1e9c raise other exceptions in antiflood 2022-09-10 21:46:16 +08:00
da5084f53c Update asyncio_helper.py 2022-09-10 14:36:56 +04:00
2f8d878f06 Fixed difference between request_timeout and timeout.
getUpdates parameter may contain 2 parameters: request_timeout & timeout. other methods may contain timeout parameter that should be applied to ClientTimeout.
2022-09-10 14:34:56 +04:00
783beb165b raise other exceptions in antiflood 2022-09-10 15:59:40 +08:00
4fd01e3ac8 Merge pull request #1703 from coder2020official/downloadfile
Fix #1702
2022-09-09 21:09:25 +04:00
b4c28de104 Update asyncio_helper.py 2022-09-07 20:44:39 +04:00
de344bd5e0 Merge pull request #1701 from coder2020official/states
#1699 fixed
2022-09-06 18:16:06 +04:00
e3a4fdff9a Update asyncio_filters.py 2022-09-06 18:12:11 +04:00
71d3ec8b42 Changed user id and chat id 2022-09-06 18:11:40 +04:00
1b1d6c8239 Improved asyncio helper's logger 2022-08-30 21:26:56 +04:00
9216f15c16 Logs, file restarts, loggers to async
Added colorful logs, file restarts on changes, improved logger, added cached version of user-bot to async
2022-08-30 21:26:41 +04:00
0f7ab0d05f Added colorful logs, file restarts on changes to sync 2022-08-30 21:25:41 +04:00
e0ffe0b4f5 Added reloader to ext 2022-08-30 21:24:54 +04:00
f4c5dd0d22 Merge pull request #1691 from ananthb/master
Starlette ASGI example
2022-08-30 15:55:28 +03:00
e4179ea65f Add SSL cert 2022-08-30 17:27:43 +05:30
d7770bf670 Starlette ASGI example 2022-08-30 17:05:56 +05:30
095bf03227 Merge pull request #1688 from ananthb/patch-1
Import aioredis from redis module too
2022-08-30 12:28:18 +04:00
85bd174fdc Update redis_storage.py 2022-08-30 12:26:34 +04:00
b86c38367a Import aioredis from redis module too
aioredis is available in redis-py as of version 4.2.0rc1: https://github.com/aio-libs/aioredis-py#-aioredis-is-now-in-redis-py-420rc1-
Try importing from the new package as well.
2022-08-28 17:32:56 +05:30
b8214d32d5 Merge pull request #1679 from Badiboy/master
Code simplify and sync/async unificatiion
2022-08-22 12:20:36 +03:00
f4e66f6807 Added traceback for handlers exception 2022-08-21 22:27:02 +03:00
b1a4136603 Code simplify and sync/async unificatiion 2022-08-21 20:32:37 +03:00
3d97b08289 Merge pull request #1678 from coder2020official/master
Fixed bug with searching a new handler after the execution of handler
2022-08-21 19:38:59 +03:00
3d2576ca24 Fixed bug with searching a new handler after the execution of handler 2022-08-21 20:42:55 +05:00
b2d2ab5c33 Merge pull request #1675 from coder2020official/master
Fixed #1650
2022-08-17 00:38:59 +03:00
c9a732e3dd Merge branch 'eternnoir:master' into master 2022-08-16 21:39:55 +05:00
01be1fb583 Fixes #1650 2022-08-16 21:39:20 +05:00
7b95874627 Merge pull request #1672 from Badiboy/master
Typo fix
2022-08-16 17:34:57 +03:00
426f9f3787 Typo fix
and minor code opt
2022-08-16 17:12:50 +03:00
51 changed files with 35088 additions and 503 deletions

View File

@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.6','3.7','3.8','3.9', '3.10', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9']
python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11', 'pypy-3.7', 'pypy-3.8', 'pypy-3.9']
name: ${{ matrix.python-version }} and tests
steps:
- uses: actions/checkout@v2

View File

@ -4,6 +4,7 @@ python:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "pypy3"
install: "pip install -r requirements.txt"
script:

View File

@ -11,7 +11,7 @@
<p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.</p>
<p align="center">Both synchronous and asynchronous.</p>
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#august-12-2022">6.2</a>!
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#december-30-2022">6.4</a>!
<h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>
@ -69,7 +69,7 @@
## Getting started
This API is tested with Python 3.6-3.10 and Pypy 3.
This API is tested with Python 3.7-3.11 and Pypy 3.
There are two ways to install the library:
* Installation using pip (a Python package manager):
@ -877,6 +877,7 @@ Here are some examples of template:
* [GrandQuiz Bot](https://github.com/Carlosma7/TFM-GrandQuiz) by [Carlosma7](https://github.com/Carlosma7). This bot is a trivia game that allows you to play with people from different ages. This project addresses the use of a system through chatbots to carry out a social and intergenerational game as an alternative to traditional game development.
* [Diccionario de la RAE](https://t.me/dleraebot) ([source](https://github.com/studentenherz/dleraebot)) This bot lets you find difinitions of words in Spanish using [RAE's dictionary](https://dle.rae.es/). It features direct message and inline search.
* [remoteTelegramShell](https://github.com/EnriqueMoran/remoteTelegramShell) by [EnriqueMoran](https://github.com/EnriqueMoran). Control your LinuxOS computer through Telegram.
* [Commerce Telegram Bot](https://github.com/ayitinya/commerce-telegram-bot/). Make purchases of items in a store with an Admin panel for data control and notifications.
* [Pyfram-telegram-bot](https://github.com/skelly37/pyfram-telegram-bot) Query wolframalpha.com and make use of its API through Telegram.
* [TranslateThisVideoBot](https://gitlab.com/WuerfelDev/translatethisvideo) This Bot can understand spoken text in videos and translate it to English
* [Zyprexa](https://t.me/mathemathicsBot) ([source](https://github.com/atif5/zyprexa)) Zyprexa can solve, help you solve any mathematical problem you encounter and convert your regular mathematical expressions into beautiful imagery using LaTeX.
@ -885,5 +886,6 @@ Here are some examples of template:
* [Gugumoe-bot](http://t.me/gugumoe_bot) ([source](https://github.com/GooGuJiang/Gugumoe-bot)) by [咕谷酱](https://gmoe.cc) GuXiaoJiang is a multi-functional robot, such as OSU game information query, IP test, animation screenshot search and other functions.
* [Feedback-bot](https://github.com/coder2020official/feedbackbot) A feedback bot for user-admin communication. Made on AsyncTeleBot, using [template](https://github.com/coder2020official/asynctelebot_template).
* [TeleServ](https://github.com/ablakely/TeleServ) by [ablakely](https://github.com/ablakely) This is a Telegram to IRC bridge which links as an IRC server and makes Telegram users appear as native IRC users.
* [Simple Store Bot](https://github.com/AntonGlyzin/myshopbot) by [Anton Glyzin](https://github.com/AntonGlyzin) This is a simple telegram-store with an admin panel. Designed according to a template.
**Want to have your bot listed here? Just make a pull request. Only bots with public source code are accepted.**

View File

@ -22,7 +22,7 @@ copyright = '2022, coder2020official'
author = 'coder2020official'
# The full version, including alpha/beta/rc tags
release = '4.7.0'
release = '4.9.0'
# -- General configuration ---------------------------------------------------
@ -68,3 +68,5 @@ html_theme_options = {
"light_logo": "logo.png",
"dark_logo": "logo2.png",
}
locale_dirs = ["locales/"]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,127 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../calldata.rst:4
msgid "Callback data factory"
msgstr ""
#: ../../calldata.rst:6
msgid "Callback data factory in pyTelegramBotAPI"
msgstr ""
#: ../../calldata.rst:6
msgid ""
"ptba, pytba, pyTelegramBotAPI, callbackdatafactory, guide, callbackdata, "
"factory"
msgstr ""
#: ../../calldata.rst:12
msgid "callback\\_data file"
msgstr ""
#: of telebot.callback_data:1
msgid "Callback data factory's file."
msgstr ""
#: of telebot.callback_data.CallbackData:1
#: telebot.callback_data.CallbackDataFilter:1
msgid "Bases: :py:class:`object`"
msgstr ""
#: of telebot.callback_data.CallbackData:1
msgid "Callback data factory This class will help you to work with CallbackQuery"
msgstr ""
#: of telebot.callback_data.CallbackData.filter:1
msgid "Generate filter"
msgstr ""
#: of telebot.callback_data.CallbackData.filter
#: telebot.callback_data.CallbackData.new
#: telebot.callback_data.CallbackData.parse
#: telebot.callback_data.CallbackDataFilter.check
msgid "Parameters"
msgstr ""
#: of telebot.callback_data.CallbackData.filter:3
msgid "specified named parameters will be checked with CallbackQuery.data"
msgstr ""
#: of telebot.callback_data.CallbackData.filter
#: telebot.callback_data.CallbackData.new
#: telebot.callback_data.CallbackData.parse
#: telebot.callback_data.CallbackDataFilter.check
msgid "Returns"
msgstr ""
#: of telebot.callback_data.CallbackData.filter:4
msgid "CallbackDataFilter class"
msgstr ""
#: of telebot.callback_data.CallbackData.new:1
msgid "Generate callback data"
msgstr ""
#: of telebot.callback_data.CallbackData.new:3
msgid "positional parameters of CallbackData instance parts"
msgstr ""
#: of telebot.callback_data.CallbackData.new:4
msgid "named parameters"
msgstr ""
#: of telebot.callback_data.CallbackData.new:5
msgid "str"
msgstr ""
#: of telebot.callback_data.CallbackData.parse:1
msgid "Parse data from the callback data"
msgstr ""
#: of telebot.callback_data.CallbackData.parse:3
msgid ""
"string, use to telebot.types.CallbackQuery to parse it from string to a "
"dict"
msgstr ""
#: of telebot.callback_data.CallbackData.parse:4
msgid "dict parsed from callback data"
msgstr ""
#: of telebot.callback_data.CallbackDataFilter:1
msgid "Filter for CallbackData."
msgstr ""
#: of telebot.callback_data.CallbackDataFilter.check:1
msgid "Checks if query.data appropriates to specified config"
msgstr ""
#: of telebot.callback_data.CallbackDataFilter.check:3
msgid "telebot.types.CallbackQuery"
msgstr ""
#: of telebot.callback_data.CallbackDataFilter.check:6
msgid "True if query.data appropriates to specified config"
msgstr ""
#: of telebot.callback_data.CallbackDataFilter.check
msgid "Return type"
msgstr ""

View File

@ -0,0 +1,251 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../formatting.rst:3
msgid "Formatting options"
msgstr ""
#: ../../formatting.rst:5
msgid "Formatting options in pyTelegramBotAPI"
msgstr ""
#: ../../formatting.rst:5
msgid "html, markdown, parse_mode, formatting, ptba, pytba, pyTelegramBotAPI"
msgstr ""
#: of telebot.formatting:1
msgid "Markdown & HTML formatting functions."
msgstr ""
#: of telebot.formatting.escape_html:1
msgid "Escapes HTML characters in a string of HTML."
msgstr ""
#: of telebot.formatting.escape_html telebot.formatting.escape_markdown
#: telebot.formatting.format_text telebot.formatting.hbold
#: telebot.formatting.hcode telebot.formatting.hide_link
#: telebot.formatting.hitalic telebot.formatting.hlink telebot.formatting.hpre
#: telebot.formatting.hspoiler telebot.formatting.hstrikethrough
#: telebot.formatting.hunderline telebot.formatting.mbold
#: telebot.formatting.mcode telebot.formatting.mitalic telebot.formatting.mlink
#: telebot.formatting.mspoiler telebot.formatting.mstrikethrough
#: telebot.formatting.munderline
msgid "Parameters"
msgstr ""
#: of telebot.formatting.escape_html:3
msgid "The string of HTML to escape."
msgstr ""
#: of telebot.formatting.escape_html telebot.formatting.escape_markdown
#: telebot.formatting.format_text telebot.formatting.hbold
#: telebot.formatting.hcode telebot.formatting.hide_link
#: telebot.formatting.hitalic telebot.formatting.hlink telebot.formatting.hpre
#: telebot.formatting.hspoiler telebot.formatting.hstrikethrough
#: telebot.formatting.hunderline telebot.formatting.mbold
#: telebot.formatting.mcode telebot.formatting.mitalic telebot.formatting.mlink
#: telebot.formatting.mspoiler telebot.formatting.mstrikethrough
#: telebot.formatting.munderline
msgid "Returns"
msgstr ""
#: of telebot.formatting.escape_html:6 telebot.formatting.escape_markdown:8
msgid "The escaped string."
msgstr ""
#: of telebot.formatting.escape_html telebot.formatting.escape_markdown
#: telebot.formatting.format_text telebot.formatting.hbold
#: telebot.formatting.hcode telebot.formatting.hide_link
#: telebot.formatting.hitalic telebot.formatting.hlink telebot.formatting.hpre
#: telebot.formatting.hspoiler telebot.formatting.hstrikethrough
#: telebot.formatting.hunderline telebot.formatting.mbold
#: telebot.formatting.mcode telebot.formatting.mitalic telebot.formatting.mlink
#: telebot.formatting.mspoiler telebot.formatting.mstrikethrough
#: telebot.formatting.munderline
msgid "Return type"
msgstr ""
#: of telebot.formatting.escape_html:7 telebot.formatting.escape_markdown:9
#: telebot.formatting.format_text:17 telebot.formatting.hbold:10
#: telebot.formatting.hcode:10 telebot.formatting.hide_link:7
#: telebot.formatting.hitalic:10 telebot.formatting.hlink:13
#: telebot.formatting.hpre:10 telebot.formatting.hspoiler:10
#: telebot.formatting.hstrikethrough:10 telebot.formatting.hunderline:10
#: telebot.formatting.mbold:10 telebot.formatting.mcode:10
#: telebot.formatting.mitalic:10 telebot.formatting.mlink:13
#: telebot.formatting.mspoiler:10 telebot.formatting.mstrikethrough:10
#: telebot.formatting.munderline:10
msgid ":obj:`str`"
msgstr ""
#: of telebot.formatting.escape_markdown:1
msgid "Escapes Markdown characters in a string of Markdown."
msgstr ""
#: of telebot.formatting.escape_markdown:3
msgid "Credits to: simonsmh"
msgstr ""
#: of telebot.formatting.escape_markdown:5
msgid "The string of Markdown to escape."
msgstr ""
#: of telebot.formatting.format_text:1
msgid "Formats a list of strings into a single string."
msgstr ""
#: of telebot.formatting.format_text:10
msgid "Strings to format."
msgstr ""
#: of telebot.formatting.format_text:13
msgid "The separator to use between each string."
msgstr ""
#: of telebot.formatting.format_text:16 telebot.formatting.hbold:9
#: telebot.formatting.hcode:9 telebot.formatting.hitalic:9
#: telebot.formatting.hlink:12 telebot.formatting.hpre:9
#: telebot.formatting.hspoiler:9 telebot.formatting.hstrikethrough:9
#: telebot.formatting.hunderline:9 telebot.formatting.mbold:9
#: telebot.formatting.mcode:9 telebot.formatting.mitalic:9
#: telebot.formatting.mlink:12 telebot.formatting.mspoiler:9
#: telebot.formatting.mstrikethrough:9 telebot.formatting.munderline:9
msgid "The formatted string."
msgstr ""
#: of telebot.formatting.hbold:1
msgid "Returns an HTML-formatted bold string."
msgstr ""
#: of telebot.formatting.hbold:3 telebot.formatting.mbold:3
msgid "The string to bold."
msgstr ""
#: of telebot.formatting.hbold:6 telebot.formatting.hcode:6
#: telebot.formatting.hitalic:6 telebot.formatting.hlink:9
#: telebot.formatting.hpre:6 telebot.formatting.hspoiler:6
#: telebot.formatting.hstrikethrough:6 telebot.formatting.hunderline:6
#: telebot.formatting.mbold:6 telebot.formatting.mcode:6
#: telebot.formatting.mitalic:6 telebot.formatting.mlink:9
#: telebot.formatting.mspoiler:6 telebot.formatting.mstrikethrough:6
#: telebot.formatting.munderline:6
msgid "True if you need to escape special characters. Defaults to True."
msgstr ""
#: of telebot.formatting.hcode:1
msgid "Returns an HTML-formatted code string."
msgstr ""
#: of telebot.formatting.hcode:3 telebot.formatting.mcode:3
msgid "The string to code."
msgstr ""
#: of telebot.formatting.hide_link:1
msgid "Hide url of an image."
msgstr ""
#: of telebot.formatting.hide_link:3
msgid "The url of the image."
msgstr ""
#: of telebot.formatting.hide_link:6
msgid "The hidden url."
msgstr ""
#: of telebot.formatting.hitalic:1
msgid "Returns an HTML-formatted italic string."
msgstr ""
#: of telebot.formatting.hitalic:3 telebot.formatting.mitalic:3
msgid "The string to italicize."
msgstr ""
#: of telebot.formatting.hlink:1
msgid "Returns an HTML-formatted link string."
msgstr ""
#: of telebot.formatting.hlink:3 telebot.formatting.mlink:3
msgid "The string to link."
msgstr ""
#: of telebot.formatting.hlink:6 telebot.formatting.mlink:6
msgid "The URL to link to."
msgstr ""
#: of telebot.formatting.hpre:1
msgid "Returns an HTML-formatted preformatted string."
msgstr ""
#: of telebot.formatting.hpre:3
msgid "The string to preformatted."
msgstr ""
#: of telebot.formatting.hspoiler:1
msgid "Returns an HTML-formatted spoiler string."
msgstr ""
#: of telebot.formatting.hspoiler:3 telebot.formatting.mspoiler:3
msgid "The string to spoiler."
msgstr ""
#: of telebot.formatting.hstrikethrough:1
msgid "Returns an HTML-formatted strikethrough string."
msgstr ""
#: of telebot.formatting.hstrikethrough:3 telebot.formatting.mstrikethrough:3
msgid "The string to strikethrough."
msgstr ""
#: of telebot.formatting.hunderline:1
msgid "Returns an HTML-formatted underline string."
msgstr ""
#: of telebot.formatting.hunderline:3 telebot.formatting.munderline:3
msgid "The string to underline."
msgstr ""
#: of telebot.formatting.mbold:1
msgid "Returns a Markdown-formatted bold string."
msgstr ""
#: of telebot.formatting.mcode:1
msgid "Returns a Markdown-formatted code string."
msgstr ""
#: of telebot.formatting.mitalic:1
msgid "Returns a Markdown-formatted italic string."
msgstr ""
#: of telebot.formatting.mlink:1
msgid "Returns a Markdown-formatted link string."
msgstr ""
#: of telebot.formatting.mspoiler:1
msgid "Returns a Markdown-formatted spoiler string."
msgstr ""
#: of telebot.formatting.mstrikethrough:1
msgid "Returns a Markdown-formatted strikethrough string."
msgstr ""
#: of telebot.formatting.munderline:1
msgid "Returns a Markdown-formatted underline string."
msgstr ""

View File

@ -0,0 +1,120 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../index.rst:8
msgid "Welcome to pyTelegramBotAPI's documentation!"
msgstr ""
#: ../../index.rst:10
msgid "Official documentation of pyTelegramBotAPI"
msgstr ""
#: ../../index.rst:10
msgid "ptba, pytba, pyTelegramBotAPI, documentation, guide"
msgstr ""
#: ../../index.rst:17
msgid "TeleBot"
msgstr ""
#: ../../index.rst:18
msgid ""
"TeleBot is synchronous and asynchronous implementation of `Telegram Bot "
"API <https://core.telegram.org/bots/api>`_."
msgstr ""
#: ../../index.rst:21
msgid "Chats"
msgstr ""
#: ../../index.rst:22
msgid ""
"English chat: `Private chat "
"<https://telegram.me/joinchat/Bn4ixj84FIZVkwhk2jag6A>`__"
msgstr ""
#: ../../index.rst:24
msgid ""
"Russian chat: `@pytelegrambotapi_talks_ru "
"<https://t.me/pytelegrambotapi_talks_ru>`__"
msgstr ""
#: ../../index.rst:26
msgid "News: `@pyTelegramBotAPI <https://t.me/pytelegrambotapi>`__"
msgstr ""
#: ../../index.rst:28
msgid "Pypi: `Pypi <https://pypi.org/project/pyTelegramBotAPI/>`__"
msgstr ""
#: ../../index.rst:30
msgid ""
"Source: `Github repository "
"<https://github.com/eternnoir/pyTelegramBotAPI>`__"
msgstr ""
#: ../../index.rst:33
msgid "Some features:"
msgstr ""
#: ../../index.rst:34
msgid "Easy to learn and use."
msgstr ""
#: ../../index.rst:36
msgid "Easy to understand."
msgstr ""
#: ../../index.rst:38
msgid "Both sync and async."
msgstr ""
#: ../../index.rst:40
msgid "Examples on features."
msgstr ""
#: ../../index.rst:42
msgid "States"
msgstr ""
#: ../../index.rst:44
msgid "And more..."
msgstr ""
#: ../../index.rst:47
msgid "Content"
msgstr ""
#: ../../index.rst:63
msgid "Indices and tables"
msgstr ""
#: ../../index.rst:65
msgid ":ref:`genindex`"
msgstr ""
#: ../../index.rst:66
msgid ":ref:`modindex`"
msgstr ""
#: ../../index.rst:67
msgid ":ref:`search`"
msgstr ""

View File

@ -0,0 +1,58 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../install.rst:3
msgid "Installation Guide"
msgstr ""
#: ../../install.rst:5
msgid "Installation of pyTelegramBotAPI"
msgstr ""
#: ../../install.rst:5
msgid "ptba, pytba, pyTelegramBotAPI, installation, guide"
msgstr ""
#: ../../install.rst:11
msgid "Using PIP"
msgstr ""
#: ../../install.rst:17
msgid "Using pipenv"
msgstr ""
#: ../../install.rst:23
msgid "By cloning repository"
msgstr ""
#: ../../install.rst:31
msgid "Directly using pip"
msgstr ""
#: ../../install.rst:37
msgid "It is generally recommended to use the first option."
msgstr ""
#: ../../install.rst:39
msgid ""
"While the API is production-ready, it is still under development and it "
"has regular updates, do not forget to update it regularly by calling:"
msgstr ""

View File

@ -0,0 +1,40 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../quick_start.rst:4
msgid "Quick start"
msgstr ""
#: ../../quick_start.rst:6
msgid "Quickstart guide"
msgstr ""
#: ../../quick_start.rst:6
msgid "ptba, pytba, pyTelegramBotAPI, quickstart, guide"
msgstr ""
#: ../../quick_start.rst:11
msgid "Synchronous TeleBot"
msgstr ""
#: ../../quick_start.rst:16
msgid "Asynchronous TeleBot"
msgstr ""

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,345 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../util.rst:3
msgid "Utils"
msgstr ""
#: ../../util.rst:5
msgid "Utils in pyTelegramBotAPI"
msgstr ""
#: ../../util.rst:5
msgid "ptba, pytba, pyTelegramBotAPI, utils, guide"
msgstr ""
#: ../../util.rst:11
msgid "util file"
msgstr ""
#: of telebot.util.antiflood:1
msgid ""
"Use this function inside loops in order to avoid getting TooManyRequests "
"error. Example:"
msgstr ""
#: of telebot.util.antiflood telebot.util.escape telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.is_bytes telebot.util.is_command
#: telebot.util.is_dict telebot.util.is_pil_image
#: telebot.util.parse_web_app_data telebot.util.quick_markup
#: telebot.util.smart_split telebot.util.split_string telebot.util.user_link
#: telebot.util.validate_web_app_data telebot.util.webhook_google_functions
msgid "Parameters"
msgstr ""
#: of telebot.util.antiflood:10
msgid "The function to call"
msgstr ""
#: of telebot.util.antiflood:13
msgid "The arguments to pass to the function"
msgstr ""
#: of telebot.util.antiflood:16
msgid "The keyword arguments to pass to the function"
msgstr ""
#: of telebot.util.antiflood telebot.util.escape telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.generate_random_token
#: telebot.util.is_bytes telebot.util.is_command telebot.util.is_dict
#: telebot.util.is_pil_image telebot.util.parse_web_app_data
#: telebot.util.quick_markup telebot.util.smart_split telebot.util.split_string
#: telebot.util.user_link telebot.util.validate_web_app_data
#: telebot.util.webhook_google_functions
msgid "Returns"
msgstr ""
#: of telebot.util.antiflood:19
msgid "None"
msgstr ""
#: of telebot.util.chunks:1
msgid "Yield successive n-sized chunks from lst."
msgstr ""
#: ../../docstring of telebot.util.content_type_media:1
msgid "Contains all media content types."
msgstr ""
#: ../../docstring of telebot.util.content_type_service:1
msgid "Contains all service content types such as `User joined the group`."
msgstr ""
#: of telebot.util.escape:1
msgid ""
"Replaces the following chars in `text` ('&' with '&amp;', '<' with '&lt;'"
" and '>' with '&gt;')."
msgstr ""
#: of telebot.util.escape:3
msgid "the text to escape"
msgstr ""
#: of telebot.util.escape:4
msgid "the escaped text"
msgstr ""
#: of telebot.util.extract_arguments:1
msgid "Returns the argument after the command."
msgstr ""
#: of telebot.util.extract_arguments:3 telebot.util.extract_command:4
msgid "Examples:"
msgstr ""
#: of telebot.util.extract_arguments:10
msgid "String to extract the arguments from a command"
msgstr ""
#: of telebot.util.extract_arguments:13
msgid "the arguments if `text` is a command (according to is_command), else None."
msgstr ""
#: of telebot.util.extract_arguments telebot.util.extract_command
#: telebot.util.generate_random_token telebot.util.is_bytes
#: telebot.util.is_command telebot.util.is_dict telebot.util.is_pil_image
#: telebot.util.quick_markup telebot.util.smart_split telebot.util.split_string
#: telebot.util.user_link
msgid "Return type"
msgstr ""
#: of telebot.util.extract_arguments:14 telebot.util.extract_command:16
msgid ":obj:`str` or :obj:`None`"
msgstr ""
#: of telebot.util.extract_command:1
msgid ""
"Extracts the command from `text` (minus the '/') if `text` is a command "
"(see is_command). If `text` is not a command, this function returns None."
msgstr ""
#: of telebot.util.extract_command:12
msgid "String to extract the command from"
msgstr ""
#: of telebot.util.extract_command:15
msgid "the command if `text` is a command (according to is_command), else None."
msgstr ""
#: of telebot.util.generate_random_token:1
msgid ""
"Generates a random token consisting of letters and digits, 16 characters "
"long."
msgstr ""
#: of telebot.util.generate_random_token:3
msgid "a random token"
msgstr ""
#: of telebot.util.generate_random_token:4 telebot.util.user_link:22
msgid ":obj:`str`"
msgstr ""
#: of telebot.util.is_bytes:1
msgid "Returns True if the given object is a bytes object."
msgstr ""
#: of telebot.util.is_bytes:3 telebot.util.is_dict:3
#: telebot.util.is_pil_image:3
msgid "object to be checked"
msgstr ""
#: of telebot.util.is_bytes:6
msgid "True if the given object is a bytes object."
msgstr ""
#: of telebot.util.is_bytes:7 telebot.util.is_command:7 telebot.util.is_dict:7
#: telebot.util.is_pil_image:7
msgid ":obj:`bool`"
msgstr ""
#: of telebot.util.is_command:1
msgid ""
"Checks if `text` is a command. Telegram chat commands start with the '/' "
"character."
msgstr ""
#: of telebot.util.is_command:3
msgid "Text to check."
msgstr ""
#: of telebot.util.is_command:6
msgid "True if `text` is a command, else False."
msgstr ""
#: of telebot.util.is_dict:1
msgid "Returns True if the given object is a dictionary."
msgstr ""
#: of telebot.util.is_dict:6
msgid "True if the given object is a dictionary."
msgstr ""
#: of telebot.util.is_pil_image:1
msgid "Returns True if the given object is a PIL.Image.Image object."
msgstr ""
#: of telebot.util.is_pil_image:6
msgid "True if the given object is a PIL.Image.Image object."
msgstr ""
#: of telebot.util.is_string:1
msgid "Returns True if the given object is a string."
msgstr ""
#: of telebot.util.parse_web_app_data:1
msgid "Parses web app data."
msgstr ""
#: of telebot.util.parse_web_app_data:3 telebot.util.validate_web_app_data:3
msgid "The bot token"
msgstr ""
#: of telebot.util.parse_web_app_data:6 telebot.util.validate_web_app_data:6
msgid "The raw init data"
msgstr ""
#: of telebot.util.parse_web_app_data:9 telebot.util.validate_web_app_data:9
msgid "The parsed init data"
msgstr ""
#: of telebot.util.quick_markup:1
msgid ""
"Returns a reply markup from a dict in this format: {'text': kwargs} This "
"is useful to avoid always typing 'btn1 = InlineKeyboardButton(...)' 'btn2"
" = InlineKeyboardButton(...)'"
msgstr ""
#: of telebot.util.quick_markup:4 telebot.util.user_link:5
msgid "Example:"
msgstr ""
#: of telebot.util.quick_markup:6
msgid "Using quick_markup:"
msgstr ""
#: of telebot.util.quick_markup:29
msgid ""
"a dict containing all buttons to create in this format: {text: kwargs} "
"{str:}"
msgstr ""
#: of telebot.util.quick_markup:32
msgid "int row width"
msgstr ""
#: of telebot.util.quick_markup:35
msgid "InlineKeyboardMarkup"
msgstr ""
#: of telebot.util.quick_markup:36
msgid ":obj:`types.InlineKeyboardMarkup`"
msgstr ""
#: of telebot.util.smart_split:1
msgid ""
"Splits one string into multiple strings, with a maximum amount of "
"`chars_per_string` characters per string. This is very useful for "
"splitting one giant message into multiples. If `chars_per_string` > 4096:"
" `chars_per_string` = 4096. Splits by '\\n', '. ' or ' ' in exactly this "
"priority."
msgstr ""
#: of telebot.util.smart_split:6 telebot.util.split_string:4
msgid "The text to split"
msgstr ""
#: of telebot.util.smart_split:9
msgid "The number of maximum characters per part the text is split to."
msgstr ""
#: of telebot.util.smart_split:12 telebot.util.split_string:10
msgid "The splitted text as a list of strings."
msgstr ""
#: of telebot.util.smart_split:13 telebot.util.split_string:11
msgid ":obj:`list` of :obj:`str`"
msgstr ""
#: of telebot.util.split_string:1
msgid ""
"Splits one string into multiple strings, with a maximum amount of "
"`chars_per_string` characters per string. This is very useful for "
"splitting one giant message into multiples."
msgstr ""
#: of telebot.util.split_string:7
msgid "The number of characters per line the text is split into."
msgstr ""
#: ../../docstring of telebot.util.update_types:1
msgid "All update types, should be used for allowed_updates parameter in polling."
msgstr ""
#: of telebot.util.user_link:1
msgid ""
"Returns an HTML user link. This is useful for reports. Attention: Don't "
"forget to set parse_mode to 'HTML'!"
msgstr ""
#: of telebot.util.user_link:11
msgid ""
"You can use formatting.* for all other formatting options(bold, italic, "
"links, and etc.) This method is kept for backward compatibility, and it "
"is recommended to use formatting.* for more options."
msgstr ""
#: of telebot.util.user_link:15
msgid "the user (not the user_id)"
msgstr ""
#: of telebot.util.user_link:18
msgid "include the user_id"
msgstr ""
#: of telebot.util.user_link:21
msgid "HTML user link"
msgstr ""
#: of telebot.util.validate_web_app_data:1
msgid "Validates web app data."
msgstr ""
#: of telebot.util.webhook_google_functions:1
msgid "A webhook endpoint for Google Cloud Functions FaaS."
msgstr ""
#: of telebot.util.webhook_google_functions:3
msgid "The bot instance"
msgstr ""
#: of telebot.util.webhook_google_functions:6
msgid "The request object"
msgstr ""
#: of telebot.util.webhook_google_functions:9
msgid "The response object"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,127 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../calldata.rst:4
msgid "Callback data factory"
msgstr ""
#: ../../calldata.rst:6
msgid "Callback data factory in pyTelegramBotAPI"
msgstr ""
#: ../../calldata.rst:6
msgid ""
"ptba, pytba, pyTelegramBotAPI, callbackdatafactory, guide, callbackdata, "
"factory"
msgstr ""
#: ../../calldata.rst:12
msgid "callback\\_data file"
msgstr ""
#: of telebot.callback_data:1
msgid "Callback data factory's file."
msgstr ""
#: of telebot.callback_data.CallbackData:1
#: telebot.callback_data.CallbackDataFilter:1
msgid "Bases: :py:class:`object`"
msgstr ""
#: of telebot.callback_data.CallbackData:1
msgid "Callback data factory This class will help you to work with CallbackQuery"
msgstr ""
#: of telebot.callback_data.CallbackData.filter:1
msgid "Generate filter"
msgstr ""
#: of telebot.callback_data.CallbackData.filter
#: telebot.callback_data.CallbackData.new
#: telebot.callback_data.CallbackData.parse
#: telebot.callback_data.CallbackDataFilter.check
msgid "Parameters"
msgstr ""
#: of telebot.callback_data.CallbackData.filter:3
msgid "specified named parameters will be checked with CallbackQuery.data"
msgstr ""
#: of telebot.callback_data.CallbackData.filter
#: telebot.callback_data.CallbackData.new
#: telebot.callback_data.CallbackData.parse
#: telebot.callback_data.CallbackDataFilter.check
msgid "Returns"
msgstr ""
#: of telebot.callback_data.CallbackData.filter:4
msgid "CallbackDataFilter class"
msgstr ""
#: of telebot.callback_data.CallbackData.new:1
msgid "Generate callback data"
msgstr ""
#: of telebot.callback_data.CallbackData.new:3
msgid "positional parameters of CallbackData instance parts"
msgstr ""
#: of telebot.callback_data.CallbackData.new:4
msgid "named parameters"
msgstr ""
#: of telebot.callback_data.CallbackData.new:5
msgid "str"
msgstr ""
#: of telebot.callback_data.CallbackData.parse:1
msgid "Parse data from the callback data"
msgstr ""
#: of telebot.callback_data.CallbackData.parse:3
msgid ""
"string, use to telebot.types.CallbackQuery to parse it from string to a "
"dict"
msgstr ""
#: of telebot.callback_data.CallbackData.parse:4
msgid "dict parsed from callback data"
msgstr ""
#: of telebot.callback_data.CallbackDataFilter:1
msgid "Filter for CallbackData."
msgstr ""
#: of telebot.callback_data.CallbackDataFilter.check:1
msgid "Checks if query.data appropriates to specified config"
msgstr ""
#: of telebot.callback_data.CallbackDataFilter.check:3
msgid "telebot.types.CallbackQuery"
msgstr ""
#: of telebot.callback_data.CallbackDataFilter.check:6
msgid "True if query.data appropriates to specified config"
msgstr ""
#: of telebot.callback_data.CallbackDataFilter.check
msgid "Return type"
msgstr ""

View File

@ -0,0 +1,251 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../formatting.rst:3
msgid "Formatting options"
msgstr "Параметры форматирования"
#: ../../formatting.rst:5
msgid "Formatting options in pyTelegramBotAPI"
msgstr "Параметры форматирования в pyTelegramBotAPI"
#: ../../formatting.rst:5
msgid "html, markdown, parse_mode, formatting, ptba, pytba, pyTelegramBotAPI"
msgstr "html, markdown, parse_mode, форматирование, ptba, pytba, pyTelegramBotAPI"
#: of telebot.formatting:1
msgid "Markdown & HTML formatting functions."
msgstr "Функции форматирования Markdown & HTML."
#: of telebot.formatting.escape_html:1
msgid "Escapes HTML characters in a string of HTML."
msgstr "Пропускает HTML символы в HTML строке."
#: of telebot.formatting.escape_html telebot.formatting.escape_markdown
#: telebot.formatting.format_text telebot.formatting.hbold
#: telebot.formatting.hcode telebot.formatting.hide_link
#: telebot.formatting.hitalic telebot.formatting.hlink telebot.formatting.hpre
#: telebot.formatting.hspoiler telebot.formatting.hstrikethrough
#: telebot.formatting.hunderline telebot.formatting.mbold
#: telebot.formatting.mcode telebot.formatting.mitalic telebot.formatting.mlink
#: telebot.formatting.mspoiler telebot.formatting.mstrikethrough
#: telebot.formatting.munderline
msgid "Parameters"
msgstr ""
#: of telebot.formatting.escape_html:3
msgid "The string of HTML to escape."
msgstr "HTML строка, которую нужно пропустить."
#: of telebot.formatting.escape_html telebot.formatting.escape_markdown
#: telebot.formatting.format_text telebot.formatting.hbold
#: telebot.formatting.hcode telebot.formatting.hide_link
#: telebot.formatting.hitalic telebot.formatting.hlink telebot.formatting.hpre
#: telebot.formatting.hspoiler telebot.formatting.hstrikethrough
#: telebot.formatting.hunderline telebot.formatting.mbold
#: telebot.formatting.mcode telebot.formatting.mitalic telebot.formatting.mlink
#: telebot.formatting.mspoiler telebot.formatting.mstrikethrough
#: telebot.formatting.munderline
msgid "Returns"
msgstr ""
#: of telebot.formatting.escape_html:6 telebot.formatting.escape_markdown:8
msgid "The escaped string."
msgstr "Пропускаемая строка."
#: of telebot.formatting.escape_html telebot.formatting.escape_markdown
#: telebot.formatting.format_text telebot.formatting.hbold
#: telebot.formatting.hcode telebot.formatting.hide_link
#: telebot.formatting.hitalic telebot.formatting.hlink telebot.formatting.hpre
#: telebot.formatting.hspoiler telebot.formatting.hstrikethrough
#: telebot.formatting.hunderline telebot.formatting.mbold
#: telebot.formatting.mcode telebot.formatting.mitalic telebot.formatting.mlink
#: telebot.formatting.mspoiler telebot.formatting.mstrikethrough
#: telebot.formatting.munderline
msgid "Return type"
msgstr ""
#: of telebot.formatting.escape_html:7 telebot.formatting.escape_markdown:9
#: telebot.formatting.format_text:17 telebot.formatting.hbold:10
#: telebot.formatting.hcode:10 telebot.formatting.hide_link:7
#: telebot.formatting.hitalic:10 telebot.formatting.hlink:13
#: telebot.formatting.hpre:10 telebot.formatting.hspoiler:10
#: telebot.formatting.hstrikethrough:10 telebot.formatting.hunderline:10
#: telebot.formatting.mbold:10 telebot.formatting.mcode:10
#: telebot.formatting.mitalic:10 telebot.formatting.mlink:13
#: telebot.formatting.mspoiler:10 telebot.formatting.mstrikethrough:10
#: telebot.formatting.munderline:10
msgid ":obj:`str`"
msgstr ""
#: of telebot.formatting.escape_markdown:1
msgid "Escapes Markdown characters in a string of Markdown."
msgstr "Пропускает Markdown символы в Markdown строке."
#: of telebot.formatting.escape_markdown:3
msgid "Credits to: simonsmh"
msgstr ""
#: of telebot.formatting.escape_markdown:5
msgid "The string of Markdown to escape."
msgstr "Markdown строка, которую нужно пропустить."
#: of telebot.formatting.format_text:1
msgid "Formats a list of strings into a single string."
msgstr "Преобразовывает набор строк в одну."
#: of telebot.formatting.format_text:10
msgid "Strings to format."
msgstr "Строки для преобразования."
#: of telebot.formatting.format_text:13
msgid "The separator to use between each string."
msgstr "Символ для разделения строк."
#: of telebot.formatting.format_text:16 telebot.formatting.hbold:9
#: telebot.formatting.hcode:9 telebot.formatting.hitalic:9
#: telebot.formatting.hlink:12 telebot.formatting.hpre:9
#: telebot.formatting.hspoiler:9 telebot.formatting.hstrikethrough:9
#: telebot.formatting.hunderline:9 telebot.formatting.mbold:9
#: telebot.formatting.mcode:9 telebot.formatting.mitalic:9
#: telebot.formatting.mlink:12 telebot.formatting.mspoiler:9
#: telebot.formatting.mstrikethrough:9 telebot.formatting.munderline:9
msgid "The formatted string."
msgstr "Преобразованная строка."
#: of telebot.formatting.hbold:1
msgid "Returns an HTML-formatted bold string."
msgstr "Возвращает выделенную жирным шрифтом HTML строку."
#: of telebot.formatting.hbold:3 telebot.formatting.mbold:3
msgid "The string to bold."
msgstr "Строка для выделения жирным шрифтом."
#: of telebot.formatting.hbold:6 telebot.formatting.hcode:6
#: telebot.formatting.hitalic:6 telebot.formatting.hlink:9
#: telebot.formatting.hpre:6 telebot.formatting.hspoiler:6
#: telebot.formatting.hstrikethrough:6 telebot.formatting.hunderline:6
#: telebot.formatting.mbold:6 telebot.formatting.mcode:6
#: telebot.formatting.mitalic:6 telebot.formatting.mlink:9
#: telebot.formatting.mspoiler:6 telebot.formatting.mstrikethrough:6
#: telebot.formatting.munderline:6
msgid "True if you need to escape special characters. Defaults to True."
msgstr "True если вам нужно пропустить спец. символы. По умолчанию True."
#: of telebot.formatting.hcode:1
msgid "Returns an HTML-formatted code string."
msgstr "Возвращает выделенную как код HTML строку."
#: of telebot.formatting.hcode:3 telebot.formatting.mcode:3
msgid "The string to code."
msgstr "Строка для выделения как код."
#: of telebot.formatting.hide_link:1
msgid "Hide url of an image."
msgstr "Делает невидимым URL изображения."
#: of telebot.formatting.hide_link:3
msgid "The url of the image."
msgstr "URL изображения."
#: of telebot.formatting.hide_link:6
msgid "The hidden url."
msgstr "Невидимый URL."
#: of telebot.formatting.hitalic:1
msgid "Returns an HTML-formatted italic string."
msgstr "Возвращает выделенную курсивом HTML строку."
#: of telebot.formatting.hitalic:3 telebot.formatting.mitalic:3
msgid "The string to italicize."
msgstr "Строка для выделения курсивом."
#: of telebot.formatting.hlink:1
msgid "Returns an HTML-formatted link string."
msgstr "Возвращает HTML строку с гиперссылкой."
#: of telebot.formatting.hlink:3 telebot.formatting.mlink:3
msgid "The string to link."
msgstr "Строка для добавления гиперссылки."
#: of telebot.formatting.hlink:6 telebot.formatting.mlink:6
msgid "The URL to link to."
msgstr "URL для создания гиперссылки."
#: of telebot.formatting.hpre:1
msgid "Returns an HTML-formatted preformatted string."
msgstr "Возвращает предварительно отформатированную HTML строку."
#: of telebot.formatting.hpre:3
msgid "The string to preformatted."
msgstr "Строка для предварительного форматирования."
#: of telebot.formatting.hspoiler:1
msgid "Returns an HTML-formatted spoiler string."
msgstr "Возвращает выделенную как спойлер HTML строку."
#: of telebot.formatting.hspoiler:3 telebot.formatting.mspoiler:3
msgid "The string to spoiler."
msgstr "Строка для выделения как спойлер."
#: of telebot.formatting.hstrikethrough:1
msgid "Returns an HTML-formatted strikethrough string."
msgstr "Возвращает зачеркнутую HTML строку."
#: of telebot.formatting.hstrikethrough:3 telebot.formatting.mstrikethrough:3
msgid "The string to strikethrough."
msgstr "Строка для зачеркивания."
#: of telebot.formatting.hunderline:1
msgid "Returns an HTML-formatted underline string."
msgstr "Возвращает подчеркнутую HTML строку."
#: of telebot.formatting.hunderline:3 telebot.formatting.munderline:3
msgid "The string to underline."
msgstr "Строка для подчёркивания."
#: of telebot.formatting.mbold:1
msgid "Returns a Markdown-formatted bold string."
msgstr "Возвращает выделенную жирным шрифтом Markdown строку."
#: of telebot.formatting.mcode:1
msgid "Returns a Markdown-formatted code string."
msgstr "Возвращает выделенную как код Markdown строку."
#: of telebot.formatting.mitalic:1
msgid "Returns a Markdown-formatted italic string."
msgstr "Возвращает выделенную курсивом Markdown строку."
#: of telebot.formatting.mlink:1
msgid "Returns a Markdown-formatted link string."
msgstr "Возвращает Markdown строку с гиперссылкой."
#: of telebot.formatting.mspoiler:1
msgid "Returns a Markdown-formatted spoiler string."
msgstr "Возвращает выделенную как спойлер Markdown строку."
#: of telebot.formatting.mstrikethrough:1
msgid "Returns a Markdown-formatted strikethrough string."
msgstr "Возвращает зачеркнутую Markdown строку."
#: of telebot.formatting.munderline:1
msgid "Returns a Markdown-formatted underline string."
msgstr "Возвращает подчеркнутую Markdown строку."

View File

@ -0,0 +1,120 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../index.rst:8
msgid "Welcome to pyTelegramBotAPI's documentation!"
msgstr ""
#: ../../index.rst:10
msgid "Official documentation of pyTelegramBotAPI"
msgstr ""
#: ../../index.rst:10
msgid "ptba, pytba, pyTelegramBotAPI, documentation, guide"
msgstr ""
#: ../../index.rst:17
msgid "TeleBot"
msgstr ""
#: ../../index.rst:18
msgid ""
"TeleBot is synchronous and asynchronous implementation of `Telegram Bot "
"API <https://core.telegram.org/bots/api>`_."
msgstr ""
#: ../../index.rst:21
msgid "Chats"
msgstr ""
#: ../../index.rst:22
msgid ""
"English chat: `Private chat "
"<https://telegram.me/joinchat/Bn4ixj84FIZVkwhk2jag6A>`__"
msgstr ""
#: ../../index.rst:24
msgid ""
"Russian chat: `@pytelegrambotapi_talks_ru "
"<https://t.me/pytelegrambotapi_talks_ru>`__"
msgstr ""
#: ../../index.rst:26
msgid "News: `@pyTelegramBotAPI <https://t.me/pytelegrambotapi>`__"
msgstr ""
#: ../../index.rst:28
msgid "Pypi: `Pypi <https://pypi.org/project/pyTelegramBotAPI/>`__"
msgstr ""
#: ../../index.rst:30
msgid ""
"Source: `Github repository "
"<https://github.com/eternnoir/pyTelegramBotAPI>`__"
msgstr ""
#: ../../index.rst:33
msgid "Some features:"
msgstr ""
#: ../../index.rst:34
msgid "Easy to learn and use."
msgstr ""
#: ../../index.rst:36
msgid "Easy to understand."
msgstr ""
#: ../../index.rst:38
msgid "Both sync and async."
msgstr ""
#: ../../index.rst:40
msgid "Examples on features."
msgstr ""
#: ../../index.rst:42
msgid "States"
msgstr ""
#: ../../index.rst:44
msgid "And more..."
msgstr ""
#: ../../index.rst:47
msgid "Content"
msgstr ""
#: ../../index.rst:63
msgid "Indices and tables"
msgstr ""
#: ../../index.rst:65
msgid ":ref:`genindex`"
msgstr ""
#: ../../index.rst:66
msgid ":ref:`modindex`"
msgstr ""
#: ../../index.rst:67
msgid ":ref:`search`"
msgstr ""

View File

@ -0,0 +1,59 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../install.rst:3
msgid "Installation Guide"
msgstr "Гайд по установке"
#: ../../install.rst:5
msgid "Installation of pyTelegramBotAPI"
msgstr "Установка pyTelegramBotAPI"
#: ../../install.rst:5
msgid "ptba, pytba, pyTelegramBotAPI, installation, guide"
msgstr "ptba, pytba, pyTelegramBotAPI, установка, гайд"
#: ../../install.rst:11
msgid "Using PIP"
msgstr "Используя PIP"
#: ../../install.rst:17
msgid "Using pipenv"
msgstr "Используя pipenv"
#: ../../install.rst:23
msgid "By cloning repository"
msgstr "Клонируя репозиторий"
#: ../../install.rst:31
msgid "Directly using pip"
msgstr "Напрямую используя pip"
#: ../../install.rst:37
msgid "It is generally recommended to use the first option."
msgstr "Рекомендуется использовать первый вариант."
#: ../../install.rst:39
msgid ""
"While the API is production-ready, it is still under development and it "
"has regular updates, do not forget to update it regularly by calling:"
msgstr "Новые версии библиотеки имеют больше фич, улучшений и баг фиксов. Не забывайте"
" обновляться вызывая:"

View File

@ -0,0 +1,40 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../quick_start.rst:4
msgid "Quick start"
msgstr "Быстрый старт"
#: ../../quick_start.rst:6
msgid "Quickstart guide"
msgstr "Быстрый старт - гайд"
#: ../../quick_start.rst:6
msgid "ptba, pytba, pyTelegramBotAPI, quickstart, guide"
msgstr "ptba, pytba, pyTelegramBotAPI, быстрый старт, гайд"
#: ../../quick_start.rst:11
msgid "Synchronous TeleBot"
msgstr "Синхронный телебот"
#: ../../quick_start.rst:16
msgid "Asynchronous TeleBot"
msgstr "Асинхронный телебот"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,366 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2022, coder2020official
# This file is distributed under the same license as the pyTelegramBotAPI
# Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pyTelegramBotAPI Documentation \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 14:44+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: ../../util.rst:3
msgid "Utils"
msgstr "Утилиты"
#: ../../util.rst:5
msgid "Utils in pyTelegramBotAPI"
msgstr "Утилиты в pyTelegramBotAPI"
#: ../../util.rst:5
msgid "ptba, pytba, pyTelegramBotAPI, utils, guide"
msgstr "ptba, pytba, pyTelegramBotAPI, утилиты, гайд"
#: ../../util.rst:11
msgid "util file"
msgstr "Файл util"
#: of telebot.util.antiflood:1
msgid ""
"Use this function inside loops in order to avoid getting TooManyRequests "
"error. Example:"
msgstr "Используйте эту функцию в циклах, чтобы избежать ошибки TooManyRequests. Пример:"
#: of telebot.util.antiflood telebot.util.escape telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.is_bytes telebot.util.is_command
#: telebot.util.is_dict telebot.util.is_pil_image
#: telebot.util.parse_web_app_data telebot.util.quick_markup
#: telebot.util.smart_split telebot.util.split_string telebot.util.user_link
#: telebot.util.validate_web_app_data telebot.util.webhook_google_functions
msgid "Parameters"
msgstr ""
#: of telebot.util.antiflood:10
msgid "The function to call"
msgstr "Вызываемая функция"
#: of telebot.util.antiflood:13
msgid "The arguments to pass to the function"
msgstr "Аргументы, для передачи в функцию"
#: of telebot.util.antiflood:16
msgid "The keyword arguments to pass to the function"
msgstr "Именованные аргументы для передачи в функцию"
#: of telebot.util.antiflood telebot.util.escape telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.generate_random_token
#: telebot.util.is_bytes telebot.util.is_command telebot.util.is_dict
#: telebot.util.is_pil_image telebot.util.parse_web_app_data
#: telebot.util.quick_markup telebot.util.smart_split telebot.util.split_string
#: telebot.util.user_link telebot.util.validate_web_app_data
#: telebot.util.webhook_google_functions
msgid "Returns"
msgstr ""
#: of telebot.util.antiflood:19
msgid "None"
msgstr ""
#: of telebot.util.chunks:1
msgid "Yield successive n-sized chunks from lst."
msgstr "Генерирует последовательные части списка, состоящие из n элементов."
#: ../../docstring of telebot.util.content_type_media:1
msgid "Contains all media content types."
msgstr "Содержит все виды медиа."
#: ../../docstring of telebot.util.content_type_service:1
msgid "Contains all service content types such as `User joined the group`."
msgstr "Содержит все виды сервисных сообщений, такие как `User joined the group`."
#: of telebot.util.escape:1
msgid ""
"Replaces the following chars in `text` ('&' with '&amp;', '<' with '&lt;'"
" and '>' with '&gt;')."
msgstr "Заменяет следующие символы в `text` ('&' на '&amp;', '<' на '&lt;'"
" и '>' на '&gt;')."
#: of telebot.util.escape:3
msgid "the text to escape"
msgstr "Текст для замены символов"
#: of telebot.util.escape:4
msgid "the escaped text"
msgstr "Отформатированный текст"
#: of telebot.util.extract_arguments:1
msgid "Returns the argument after the command."
msgstr "Возвращает аргументы команды."
#: of telebot.util.extract_arguments:3 telebot.util.extract_command:4
msgid "Examples:"
msgstr "Примеры:"
#: of telebot.util.extract_arguments:10
msgid "String to extract the arguments from a command"
msgstr "Строка для извлечения аргументов команды"
#: of telebot.util.extract_arguments:13
msgid "the arguments if `text` is a command (according to is_command), else None."
msgstr "Аргументы, если `text` является командой (согласно is_command), в остальных случаях None."
#: of telebot.util.extract_arguments telebot.util.extract_command
#: telebot.util.generate_random_token telebot.util.is_bytes
#: telebot.util.is_command telebot.util.is_dict telebot.util.is_pil_image
#: telebot.util.quick_markup telebot.util.smart_split telebot.util.split_string
#: telebot.util.user_link
msgid "Return type"
msgstr ""
#: of telebot.util.extract_arguments:14 telebot.util.extract_command:16
msgid ":obj:`str` or :obj:`None`"
msgstr ":obj:`str` или :obj:`None`"
#: of telebot.util.extract_command:1
msgid ""
"Extracts the command from `text` (minus the '/') if `text` is a command "
"(see is_command). If `text` is not a command, this function returns None."
msgstr ""
"Извлекает команду из `text` (исключает '/') если `text` является командой "
"(см. is_command). Если `text` не является командой, эта функция возвращает None."
#: of telebot.util.extract_command:12
msgid "String to extract the command from"
msgstr "Строка, из которой нужно извлечь команду"
#: of telebot.util.extract_command:15
msgid "the command if `text` is a command (according to is_command), else None."
msgstr "Команда, если `text` является командой (согласно is_command), в остальных случаях None."
#: of telebot.util.generate_random_token:1
msgid ""
"Generates a random token consisting of letters and digits, 16 characters "
"long."
msgstr "Генерирует рандомный токен, состоящий из латинских букв и цифр длиной 16 символов."
#: of telebot.util.generate_random_token:3
msgid "a random token"
msgstr "Сгенерированный токен"
#: of telebot.util.generate_random_token:4 telebot.util.user_link:22
msgid ":obj:`str`"
msgstr ""
#: of telebot.util.is_bytes:1
msgid "Returns True if the given object is a bytes object."
msgstr "Возвращает True если полученный объект является bytes."
#: of telebot.util.is_bytes:3 telebot.util.is_dict:3
#: telebot.util.is_pil_image:3
msgid "object to be checked"
msgstr "Объект для проверки"
#: of telebot.util.is_bytes:6
msgid "True if the given object is a bytes object."
msgstr "True, если полученный объект является bytes."
#: of telebot.util.is_bytes:7 telebot.util.is_command:7 telebot.util.is_dict:7
#: telebot.util.is_pil_image:7
msgid ":obj:`bool`"
msgstr ""
#: of telebot.util.is_command:1
msgid ""
"Checks if `text` is a command. Telegram chat commands start with the '/' "
"character."
msgstr ""
"Проверяет, является ли `text` командой. Команды в Telegram начинаются "
"с символа '/'."
#: of telebot.util.is_command:3
msgid "Text to check."
msgstr "Текст для проверки."
#: of telebot.util.is_command:6
msgid "True if `text` is a command, else False."
msgstr "True, если `text` является командой, иначе False."
#: of telebot.util.is_dict:1
msgid "Returns True if the given object is a dictionary."
msgstr "Возвращает True, если полученный объект является словарём (dict)."
#: of telebot.util.is_dict:6
msgid "True if the given object is a dictionary."
msgstr "True, если полученный объект является словарём (dict)."
#: of telebot.util.is_pil_image:1
msgid "Returns True if the given object is a PIL.Image.Image object."
msgstr "Возвращает True, если полученный объект является PIL.Image.Image."
#: of telebot.util.is_pil_image:6
msgid "True if the given object is a PIL.Image.Image object."
msgstr "True, если полученный объект является PIL.Image.Image."
#: of telebot.util.is_string:1
msgid "Returns True if the given object is a string."
msgstr "Возвращает True, если полученный объект является строкой (str)."
#: of telebot.util.parse_web_app_data:1
msgid "Parses web app data."
msgstr "Обрабатывает данные, полученные от web app."
#: of telebot.util.parse_web_app_data:3 telebot.util.validate_web_app_data:3
msgid "The bot token"
msgstr "Токен бота"
#: of telebot.util.parse_web_app_data:6 telebot.util.validate_web_app_data:6
msgid "The raw init data"
msgstr "Необработанные данные"
#: of telebot.util.parse_web_app_data:9 telebot.util.validate_web_app_data:9
msgid "The parsed init data"
msgstr "Обработанные данные"
#: of telebot.util.quick_markup:1
msgid ""
"Returns a reply markup from a dict in this format: {'text': kwargs} This "
"is useful to avoid always typing 'btn1 = InlineKeyboardButton(...)' 'btn2"
" = InlineKeyboardButton(...)'"
msgstr ""
"Возвращает reply markup из словаря следующего формата: {'text': kwargs}. Удобно "
"использовать вместо постоянного использования 'btn1 = InlineKeyboardButton(...)' 'btn2"
" = InlineKeyboardButton(...)'"
#: of telebot.util.quick_markup:4 telebot.util.user_link:5
msgid "Example:"
msgstr "Пример:"
#: of telebot.util.quick_markup:6
msgid "Using quick_markup:"
msgstr "Используя quick_markup:"
#: of telebot.util.quick_markup:29
msgid ""
"a dict containing all buttons to create in this format: {text: kwargs} "
"{str:}"
msgstr ""
"Словарь, содержащий все кнопки для создания reply markup в следующем "
"формате: {text: kwargs} {str:}"
#: of telebot.util.quick_markup:32
msgid "int row width"
msgstr "Количество кнопок в одной строке, int"
#: of telebot.util.quick_markup:35
msgid "InlineKeyboardMarkup"
msgstr ""
#: of telebot.util.quick_markup:36
msgid ":obj:`types.InlineKeyboardMarkup`"
msgstr ""
#: of telebot.util.smart_split:1
msgid ""
"Splits one string into multiple strings, with a maximum amount of "
"`chars_per_string` characters per string. This is very useful for "
"splitting one giant message into multiples. If `chars_per_string` > 4096:"
" `chars_per_string` = 4096. Splits by '\\n', '. ' or ' ' in exactly this "
"priority."
msgstr ""
"Разбивает строку на несколько, каждая из которых будет не длиннее `characters_per_string`. "
"Удобно использовать для разбиения одного гигантского сообщения на несколько. "
"Если `chars_per_string` > 4096: `chars_per_string` = 4096. Разбивает строку по '\\n', '. ' или ' ' "
"именно в таком порядке."
#: of telebot.util.smart_split:6 telebot.util.split_string:4
msgid "The text to split"
msgstr "Текст для разбиения"
#: of telebot.util.smart_split:9
msgid "The number of maximum characters per part the text is split to."
msgstr "Максимальное количество символов в части текста, на которые он будет разбит."
#: of telebot.util.smart_split:12 telebot.util.split_string:10
msgid "The splitted text as a list of strings."
msgstr "Список частей разбитого текста."
#: of telebot.util.smart_split:13 telebot.util.split_string:11
msgid ":obj:`list` of :obj:`str`"
msgstr ""
#: of telebot.util.split_string:1
msgid ""
"Splits one string into multiple strings, with a maximum amount of "
"`chars_per_string` characters per string. This is very useful for "
"splitting one giant message into multiples."
msgstr ""
"Разбивает одну строку на несколько, каждая из которых будет не длиннее `characters_per_string`. "
"Удобно использовать для разбиения одного гигантского сообщения на несколько."
#: of telebot.util.split_string:7
msgid "The number of characters per line the text is split into."
msgstr "Количество символов в одной строке, на которые будет разбит текст."
#: ../../docstring of telebot.util.update_types:1
msgid "All update types, should be used for allowed_updates parameter in polling."
msgstr "Все виды апдейтов, рекомендуется использовать в качестве параметра allowed_updates функции polling."
#: of telebot.util.user_link:1
msgid ""
"Returns an HTML user link. This is useful for reports. Attention: Don't "
"forget to set parse_mode to 'HTML'!"
msgstr ""
"Возвращает HTML ссылку на пользователя. Удобно использовать для отчетов. Важно: Не "
"забудьте установить значение 'HTML' в parse_mode!"
#: of telebot.util.user_link:11
msgid ""
"You can use formatting.* for all other formatting options(bold, italic, "
"links, and etc.) This method is kept for backward compatibility, and it "
"is recommended to use formatting.* for more options."
msgstr ""
"Вы можете использовать formatting.* во всех остальных вариантах форматирования(bold, italic, "
"links, и прочее). Этот метод сохранён для обратной совместимости, рекомендуется "
"использовать formatting.* для большего количества вариантов."
#: of telebot.util.user_link:15
msgid "the user (not the user_id)"
msgstr "Пользователь (не id пользователя)"
#: of telebot.util.user_link:18
msgid "include the user_id"
msgstr "Добавить id пользователя"
#: of telebot.util.user_link:21
msgid "HTML user link"
msgstr "Ссылка на пользователя в формате HTML"
#: of telebot.util.validate_web_app_data:1
msgid "Validates web app data."
msgstr "Проверяет данные, полученные от web app."
#: of telebot.util.webhook_google_functions:1
msgid "A webhook endpoint for Google Cloud Functions FaaS."
msgstr "Endpoint вебхука для Google Cloud Functions FaaS."
#: of telebot.util.webhook_google_functions:3
msgid "The bot instance"
msgstr "Инстанс бота"
#: of telebot.util.webhook_google_functions:6
msgid "The request object"
msgstr "HTTP-запрос"
#: of telebot.util.webhook_google_functions:9
msgid "The response object"
msgstr "Объект, полученный в качестве ответа"

View File

@ -0,0 +1,27 @@
from telebot.async_telebot import AsyncTeleBot
from telebot.asyncio_handler_backends import ContinueHandling
bot = AsyncTeleBot('TOKEN')
@bot.message_handler(commands=['start'])
async def start(message):
await bot.send_message(message.chat.id, 'Hello World!')
return ContinueHandling()
@bot.message_handler(commands=['start'])
async def start2(message):
"""
This handler comes after the first one, but it will never be called.
But you can call it by returning ContinueHandling() in the first handler.
If you return ContinueHandling() in the first handler, the next
registered handler with appropriate filters will be called.
"""
await bot.send_message(message.chat.id, 'Hello World2!')
import asyncio
asyncio.run(bot.polling()) # just a reminder that infinity polling
# wraps polling into try/except block just as sync version,
# but you can use any of them because neither of them stops if you
# pass non_stop=True

View File

@ -0,0 +1,28 @@
#!/usr/bin/python
# This is a simple echo bot using the decorator mechanism.
# It echoes any incoming text messages.
from telebot.async_telebot import AsyncTeleBot
bot = AsyncTeleBot('TOKEN')
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
async def send_welcome(message):
await bot.reply_to(message, """\
Hi there, I am EchoBot.
I am here to echo your kind words back to you. Just say anything nice and I'll say the exact same thing to you!\
""")
# Handle all other messages with content_type 'text' (content_types defaults to ['text'])
@bot.message_handler(func=lambda message: True)
async def echo_message(message):
await bot.reply_to(message, message.text)
import asyncio
# only for versions 4.7.0+
asyncio.run(bot.polling(restart_on_change=True))

View File

@ -0,0 +1,89 @@
#!/usr/bin/env python
"""
Asynchronous Telegram Echo Bot example.
This is a simple bot that echoes each message that is received onto the chat.
It uses the Starlette ASGI framework to receive updates via webhook requests.
"""
import uvicorn
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import PlainTextResponse, Response
from starlette.routing import Route
from telebot.async_telebot import AsyncTeleBot
from telebot.types import Message, Update
API_TOKEN = "TOKEN"
WEBHOOK_HOST = "<ip/domain>"
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
WEBHOOK_LISTEN = "0.0.0.0"
WEBHOOK_SSL_CERT = "./webhook_cert.pem" # Path to the ssl certificate
WEBHOOK_SSL_PRIV = "./webhook_pkey.pem" # Path to the ssl private key
WEBHOOK_URL = f"https://{WEBHOOK_HOST}:{WEBHOOK_PORT}/telegram"
WEBHOOK_SECRET_TOKEN = "SECRET_TOKEN"
logger = telebot.logger
telebot.logger.setLevel(logging.INFO)
bot = AsyncTeleBot(token=API_TOKEN)
# BOT HANDLERS
@bot.message_handler(commands=["help", "start"])
async def send_welcome(message: Message):
"""
Handle '/start' and '/help'
"""
await bot.reply_to(
message,
("Hi there, I am EchoBot.\n" "I am here to echo your kind words back to you."),
)
@bot.message_handler(func=lambda _: True, content_types=["text"])
async def echo_message(message: Message):
"""
Handle all other messages
"""
await bot.reply_to(message, message.text)
# WEBSERVER HANDLERS
async def telegram(request: Request) -> Response:
"""Handle incoming Telegram updates."""
token_header_name = "X-Telegram-Bot-Api-Secret-Token"
if request.headers.get(token_header_name) != WEBHOOK_SECRET_TOKEN:
return PlainTextResponse("Forbidden", status_code=403)
await bot.process_new_updates([Update.de_json(await request.json())])
return Response()
async def startup() -> None:
"""Register webhook for telegram updates."""
webhook_info = await bot.get_webhook_info(30)
if WEBHOOK_URL != webhook_info.url:
logger.debug(
f"updating webhook url, old: {webhook_info.url}, new: {WEBHOOK_URL}"
)
if not await bot.set_webhook(
url=WEBHOOK_URL, secret_token=WEBHOOK_SECRET_TOKEN
):
raise RuntimeError("unable to set webhook")
app = Starlette(
routes=[
Route("/telegram", telegram, methods=["POST"]),
],
on_startup=[startup],
)
uvicorn.run(
app,
host=WEBHOOK_HOST,
port=WEBHOOK_LISTEN,
ssl_certfile=WEBHOOK_SSL_CERT,
ssl_keyfile=WEBHOOK_SSL_PRIV,
)

View File

@ -0,0 +1,23 @@
from telebot import TeleBot
from telebot.handler_backends import ContinueHandling
bot = TeleBot('TOKEN')
@bot.message_handler(commands=['start'])
def start(message):
bot.send_message(message.chat.id, 'Hello World!')
return ContinueHandling()
@bot.message_handler(commands=['start'])
def start2(message):
"""
This handler comes after the first one, but it will never be called.
But you can call it by returning ContinueHandling() in the first handler.
If you return ContinueHandling() in the first handler, the next
registered handler with appropriate filters will be called.
"""
bot.send_message(message.chat.id, 'Hello World2!')
bot.infinity_polling()

View File

@ -0,0 +1,28 @@
#!/usr/bin/python
# This is a simple echo bot using the decorator mechanism.
# It echoes any incoming text messages.
import telebot
API_TOKEN = '<api_token>'
bot = telebot.TeleBot(API_TOKEN)
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message, """\
Hi there, I am EchoBot.
I am here to echo your kind words back to you. Just say anything nice and I'll say the exact same thing to you!\
""")
# Handle all other messages with content_type 'text' (content_types defaults to ['text'])
@bot.message_handler(func=lambda message: True)
def echo_message(message):
bot.reply_to(message, message.text)
# only for versions 4.7.0+
bot.infinity_polling(restart_on_change=True)

View File

@ -42,7 +42,7 @@ def query_video(inline_query):
try:
r = types.InlineQueryResultVideo('1',
'https://github.com/eternnoir/pyTelegramBotAPI/blob/master/tests/test_data/test_video.mp4?raw=true',
'video/mp4', 'Video',
'video/mp4',
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/rooster.jpg',
'Title'
)

View File

@ -0,0 +1,50 @@
"""
Example of running PyTelegramBotAPI serverless in Amazon AWS Lambdaю
You have to set your lambda's url as telegram webhook manually https://core.telegram.org/bots/api#setwebhook
"""
import logging
import telebot
import json
import os
API_TOKEN = os.environ['TELEGRAM_TOKEN']
logger = telebot.logger
telebot.logger.setLevel(logging.INFO)
bot = telebot.TeleBot(API_TOKEN, threaded=False)
def process_event(event):
# Get telegram webhook json from event
request_body_dict = json.loads(event['body'])
# Parse updates from json
update = telebot.types.Update.de_json(request_body_dict)
# Run handlers and etc for updates
bot.process_new_updates([update])
def lambda_handler(event, context):
# Process event from aws and respond
process_event(event)
return {
'statusCode': 200
}
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message,
("Hi there, I am EchoBot.\n"
"I am here to echo your kind words back to you."))
# Handle all other messages
@bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)

View File

@ -1,4 +1,4 @@
pytest
requests==2.20.0
wheel==0.24.0
wheel==0.38.1
aiohttp>=3.8.0,<3.9.0

View File

@ -31,6 +31,9 @@ setup(name='pyTelegramBotAPI',
'aiohttp': 'aiohttp',
'fastapi': 'fastapi',
'uvicorn': 'uvicorn',
'psutil': 'psutil',
'coloredlogs': 'coloredlogs',
'watchdog': 'watchdog'
},
classifiers=[
'Development Status :: 5 - Production/Stable',

File diff suppressed because it is too large Load Diff

View File

@ -111,7 +111,13 @@ def _make_request(token, method_name, method='get', params=None, files=None):
params = params or None # Set params to None if empty
result = None
if RETRY_ON_ERROR and RETRY_ENGINE == 1:
if CUSTOM_REQUEST_SENDER:
# noinspection PyCallingNonCallable
result = CUSTOM_REQUEST_SENDER(
method, request_url, params=params, files=files,
timeout=(connect_timeout, read_timeout), proxies=proxy)
elif RETRY_ON_ERROR and RETRY_ENGINE == 1:
got_result = False
current_try = 0
while not got_result and current_try<MAX_RETRIES-1:
@ -146,11 +152,6 @@ def _make_request(token, method_name, method='get', params=None, files=None):
result = http.request(
method, request_url, params=params, files=files,
timeout=(connect_timeout, read_timeout), proxies=proxy)
elif CUSTOM_REQUEST_SENDER:
# noinspection PyCallingNonCallable
result = CUSTOM_REQUEST_SENDER(
method, request_url, params=params, files=files,
timeout=(connect_timeout, read_timeout), proxies=proxy)
else:
result = _get_req_session().request(
method, request_url, params=params, files=files,
@ -236,23 +237,8 @@ def send_message(
token, chat_id, text,
disable_web_page_preview=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None,
entities=None, allow_sending_without_reply=None, protect_content=None):
"""
Use this method to send text messages. On success, the sent Message is returned.
:param token:
:param chat_id:
:param text:
:param disable_web_page_preview:
:param reply_to_message_id:
:param reply_markup:
:param parse_mode:
:param disable_notification:
:param timeout:
:param entities:
:param allow_sending_without_reply:
:param protect_content:
:return:
"""
entities=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
method_url = r'sendMessage'
payload = {'chat_id': str(chat_id), 'text': text}
if disable_web_page_preview is not None:
@ -273,6 +259,8 @@ def send_message(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload, method='post')
@ -399,7 +387,7 @@ def get_chat_member(token, chat_id, user_id):
def forward_message(
token, chat_id, from_chat_id, message_id,
disable_notification=None, timeout=None, protect_content=None):
disable_notification=None, timeout=None, protect_content=None, message_thread_id=None):
method_url = r'forwardMessage'
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
if disable_notification is not None:
@ -408,12 +396,14 @@ def forward_message(
payload['timeout'] = timeout
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_mode=None, caption_entities=None,
disable_notification=None, reply_to_message_id=None, allow_sending_without_reply=None,
reply_markup=None, timeout=None, protect_content=None):
reply_markup=None, timeout=None, protect_content=None, message_thread_id=None):
method_url = r'copyMessage'
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
if caption is not None:
@ -434,13 +424,15 @@ def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_m
payload['timeout'] = timeout
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
def send_dice(
token, chat_id,
emoji=None, disable_notification=None, reply_to_message_id=None,
reply_markup=None, timeout=None, allow_sending_without_reply=None, protect_content=None):
reply_markup=None, timeout=None, allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendDice'
payload = {'chat_id': chat_id}
if emoji:
@ -457,6 +449,8 @@ def send_dice(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
@ -464,7 +458,8 @@ def send_photo(
token, chat_id, photo,
caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None,
caption_entities=None, allow_sending_without_reply=None, protect_content=None):
caption_entities=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None, has_spoiler=None):
method_url = r'sendPhoto'
payload = {'chat_id': chat_id}
files = None
@ -492,13 +487,17 @@ def send_photo(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_media_group(
token, chat_id, media,
disable_notification=None, reply_to_message_id=None,
timeout=None, allow_sending_without_reply=None, protect_content=None):
timeout=None, allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendMediaGroup'
media_json, files = convert_input_media_array(media)
payload = {'chat_id': chat_id, 'media': media_json}
@ -512,6 +511,8 @@ def send_media_group(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
return _make_request(
token, method_url, params=payload,
method='post' if files else 'get',
@ -523,7 +524,8 @@ def send_location(
live_period=None, reply_to_message_id=None,
reply_markup=None, disable_notification=None,
timeout=None, horizontal_accuracy=None, heading=None,
proximity_alert_radius=None, allow_sending_without_reply=None, protect_content=None):
proximity_alert_radius=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
method_url = r'sendLocation'
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude}
if live_period:
@ -546,6 +548,8 @@ def send_location(
payload['timeout'] = timeout
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
@ -597,7 +601,7 @@ def send_venue(
foursquare_id=None, foursquare_type=None, disable_notification=None,
reply_to_message_id=None, reply_markup=None, timeout=None,
allow_sending_without_reply=None, google_place_id=None,
google_place_type=None, protect_content=None):
google_place_type=None, protect_content=None, message_thread_id=None):
method_url = r'sendVenue'
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude, 'title': title, 'address': address}
if foursquare_id:
@ -620,13 +624,15 @@ def send_venue(
payload['google_place_type'] = google_place_type
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
def send_contact(
token, chat_id, phone_number, first_name, last_name=None, vcard=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
allow_sending_without_reply=None, protect_content=None):
allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendContact'
payload = {'chat_id': chat_id, 'phone_number': phone_number, 'first_name': first_name}
if last_name:
@ -645,21 +651,26 @@ def send_contact(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
def send_chat_action(token, chat_id, action, timeout=None):
def send_chat_action(token, chat_id, action, timeout=None, message_thread_id=None):
method_url = r'sendChatAction'
payload = {'chat_id': chat_id, 'action': action}
if timeout:
payload['timeout'] = timeout
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
def send_video(token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, supports_streaming=None, disable_notification=None, timeout=None,
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None, protect_content=None):
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None, has_spoiler=None):
method_url = r'sendVideo'
payload = {'chat_id': chat_id}
files = None
@ -701,13 +712,18 @@ def send_video(token, chat_id, data, duration=None, caption=None, reply_to_messa
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_animation(
token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None, thumb=None, caption_entities=None,
allow_sending_without_reply=None, protect_content=None, width=None, height=None):
allow_sending_without_reply=None, protect_content=None, width=None, height=None, message_thread_id=None,
has_spoiler=None):
method_url = r'sendAnimation'
payload = {'chat_id': chat_id}
files = None
@ -747,12 +763,16 @@ def send_animation(
payload['width'] = width
if height:
payload['height'] = height
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_voice(token, chat_id, voice, caption=None, duration=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None, caption_entities=None,
allow_sending_without_reply=None, protect_content=None):
allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendVoice'
payload = {'chat_id': chat_id}
files = None
@ -780,11 +800,14 @@ def send_voice(token, chat_id, voice, caption=None, duration=None, reply_to_mess
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_message_id=None, reply_markup=None,
disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None, protect_content=None):
disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
method_url = r'sendVideoNote'
payload = {'chat_id': chat_id}
files = None
@ -818,12 +841,14 @@ def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_m
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_audio(token, chat_id, audio, caption=None, duration=None, performer=None, title=None, reply_to_message_id=None,
reply_markup=None, parse_mode=None, disable_notification=None, timeout=None, thumb=None,
caption_entities=None, allow_sending_without_reply=None, protect_content=None):
caption_entities=None, allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendAudio'
payload = {'chat_id': chat_id}
files = None
@ -863,13 +888,15 @@ def send_audio(token, chat_id, audio, caption=None, duration=None, performer=Non
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_markup=None, parse_mode=None,
disable_notification=None, timeout=None, caption=None, thumb=None, caption_entities=None,
allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None,
protect_content = None):
protect_content = None, message_thread_id=None):
method_url = get_method_by_type(data_type)
payload = {'chat_id': chat_id}
files = None
@ -908,6 +935,8 @@ def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_m
payload['protect_content'] = protect_content
if method_url == 'sendDocument' and disable_content_type_detection is not None:
payload['disable_content_type_detection'] = disable_content_type_detection
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload, files=files, method='post')
@ -976,7 +1005,8 @@ def promote_chat_member(
token, chat_id, user_id, can_change_info=None, can_post_messages=None,
can_edit_messages=None, can_delete_messages=None, can_invite_users=None,
can_restrict_members=None, can_pin_messages=None, can_promote_members=None,
is_anonymous=None, can_manage_chat=None, can_manage_video_chats=None):
is_anonymous=None, can_manage_chat=None, can_manage_video_chats=None,
can_manage_topics=None):
method_url = 'promoteChatMember'
payload = {'chat_id': chat_id, 'user_id': user_id}
if can_change_info is not None:
@ -1001,6 +1031,8 @@ def promote_chat_member(
payload['can_manage_chat'] = can_manage_chat
if can_manage_video_chats is not None:
payload['can_manage_video_chats'] = can_manage_video_chats
if can_manage_topics is not None:
payload['can_manage_topics'] = can_manage_topics
return _make_request(token, method_url, params=payload, method='post')
@ -1313,7 +1345,7 @@ def delete_message(token, chat_id, message_id, timeout=None):
def send_game(
token, chat_id, game_short_name,
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
allow_sending_without_reply=None, protect_content=None):
allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendGame'
payload = {'chat_id': chat_id, 'game_short_name': game_short_name}
if disable_notification is not None:
@ -1328,6 +1360,8 @@ def send_game(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
@ -1393,7 +1427,7 @@ def send_invoice(
send_phone_number_to_provider = None, send_email_to_provider = None, is_flexible=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, provider_data=None,
timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None,
protect_content=None):
protect_content=None, message_thread_id=None):
"""
Use this method to send invoices. On success, the sent Message is returned.
:param token: Bot's token (you don't need to fill this)
@ -1474,6 +1508,8 @@ def send_invoice(
payload['suggested_tip_amounts'] = json.dumps(suggested_tip_amounts)
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
@ -1682,7 +1718,7 @@ def send_poll(
is_anonymous = None, type = None, allows_multiple_answers = None, correct_option_id = None,
explanation = None, explanation_parse_mode=None, open_period = None, close_date = None, is_closed = None,
disable_notification=False, reply_to_message_id=None, allow_sending_without_reply=None,
reply_markup=None, timeout=None, explanation_entities=None, protect_content=None):
reply_markup=None, timeout=None, explanation_entities=None, protect_content=None, message_thread_id=None):
method_url = r'sendPoll'
payload = {
'chat_id': str(chat_id),
@ -1726,8 +1762,51 @@ def send_poll(
types.MessageEntity.to_list_of_dicts(explanation_entities))
if protect_content:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
def create_forum_topic(token, chat_id, name, icon_color=None, icon_custom_emoji_id=None):
method_url = r'createForumTopic'
payload = {'chat_id': chat_id, 'name': name}
if icon_color:
payload['icon_color'] = icon_color
if icon_custom_emoji_id:
payload['icon_custom_emoji_id'] = icon_custom_emoji_id
return _make_request(token, method_url, params=payload)
def edit_forum_topic(token, chat_id, message_thread_id, name=None, icon_custom_emoji_id=None):
method_url = r'editForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
if name is not None:
payload['name'] = name
if icon_custom_emoji_id is not None:
payload['icon_custom_emoji_id'] = icon_custom_emoji_id
return _make_request(token, method_url, params=payload)
def close_forum_topic(token, chat_id, message_thread_id):
method_url = r'closeForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
return _make_request(token, method_url, params=payload)
def reopen_forum_topic(token, chat_id, message_thread_id):
method_url = r'reopenForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
return _make_request(token, method_url, params=payload)
def delete_forum_topic(token, chat_id, message_thread_id):
method_url = r'deleteForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
return _make_request(token, method_url, params=payload)
def unpin_all_forum_topic_messages(token, chat_id, message_thread_id):
method_url = r'unpinAllForumTopicMessages'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
return _make_request(token, method_url, params=payload)
def get_forum_topic_icon_stickers(token):
method_url = r'getForumTopicIconStickers'
return _make_request(token, method_url)
def stop_poll(token, chat_id, message_id, reply_markup=None):
method_url = r'stopPoll'
@ -1736,6 +1815,31 @@ def stop_poll(token, chat_id, message_id, reply_markup=None):
payload['reply_markup'] = _convert_markup(reply_markup)
return _make_request(token, method_url, params=payload)
def edit_general_forum_topic(token, chat_id, name):
method_url = r'editGeneralForumTopic'
payload = {'chat_id': chat_id, 'name': name}
return _make_request(token, method_url, params=payload)
def close_general_forum_topic(token, chat_id):
method_url = r'closeGeneralForumTopic'
payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload)
def reopen_general_forum_topic(token, chat_id):
method_url = r'reopenGeneralForumTopic'
payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload)
def hide_general_forum_topic(token, chat_id):
method_url = r'hideGeneralForumTopic'
payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload)
def unhide_general_forum_topic(token, chat_id):
method_url = r'unhideGeneralForumTopic'
payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload)
def _convert_list_json_serializable(results):
ret = ''

File diff suppressed because it is too large Load Diff

View File

@ -420,7 +420,7 @@ class StateFilter(AdvancedCustomFilter):
text = text.name
if message.chat.type in ['group', 'supergroup']:
group_state = await self.bot.current_states.get_state(user_id, chat_id)
group_state = await self.bot.current_states.get_state(chat_id, user_id)
if group_state == text:
return True
elif type(text) is list and group_state in text:
@ -428,7 +428,7 @@ class StateFilter(AdvancedCustomFilter):
else:
user_state = await self.bot.current_states.get_state(user_id, chat_id)
user_state = await self.bot.current_states.get_state(chat_id, user_id)
if user_state == text:
return True
elif type(text) is list and user_state in text:

View File

@ -3,8 +3,6 @@ File with all middleware classes, states.
"""
class BaseMiddleware:
"""
Base class for middleware.
@ -96,6 +94,7 @@ class SkipHandler:
def __init__(self) -> None:
pass
class CancelUpdate:
"""
Class for canceling updates.
@ -106,4 +105,27 @@ class CancelUpdate:
"""
def __init__(self) -> None:
pass
pass
class ContinueHandling:
"""
Class for continue updates in handlers.
Just return instance of this class
in handlers to continue process.
.. code-block:: python3
:caption: Example of using ContinueHandling
@bot.message_handler(commands=['start'])
async def start(message):
await bot.send_message(message.chat.id, 'Hello World!')
return ContinueHandling()
@bot.message_handler(commands=['start'])
async def start2(message):
await bot.send_message(message.chat.id, 'Hello World2!')
"""
def __init__(self) -> None:
pass

View File

@ -13,15 +13,17 @@ API_URL = 'https://api.telegram.org/bot{0}/{1}'
from datetime import datetime
from telebot import util, logger
from telebot import util
import logging
logger = logging.getLogger('TeleBot')
proxy = None
session = None
FILE_URL = None
REQUEST_TIMEOUT = None
REQUEST_TIMEOUT = 300
MAX_RETRIES = 3
REQUEST_LIMIT = 50
@ -56,10 +58,29 @@ class SessionManager:
session_manager = SessionManager()
async def _process_request(token, url, method='get', params=None, files=None, request_timeout=None):
async def _process_request(token, url, method='get', params=None, files=None, **kwargs):
# Let's resolve all timeout parameters.
# getUpdates parameter may contain 2 parameters: request_timeout & timeout.
# other methods may contain timeout parameter that should be applied to
# ClientTimeout only.
# timeout should be added to params for getUpdates. All other timeout's should be used
# for request timeout.
# here we got request_timeout, so this is getUpdates method.
if 'request_timeout' in kwargs:
request_timeout = kwargs.pop('request_timeout')
else:
# let's check for timeout in params
request_timeout = params.pop('timeout', None) if params else None
# we will apply default request_timeout if there is no timeout in params
# otherwise, we will use timeout parameter applied for payload.
request_timeout = REQUEST_TIMEOUT if request_timeout is None else request_timeout
# Preparing data by adding all parameters and files to FormData
params = _prepare_data(params, files)
if request_timeout is None:
request_timeout = REQUEST_TIMEOUT
timeout = aiohttp.ClientTimeout(total=request_timeout)
got_result = False
current_try=0
@ -150,24 +171,22 @@ async def get_file(token, file_id):
async def get_file_url(token, file_id):
if FILE_URL is None:
return "https://api.telegram.org/file/bot{0}/{1}".format(token, await get_file(token, file_id)['file_path'])
return "https://api.telegram.org/file/bot{0}/{1}".format(token, (await get_file(token, file_id))['file_path'])
else:
# noinspection PyUnresolvedReferences
return FILE_URL.format(token, await get_file(token, file_id)['file_path'])
return FILE_URL.format(token, (await get_file(token, file_id))['file_path'])
async def download_file(token, file_path):
if FILE_URL is None:
url = "https://api.telegram.org/file/bot{0}/{1}".format(token, file_path)
else:
# noinspection PyUnresolvedReferences
url = FILE_URL.format(token, file_path)
async with await session_manager.get_session() as session:
async with session.get(url, proxy=proxy) as response:
result = await response.read()
if response.status != 200:
raise ApiHTTPException('Download file', result)
else: url = FILE_URL.format(token, file_path)
session = await session_manager.get_session()
async with session.get(url, proxy=proxy) as response:
if response.status != 200:
raise ApiHTTPException('Download file', result)
result = await response.read()
return result
@ -259,23 +278,8 @@ async def send_message(
token, chat_id, text,
disable_web_page_preview=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None,
entities=None, allow_sending_without_reply=None, protect_content=None):
"""
Use this method to send text messages. On success, the sent Message is returned.
:param token:
:param chat_id:
:param text:
:param disable_web_page_preview:
:param reply_to_message_id:
:param reply_markup:
:param parse_mode:
:param disable_notification:
:param timeout:
:param entities:
:param allow_sending_without_reply:
:param protect_content:
:return:
"""
entities=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
method_name = 'sendMessage'
params = {'chat_id': str(chat_id), 'text': text}
if disable_web_page_preview is not None:
@ -296,6 +300,8 @@ async def send_message(
params['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
params['protect_content'] = protect_content
if message_thread_id:
params['message_thread_id'] = message_thread_id
return await _process_request(token, method_name, params=params)
@ -373,7 +379,8 @@ async def get_chat_member(token, chat_id, user_id):
async def forward_message(
token, chat_id, from_chat_id, message_id,
disable_notification=None, timeout=None, protect_content=None):
disable_notification=None, timeout=None, protect_content=None,
message_thread_id=None):
method_url = r'forwardMessage'
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
if disable_notification is not None:
@ -382,12 +389,14 @@ async def forward_message(
payload['timeout'] = timeout
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
async def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_mode=None, caption_entities=None,
disable_notification=None, reply_to_message_id=None, allow_sending_without_reply=None,
reply_markup=None, timeout=None, protect_content=None):
reply_markup=None, timeout=None, protect_content=None, message_thread_id=None):
method_url = r'copyMessage'
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
if caption is not None:
@ -408,13 +417,16 @@ async def copy_message(token, chat_id, from_chat_id, message_id, caption=None, p
payload['timeout'] = timeout
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
async def send_dice(
token, chat_id,
emoji=None, disable_notification=None, reply_to_message_id=None,
reply_markup=None, timeout=None, allow_sending_without_reply=None, protect_content=None):
reply_markup=None, timeout=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
method_url = r'sendDice'
payload = {'chat_id': chat_id}
if emoji:
@ -431,6 +443,8 @@ async def send_dice(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
@ -438,7 +452,8 @@ async def send_photo(
token, chat_id, photo,
caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None,
caption_entities=None, allow_sending_without_reply=None, protect_content=None):
caption_entities=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None, has_spoiler=None):
method_url = r'sendPhoto'
payload = {'chat_id': chat_id}
files = None
@ -466,13 +481,17 @@ async def send_photo(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_media_group(
token, chat_id, media,
disable_notification=None, reply_to_message_id=None,
timeout=None, allow_sending_without_reply=None, protect_content=None):
timeout=None, allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendMediaGroup'
media_json, files = await convert_input_media_array(media)
payload = {'chat_id': chat_id, 'media': media_json}
@ -486,6 +505,8 @@ async def send_media_group(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(
token, method_url, params=payload,
method='post' if files else 'get',
@ -497,7 +518,7 @@ async def send_location(
live_period=None, reply_to_message_id=None,
reply_markup=None, disable_notification=None,
timeout=None, horizontal_accuracy=None, heading=None,
proximity_alert_radius=None, allow_sending_without_reply=None, protect_content=None):
proximity_alert_radius=None, allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendLocation'
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude}
if live_period:
@ -520,6 +541,8 @@ async def send_location(
payload['timeout'] = timeout
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
@ -571,7 +594,7 @@ async def send_venue(
foursquare_id=None, foursquare_type=None, disable_notification=None,
reply_to_message_id=None, reply_markup=None, timeout=None,
allow_sending_without_reply=None, google_place_id=None,
google_place_type=None, protect_content=None):
google_place_type=None, protect_content=None, message_thread_id=None):
method_url = r'sendVenue'
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude, 'title': title, 'address': address}
if foursquare_id:
@ -594,13 +617,15 @@ async def send_venue(
payload['google_place_type'] = google_place_type
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
async def send_contact(
token, chat_id, phone_number, first_name, last_name=None, vcard=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
allow_sending_without_reply=None, protect_content=None):
allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendContact'
payload = {'chat_id': chat_id, 'phone_number': phone_number, 'first_name': first_name}
if last_name:
@ -619,21 +644,25 @@ async def send_contact(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
async def send_chat_action(token, chat_id, action, timeout=None):
async def send_chat_action(token, chat_id, action, timeout=None, message_thread_id=None):
method_url = r'sendChatAction'
payload = {'chat_id': chat_id, 'action': action}
if timeout:
payload['timeout'] = timeout
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
async def send_video(token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, supports_streaming=None, disable_notification=None, timeout=None,
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None,
protect_content=None):
protect_content=None, message_thread_id=None, has_spoiler=None):
method_url = r'sendVideo'
payload = {'chat_id': chat_id}
files = None
@ -675,13 +704,18 @@ async def send_video(token, chat_id, data, duration=None, caption=None, reply_to
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_animation(
token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None, thumb=None, caption_entities=None,
allow_sending_without_reply=None, width=None, height=None, protect_content=None):
allow_sending_without_reply=None, width=None, height=None, protect_content=None, message_thread_id=None,
has_spoiler=None):
method_url = r'sendAnimation'
payload = {'chat_id': chat_id}
files = None
@ -721,12 +755,16 @@ async def send_animation(
payload['height'] = height
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_voice(token, chat_id, voice, caption=None, duration=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None, caption_entities=None,
allow_sending_without_reply=None, protect_content=None):
allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendVoice'
payload = {'chat_id': chat_id}
files = None
@ -754,11 +792,14 @@ async def send_voice(token, chat_id, voice, caption=None, duration=None, reply_t
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_message_id=None, reply_markup=None,
disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None, protect_content=None):
disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
method_url = r'sendVideoNote'
payload = {'chat_id': chat_id}
files = None
@ -792,12 +833,14 @@ async def send_video_note(token, chat_id, data, duration=None, length=None, repl
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_audio(token, chat_id, audio, caption=None, duration=None, performer=None, title=None, reply_to_message_id=None,
reply_markup=None, parse_mode=None, disable_notification=None, timeout=None, thumb=None,
caption_entities=None, allow_sending_without_reply=None, protect_content=None):
caption_entities=None, allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendAudio'
payload = {'chat_id': chat_id}
files = None
@ -837,12 +880,15 @@ async def send_audio(token, chat_id, audio, caption=None, duration=None, perform
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_markup=None, parse_mode=None,
disable_notification=None, timeout=None, caption=None, thumb=None, caption_entities=None,
allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None, protect_content=None):
allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None, protect_content=None,
message_thread_id=None):
method_url = await get_method_by_type(data_type)
payload = {'chat_id': chat_id}
files = None
@ -881,6 +927,8 @@ async def send_data(token, chat_id, data, data_type, reply_to_message_id=None, r
payload['protect_content'] = protect_content
if method_url == 'sendDocument' and disable_content_type_detection is not None:
payload['disable_content_type_detection'] = disable_content_type_detection
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload, files=files, method='post')
@ -949,7 +997,7 @@ async def promote_chat_member(
token, chat_id, user_id, can_change_info=None, can_post_messages=None,
can_edit_messages=None, can_delete_messages=None, can_invite_users=None,
can_restrict_members=None, can_pin_messages=None, can_promote_members=None,
is_anonymous=None, can_manage_chat=None, can_manage_video_chats=None):
is_anonymous=None, can_manage_chat=None, can_manage_video_chats=None, can_manage_topics=None):
method_url = 'promoteChatMember'
payload = {'chat_id': chat_id, 'user_id': user_id}
if can_change_info is not None:
@ -974,6 +1022,8 @@ async def promote_chat_member(
payload['can_manage_chat'] = can_manage_chat
if can_manage_video_chats is not None:
payload['can_manage_video_chats'] = can_manage_video_chats
if can_manage_topics is not None:
payload['can_manage_topics'] = can_manage_topics
return await _process_request(token, method_url, params=payload, method='post')
@ -1285,7 +1335,7 @@ async def delete_message(token, chat_id, message_id, timeout=None):
async def send_game(
token, chat_id, game_short_name,
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
allow_sending_without_reply=None, protect_content=None):
allow_sending_without_reply=None, protect_content=None, message_thread_id=None):
method_url = r'sendGame'
payload = {'chat_id': chat_id, 'game_short_name': game_short_name}
if disable_notification is not None:
@ -1300,6 +1350,8 @@ async def send_game(
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
@ -1364,7 +1416,8 @@ async def send_invoice(
need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None,
send_phone_number_to_provider = None, send_email_to_provider = None, is_flexible=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, provider_data=None,
timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None, protect_content=None):
timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None, protect_content=None,
message_thread_id=None):
"""
Use this method to send invoices. On success, the sent Message is returned.
:param token: Bot's token (you don't need to fill this)
@ -1445,6 +1498,8 @@ async def send_invoice(
payload['suggested_tip_amounts'] = json.dumps(suggested_tip_amounts)
if protect_content is not None:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
@ -1653,7 +1708,7 @@ async def send_poll(
is_anonymous = None, type = None, allows_multiple_answers = None, correct_option_id = None,
explanation = None, explanation_parse_mode=None, open_period = None, close_date = None, is_closed = None,
disable_notification=False, reply_to_message_id=None, allow_sending_without_reply=None,
reply_markup=None, timeout=None, explanation_entities=None, protect_content=None):
reply_markup=None, timeout=None, explanation_entities=None, protect_content=None, message_thread_id=None):
method_url = r'sendPoll'
payload = {
'chat_id': str(chat_id),
@ -1697,6 +1752,76 @@ async def send_poll(
types.MessageEntity.to_list_of_dicts(explanation_entities))
if protect_content:
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
async def create_forum_topic(token, chat_id, name, icon_color=None, icon_custom_emoji_id=None):
method_url = r'createForumTopic'
payload = {'chat_id': chat_id, 'name': name}
if icon_color:
payload['icon_color'] = icon_color
if icon_custom_emoji_id:
payload['icon_custom_emoji_id'] = icon_custom_emoji_id
return await _process_request(token, method_url, params=payload)
async def edit_forum_topic(token, chat_id, message_thread_id, name=None, icon_custom_emoji_id=None):
method_url = r'editForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
if name is not None:
payload['name'] = name
if icon_custom_emoji_id is not None:
payload['icon_custom_emoji_id'] = icon_custom_emoji_id
return await _process_request(token, method_url, params=payload)
async def close_forum_topic(token, chat_id, message_thread_id):
method_url = r'closeForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
return await _process_request(token, method_url, params=payload)
async def reopen_forum_topic(token, chat_id, message_thread_id):
method_url = r'reopenForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
return await _process_request(token, method_url, params=payload)
async def delete_forum_topic(token, chat_id, message_thread_id):
method_url = r'deleteForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
return await _process_request(token, method_url, params=payload)
async def unpin_all_forum_topic_messages(token, chat_id, message_thread_id):
method_url = r'unpinAllForumTopicMessages'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
return await _process_request(token, method_url, params=payload)
async def get_forum_topic_icon_stickers(token):
method_url = r'getForumTopicIconStickers'
return await _process_request(token, method_url)
async def edit_general_forum_topic(token, chat_id, name):
method_url = r'editGeneralForumTopic'
payload = {'chat_id': chat_id, 'name': name}
return await _process_request(token, method_url, params=payload)
async def close_general_forum_topic(token, chat_id):
method_url = r'closeGeneralForumTopic'
payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload)
async def reopen_general_forum_topic(token, chat_id):
method_url = r'reopenGeneralForumTopic'
payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload)
async def hide_general_forum_topic(token, chat_id):
method_url = r'hideGeneralForumTopic'
payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload)
async def unhide_general_forum_topic(token, chat_id):
method_url = r'unhideGeneralForumTopic'
payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload)
async def _convert_list_json_serializable(results):

View File

@ -5,8 +5,11 @@ import json
redis_installed = True
try:
import aioredis
except:
redis_installed = False
except ImportError:
try:
from redis import asyncio as aioredis
except ImportError:
redis_installed = False
class StateRedisStorage(StateStorageBase):

View File

@ -428,7 +428,7 @@ class StateFilter(AdvancedCustomFilter):
text = text.name
if message.chat.type in ['group', 'supergroup']:
group_state = self.bot.current_states.get_state(user_id, chat_id)
group_state = self.bot.current_states.get_state(chat_id, user_id)
if group_state == text:
return True
elif type(text) is list and group_state in text:
@ -436,7 +436,7 @@ class StateFilter(AdvancedCustomFilter):
else:
user_state = self.bot.current_states.get_state(user_id, chat_id)
user_state = self.bot.current_states.get_state(chat_id, user_id)
if user_state == text:
return True
elif type(text) is list and user_state in text:

View File

@ -25,11 +25,11 @@ from typing import Optional
class AsyncWebhookListener:
def __init__(self, bot,
secret_token: str, host: Optional[str]="127.0.0.1",
secret_token: str,
host: Optional[str]="127.0.0.1",
port: Optional[int]=443,
ssl_context: Optional[tuple]=None,
url_path: Optional[str]=None,
debug: Optional[bool]=False
) -> None:
"""
Aynchronous implementation of webhook listener
@ -55,9 +55,6 @@ class AsyncWebhookListener:
:param url_path: Webhook url path
:type url_path: str
:param debug: Debug mode
:type debug: bool
:raises ImportError: If FastAPI or uvicorn is not installed.
:raises ImportError: If Starlette version is too old.
@ -72,7 +69,6 @@ class AsyncWebhookListener:
self._host = host
self._ssl_context = ssl_context
self._url_path = url_path
self._debug = debug
self._prepare_endpoint_urls()
@ -119,7 +115,6 @@ class AsyncWebhookListener:
config = Config(app=self.app,
host=self._host,
port=self._port,
debug=self._debug,
ssl_certfile=self._ssl_context[0],
ssl_keyfile=self._ssl_context[1]
)

31
telebot/ext/reloader.py Normal file
View File

@ -0,0 +1,31 @@
from watchdog.events import FileSystemEventHandler
from watchdog.events import FileSystemEvent
import psutil
import os
import sys
import logging
logger = logging.getLogger('TeleBot')
class EventHandler(FileSystemEventHandler):
def on_any_event(self, event: FileSystemEvent):
logger.info('* Detected changes in: %s, reloading', (event.src_path))
restart_file()
def restart_file():
try:
p = psutil.Process(os.getpid())
for handler in p.open_files() + p.connections():
os.close(handler.fd)
except OSError:
pass
except Exception as e:
logger.error(e)
python = sys.executable
if os.name == 'nt':
os.execv(sys.executable, ['python'] + sys.argv)
else:
os.execl(python, python, *sys.argv)

View File

@ -1,6 +1,5 @@
"""
This file is used by TeleBot.run_webhooks() function.
Fastapi is required to run this script.
"""
@ -15,31 +14,27 @@ try:
except ImportError:
fastapi_installed = False
from telebot.types import Update
from typing import Optional
class SyncWebhookListener:
def __init__(self, bot,
secret_token: str, host: Optional[str]="127.0.0.1",
secret_token: str,
host: Optional[str]="127.0.0.1",
port: Optional[int]=443,
ssl_context: Optional[tuple]=None,
url_path: Optional[str]=None,
debug: Optional[bool]=False
) -> None:
"""
Aynchronous implementation of webhook listener
for asynchronous version of telebot.
Synchronous implementation of webhook listener
for synchronous version of telebot.
Not supposed to be used manually by user.
Use AsyncTeleBot.run_webhooks() instead.
Use TeleBot.run_webhooks() instead.
:param bot: AsyncTeleBot instance.
:type bot: telebot.async_telebot.AsyncTeleBot
:param bot: TeleBot instance.
:type bot: telebot.TeleBot
:param secret_token: Telegram secret token
:type secret_token: str
@ -56,9 +51,6 @@ class SyncWebhookListener:
:param url_path: Webhook url path
:type url_path: str
:param debug: Debug mode
:type debug: bool
:raises ImportError: If FastAPI or uvicorn is not installed.
:raises ImportError: If Starlette version is too old.
@ -73,11 +65,11 @@ class SyncWebhookListener:
self._host = host
self._ssl_context = ssl_context
self._url_path = url_path
self._debug = debug
self._prepare_endpoint_urls()
def _check_dependencies(self):
@staticmethod
def _check_dependencies():
if not fastapi_installed:
raise ImportError('Fastapi or uvicorn is not installed. Please install it via pip.')
@ -119,7 +111,6 @@ class SyncWebhookListener:
uvicorn.run(app=self.app,
host=self._host,
port=self._port,
debug=self._debug,
ssl_certfile=self._ssl_context[0],
ssl_keyfile=self._ssl_context[1]
)

View File

@ -61,8 +61,8 @@ def escape_markdown(content: str) -> str:
:rtype: :obj:`str`
"""
parse = re.sub(r"([_*\[\]()~`>\#\+\-=|\.!])", r"\\\1", content)
reparse = re.sub(r"\\\\([_*\[\]()~`>\#\+\-=|\.!])", r"\1", parse)
parse = re.sub(r"([_*\[\]()~`>\#\+\-=|\.!\{\}])", r"\\\1", content)
reparse = re.sub(r"\\\\([_*\[\]()~`>\#\+\-=|\.!\{\}])", r"\1", parse)
return reparse
@ -323,4 +323,4 @@ def hide_link(url: str) -> str:
:return: The hidden url.
:rtype: :obj:`str`
"""
return f'<a href="{url}">&#8288;</a>'
return f'<a href="{url}">&#8288;</a>'

View File

@ -174,7 +174,6 @@ class State:
def __str__(self) -> str:
return self.name
class StatesGroup:
"""
@ -192,9 +191,6 @@ class StatesGroup:
value.name = ':'.join((cls.__name__, name))
value.group = cls
class BaseMiddleware:
"""
@ -253,10 +249,10 @@ class SkipHandler:
Update will go to post_process,
but will skip execution of handler.
"""
def __init__(self) -> None:
pass
class CancelUpdate:
"""
Class for canceling updates.
@ -265,6 +261,28 @@ class CancelUpdate:
Update will skip handler and execution
of post_process in middlewares.
"""
def __init__(self) -> None:
pass
pass
class ContinueHandling:
"""
Class for continue updates in handlers.
Just return instance of this class
in handlers to continue process.
.. code-block:: python3
:caption: Example of using ContinueHandling
@bot.message_handler(commands=['start'])
def start(message):
bot.send_message(message.chat.id, 'Hello World!')
return ContinueHandling()
@bot.message_handler(commands=['start'])
def start2(message):
bot.send_message(message.chat.id, 'Hello World2!')
"""
def __init__(self) -> None:
pass

View File

@ -41,7 +41,10 @@ class StateStorageBase:
def get_state(self, chat_id, user_id):
raise NotImplementedError
def get_interactive_data(self, chat_id, user_id):
raise NotImplementedError
def save(self, chat_id, user_id, data):
raise NotImplementedError

View File

@ -3,6 +3,7 @@ from telebot.storage.base_storage import StateStorageBase, StateContext
class StateMemoryStorage(StateStorageBase):
def __init__(self) -> None:
super().__init__()
self.data = {}
#
# {chat_id: {user_id: {'state': None, 'data': {}}, ...}, ...}

View File

@ -5,8 +5,8 @@ import pickle
class StatePickleStorage(StateStorageBase):
# noinspection PyMissingConstructor
def __init__(self, file_path="./.state-save/states.pkl") -> None:
super().__init__()
self.file_path = file_path
self.create_dir()
self.data = self.read()

View File

@ -16,6 +16,7 @@ class StateRedisStorage(StateStorageBase):
TeleBot(storage=StateRedisStorage())
"""
def __init__(self, host='localhost', port=6379, db=0, password=None, prefix='telebot_'):
super().__init__()
self.redis = ConnectionPool(host=host, port=port, db=db, password=password)
#self.con = Redis(connection_pool=self.redis) -> use this when necessary
#

View File

@ -515,9 +515,20 @@ class Chat(JsonDeserializable):
:param last_name: Optional. Last name of the other party in a private chat
:type last_name: :obj:`str`
:param is_forum: Optional. True, if the supergroup chat is a forum (has topics enabled)
:type is_forum: :obj:`bool`
:param photo: Optional. Chat photo. Returned only in getChat.
:type photo: :class:`telebot.types.ChatPhoto`
:param active_usernames: Optional. If non-empty, the list of all active chat usernames; for private chats, supergroups and channels.
Returned only in getChat.
:type active_usernames: :obj:`list` of :obj:`str`
:param emoji_status_custom_emoji_id: Optional. Custom emoji identifier of emoji status of the other party in a private chat.
Returned only in getChat.
:type emoji_status_custom_emoji_id: :obj:`str`
:param bio: Optional. Bio of the other party in a private chat. Returned only in getChat.
:type bio: :obj:`str`
@ -559,6 +570,14 @@ class Chat(JsonDeserializable):
automatically deleted; in seconds. Returned only in getChat.
:type message_auto_delete_time: :obj:`int`
:param has_aggressive_anti_spam_enabled: Optional. :obj:`bool`, if the chat has enabled aggressive anti-spam
protection. Returned only in getChat.
:type has_aggressive_anti_spam_enabled: :obj:`bool`
:param has_hidden_members: Optional. :obj:`bool`, if the chat has enabled hidden members. Returned only in
getChat.
:type has_hidden_members: :obj:`bool`
:param has_protected_content: Optional. :obj:`bool`, if messages from the chat can't be forwarded to other
chats. Returned only in getChat.
:type has_protected_content: :obj:`bool`
@ -603,13 +622,16 @@ class Chat(JsonDeserializable):
permissions=None, slow_mode_delay=None,
message_auto_delete_time=None, has_protected_content=None, sticker_set_name=None,
can_set_sticker_set=None, linked_chat_id=None, location=None,
join_to_send_messages=None, join_by_request=None, has_restricted_voice_and_video_messages=None, **kwargs):
join_to_send_messages=None, join_by_request=None, has_restricted_voice_and_video_messages=None,
is_forum=None, active_usernames=None, emoji_status_custom_emoji_id=None,
has_hidden_members=None, has_aggressive_anti_spam_enabled=None, **kwargs):
self.id: int = id
self.type: str = type
self.title: str = title
self.username: str = username
self.first_name: str = first_name
self.last_name: str = last_name
self.is_forum: bool = is_forum
self.photo: ChatPhoto = photo
self.bio: str = bio
self.join_to_send_messages: bool = join_to_send_messages
@ -627,6 +649,10 @@ class Chat(JsonDeserializable):
self.can_set_sticker_set: bool = can_set_sticker_set
self.linked_chat_id: int = linked_chat_id
self.location: ChatLocation = location
self.active_usernames: List[str] = active_usernames
self.emoji_status_custom_emoji_id: str = emoji_status_custom_emoji_id
self.has_hidden_members: bool = has_hidden_members
self.has_aggressive_anti_spam_enabled: bool = has_aggressive_anti_spam_enabled
class MessageID(JsonDeserializable):
@ -690,6 +716,9 @@ class Message(JsonDeserializable):
:param message_id: Unique message identifier inside this chat
:type message_id: :obj:`int`
:param message_thread_id: Optional. Unique identifier of a message thread to which the message belongs; for supergroups only
:type message_thread_id: :obj:`int`
:param from_user: Optional. Sender of the message; empty for messages sent to channels. For backward compatibility, the
field contains a fake sender user in non-channel chats, if the message was sent on behalf of a chat.
:type from_user: :class:`telebot.types.User`
@ -728,6 +757,9 @@ class Message(JsonDeserializable):
:param forward_date: Optional. For forwarded messages, date the original message was sent in Unix time
:type forward_date: :obj:`int`
:param is_topic_message: Optional. True, if the message is sent to a forum topic
:type is_topic_message: :obj:`bool`
:param is_automatic_forward: Optional. :obj:`bool`, if the message is a channel post that was automatically
forwarded to the connected discussion group
:type is_automatic_forward: :obj:`bool`
@ -791,6 +823,9 @@ class Message(JsonDeserializable):
commands, etc. that appear in the caption
:type caption_entities: :obj:`list` of :class:`telebot.types.MessageEntity`
:param has_media_spoiler: Optional. True, if the message media is covered by a spoiler animation
:type has_media_spoiler: :obj:`bool`
:param contact: Optional. Message is a shared contact, information about the contact
:type contact: :class:`telebot.types.Contact`
@ -871,6 +906,10 @@ class Message(JsonDeserializable):
Telegram Login »
:type connected_website: :obj:`str`
:param write_access_allowed: Optional. Service message: the user allowed the bot added to the attachment
menu to write messages
:type write_access_allowed: :class:`telebot.types.WriteAccessAllowed`
:param passport_data: Optional. Telegram Passport data
:type passport_data: :class:`telebot.types.PassportData`
@ -878,6 +917,24 @@ class Message(JsonDeserializable):
proximity alert while sharing Live Location.
:type proximity_alert_triggered: :class:`telebot.types.ProximityAlertTriggered`
:param forum_topic_created: Optional. Service message: forum topic created
:type forum_topic_created: :class:`telebot.types.ForumTopicCreated`
:param forum_topic_edited: Optional. Service message: forum topic edited
:type forum_topic_edited: :class:`telebot.types.ForumTopicEdited`
:param forum_topic_closed: Optional. Service message: forum topic closed
:type forum_topic_closed: :class:`telebot.types.ForumTopicClosed`
:param forum_topic_reopened: Optional. Service message: forum topic reopened
:type forum_topic_reopened: :class:`telebot.types.ForumTopicReopened`
:param general_forum_topic_hidden: Optional. Service message: the 'General' forum topic hidden
:type general_forum_topic_hidden: :class:`telebot.types.GeneralForumTopicHidden`
:param general_forum_topic_unhidden: Optional. Service message: the 'General' forum topic unhidden
:type general_forum_topic_unhidden: :class:`telebot.types.GeneralForumTopicUnhidden`
:param video_chat_scheduled: Optional. Service message: video chat scheduled
:type video_chat_scheduled: :class:`telebot.types.VideoChatScheduled`
@ -926,6 +983,10 @@ class Message(JsonDeserializable):
opts['forward_date'] = obj.get('forward_date')
if 'is_automatic_forward' in obj:
opts['is_automatic_forward'] = obj.get('is_automatic_forward')
if 'is_topic_message' in obj:
opts['is_topic_message'] = obj.get('is_topic_message')
if 'message_thread_id' in obj:
opts['message_thread_id'] = obj.get('message_thread_id')
if 'reply_to_message' in obj:
opts['reply_to_message'] = Message.de_json(obj['reply_to_message'])
if 'via_bot' in obj:
@ -1067,6 +1128,29 @@ class Message(JsonDeserializable):
content_type = 'message_auto_delete_timer_changed'
if 'reply_markup' in obj:
opts['reply_markup'] = InlineKeyboardMarkup.de_json(obj['reply_markup'])
if 'forum_topic_created' in obj:
opts['forum_topic_created'] = ForumTopicCreated.de_json(obj['forum_topic_created'])
content_type = 'forum_topic_created'
if 'forum_topic_closed' in obj:
opts['forum_topic_closed'] = ForumTopicClosed.de_json(obj['forum_topic_closed'])
content_type = 'forum_topic_closed'
if 'forum_topic_reopened' in obj:
opts['forum_topic_reopened'] = ForumTopicReopened.de_json(obj['forum_topic_reopened'])
content_type = 'forum_topic_reopened'
if 'has_media_spoiler' in obj:
opts['has_media_spoiler'] = obj['has_media_spoiler']
if 'forum_topic_edited' in obj:
opts['forum_topic_edited'] = ForumTopicEdited.de_json(obj['forum_topic_edited'])
content_type = 'forum_topic_edited'
if 'general_forum_topic_hidden' in obj:
opts['general_forum_topic_hidden'] = GeneralForumTopicHidden.de_json(obj['general_forum_topic_hidden'])
content_type = 'general_forum_topic_hidden'
if 'general_forum_topic_unhidden' in obj:
opts['general_forum_topic_unhidden'] = GeneralForumTopicUnhidden.de_json(obj['general_forum_topic_unhidden'])
content_type = 'general_forum_topic_unhidden'
if 'write_access_allowed' in obj:
opts['write_access_allowed'] = WriteAccessAllowed.de_json(obj['write_access_allowed'])
content_type = 'write_access_allowed'
return cls(message_id, from_user, date, chat, content_type, opts, json_string)
@classmethod
@ -1152,6 +1236,16 @@ class Message(JsonDeserializable):
self.successful_payment: Optional[SuccessfulPayment] = None
self.connected_website: Optional[str] = None
self.reply_markup: Optional[InlineKeyboardMarkup] = None
self.message_thread_id: Optional[int] = None
self.is_topic_message: Optional[bool] = None
self.forum_topic_created: Optional[ForumTopicCreated] = None
self.forum_topic_closed: Optional[ForumTopicClosed] = None
self.forum_topic_reopened: Optional[ForumTopicReopened] = None
self.has_media_spoiler: Optional[bool] = None
self.forum_topic_edited: Optional[ForumTopicEdited] = None
self.general_forum_topic_hidden: Optional[GeneralForumTopicHidden] = None
self.general_forum_topic_unhidden: Optional[GeneralForumTopicUnhidden] = None
self.write_access_allowed: Optional[WriteAccessAllowed] = None
for key in options:
setattr(self, key, options[key])
self.json = json_string
@ -1223,11 +1317,20 @@ class Message(JsonDeserializable):
html_text += func(utf16_text[offset * 2 : (offset + entity.length) * 2], entity.type, entity.url, entity.user)
offset += entity.length
else:
# TODO: process nested entities from Bot API 4.5
# Now ignoring them
pass
# Here we are processing nested entities.
# We shouldn't update offset, because they are the same as entity before.
# And, here we are replacing previous string with a new html-rendered text(previous string is already html-rendered,
# And we don't change it).
entity_string = utf16_text[entity.offset * 2 : (entity.offset + entity.length) * 2]
formatted_string = func(entity_string, entity.type, entity.url, entity.user)
entity_string_decoded = entity_string.decode("utf-16-le")
last_occurence = html_text.rfind(entity_string_decoded)
string_length = len(entity_string_decoded)
#html_text = html_text.replace(html_text[last_occurence:last_occurence+string_length], formatted_string)
html_text = html_text[:last_occurence] + formatted_string + html_text[last_occurence+string_length:]
if offset * 2 < len(utf16_text):
html_text += func(utf16_text[offset * 2:])
return html_text
@property
@ -1998,13 +2101,21 @@ class ReplyKeyboardMarkup(JsonSerializable):
replies to the request with a keyboard to select the new language. Other users in the group don't see the keyboard.
:type selective: :obj:`bool`
:param is_persistent: Optional. Use this parameter if you want to show the keyboard to specific users only.
Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a
reply (has reply_to_message_id), sender of the original message.
Example: A user requests to change the bot's language, bot replies to the request with a keyboard to
select the new language. Other users in the group don't see the keyboard.
:return: Instance of the class
:rtype: :class:`telebot.types.ReplyKeyboardMarkup`
"""
max_row_keys = 12
def __init__(self, resize_keyboard: Optional[bool]=None, one_time_keyboard: Optional[bool]=None,
selective: Optional[bool]=None, row_width: int=3, input_field_placeholder: Optional[str]=None):
selective: Optional[bool]=None, row_width: int=3, input_field_placeholder: Optional[str]=None,
is_persistent: Optional[bool]=None):
if row_width > self.max_row_keys:
# Todo: Will be replaced with Exception in future releases
if not DISABLE_KEYLEN_ERROR:
@ -2017,6 +2128,7 @@ class ReplyKeyboardMarkup(JsonSerializable):
self.row_width: int = row_width
self.input_field_placeholder: str = input_field_placeholder
self.keyboard: List[List[KeyboardButton]] = []
self.is_persistent: bool = is_persistent
def add(self, *args, row_width=None):
"""
@ -2082,6 +2194,8 @@ class ReplyKeyboardMarkup(JsonSerializable):
json_dict['selective'] = self.selective
if self.input_field_placeholder:
json_dict['input_field_placeholder'] = self.input_field_placeholder
if self.is_persistent is not None:
json_dict['is_persistent'] = self.is_persistent
return json.dumps(json_dict)
@ -2555,7 +2669,7 @@ class ChatMember(JsonDeserializable):
can_send_messages=None, can_send_media_messages=None, can_send_polls=None,
can_send_other_messages=None, can_add_web_page_previews=None,
can_manage_chat=None, can_manage_video_chats=None,
until_date=None, **kwargs):
until_date=None, can_manage_topics=None, **kwargs):
self.user: User = user
self.status: str = status
self.custom_title: str = custom_title
@ -2579,6 +2693,7 @@ class ChatMember(JsonDeserializable):
self.can_manage_video_chats: bool = can_manage_video_chats
self.can_manage_voice_chats: bool = self.can_manage_video_chats # deprecated, for backward compatibility
self.until_date: int = until_date
self.can_manage_topics: bool = can_manage_topics
class ChatMemberOwner(ChatMember):
@ -2658,6 +2773,10 @@ class ChatMemberAdministrator(ChatMember):
:param can_pin_messages: Optional. True, if the user is allowed to pin messages; groups and supergroups only
:type can_pin_messages: :obj:`bool`
:param can_manage_topics: Optional. True, if the user is allowed to create, rename, close, and reopen forum topics;
supergroups only
:type can_manage_topics: :obj:`bool`
:param custom_title: Optional. Custom title for this user
:type custom_title: :obj:`str`
@ -2709,6 +2828,9 @@ class ChatMemberRestricted(ChatMember):
:param can_pin_messages: True, if the user is allowed to pin messages
:type can_pin_messages: :obj:`bool`
:param can_manage_topics: True, if the user is allowed to create forum topics
:type can_manage_topics: :obj:`bool`
:param can_send_messages: True, if the user is allowed to send text messages, contacts, locations and venues
:type can_send_messages: :obj:`bool`
@ -2811,6 +2933,10 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable):
:param can_pin_messages: Optional. True, if the user is allowed to pin messages. Ignored in public supergroups
:type can_pin_messages: :obj:`bool`
:param can_manage_topics: Optional. True, if the user is allowed to create forum topics. If omitted defaults to the
value of can_pin_messages
:type can_manage_topics: :obj:`bool`
:return: Instance of the class
:rtype: :class:`telebot.types.ChatPermissions`
"""
@ -2823,7 +2949,8 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable):
def __init__(self, can_send_messages=None, can_send_media_messages=None,
can_send_polls=None, can_send_other_messages=None,
can_add_web_page_previews=None, can_change_info=None,
can_invite_users=None, can_pin_messages=None, **kwargs):
can_invite_users=None, can_pin_messages=None,
can_manage_topics=None, **kwargs):
self.can_send_messages: bool = can_send_messages
self.can_send_media_messages: bool = can_send_media_messages
self.can_send_polls: bool = can_send_polls
@ -2832,6 +2959,7 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable):
self.can_change_info: bool = can_change_info
self.can_invite_users: bool = can_invite_users
self.can_pin_messages: bool = can_pin_messages
self.can_manage_topics: bool = can_manage_topics
def to_json(self):
return json.dumps(self.to_dict())
@ -2854,6 +2982,9 @@ class ChatPermissions(JsonDeserializable, JsonSerializable, Dictionaryable):
json_dict['can_invite_users'] = self.can_invite_users
if self.can_pin_messages is not None:
json_dict['can_pin_messages'] = self.can_pin_messages
if self.can_manage_topics is not None:
json_dict['can_manage_topics'] = self.can_manage_topics
return json_dict
@ -5691,9 +5822,6 @@ class InputMediaPhoto(InputMedia):
Telegram Documentation: https://core.telegram.org/bots/api#inputmediaphoto
:param type: Type of the result, must be photo
:type type: :obj:`str`
:param media: File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an
HTTP URL for Telegram to get a file from the Internet, or pass “attach://<file_attach_name>” to upload a new one using
multipart/form-data under <file_attach_name> name. More information on Sending Files »
@ -5710,17 +5838,26 @@ class InputMediaPhoto(InputMedia):
instead of parse_mode
:type caption_entities: :obj:`list` of :class:`telebot.types.MessageEntity`
:param has_spoiler: Optional. True, if the uploaded photo is a spoiler
:type has_spoiler: :obj:`bool`
:return: Instance of the class
:rtype: :class:`telebot.types.InputMediaPhoto`
"""
def __init__(self, media, caption=None, parse_mode=None):
def __init__(self, media, caption=None, parse_mode=None, caption_entities=None, has_spoiler=None):
if util.is_pil_image(media):
media = util.pil_image_to_file(media)
super(InputMediaPhoto, self).__init__(type="photo", media=media, caption=caption, parse_mode=parse_mode)
super(InputMediaPhoto, self).__init__(
type="photo", media=media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities)
self.has_spoiler: Optional[bool] = has_spoiler
def to_dict(self):
return super(InputMediaPhoto, self).to_dict()
ret = super(InputMediaPhoto, self).to_dict()
if self.has_spoiler is not None:
ret['has_spoiler'] = self.has_spoiler
return ret
class InputMediaVideo(InputMedia):
@ -5729,9 +5866,6 @@ class InputMediaVideo(InputMedia):
Telegram Documentation: https://core.telegram.org/bots/api#inputmediavideo
:param type: Type of the result, must be video
:type type: :obj:`str`
:param media: File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an
HTTP URL for Telegram to get a file from the Internet, or pass “attach://<file_attach_name>” to upload a new one using
multipart/form-data under <file_attach_name> name. More information on Sending Files »
@ -5767,17 +5901,22 @@ class InputMediaVideo(InputMedia):
:param supports_streaming: Optional. Pass True, if the uploaded video is suitable for streaming
:type supports_streaming: :obj:`bool`
:param has_spoiler: Optional. True, if the uploaded video is a spoiler
:type has_spoiler: :obj:`bool`
:return: Instance of the class
:rtype: :class:`telebot.types.InputMediaVideo`
"""
def __init__(self, media, thumb=None, caption=None, parse_mode=None, width=None, height=None, duration=None,
supports_streaming=None):
super(InputMediaVideo, self).__init__(type="video", media=media, caption=caption, parse_mode=parse_mode)
def __init__(self, media, thumb=None, caption=None, parse_mode=None, caption_entities=None,
width=None, height=None, duration=None, supports_streaming=None, has_spoiler=None):
super(InputMediaVideo, self).__init__(
type="video", media=media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities)
self.thumb = thumb
self.width = width
self.height = height
self.duration = duration
self.supports_streaming = supports_streaming
self.has_spoiler: Optional[bool] = has_spoiler
def to_dict(self):
ret = super(InputMediaVideo, self).to_dict()
@ -5791,6 +5930,8 @@ class InputMediaVideo(InputMedia):
ret['duration'] = self.duration
if self.supports_streaming:
ret['supports_streaming'] = self.supports_streaming
if self.has_spoiler is not None:
ret['has_spoiler'] = self.has_spoiler
return ret
@ -5800,9 +5941,6 @@ class InputMediaAnimation(InputMedia):
Telegram Documentation: https://core.telegram.org/bots/api#inputmediaanimation
:param type: Type of the result, must be animation
:type type: :obj:`str`
:param media: File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an
HTTP URL for Telegram to get a file from the Internet, or pass “attach://<file_attach_name>” to upload a new one using
multipart/form-data under <file_attach_name> name. More information on Sending Files »
@ -5835,15 +5973,21 @@ class InputMediaAnimation(InputMedia):
:param duration: Optional. Animation duration in seconds
:type duration: :obj:`int`
:param has_spoiler: Optional. True, if the uploaded animation is a spoiler
:type has_spoiler: :obj:`bool`
:return: Instance of the class
:rtype: :class:`telebot.types.InputMediaAnimation`
"""
def __init__(self, media, thumb=None, caption=None, parse_mode=None, width=None, height=None, duration=None):
super(InputMediaAnimation, self).__init__(type="animation", media=media, caption=caption, parse_mode=parse_mode)
def __init__(self, media, thumb=None, caption=None, parse_mode=None, caption_entities=None,
width=None, height=None, duration=None, has_spoiler=None):
super(InputMediaAnimation, self).__init__(
type="animation", media=media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities)
self.thumb = thumb
self.width = width
self.height = height
self.duration = duration
self.has_spoiler: Optional[bool] = has_spoiler
def to_dict(self):
ret = super(InputMediaAnimation, self).to_dict()
@ -5855,6 +5999,8 @@ class InputMediaAnimation(InputMedia):
ret['height'] = self.height
if self.duration:
ret['duration'] = self.duration
if self.has_spoiler is not None:
ret['has_spoiler'] = self.has_spoiler
return ret
@ -5864,9 +6010,6 @@ class InputMediaAudio(InputMedia):
Telegram Documentation: https://core.telegram.org/bots/api#inputmediaaudio
:param type: Type of the result, must be audio
:type type: :obj:`str`
:param media: File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an
HTTP URL for Telegram to get a file from the Internet, or pass “attach://<file_attach_name>” to upload a new one using
multipart/form-data under <file_attach_name> name. More information on Sending Files »
@ -5902,8 +6045,10 @@ class InputMediaAudio(InputMedia):
:return: Instance of the class
:rtype: :class:`telebot.types.InputMediaAudio`
"""
def __init__(self, media, thumb=None, caption=None, parse_mode=None, duration=None, performer=None, title=None):
super(InputMediaAudio, self).__init__(type="audio", media=media, caption=caption, parse_mode=parse_mode)
def __init__(self, media, thumb=None, caption=None, parse_mode=None, caption_entities=None,
duration=None, performer=None, title=None):
super(InputMediaAudio, self).__init__(
type="audio", media=media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities)
self.thumb = thumb
self.duration = duration
self.performer = performer
@ -5928,10 +6073,7 @@ class InputMediaDocument(InputMedia):
Telegram Documentation: https://core.telegram.org/bots/api#inputmediadocument
:param type: Type of the result, must be document
:type type: :obj:`str`
:param media: File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an
:param media: File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an
HTTP URL for Telegram to get a file from the Internet, or pass “attach://<file_attach_name>” to upload a new one using
multipart/form-data under <file_attach_name> name. More information on Sending Files »
:type media: :obj:`str`
@ -5961,8 +6103,10 @@ class InputMediaDocument(InputMedia):
:return: Instance of the class
:rtype: :class:`telebot.types.InputMediaDocument`
"""
def __init__(self, media, thumb=None, caption=None, parse_mode=None, disable_content_type_detection=None):
super(InputMediaDocument, self).__init__(type="document", media=media, caption=caption, parse_mode=parse_mode)
def __init__(self, media, thumb=None, caption=None, parse_mode=None, caption_entities=None,
disable_content_type_detection=None):
super(InputMediaDocument, self).__init__(
type="document", media=media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities)
self.thumb = thumb
self.disable_content_type_detection = disable_content_type_detection
@ -6584,6 +6728,9 @@ class ChatAdministratorRights(JsonDeserializable, JsonSerializable, Dictionaryab
:param can_pin_messages: Optional. True, if the user is allowed to pin messages; groups and supergroups only
:type can_pin_messages: :obj:`bool`
:param can_manage_topics: Optional. True, if the user is allowed to create, rename, close, and reopen forum topics; supergroups only
:type can_manage_topics: :obj:`bool`
:return: Instance of the class
:rtype: :class:`telebot.types.ChatAdministratorRights`
"""
@ -6598,7 +6745,7 @@ class ChatAdministratorRights(JsonDeserializable, JsonSerializable, Dictionaryab
can_delete_messages: bool, can_manage_video_chats: bool, can_restrict_members: bool,
can_promote_members: bool, can_change_info: bool, can_invite_users: bool,
can_post_messages: bool=None, can_edit_messages: bool=None,
can_pin_messages: bool=None) -> None:
can_pin_messages: bool=None, can_manage_topics: bool=None) -> None:
self.is_anonymous: bool = is_anonymous
self.can_manage_chat: bool = can_manage_chat
@ -6611,6 +6758,7 @@ class ChatAdministratorRights(JsonDeserializable, JsonSerializable, Dictionaryab
self.can_post_messages: bool = can_post_messages
self.can_edit_messages: bool = can_edit_messages
self.can_pin_messages: bool = can_pin_messages
self.can_manage_topics: bool = can_manage_topics
def to_dict(self):
json_dict = {
@ -6629,6 +6777,8 @@ class ChatAdministratorRights(JsonDeserializable, JsonSerializable, Dictionaryab
json_dict['can_edit_messages'] = self.can_edit_messages
if self.can_pin_messages is not None:
json_dict['can_pin_messages'] = self.can_pin_messages
if self.can_manage_topics is not None:
json_dict['can_manage_topics'] = self.can_manage_topics
return json_dict
def to_json(self):
@ -6695,3 +6845,172 @@ class InputFile:
File object.
"""
return self._file
class ForumTopicCreated(JsonDeserializable):
"""
This object represents a service message about a new forum topic created in the chat.
Telegram documentation: https://core.telegram.org/bots/api#forumtopiccreated
:param name: Name of the topic
:type name: :obj:`str`
:param icon_color: Color of the topic icon in RGB format
:type icon_color: :obj:`int`
:param icon_custom_emoji_id: Optional. Unique identifier of the custom emoji shown as the topic icon
:type icon_custom_emoji_id: :obj:`str`
:return: Instance of the class
:rtype: :class:`telebot.types.ForumTopicCreated`
"""
@classmethod
def de_json(cls, json_string):
if json_string is None: return None
obj = cls.check_json(json_string)
return cls(**obj)
def __init__(self, name: str, icon_color: int, icon_custom_emoji_id: Optional[str]=None) -> None:
self.name: str = name
self.icon_color: int = icon_color
self.icon_custom_emoji_id: Optional[str] = icon_custom_emoji_id
class ForumTopicClosed(JsonDeserializable):
"""
This object represents a service message about a forum topic closed in the chat. Currently holds no information.
Telegram documentation: https://core.telegram.org/bots/api#forumtopicclosed
"""
# for future use
@classmethod
def de_json(cls, json_string):
return cls()
def __init__(self) -> None:
pass
class ForumTopicReopened(JsonDeserializable):
"""
This object represents a service message about a forum topic reopened in the chat. Currently holds no information.
Telegram documentation: https://core.telegram.org/bots/api#forumtopicreopened
"""
# for future use
@classmethod
def de_json(cls, json_string):
return cls()
def __init__(self) -> None:
pass
class ForumTopicEdited(JsonDeserializable):
"""
This object represents a service message about an edited forum topic.
Telegram documentation: https://core.telegram.org/bots/api#forumtopicedited
:param name: Optional, Name of the topic(if updated)
:type name: :obj:`str`
:param icon_custom_emoji_id: Optional. New identifier of the custom emoji shown as the topic icon, if it was edited;
an empty string if the icon was removed
:type icon_custom_emoji_id: :obj:`str`
"""
@classmethod
def de_json(cls, json_string):
if json_string is None: return None
obj = cls.check_json(json_string)
return cls(**obj)
def __init__(self, name: Optional[str]=None, icon_custom_emoji_id: Optional[str]=None) -> None:
self.name: Optional[str] = name
self.icon_custom_emoji_id: Optional[str] = icon_custom_emoji_id
class GeneralForumTopicHidden(JsonDeserializable):
"""
This object represents a service message about General forum topic hidden in the chat.
Currently holds no information.
Telegram documentation: https://core.telegram.org/bots/api#generalforumtopichidden
"""
@classmethod
def de_json(cls, json_string):
return cls()
def __init__(self) -> None:
pass
class GeneralForumTopicUnhidden(JsonDeserializable):
"""
This object represents a service message about General forum topic unhidden in the chat.
Currently holds no information.
Telegram documentation: https://core.telegram.org/bots/api#generalforumtopicunhidden
"""
@classmethod
def de_json(cls, json_string):
return cls()
def __init__(self) -> None:
pass
class ForumTopic(JsonDeserializable):
"""
This object represents a forum topic.
Telegram documentation: https://core.telegram.org/bots/api#forumtopic
:param message_thread_id: Unique identifier of the forum topic
:type message_thread_id: :obj:`int`
:param name: Name of the topic
:type name: :obj:`str`
:param icon_color: Color of the topic icon in RGB format
:type icon_color: :obj:`int`
:param icon_custom_emoji_id: Optional. Unique identifier of the custom emoji shown as the topic icon
:type icon_custom_emoji_id: :obj:`str`
:return: Instance of the class
:rtype: :class:`telebot.types.ForumTopic`
"""
@classmethod
def de_json(cls, json_string):
if json_string is None: return None
obj = cls.check_json(json_string)
return cls(**obj)
def __init__(self, message_thread_id: int, name: str, icon_color: int, icon_custom_emoji_id: Optional[str]=None) -> None:
self.message_thread_id: int = message_thread_id
self.name: str = name
self.icon_color: int = icon_color
self.icon_custom_emoji_id: Optional[str] = icon_custom_emoji_id
class WriteAccessAllowed(JsonDeserializable):
"""
This object represents a service message about a user allowed to post messages in the chat.
Currently holds no information.
Telegram documentation: https://core.telegram.org/bots/api#writeaccessallowed
"""
@classmethod
def de_json(cls, json_string):
return cls()
def __init__(self) -> None:
pass

View File

@ -37,8 +37,9 @@ thread_local = threading.local()
#: Contains all media content types.
content_type_media = [
'text', 'audio', 'animation', 'document', 'photo', 'sticker', 'video', 'video_note', 'voice', 'contact', 'dice', 'poll',
'venue', 'location'
'text', 'audio', 'document', 'animation', 'game', 'photo', 'sticker', 'video', 'video_note', 'voice', 'contact',
'location', 'venue', 'dice', 'invoice', 'successful_payment', 'connected_website', 'poll', 'passport_data',
'web_app_data',
]
#: Contains all service content types such as `User joined the group`.
@ -46,14 +47,15 @@ content_type_service = [
'new_chat_members', 'left_chat_member', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created',
'supergroup_chat_created', 'channel_chat_created', 'migrate_to_chat_id', 'migrate_from_chat_id', 'pinned_message',
'proximity_alert_triggered', 'video_chat_scheduled', 'video_chat_started', 'video_chat_ended',
'video_chat_participants_invited', 'message_auto_delete_timer_changed'
'video_chat_participants_invited', 'message_auto_delete_timer_changed', 'forum_topic_created', 'forum_topic_closed',
'forum_topic_reopened',
]
#: All update types, should be used for allowed_updates parameter in polling.
update_types = [
"message", "edited_message", "channel_post", "edited_channel_post", "inline_query",
"chosen_inline_result", "callback_query", "shipping_query", "pre_checkout_query", "poll", "poll_answer",
"my_chat_member", "chat_member", "chat_join_request"
"message", "edited_message", "channel_post", "edited_channel_post", "inline_query", "chosen_inline_result",
"callback_query", "shipping_query", "pre_checkout_query", "poll", "poll_answer", "my_chat_member", "chat_member",
"chat_join_request",
]
@ -397,7 +399,10 @@ def escape(text: str) -> str:
:return: the escaped text
"""
chars = {"&": "&amp;", "<": "&lt;", ">": "&gt;"}
for old, new in chars.items(): text = text.replace(old, new)
if text is None:
return None
for old, new in chars.items():
text = text.replace(old, new)
return text
@ -647,15 +652,15 @@ def antiflood(function: Callable, *args, **kwargs):
"""
from telebot.apihelper import ApiTelegramException
from time import sleep
msg = None
try:
msg = function(*args, **kwargs)
return function(*args, **kwargs)
except ApiTelegramException as ex:
if ex.error_code == 429:
sleep(ex.result_json['parameters']['retry_after'])
msg = function(*args, **kwargs)
finally:
return msg
return function(*args, **kwargs)
else:
raise
def parse_web_app_data(token: str, raw_init_data: str):

View File

@ -1,3 +1,3 @@
# Versions should comply with PEP440.
# This line is parsed in setup.py:
__version__ = '4.7.0'
__version__ = '4.9.0'