Compare commits

...

251 Commits

Author SHA1 Message Date
_run e10517e088
Merge pull request #2017 from Artin-GH/patch-1
Fix backslash (\) issue in escape_markdown
2023-07-30 23:19:57 +05:00
Artin GH 1946393c36
Fix backslash (\) issue in escape_markdown 2023-07-14 16:39:50 +03:30
Badiboy 0f52ca688f
Merge pull request #2015 from Badiboy/master
Fix aioredis version check for regular redis
2023-07-14 13:00:03 +03:00
Badiboy b18bcd494a Fix aioredis version check for regular redis 2023-07-12 19:48:22 +03:00
Badiboy 8f41df0ee4
Merge pull request #2012 from Kourva/master
Update README.md
2023-07-10 19:01:09 +03:00
Kourva cb7f6a8c99
Update README.md 2023-07-10 03:05:34 +03:30
_run 3960115ec7
Merge pull request #2009 from coder2020official/fileupload
Fixes #1944: uploading file from memory
2023-07-09 00:06:02 +05:00
_run 916569cdc5
Fixes #1944: uploading file from memory 2023-07-08 23:42:47 +05:00
_run 75d3fa2eba
Merge pull request #2008 from coder2020official/middleware
Fix issue with post_process in async not receiving the error
2023-07-08 23:25:05 +05:00
_run 67e3774e8e
Fix issue with post_process in async not receiving the error 2023-07-08 23:23:23 +05:00
_run f799157314
Merge pull request #2007 from coder2020official/master
Updated all russian docstrings, currently without translation.
2023-07-08 23:15:05 +05:00
coder2020official af3a98057f Updated all russian docstrings, currently without translation. 2023-07-08 23:10:41 +05:00
_run 447fc1d461
Merge pull request #2006 from coder2020official/master
Fixed deprecation warning for readthedocs.org
2023-07-08 23:01:57 +05:00
_run fb98df3dfe
Fixed deprecation warning for readthedocs.org 2023-07-08 22:57:13 +05:00
Badiboy 0b34da3900
Merge pull request #1996 from artemetra/master
Fix typo in docs
2023-06-18 23:19:00 +03:00
Artem Lukin 5ea1abaadd
fix typo in docs 2023-06-18 01:57:08 +02:00
Badiboy 5a81353420
Merge pull request #1991 from eternnoir/dependabot/pip/requests-2.31.0
Bump requests from 2.20.0 to 2.31.0
2023-05-28 22:27:49 +03:00
dependabot[bot] eaf90cce7f
Bump requests from 2.20.0 to 2.31.0
Bumps [requests](https://github.com/psf/requests) from 2.20.0 to 2.31.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.20.0...v2.31.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 21:33:40 +00:00
Badiboy b219218c8d
Merge pull request #1988 from Badiboy/master
Bump version to 4.12.0
2023-05-18 18:09:13 +03:00
Badiboy 2dac17aa75 Bump version to 4.12.0 2023-05-18 18:07:09 +03:00
Badiboy 48377ac905
Merge pull request #1947 from alex75311/edit_antiflood_method
redesigned the antiflood method for guaranteed message delivery
2023-05-08 09:10:28 +03:00
Alexey Isaev 14294d1aa3 redesigned the antiflood method for guaranteed message delivery 2023-05-04 23:08:10 +03:00
_run ea3c159044
Merge pull request #1975 from engAmirEng/feature/async-func-filter
bring back the async func message_filter
2023-05-02 20:43:48 +04:00
AmirW 58d53e1a54 bring back the async func message_filter
-fixes #1974
- related commits: c84896391e f69a2ba044
2023-04-28 16:12:23 +03:30
Badiboy abec3dc60e
Merge pull request #1969 from coder2020official/botapi6.7
Bot API 6.7 - Not much to do, just minor improvements
2023-04-24 09:38:21 +03:00
coder2020official ecb5d9b4f6 Added tests for __html_text, fixed the bug, added custom_emoji for entities 2023-04-22 22:53:57 +04:00
coder2020official 26575dc5e7 Added support for launching Web Apps from inline query results by replacing the parameters switch_pm_text and switch_pm_parameter of the method answerInlineQuery with the parameter button of type InlineQueryResultsButton. 2023-04-22 20:51:08 +04:00
coder2020official be69feb252 * Added a test for message entity __html_text function. #1971 should be fixed and then todo can be done. 2023-04-22 20:38:05 +04:00
coder2020official 1d62adc262 Added the ability to get the current bot name in the given language as the class BotName using the method getMyName. 2023-04-22 18:30:46 +04:00
coder2020official 77e1928628 Added the ability to set different bot names for different user languages using the method setMyName. 2023-04-22 18:25:24 +04:00
coder2020official d6f4987197 Added the field via_chat_folder_invite_link to the class ChatMemberUpdated. 2023-04-21 22:30:32 +04:00
coder2020official 966b451869 Added the field switch_inline_query_chosen_chat of the type SwitchInlineQueryChosenChat to the class InlineKeyboardButton, which allows bots to switch to inline mode in a chosen chat of the given type. 2023-04-21 22:28:20 +04:00
coder2020official d1417e5616 Added the field web_app_name to the class WriteAccessAllowed. 2023-04-21 22:14:16 +04:00
_run a7cafd1f24
Update README.md 2023-04-21 21:27:08 +04:00
Badiboy 92907ced30
Merge pull request #1966 from Badiboy/master
Bump version to 4.11.0
2023-04-15 22:40:59 +03:00
Badiboy 1b2ed0e2f7 Bump version to 4.11.0 2023-04-15 22:39:14 +03:00
_run 370f0370c7
Merge pull request #1964 from Cub11k/add_state_list
Add state_list to StatesGroup
2023-04-15 01:53:00 +05:00
Cub11k e4bddd91cb Define state_list in __init_subclass__ 2023-04-14 22:11:08 +03:00
Cub11k d466da3542 Add state_list to StatesGroup 2023-04-14 22:00:42 +03:00
Badiboy e64c06b7bc
Merge pull request #1951 from mikelei8291/doc-fix
Fix documentation for `InlineKeyboardMarkup` and `quick_markup`
2023-04-03 19:10:10 +03:00
Badiboy 7d168ebbd8
Merge pull request #1961 from fcoagz/patch-2
Update README.md
2023-04-03 18:56:38 +03:00
Francisco Griman c5689f383b
edit 2023-04-03 11:49:21 -04:00
Francisco Griman 8796168efb
Update README.md 2023-04-03 11:27:15 -04:00
_run 100659fecd
Merge pull request #1958 from coder2020official/master
Fix storage not saving data sometimes
2023-04-03 01:01:11 +05:00
_run 7bf87a306a
Update redis_storage.py 2023-04-03 01:00:48 +05:00
_run 351d021e01
Update redis_storage.py 2023-04-03 01:00:29 +05:00
Badiboy 4ffe0f8833
Merge pull request #1952 from Badiboy/master
More changes from review of bot api 6.6
2023-03-27 23:17:24 +03:00
Badiboy 3f07dc4ce8
thumb
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-26 20:04:29 +03:00
Badiboy 2e589ab6e1 Thumb type spec 2023-03-26 18:00:35 +03:00
Badiboy 8b63f6a6ef Merge branch 'master' of https://github.com/Badiboy/pyTelegramBotAPI 2023-03-26 17:41:25 +03:00
Badiboy dc98aca173 Merge remote-tracking branch 'upstream/master' 2023-03-26 17:40:55 +03:00
Badiboy 39360e0640
send_video thumbnail hint
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-25 16:38:16 +03:00
Badiboy b1c172c421
send_document thumbnail hint
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-25 16:38:05 +03:00
Badiboy 6b5c263ee8
send_animtion thumbnail hint
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-25 16:37:46 +03:00
Badiboy 46100edd97
send_video_note thumbnail hint
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-25 16:37:22 +03:00
Badiboy 018b89cdc0
send_document thumbnail
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-25 16:37:03 +03:00
Badiboy f3486b3730
send_document thumbnail
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-25 16:36:36 +03:00
Badiboy b0e64d828c
send_video thumbnail hint
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-25 16:36:10 +03:00
Badiboy 14434b398e
send_animation thumbnail hint
Co-authored-by: _run <khumogo1@gmail.com>
2023-03-25 16:34:08 +03:00
_run 1d62bf2ac8
Merge pull request #1949 from codebyzen/master
I added CalendarIT Telegram bot (with link to bot), can post acquainted with what is happening today, tomorrow or what happened 20 years ago to channel.
2023-03-25 16:40:46 +04:00
Badiboy fe2e9a7a30 thumb_url etc. converted to properties 2023-03-25 15:22:30 +03:00
Badiboy c9ef0d71f0 Deprecation warnings equalisation 2023-03-25 15:17:29 +03:00
Badiboy b0740a920a Set "thumb" as property in types 2023-03-25 15:08:40 +03:00
Badiboy 6a9c25cf80 Fix set_sticker_set_thumb and set_sticker_set_thumbnail 2023-03-25 14:56:31 +03:00
Badiboy e56c60ac00 thumb deprecation typo and thumb->thumbnail param rename 2023-03-25 14:44:50 +03:00
Badiboy 7c7a063fb6 Fix some code hints 2023-03-25 14:38:02 +03:00
Mike Lei bd69492ed4
Fix documentation for `InlineKeyboardMarkup` and `quick_markup` 2023-03-23 18:52:40 +00:00
C̷̱̺͙͓̪͔̹͉͉̯̖̟̀͆́̽̔̈̚͠͝o̶̥̻̻̖̮͚͒̂̒͌̾̇͗͘͝d̸̢̡͈̮̦͈͙̖͔̦̭̩̰͎͉̣̰͆̈́͘͝e̸͖͆̎̏͒̀̈́͛́̍̀̀̿̚͝B̵̨̯̹̝͙͉̲̟̳̟͎̪̫̪̤̒͋̉̑̐̒̅̅̋͜y̵̞͚͕̭̤̱͖̟̫̜̓͐̏̕ͅZ̸͎̫̖͍̪̓̐͆e̶͈͇̽̔͂̉͊̈́ņ̶̣̣͎̤̯͖͉͍̳͇͈̘̳̗͚́̄̊̂̊̏̄͐͐̿̓́̽̃̄̚͝ 37cdb52ed2 Merge branch 'master' of https://github.com/eternnoir/pyTelegramBotAPI 2023-03-19 17:39:29 +03:00
C̷̱̺͙͓̪͔̹͉͉̯̖̟̀͆́̽̔̈̚͠͝o̶̥̻̻̖̮͚͒̂̒͌̾̇͗͘͝d̸̢̡͈̮̦͈͙̖͔̦̭̩̰͎͉̣̰͆̈́͘͝e̸͖͆̎̏͒̀̈́͛́̍̀̀̿̚͝B̵̨̯̹̝͙͉̲̟̳̟͎̪̫̪̤̒͋̉̑̐̒̅̅̋͜y̵̞͚͕̭̤̱͖̟̫̜̓͐̏̕ͅZ̸͎̫̖͍̪̓̐͆e̶͈͇̽̔͂̉͊̈́ņ̶̣̣͎̤̯͖͉͍̳͇͈̘̳̗͚́̄̊̂̊̏̄͐͐̿̓́̽̃̄̚͝ d8569394b0 Update README.md
I added CalendarIT Telegram bot, can post acquainted with what is happening today, tomorrow or what happened 20 years ago to channel.
2023-03-19 17:39:24 +03:00
_run da57174635
Merge pull request #1948 from coder2020official/botapi6.6
Changes from review of bot api 6.6
2023-03-19 18:25:37 +04:00
_run 776ce0a7eb
Merge pull request #1942 from arashnm80/master
add SpotSeekBot
2023-03-19 17:36:48 +04:00
coder2020official 886806135e Merge branch 'botapi6.6' of https://github.com/coder2020official/pyTelegramBotAPI into botapi6.6 2023-03-19 17:31:55 +04:00
coder2020official 1e450ebd15 Bot API 6.6 review changes 2023-03-19 17:31:53 +04:00
_run 41521f5618
Merge pull request #1937 from coder2020official/botapi6.6
I'm back: Bot API 6.6 Update
2023-03-19 13:27:52 +04:00
_run 603a7cf9f2
Update telebot/asyncio_helper.py 2023-03-15 05:48:41 +04:00
_run 535a14ca0c
Update telebot/apihelper.py 2023-03-15 05:48:16 +04:00
_run 67a52b2e98
Apply suggestions from code review 2023-03-15 05:46:03 +04:00
Arash Nemat Zadeh c47c26d2b0
Update README.md 2023-03-14 17:29:51 +03:30
coder2020official 9d2f7c02a4 Fixing tests attempt 1 2023-03-11 23:54:57 +04:00
coder2020official 991679bedc Renamed all necessary thumbs to thumbnails in types.py 2023-03-11 23:53:16 +04:00
coder2020official 3b4e6fed04 Renamed the method setStickerSetThumb to setStickerSetThumbnail and its parameter thumb to thumbnail. 2023-03-11 23:37:32 +04:00
coder2020official 5c6b867582 Renamed the field thumb in the classes Animation, Audio, Document, Sticker, Video, VideoNote, InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaVideo, StickerSet to thumbnail. Renamed the parameter thumb in the methods sendAnimation, sendAudio, sendDocument, sendVideo, sendVideoNote to thumbnail. 2023-03-11 23:34:17 +04:00
coder2020official 715aabaf49 Added the method setStickerMaskPosition for changing the mask position of a mask sticker. 2023-03-11 23:06:57 +04:00
coder2020official 9fa5b91e58 Added the method setStickerKeywords for changing the search keywords assigned to a sticker. 2023-03-11 22:58:41 +04:00
coder2020official de5a32e45c Fixed custom_emoji_ids and added set_sticker_emoji_list, and and fixed some typehints 2023-03-11 22:53:33 +04:00
coder2020official db087427fc Added the method deleteStickerSet for complete deletion of a given sticker set that was created by the bot. 2023-03-11 22:27:37 +04:00
coder2020official 385fc6a6da Added the method setStickerSetTitle for editing the title of sticker sets created by the bot. 2023-03-11 22:24:34 +04:00
coder2020official ac0b386625 Added the method setCustomEmojiStickerSetThumbnail for editing the thumbnail of custom emoji sticker sets created by the bot. 2023-03-11 22:19:49 +04:00
coder2020official ae44b0022d Added support for .WEBP, .TGS, and .WEBM files in uploadStickerFile by replacing the parameter png_sticker in the method uploadStickerFile with the parameters sticker and sticker_format. 2023-03-11 22:15:31 +04:00
coder2020official 73135d6012 Added support for .WEBP files in createNewStickerSet and addStickerToSet. 2023-03-11 22:03:37 +04:00
coder2020official 19dcce0d5b Added support for the creation of sticker sets with multiple initial stickers in createNewStickerSet by replacing the parameters png_sticker, tgs_sticker, webm_sticker, emojis and mask_position with the parameters stickers and sticker_format. 2023-03-11 21:59:22 +04:00
coder2020official f527fc91f6 Replaced the parameters png_sticker, tgs_sticker, webm_sticker, emojis and mask_position in the method addStickerToSet with the parameter sticker of the type InputSticker. 2023-03-11 18:18:07 +04:00
coder2020official c0185dad44 Added the field needs_repainting to the class Sticker. 2023-03-11 16:41:19 +04:00
coder2020official 8a858cac4e Added the parameter needs_repainting to the method createNewStickerSet to automatically change the color of emoji based on context (e.g., use text color in messages, accent color in statuses, etc.). 2023-03-11 16:39:04 +04:00
coder2020official f30457bd75 Added support for the creation of custom emoji sticker sets in createNewStickerSet. 2023-03-11 16:33:02 +04:00
coder2020official 54caf30f69 Added the parameter emoji to the method sendSticker to specify an emoji for just uploaded stickers. 2023-03-11 15:50:09 +04:00
coder2020official 09e4a2a437 Added the ability to get the current bot short description in the given language as the class BotShortDescription using the method getMyShortDescription. 2023-03-11 15:46:35 +04:00
coder2020official 9b81a29a6a Added the ability to set different bot short descriptions for different user languages using the method setMyShortDescription. 2023-03-11 15:40:54 +04:00
coder2020official 65dcd67140 Added the ability to get the current bot description in the given language as the class BotDescription using the method getMyDescription. 2023-03-11 15:35:00 +04:00
coder2020official c84b771e5a Added the ability to set different bot descriptions for different user languages using the method setMyDescription. 2023-03-10 21:36:44 +04:00
_run 2bd81a5f5c
I'm back: Bot API Update too :) 2023-03-10 15:21:07 +04:00
Badiboy 5d9a76b0dd
Merge pull request #1917 from S1RANN/master
Add a function to extract contents of entities from messages
2023-03-03 11:00:03 +03:00
Badiboy 6459f13f25
Merge pull request #1927 from Badiboy/master
New content types added + typo fix
2023-02-22 09:51:22 +03:00
Badiboy c9b6d3f868 New content types added + typo fix 2023-02-22 09:49:29 +03:00
Badiboy 80c1a4798d
Merge pull request #1921 from zeldpol/patch-1
Fix .webm upload
2023-02-18 23:46:03 +03:00
Dmitry 7a67d5f9f9
Fix .webm async upload 2023-02-18 22:36:29 +02:00
zeldpol d12ea91e12
Fix .webm upload
No need to pass file content as a header, it causes the http error "431 Request Header Fields Too Large".
2023-02-17 19:23:11 +02:00
orocane 4f2c89c4a8 Add a function to extract contents of entities from messages 2023-02-15 17:24:39 +08:00
_run fb7d60f09d
Merge pull request #1913 from coder2020official/botapi6.5
Fix #1912
2023-02-09 19:49:17 +04:00
coder2020official 8dc4e77287 Update asyncio_helper.py 2023-02-09 19:27:05 +04:00
Badiboy a999161384
Merge pull request #1911 from Badiboy/master
restrict_chat_member fix
2023-02-09 17:58:28 +03:00
Badiboy b4196f5891 restrict_chat_member fix 2023-02-09 17:56:10 +03:00
Badiboy e55fe962ca
Merge pull request #1906 from Badiboy/master
Bump version to 4.10.0
2023-02-05 13:14:08 +03:00
Badiboy 3d2c5c9590 Bump version to 4.10.0 2023-02-05 13:11:07 +03:00
_run 40567570e8
Merge pull request #1902 from coder2020official/botapi6.5
Bot API 6.5 update 🔥
2023-02-05 13:07:47 +04:00
coder2020official 4179e502c3 Fix description 2023-02-05 11:13:31 +04:00
coder2020official a9b878107c Fix can_send_media_messages param, added warnings 2023-02-04 22:24:26 +04:00
coder2020official 2094120ec7 Added user_chat_id to ChatJoinRequest; And, i corrected typehints 2023-02-04 20:07:01 +04:00
coder2020official d1348606e3 Added use_independent_chat_permissions to setchatpermissions 2023-02-04 20:04:07 +04:00
coder2020official d0d03d0c09 Added use_independent_chat_permissions for restrictchatmember 2023-02-04 19:59:49 +04:00
Badiboy fdd82a5e4b
Merge pull request #1894 from Muhammad-Aadil/master
Added poll_example.py in the examples
2023-02-04 18:46:39 +03:00
coder2020official 9e68f76f5d Replaced the fields can_send_media_messages in the classes ChatMemberRestricted and ChatPermissions with separate fields can_send_audios, can_send_documents, can_send_photos, can_send_videos, can_send_video_notes, and can_send_voice_notes for different media types. 2023-02-04 18:57:06 +04:00
coder2020official 4000c9fb48 Added chat_shared and chatshared 2023-02-04 16:58:48 +04:00
coder2020official ae42d0b1fe Added usershared and user_shared 2023-02-04 16:54:43 +04:00
coder2020official a3891ff363 Pep 0563 proposed change
https://peps.python.org/pep-0563/
2023-02-04 16:29:48 +04:00
coder2020official 4d7f5310fb Added the class KeyboardButtonRequestChat and the field request_chat to the class KeyboardButton. 2023-02-04 16:24:05 +04:00
_run 3e0d69f7f4
fixed checks x1 2023-02-04 16:16:34 +04:00
coder2020official 2e5fb10430 Added the class KeyboardButtonRequestUser and the field request_user to the class KeyboardButton. 2023-02-04 16:02:18 +04:00
_run c39c050abf
Update README.md 2023-02-04 15:32:55 +04:00
Muhammad Aadil ed6d6cc03f add poll answer handler to poll_example.py to show the example to send next poll or log user answers 2023-02-04 11:22:49 +05:00
Muhammad Aadil 10a80e1cfa add only quiz type poll example to the poll_example.py 2023-02-04 10:27:29 +05:00
Badiboy d99f48f975
Merge pull request #1893 from artyl/master
RuntimeError("cannot join current thread")
2023-01-31 20:52:59 +03:00
_run dae2790c61
Merge pull request #1898 from Badiboy/master
Async allowed_updates fix
2023-01-31 20:59:35 +04:00
Badiboy f5eac56afa Async allowed_updates fix 2023-01-31 11:19:11 +03:00
_run 268c3a9210
Merge pull request #1890 from iamnalinor/master
Fix "invite link must be non-empty" error
2023-01-28 19:35:02 +04:00
Muhammad Aadil ad7e4bbaf7 Added poll_example.py in the examples 2023-01-28 18:20:58 +05:00
Artem Lavrenov b9bedef73f Avoid raise RuntimeError(cannot join current thread) 2023-01-28 12:26:25 +03:00
Badiboy 9fb5f89f18
Merge pull request #1892 from bgelov/patch-1
Update README.md
2023-01-27 09:24:07 +03:00
Oleg Belov 409ff49603
Update README.md
Change _handeler() to _handler() in readme
2023-01-26 22:49:41 -03:00
Albert 5e0da40fcd Fix "invite link must be non-empty" error
`bot.edit_chat_invite_link` method contained a mistake: `invite_link` and `name` were supposed to be vice-versa in `apihelper.edit_chat_invite_link(...)` call. This caused to be invite_link empty or contain invalid value, resulting to get `Bad Request: invite link must be non-empty` error.
This also affected the async version.
2023-01-21 17:00:36 +04:00
Badiboy b743aa5813
Merge pull request #1884 from Cub11k/master
Remove redundant function from util
2023-01-16 16:58:58 +03:00
Cub11k 1797f076dc Remove redundant function 2023-01-16 15:45:59 +02:00
_run 68c1fe8cb5
Merge pull request #1883 from Cub11k/master
Fix type of attribute id of InlineQuery from int to str
2023-01-15 17:22:22 +04:00
Cub11k 1eda7cafd4 Fix type of attribute id of InlineQuery from int to str 2023-01-15 15:04:07 +02:00
Badiboy 291566908b
Merge pull request #1882 from CommanderCRM/patch-1
Added a bot with public source code to the list
2023-01-13 15:58:55 +03:00
Ilya Krivoshein bef29d9318
Added a bot with public source code to the list 2023-01-13 19:14:10 +07:00
Badiboy a5af586a46
Merge pull request #1881 from Cub11k/master
Create method get_media_file_id() in util.py
2023-01-10 20:48:50 +03:00
Cub11k 93dcbbeb02 Create method get_media_file_id()
Method is used to get file id of different types of media
2023-01-10 19:35:36 +02:00
Badiboy bd94d8d91c
Merge pull request #1873 from coder2020official/circular_import_fix
Little code style improvement in service_utils
2023-01-08 09:55:33 +03:00
_run 6b399ab8cd
Being specific with except block 2023-01-08 10:49:27 +04:00
_run 8744402efc
Removed built-in io module from try/except block 2023-01-08 10:48:45 +04:00
Badiboy d5bbaa900e
Merge pull request #1870 from Cub11k/master
Make create_dir() method of StatePickleStorage cross-platform instead of POSIX only.
2023-01-07 13:02:26 +03:00
Konstantin Ostashenko 02ae255701
Revert changes in util.py 2023-01-06 22:39:27 +02:00
Cub11k c27f60b94b Make create_dir() method cross-platform instead of POSIX only.
Fix for issue #1869
2023-01-06 22:36:08 +02:00
Badiboy a781929a2d
Merge pull request #1868 from Cub11k/master
Fix circular import
2023-01-06 22:51:52 +03:00
Cub11k e6f8acadf4 rename _util.py to service_utils.py 2023-01-06 21:41:30 +02:00
Cub11k c298d95d0f Move functions, required in types.py to _util.py
Add __all__ to util.py for sphinx to generate docs properly
2023-01-06 19:27:25 +02:00
Cub11k 8aee5372ee Update README.md - add link to ru docs 2023-01-05 16:25:16 +02:00
_run df105ab1d8
Merge pull request #1867 from Cub11k/master
Translated into russian files: index.po, calldata.po
2023-01-05 18:20:30 +04:00
Cub11k b93ec5d0e0 Translated calldata.po to russian 2023-01-05 16:13:00 +02:00
Cub11k f201df3275 Translated index.po to russian 2023-01-05 16:03:14 +02:00
_run 206e4e024b
Merge pull request #1865 from coder2020official/master
Fix docs issues
2023-01-04 18:08:35 +04:00
coder2020official bd1290592b Fix docs issues 2023-01-04 18:07:29 +04:00
_run 9b9eb775f7
Merge pull request #1863 from Cub11k/master
Finished translations into russian of files: sync_version.po, async_version.po
2023-01-04 17:39:34 +04:00
Konstantin Ostashenko 3cfa24f9c0
Fix msgid for forward_message:5 in async_version.po 2023-01-04 15:35:09 +02:00
Konstantin Ostashenko b540a6c4d4
Fix msgid for forward_message:5 in sync_version.po 2023-01-04 15:33:18 +02:00
Cub11k a0ba5ae9af Finished translations on sync and async versions.
Spelling fixes
2023-01-04 00:43:42 +02:00
Cub11k 651db29cb2 Fix typehints for stop_poll reply markup 2023-01-03 23:45:59 +02:00
Cub11k 490168f3f6 Some translations
Up to lines sync_version.po:4527 and async_version.po:4448
2023-01-03 19:43:36 +02:00
Cub11k bf38071e8f Some translations
Up to lines sync_version.po:3691 and async_version.po:3609
2023-01-03 17:32:31 +02:00
Konstantin Ostashenko e8aaa524fe
Merge branch 'sync_and_async_upd' into master 2023-01-02 17:41:48 +02:00
Konstantin Ostashenko e2e754fdff
Merge pull request #3 from eternnoir/master
Update fork
2023-01-02 17:35:04 +02:00
_run d64f305fd4
Merge pull request #1861 from coder2020official/docs
Updated documentation locales
2023-01-02 19:29:40 +04:00
coder2020official 611bf4235c Updated documentation locales 2023-01-02 19:27:57 +04:00
Konstantin Ostashenko fe0dc6930c
Merge pull request #2 from Cub11k/master
Update branch from master
2023-01-02 17:14:33 +02:00
Konstantin Ostashenko 6d4d3f8005
Merge pull request #1 from eternnoir/master
Update fork
2023-01-02 17:12:49 +02:00
Cub11k 0f7464e8c4 Some translations
Up to lines sync_version.po:3008 and async_version.po:3122
2023-01-02 17:09:48 +02:00
Badiboy 6f86382e33
Merge pull request #1860 from Badiboy/master
Bump version to 4.9/0
2023-01-02 18:00:39 +03:00
Badiboy 43cc203654 Bump version to 4.9/0 2023-01-02 18:00:20 +03:00
Badiboy 3b62ad4765
Merge pull request #1855 from coder2020official/botapi6.4
Bot API 6.4
2023-01-02 17:55:32 +03:00
_run 3be5015f9e
Update telebot/types.py 2023-01-02 17:55:30 +04:00
_run 267a33c329
Update telebot/types.py 2023-01-02 17:55:14 +04:00
_run 667e82d073
Update telebot/types.py 2023-01-02 17:54:35 +04:00
Cub11k dd50273c95 Some translations
Up to lines sync_version.po:2709 and async_version.po:2853
2022-12-31 14:16:13 +02:00
Cub11k 8e9d566d5c Minor fixes and some translations
Up to lines sync_version.po:2382 and async_version.po:2528
2022-12-31 00:56:38 +02:00
_run 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
Konstantin Ostashenko 68edb4990c
Fix async_version.po 2022-12-30 21:42:50 +02:00
Cub11k 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
coder2020official eed56be596 Added fields has_hidden_members and has_aggressive_anti_spam_enabled to class Chat 2022-12-30 20:38:26 +04:00
coder2020official 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
coder2020official 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
coder2020official 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
coder2020official 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
coder2020official 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
coder2020official 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
coder2020official 4d11e97c25 has_spoiler parameter
Added the parameter has_spoiler to the methods sendPhoto, sendVideo, and sendAnimation.
2022-12-30 19:20:23 +04:00
coder2020official 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
_run 24cd014410
Update README.md 2022-12-30 18:52:00 +04:00
Badiboy ba64180b5f
Merge pull request #1854 from Cub11k/master
Fixed typehints for reply markup in editing methods
2022-12-30 16:44:31 +03:00
Cub11k 3812fd05e3 Fixed typehints for reply markup in editing methods (async) 2022-12-30 14:04:12 +02:00
Cub11k 69afd7232e Fixed typehints for reply markup in editing methods 2022-12-30 14:02:02 +02:00
Badiboy 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
_run bb8023ecc6
Merge pull request #1852 from Cub11k/master
Fixed typehints for register_<any>_handler()
2022-12-28 22:14:50 +04:00
Cub11k a50a6e2e54 Fixed typehints for register_<any>_handler() 2022-12-28 20:00:06 +02:00
Badiboy 0329e5adb8
Merge pull request #1850 from ayitinya/patch-1
Update README.md
2022-12-27 09:17:26 +03:00
Rudy Ayitinya Sulley 2f25b56659
Update README.md
Adds a bot to Bots using this library list
2022-12-27 02:46:07 +00:00
dependabot[bot] 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
_run a6a22c351a
Merge pull request #1845 from Cub11k/master
Partly translated files: sync_version.po
2022-12-21 17:14:55 +04:00
Cub11k d211db90cf Update sync_version.po 2022-12-21 15:04:43 +02:00
_run 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
_run c5e733a4c1
Escape both metachars 2022-12-20 23:47:12 +04:00
_run 925f7012f1
Update formatting.py 2022-12-20 23:44:32 +04:00
_run 625ae09573
Merge pull request #1839 from coder2020official/master
Fix bug with asyncwebhooks
2022-12-19 17:35:23 +04:00
coder2020official 5b279b7ad9 (A)SyncWebhookListener changes 2022-12-19 17:28:05 +04:00
_run 247cddf23d
Merge pull request #1831 from coder2020official/reloader_fix
Update reloader.py
2022-12-19 17:17:11 +04:00
_run 171172d12e
Update async_telebot.py 2022-12-19 17:12:15 +04:00
_run c3c12b93dd
Merge pull request #1832 from coder2020official/master
Fix bug related to get_user_profile_photos
2022-12-14 14:18:18 +04:00
_run add240adfd
Update asyncio_helper.py 2022-12-14 12:41:30 +04:00
_run 45fe2ea319
Update reloader.py 2022-12-13 18:44:41 +04:00
Badiboy 6373af78f3
Merge pull request #1824 from reddere/patch-3
fixing escape()
2022-12-03 16:48:16 +03:00
reddere 4ed460b137
Update util.py 2022-12-03 14:23:10 +01:00
reddere ae20cb9f31
Update util.py 2022-12-03 14:21:31 +01:00
reddere 669c18fdc0
update
updated "== None" to "is None" and adjusted the else statement
2022-12-03 14:11:07 +01:00
reddere 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
Badiboy 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
Badiboy 43abedbff7 Fixed register_next_step_handler_by_chat_id chat_id description 2022-12-02 23:59:59 +03:00
Badiboy 42d162f732
Merge pull request #1822 from Badiboy/master
Fix caption_entities miss in InputMediaXXX
2022-12-02 23:52:54 +03:00
Badiboy cd4dc899a1 Fix caption_entities miss in InputMediaXXX 2022-12-02 23:46:26 +03:00
_run 5066626692
Merge pull request #1818 from Cub11k/master
Translated to russian file: util.po
2022-12-01 12:46:16 +04:00
Konstantin Ostashenko 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
Konstantin Ostashenko 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
Cub11k e358abc1bd Update util.po 2022-11-30 21:07:46 +02:00
_run 42da2d1794
Merge pull request #1816 from Cub11k/master
Translated into russian file: formatting.po
2022-11-30 19:44:24 +04:00
Cub11k feaef2b2b8 Merge remote-tracking branch 'origin/master' 2022-11-30 17:33:28 +02:00
Cub11k 6cf60a3dcb Update formatting.po according to comments 2022-11-30 17:33:06 +02:00
Konstantin Ostashenko 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
Cub1tor 1c2111d689 Update formatting.po 2022-11-29 20:19:25 +02:00
_run bf039df122
Merge pull request #1815 from coder2020official/master
Update install.po
2022-11-29 19:25:40 +04:00
_run 44309797d1
Update install.po 2022-11-29 19:21:05 +04:00
_run 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
abdullaev388 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
abdullaev388 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
abdullaev388 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
abdullaev388 29befa4d0c
Update install.po
translated into russian
2022-11-29 09:25:10 -05:00
abdullaev388 cce03dab78
Update quick_start.po
translated into russian
2022-11-29 09:21:24 -05:00
_run 7702d63fd7
Merge pull request #1813 from coder2020official/docs
Base of ru documentation added.
2022-11-29 17:39:30 +04:00
_run d636cdf88b
Update doc_req.txt 2022-11-29 17:37:16 +04:00
_run 06a28380d7
Update doc_req.txt 2022-11-29 17:33:42 +04:00
coder2020official d7e9d3accc Update conf.py 2022-11-29 14:59:17 +04:00
coder2020official 736c03fe84 Update conf.py 2022-11-29 14:49:32 +04:00
coder2020official 7502d26b1a Added locales 2022-11-29 14:45:51 +04:00
43 changed files with 40725 additions and 854 deletions

22
.readthedocs.yaml Normal file
View File

@ -0,0 +1,22 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.9"
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# We recommend specifying your dependencies to enable reproducible builds:
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: docs/requirements.txt

View File

@ -2,7 +2,6 @@
[![PyPi Package Version](https://img.shields.io/pypi/v/pyTelegramBotAPI.svg)](https://pypi.python.org/pypi/pyTelegramBotAPI)
[![Supported Python versions](https://img.shields.io/pypi/pyversions/pyTelegramBotAPI.svg)](https://pypi.python.org/pypi/pyTelegramBotAPI)
[![Documentation Status](https://readthedocs.org/projects/pytba/badge/?version=latest)](https://pytba.readthedocs.io/en/latest/?badge=latest)
[![Build Status](https://travis-ci.org/eternnoir/pyTelegramBotAPI.svg?branch=master)](https://travis-ci.org/eternnoir/pyTelegramBotAPI)
[![PyPi downloads](https://img.shields.io/pypi/dm/pyTelegramBotAPI.svg)](https://pypi.org/project/pyTelegramBotAPI/)
[![PyPi status](https://img.shields.io/pypi/status/pytelegrambotapi.svg?style=flat-square)](https://pypi.python.org/pypi/pytelegrambotapi)
@ -11,9 +10,10 @@
<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#november-5-2022">6.3</a>!
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#april-21-2023">6.7</a>!
<h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>
<h2><a href='https://pytba.readthedocs.io/ru/latest/index.html'>Official ru documentation</a></h2>
## Contents
@ -265,7 +265,7 @@ def test_callback(call): # <- passes a CallbackQuery type object to your functio
#### Shipping Query Handler
Handle shipping queries
`@bot.shipping_query_handeler() # <- passes a ShippingQuery type object to your function`
`@bot.shipping_query_handler() # <- passes a ShippingQuery type object to your function`
#### Pre Checkout Query Handler
Handle pre checkoupt queries
@ -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.
@ -886,5 +887,10 @@ Here are some examples of template:
* [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.
* [Media Rating Bot](https://t.me/mediaratingbot) ([source](https://github.com/CommanderCRM/MediaRatingBot))by [CommanderCRM](https://github.com/CommanderCRM). This bot aggregates media (movies, TV series, etc.) ratings from IMDb, Rotten Tomatoes, Metacritic, TheMovieDB, FilmAffinity and also provides number of votes of said media on IMDb.
* [Spot Seek Bot](https://t.me/SpotSeekBot) ([source](https://github.com/arashnm80/spot-seek-bot)) by [Arashnm80](https://github.com/arashnm80). This is a free & open source telegram bot for downloading tracks, albums or playlists from spotify.
* [CalendarIT Bot](https://t.me/calendarit_bot) ([source](https://github.com/codebyzen/CalendarIT_Telegram_Bot))by [CodeByZen](https://github.com/codebyzen). A simple, but extensible Python Telegram bot, can post acquainted with what is happening today, tomorrow or what happened 20 years ago to channel.
* [DownloadMusicBOT](https://github.com/fcoagz/DownloadMusicBOT) by *Francisco Griman* - It is a simple bot that downloads audio from YouTube videos on Telegram.
* [AwesomeChatGPTBot](https://github.com/Kourva/AwesomeChatGPTBot) - Simple ChatGTP-3.5 bot. It is FREE and can remember chat history for a while With pre-defined roles!
**Want to have your bot listed here? Just make a pull request. Only bots with public source code are accepted.**

View File

@ -18,11 +18,11 @@
# -- Project information -----------------------------------------------------
project = 'pyTelegramBotAPI Documentation'
copyright = '2022, coder2020official'
copyright = '2022-2023, coder2020official'
author = 'coder2020official'
# The full version, including alpha/beta/rc tags
release = '4.8.0'
release = '4.12.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,355 @@
# 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: 2023-07-08 23:07+0500\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"
#: ../../source/util.rst:3
msgid "Utils"
msgstr ""
#: ../../source/util.rst:5
msgid "Utils in pyTelegramBotAPI"
msgstr ""
#: ../../source/util.rst:5
msgid "ptba, pytba, pyTelegramBotAPI, utils, guide"
msgstr ""
#: ../../source/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.service_utils.is_bytes telebot.service_utils.is_dict
#: telebot.service_utils.is_pil_image telebot.util.antiflood
#: telebot.util.escape telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.is_command
#: 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 "Number of retries to send"
msgstr ""
#: of telebot.util.antiflood:16
msgid "The arguments to pass to the function"
msgstr ""
#: of telebot.util.antiflood:19
msgid "The keyword arguments to pass to the function"
msgstr ""
#: of telebot.service_utils.generate_random_token
#: telebot.service_utils.is_bytes telebot.service_utils.is_dict
#: telebot.service_utils.is_pil_image telebot.util.antiflood
#: telebot.util.escape telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.is_command
#: 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:22
msgid "None"
msgstr ""
#: of telebot.service_utils.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.service_utils.generate_random_token
#: telebot.service_utils.is_bytes telebot.service_utils.is_dict
#: telebot.service_utils.is_pil_image telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.is_command
#: 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.service_utils.generate_random_token:1
msgid ""
"Generates a random token consisting of letters and digits, 16 characters "
"long."
msgstr ""
#: of telebot.service_utils.generate_random_token:3
msgid "a random token"
msgstr ""
#: of telebot.service_utils.generate_random_token:4 telebot.util.user_link:22
msgid ":obj:`str`"
msgstr ""
#: of telebot.service_utils.is_bytes:1
msgid "Returns True if the given object is a bytes object."
msgstr ""
#: of telebot.service_utils.is_bytes:3 telebot.service_utils.is_dict:3
#: telebot.service_utils.is_pil_image:3
msgid "object to be checked"
msgstr ""
#: of telebot.service_utils.is_bytes:6
msgid "True if the given object is a bytes object."
msgstr ""
#: of telebot.service_utils.is_bytes:7 telebot.service_utils.is_dict:7
#: telebot.service_utils.is_pil_image:7 telebot.util.is_command: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.service_utils.is_dict:1
msgid "Returns True if the given object is a dictionary."
msgstr ""
#: of telebot.service_utils.is_dict:6
msgid "True if the given object is a dictionary."
msgstr ""
#: of telebot.service_utils.is_pil_image:1
msgid "Returns True if the given object is a PIL.Image.Image object."
msgstr ""
#: of telebot.service_utils.is_pil_image:6
msgid "True if the given object is a PIL.Image.Image object."
msgstr ""
#: of telebot.service_utils.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:31
msgid ""
"a dict containing all buttons to create in this format: {text: kwargs} "
"{str:}"
msgstr ""
#: of telebot.util.quick_markup:34
msgid "number of :class:`telebot.types.InlineKeyboardButton` objects on each row"
msgstr ""
#: of telebot.util.quick_markup:37
msgid "InlineKeyboardMarkup"
msgstr ""
#: of telebot.util.quick_markup:38
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 ""
#~ msgid "int row width"
#~ msgstr ""

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,130 @@
# 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 "Фабрика callback data"
#: ../../calldata.rst:6
msgid "Callback data factory in pyTelegramBotAPI"
msgstr "Фабрика callback data в pyTelegramBotAPI"
#: ../../calldata.rst:6
msgid ""
"ptba, pytba, pyTelegramBotAPI, callbackdatafactory, guide, callbackdata, "
"factory"
msgstr ""
"ptba, pytba, pyTelegramBotAPI, callbackdatafactory, гайд, callbackdata, "
"фабрика"
#: ../../calldata.rst:12
msgid "callback\\_data file"
msgstr "Файл callback\\_data"
#: of telebot.callback_data:1
msgid "Callback data factory's file."
msgstr "Файл фабрики callback data."
#: of telebot.callback_data.CallbackData:1
#: telebot.callback_data.CallbackDataFilter:1
msgid "Bases: :py:class:`object`"
msgstr "Базовые классы: :py:class:`object`"
#: of telebot.callback_data.CallbackData:1
msgid "Callback data factory This class will help you to work with CallbackQuery"
msgstr "Фабрика Callback data. Этот класс поможет вам в работе с CallbackQuery"
#: 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 "заданные именованные параметры будут проверены в CallbackQuery.data"
#: 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 "Класс CallbackDataFilter"
#: of telebot.callback_data.CallbackData.new:1
msgid "Generate callback data"
msgstr "Сгенерировать callback data"
#: of telebot.callback_data.CallbackData.new:3
msgid "positional parameters of CallbackData instance parts"
msgstr "позиционные параметры экземпляра CallbackData"
#: 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 "Получить данные из callback data"
#: of telebot.callback_data.CallbackData.parse:3
msgid ""
"string, use to telebot.types.CallbackQuery to parse it from string to a "
"dict"
msgstr ""
"string, примените к telebot.types.CallbackQuery, чтобы преобразовать "
"callback_data из строки (str) в словарь (dict)"
#: of telebot.callback_data.CallbackData.parse:4
msgid "dict parsed from callback data"
msgstr "словарь (dict), полученный из callback data"
#: of telebot.callback_data.CallbackDataFilter:1
msgid "Filter for CallbackData."
msgstr "Фильтр для CallbackData."
#: of telebot.callback_data.CallbackDataFilter.check:1
msgid "Checks if query.data appropriates to specified config"
msgstr "Проверяет, соответствует ли query.data заданной конфигурации"
#: 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 "True, если query.data соответствует заданной конфигурации"
#: 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,128 @@
# 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 "Добро пожаловать в документацию pyTelegramBotAPI!"
#: ../../index.rst:10
msgid "Official documentation of pyTelegramBotAPI"
msgstr "Официальная документация pyTelegramBotAPI"
#: ../../index.rst:10
msgid "ptba, pytba, pyTelegramBotAPI, documentation, guide"
msgstr "ptba, pytba, pyTelegramBotAPI, документация, гайд"
#: ../../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 ""
"TeleBot это синхронная и асинхронная реализация `Telegram Bot "
"API <https://core.telegram.org/bots/api>`_."
#: ../../index.rst:21
msgid "Chats"
msgstr "Чаты"
#: ../../index.rst:22
msgid ""
"English chat: `Private chat "
"<https://telegram.me/joinchat/Bn4ixj84FIZVkwhk2jag6A>`__"
msgstr ""
"Англоязычный чат: `Private chat "
"<https://telegram.me/joinchat/Bn4ixj84FIZVkwhk2jag6A>`__"
#: ../../index.rst:24
msgid ""
"Russian chat: `@pytelegrambotapi_talks_ru "
"<https://t.me/pytelegrambotapi_talks_ru>`__"
msgstr ""
"Русскоязычный чат: `@pytelegrambotapi_talks_ru "
"<https://t.me/pytelegrambotapi_talks_ru>`__"
#: ../../index.rst:26
msgid "News: `@pyTelegramBotAPI <https://t.me/pytelegrambotapi>`__"
msgstr "Новости: `@pyTelegramBotAPI <https://t.me/pytelegrambotapi>`__"
#: ../../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 ""
"Исходники: `Github repository "
"<https://github.com/eternnoir/pyTelegramBotAPI>`__"
#: ../../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 "Состояния (стейты, FSM)"
#: ../../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,393 @@
# 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: 2023-07-08 23:07+0500\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"
#: ../../source/util.rst:3
msgid "Utils"
msgstr "Утилиты"
#: ../../source/util.rst:5
msgid "Utils in pyTelegramBotAPI"
msgstr "Утилиты в pyTelegramBotAPI"
#: ../../source/util.rst:5
msgid "ptba, pytba, pyTelegramBotAPI, utils, guide"
msgstr "ptba, pytba, pyTelegramBotAPI, утилиты, гайд"
#: ../../source/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.service_utils.is_bytes telebot.service_utils.is_dict
#: telebot.service_utils.is_pil_image telebot.util.antiflood
#: telebot.util.escape telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.is_command
#: 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 "Number of retries to send"
msgstr ""
#: of telebot.util.antiflood:16
msgid "The arguments to pass to the function"
msgstr "Аргументы, для передачи в функцию"
#: of telebot.util.antiflood:19
msgid "The keyword arguments to pass to the function"
msgstr "Именованные аргументы для передачи в функцию"
#: of telebot.service_utils.generate_random_token
#: telebot.service_utils.is_bytes telebot.service_utils.is_dict
#: telebot.service_utils.is_pil_image telebot.util.antiflood
#: telebot.util.escape telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.is_command
#: 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:22
msgid "None"
msgstr ""
#: of telebot.service_utils.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.service_utils.generate_random_token
#: telebot.service_utils.is_bytes telebot.service_utils.is_dict
#: telebot.service_utils.is_pil_image telebot.util.extract_arguments
#: telebot.util.extract_command telebot.util.is_command
#: 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.service_utils.generate_random_token:1
msgid ""
"Generates a random token consisting of letters and digits, 16 characters "
"long."
msgstr ""
"Генерирует рандомный токен, состоящий из латинских букв и цифр длиной 16 "
"символов."
#: of telebot.service_utils.generate_random_token:3
msgid "a random token"
msgstr "Сгенерированный токен"
#: of telebot.service_utils.generate_random_token:4 telebot.util.user_link:22
msgid ":obj:`str`"
msgstr ""
#: of telebot.service_utils.is_bytes:1
msgid "Returns True if the given object is a bytes object."
msgstr "Возвращает True если полученный объект является bytes."
#: of telebot.service_utils.is_bytes:3 telebot.service_utils.is_dict:3
#: telebot.service_utils.is_pil_image:3
msgid "object to be checked"
msgstr "Объект для проверки"
#: of telebot.service_utils.is_bytes:6
msgid "True if the given object is a bytes object."
msgstr "True, если полученный объект является bytes."
#: of telebot.service_utils.is_bytes:7 telebot.service_utils.is_dict:7
#: telebot.service_utils.is_pil_image:7 telebot.util.is_command: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.service_utils.is_dict:1
msgid "Returns True if the given object is a dictionary."
msgstr "Возвращает True, если полученный объект является словарём (dict)."
#: of telebot.service_utils.is_dict:6
msgid "True if the given object is a dictionary."
msgstr "True, если полученный объект является словарём (dict)."
#: of telebot.service_utils.is_pil_image:1
msgid "Returns True if the given object is a PIL.Image.Image object."
msgstr "Возвращает True, если полученный объект является PIL.Image.Image."
#: of telebot.service_utils.is_pil_image:6
msgid "True if the given object is a PIL.Image.Image object."
msgstr "True, если полученный объект является PIL.Image.Image."
#: of telebot.service_utils.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:31
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:34
msgid "number of :class:`telebot.types.InlineKeyboardButton` objects on each row"
msgstr ""
#: of telebot.util.quick_markup:37
msgid "InlineKeyboardMarkup"
msgstr ""
#: of telebot.util.quick_markup:38
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 "Объект, полученный в качестве ответа"
#~ msgid "int row width"
#~ msgstr "Количество кнопок в одной строке, int"

32
examples/poll_example.py Normal file
View File

@ -0,0 +1,32 @@
#!/usr/bin/python
# This is an example file to create quiz polls
import telebot
API_TOKEN = "<api_token>"
bot = telebot.TeleBot(API_TOKEN)
@bot.message_handler(commands=["poll"])
def create_poll(message):
bot.send_message(message.chat.id, "English Article Test")
answer_options = ["a", "an", "the", "-"]
bot.send_poll(
chat_id=message.chat.id,
question="We are going to '' park.",
options=answer_options,
type="quiz",
correct_option_id=2,
is_anonymous=False,
)
@bot.poll_answer_handler()
def handle_poll(poll):
# This handler can be used to log User answers and to send next poll
pass
bot.infinity_polling()

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -355,15 +355,15 @@ def get_chat_member_count(token, chat_id):
return _make_request(token, method_url, params=payload)
def set_sticker_set_thumb(token, name, user_id, thumb):
method_url = r'setStickerSetThumb'
def set_sticker_set_thumbnail(token, name, user_id, thumbnail):
method_url = r'setStickerSetThumbnail'
payload = {'name': name, 'user_id': user_id}
files = {}
if thumb:
if not isinstance(thumb, str):
files['thumb'] = thumb
if thumbnail:
if not isinstance(thumbnail, str):
files['thumbnail'] = thumbnail
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
return _make_request(token, method_url, params=payload, files=files or None)
@ -459,7 +459,7 @@ def send_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,
message_thread_id=None):
message_thread_id=None, has_spoiler=None):
method_url = r'sendPhoto'
payload = {'chat_id': chat_id}
files = None
@ -489,6 +489,8 @@ def send_photo(
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')
@ -655,18 +657,20 @@ def send_contact(
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,
message_thread_id=None):
parse_mode=None, supports_streaming=None, disable_notification=None, timeout=None,
thumbnail=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
@ -690,14 +694,14 @@ def send_video(token, chat_id, data, duration=None, caption=None, reply_to_messa
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if width:
payload['width'] = width
if height:
@ -710,13 +714,16 @@ def send_video(token, chat_id, data, duration=None, caption=None, reply_to_messa
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, message_thread_id=None):
parse_mode=None, disable_notification=None, timeout=None, thumbnail=None, caption_entities=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
@ -738,14 +745,14 @@ def send_animation(
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if caption_entities:
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
@ -758,6 +765,8 @@ def send_animation(
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')
@ -797,7 +806,7 @@ def send_voice(token, chat_id, voice, caption=None, duration=None, reply_to_mess
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, thumbnail=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
method_url = r'sendVideoNote'
payload = {'chat_id': chat_id}
@ -820,14 +829,14 @@ def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_m
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
@ -838,7 +847,7 @@ def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_m
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,
reply_markup=None, parse_mode=None, disable_notification=None, timeout=None, thumbnail=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}
@ -865,14 +874,14 @@ def send_audio(token, chat_id, audio, caption=None, duration=None, performer=Non
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if caption_entities:
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
@ -885,9 +894,9 @@ def send_audio(token, chat_id, audio, caption=None, duration=None, performer=Non
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,
disable_notification=None, timeout=None, caption=None, thumbnail=None, caption_entities=None,
allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None,
protect_content = None, message_thread_id=None):
protect_content = None, message_thread_id=None, emoji=None):
method_url = get_method_by_type(data_type)
payload = {'chat_id': chat_id}
files = None
@ -910,14 +919,14 @@ def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_m
payload['timeout'] = timeout
if caption:
payload['caption'] = caption
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if caption_entities:
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
@ -928,6 +937,8 @@ def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_m
payload['disable_content_type_detection'] = disable_content_type_detection
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if emoji:
payload['emoji'] = emoji
return _make_request(token, method_url, params=payload, files=files, method='post')
@ -959,36 +970,19 @@ def unban_chat_member(token, chat_id, user_id, only_if_banned):
def restrict_chat_member(
token, chat_id, user_id, until_date=None,
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):
token, chat_id, user_id, permissions, until_date=None,
use_independent_chat_permissions=None):
method_url = 'restrictChatMember'
permissions = {}
if can_send_messages is not None:
permissions['can_send_messages'] = can_send_messages
if can_send_media_messages is not None:
permissions['can_send_media_messages'] = can_send_media_messages
if can_send_polls is not None:
permissions['can_send_polls'] = can_send_polls
if can_send_other_messages is not None:
permissions['can_send_other_messages'] = can_send_other_messages
if can_add_web_page_previews is not None:
permissions['can_add_web_page_previews'] = can_add_web_page_previews
if can_change_info is not None:
permissions['can_change_info'] = can_change_info
if can_invite_users is not None:
permissions['can_invite_users'] = can_invite_users
if can_pin_messages is not None:
permissions['can_pin_messages'] = can_pin_messages
permissions_json = json.dumps(permissions)
payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions_json}
payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions.to_json()}
if use_independent_chat_permissions is not None:
payload['use_independent_chat_permissions'] = use_independent_chat_permissions
if until_date is not None:
if isinstance(until_date, datetime):
payload['until_date'] = until_date.timestamp()
else:
payload['until_date'] = until_date
return _make_request(token, method_url, params=payload, method='post')
@ -1047,12 +1041,14 @@ def unban_chat_sender_chat(token, chat_id, sender_chat_id):
return _make_request(token, method_url, params=payload, method='post')
def set_chat_permissions(token, chat_id, permissions):
def set_chat_permissions(token, chat_id, permissions, use_independent_chat_permissions=None):
method_url = 'setChatPermissions'
payload = {
'chat_id': chat_id,
'permissions': permissions.to_json()
}
if use_independent_chat_permissions is not None:
payload['use_independent_chat_permissions'] = use_independent_chat_permissions
return _make_request(token, method_url, params=payload, method='post')
@ -1158,6 +1154,39 @@ def set_chat_title(token, chat_id, title):
return _make_request(token, method_url, params=payload, method='post')
def set_my_description(token, description=None, language_code=None):
method_url = r'setMyDescription'
payload = {}
if description is not None:
payload['description'] = description
if language_code is not None:
payload['language_code'] = language_code
return _make_request(token, method_url, params=payload, method='post')
def get_my_description(token, language_code=None):
method_url = r'getMyDescription'
payload = {}
if language_code:
payload['language_code'] = language_code
return _make_request(token, method_url, params=payload)
def set_my_short_description(token, short_description=None, language_code=None):
method_url = r'setMyShortDescription'
payload = {}
if short_description is not None:
payload['short_description'] = short_description
if language_code is not None:
payload['language_code'] = language_code
return _make_request(token, method_url, params=payload, method='post')
def get_my_short_description(token, language_code=None):
method_url = r'getMyShortDescription'
payload = {}
if language_code:
payload['language_code'] = language_code
return _make_request(token, method_url, params=payload)
def get_my_commands(token, scope=None, language_code=None):
method_url = r'getMyCommands'
payload = {}
@ -1167,6 +1196,22 @@ def get_my_commands(token, scope=None, language_code=None):
payload['language_code'] = language_code
return _make_request(token, method_url, params=payload)
def set_my_name(token, name=None, language_code=None):
method_url = r'setMyName'
payload = {}
if name is not None:
payload['name'] = name
if language_code is not None:
payload['language_code'] = language_code
return _make_request(token, method_url, params=payload, method='post')
def get_my_name(token, language_code=None):
method_url = r'getMyName'
payload = {}
if language_code is not None:
payload['language_code'] = language_code
return _make_request(token, method_url, params=payload)
def set_chat_menu_button(token, chat_id=None, menu_button=None):
method_url = r'setChatMenuButton'
payload = {}
@ -1450,7 +1495,8 @@ def send_invoice(
:param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest units of the currency.
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
:param protect_content:
:param protect_content: Protects the contents of the sent message from forwarding and saving
:param message_thread_id: Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
:return:
"""
method_url = r'sendInvoice'
@ -1568,7 +1614,7 @@ def answer_callback_query(token, callback_query_id, text=None, show_alert=None,
def answer_inline_query(token, inline_query_id, results, cache_time=None, is_personal=None, next_offset=None,
switch_pm_text=None, switch_pm_parameter=None):
button=None):
method_url = 'answerInlineQuery'
payload = {'inline_query_id': inline_query_id, 'results': _convert_list_json_serializable(results)}
if cache_time is not None:
@ -1577,10 +1623,8 @@ def answer_inline_query(token, inline_query_id, results, cache_time=None, is_per
payload['is_personal'] = is_personal
if next_offset is not None:
payload['next_offset'] = next_offset
if switch_pm_text:
payload['switch_pm_text'] = switch_pm_text
if switch_pm_parameter:
payload['switch_pm_parameter'] = switch_pm_parameter
if button is not None:
payload["button"] = button.to_json()
return _make_request(token, method_url, params=payload, method='post')
@ -1590,58 +1634,86 @@ def get_sticker_set(token, name):
def get_custom_emoji_stickers(token, custom_emoji_ids):
method_url = r'getCustomEmojiStickers'
return _make_request(token, method_url, params={'custom_emoji_ids': custom_emoji_ids})
return _make_request(token, method_url, params={'custom_emoji_ids': json.dumps(custom_emoji_ids)})
def set_sticker_keywords(token, sticker, keywords=None):
method_url = 'setStickerKeywords'
payload = {'sticker': sticker}
if keywords:
payload['keywords'] = json.dumps(keywords)
return _make_request(token, method_url, params=payload, method='post')
def set_sticker_mask_position(token, sticker, mask_position=None):
method_url = 'setStickerMaskPosition'
payload = {'sticker': sticker}
if mask_position:
payload['mask_position'] = mask_position.to_json()
return _make_request(token, method_url, params=payload, method='post')
def upload_sticker_file(token, user_id, png_sticker):
def upload_sticker_file(token, user_id, sticker, sticker_format):
method_url = 'uploadStickerFile'
payload = {'user_id': user_id}
files = {'png_sticker': png_sticker}
payload = {'user_id': user_id, 'sticker_format': sticker_format}
files = {'sticker': sticker}
return _make_request(token, method_url, params=payload, files=files, method='post')
def set_custom_emoji_sticker_set_thumbnail(token, name, custom_emoji_id=None):
method_url = 'setCustomEmojiStickerSetThumbnail'
payload = {'name': name}
if custom_emoji_id is not None:
payload['custom_emoji_id'] = custom_emoji_id
return _make_request(token, method_url, params=payload, method='post')
def set_sticker_set_title(token, name, title):
method_url = 'setStickerSetTitle'
payload = {'name': name, 'title': title}
return _make_request(token, method_url, params=payload, method='post')
def delete_sticker_set(token, name):
method_url = 'deleteStickerSet'
payload = {'name': name}
return _make_request(token, method_url, params=payload, method='post')
def set_sticker_emoji_list(token, sticker, emoji_list):
method_url = 'setStickerEmojiList'
payload = {'sticker': sticker, 'emoji_list': json.dumps(emoji_list)}
return _make_request(token, method_url, params=payload, method='post')
def create_new_sticker_set(
token, user_id, name, title, emojis, png_sticker, tgs_sticker,
mask_position=None, webm_sticker=None, sticker_type=None):
token, user_id, name, title, stickers, sticker_format, sticker_type=None, needs_repainting=None):
method_url = 'createNewStickerSet'
payload = {'user_id': user_id, 'name': name, 'title': title, 'emojis': emojis}
if png_sticker:
stype = 'png_sticker'
elif webm_sticker:
stype = 'webm_sticker'
else:
stype = 'tgs_sticker'
sticker = png_sticker or tgs_sticker or webm_sticker
files = None
if not util.is_string(sticker):
files = {stype: sticker}
else:
payload[stype] = sticker
if mask_position:
payload['mask_position'] = mask_position.to_json()
if webm_sticker:
payload['webm_sticker'] = webm_sticker
payload = {'user_id': user_id, 'name': name, 'title': title, 'sticker_format': sticker_format}
if sticker_type:
payload['sticker_type'] = sticker_type
if needs_repainting:
payload['needs_repainting'] = needs_repainting
files = {}
lst = []
for sticker in stickers:
json_dict, file = sticker.convert_input_sticker()
json_dict = sticker.to_dict()
if file:
list_keys = list(file.keys())
files[list_keys[0]] = file[list_keys[0]]
lst.append(json_dict)
payload['stickers'] = json.dumps(lst)
return _make_request(token, method_url, params=payload, files=files, method='post')
def add_sticker_to_set(token, user_id, name, emojis, png_sticker, tgs_sticker, mask_position, webm_sticker):
def add_sticker_to_set(token, user_id, name, sticker):
method_url = 'addStickerToSet'
payload = {'user_id': user_id, 'name': name, 'emojis': emojis}
if png_sticker:
stype = 'png_sticker'
elif webm_sticker:
stype = 'webm_sticker'
else:
stype = 'tgs_sticker'
sticker = png_sticker or tgs_sticker or webm_sticker
files = None
if not util.is_string(sticker):
files = {stype: sticker}
else:
payload[stype] = sticker
if mask_position:
payload['mask_position'] = mask_position.to_json()
json_dict, files = sticker.convert_input_sticker()
payload = {'user_id': user_id, 'name': name, 'sticker': json_dict}
return _make_request(token, method_url, params=payload, files=files, method='post')
@ -1766,9 +1838,13 @@ def create_forum_topic(token, chat_id, name, icon_color=None, icon_custom_emoji_
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, icon_custom_emoji_id):
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, 'name': name, 'icon_custom_emoji_id': icon_custom_emoji_id}
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):
@ -1802,6 +1878,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

@ -74,12 +74,18 @@ class StatesGroup:
my_state = State() # returns my_state:State string.
"""
def __init_subclass__(cls) -> None:
state_list = []
for name, value in cls.__dict__.items():
if not name.startswith('__') and not callable(value) and isinstance(value, State):
# change value of that variable
value.name = ':'.join((cls.__name__, name))
value.group = cls
state_list.append(value)
cls._state_list = state_list
@property
def state_list(self):
return self._state_list
class SkipHandler:

View File

@ -171,20 +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: url = FILE_URL.format(token, file_path)
else:
# noinspection PyUnresolvedReferences
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)
raise ApiHTTPException('Download file', response)
result = await response.read()
return result
@ -243,11 +245,11 @@ async def get_updates(token, offset=None, limit=None,
params['limit'] = limit
if timeout:
params['timeout'] = timeout
if allowed_updates:
params['allowed_updates'] = allowed_updates
if allowed_updates is not None: # Empty lists should pass
params['allowed_updates'] = json.dumps(allowed_updates)
return await _process_request(token, method_name, params=params, request_timeout=request_timeout)
async def _check_result(method_name, result):
async def _check_result(method_name, result: aiohttp.ClientResponse):
"""
Checks whether `result` is a valid API response.
A result is considered invalid if:
@ -263,7 +265,7 @@ async def _check_result(method_name, result):
try:
result_json = await result.json(encoding="utf-8")
except:
if result.status_code != 200:
if result.status != 200:
raise ApiHTTPException(method_name, result)
else:
raise ApiInvalidJSONException(method_name, result)
@ -341,15 +343,15 @@ async def get_chat_member_count(token, chat_id):
return await _process_request(token, method_url, params=payload)
async def set_sticker_set_thumb(token, name, user_id, thumb):
method_url = r'setStickerSetThumb'
async def set_sticker_set_thumbnail(token, name, user_id, thumbnail):
method_url = r'setStickerSetThumbnail'
payload = {'name': name, 'user_id': user_id}
files = {}
if thumb:
if not isinstance(thumb, str):
files['thumb'] = thumb
if thumbnail:
if not isinstance(thumbnail, str):
files['thumbnail'] = thumbnail
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
return await _process_request(token, method_url, params=payload, files=files or None)
@ -453,7 +455,7 @@ async def send_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,
message_thread_id=None):
message_thread_id=None, has_spoiler=None):
method_url = r'sendPhoto'
payload = {'chat_id': chat_id}
files = None
@ -483,6 +485,8 @@ async def send_photo(
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')
@ -647,18 +651,20 @@ async def send_contact(
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, message_thread_id=None):
parse_mode=None, supports_streaming=None, disable_notification=None, timeout=None,
thumbnail=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
@ -682,14 +688,14 @@ async def send_video(token, chat_id, data, duration=None, caption=None, reply_to
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if width:
payload['width'] = width
if height:
@ -702,13 +708,16 @@ async def send_video(token, chat_id, data, duration=None, caption=None, reply_to
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, message_thread_id=None):
parse_mode=None, disable_notification=None, timeout=None, thumbnail=None, caption_entities=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
@ -730,14 +739,14 @@ async def send_animation(
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if caption_entities:
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
@ -750,6 +759,8 @@ async def send_animation(
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')
@ -789,8 +800,8 @@ async def send_voice(token, chat_id, voice, caption=None, duration=None, reply_t
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,
message_thread_id=None):
disable_notification=None, timeout=None, thumbnail=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
method_url = r'sendVideoNote'
payload = {'chat_id': chat_id}
files = None
@ -812,14 +823,14 @@ async def send_video_note(token, chat_id, data, duration=None, length=None, repl
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
if protect_content is not None:
@ -830,8 +841,8 @@ async def send_video_note(token, chat_id, data, duration=None, length=None, repl
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, message_thread_id=None):
reply_markup=None, parse_mode=None, disable_notification=None, timeout=None, thumbnail=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
@ -857,14 +868,14 @@ async def send_audio(token, chat_id, audio, caption=None, duration=None, perform
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if caption_entities:
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
@ -877,9 +888,9 @@ async def send_audio(token, chat_id, audio, caption=None, duration=None, perform
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,
message_thread_id=None):
disable_notification=None, timeout=None, caption=None, thumbnail=None, caption_entities=None,
allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None, protect_content=None,
message_thread_id=None, emoji=None):
method_url = await get_method_by_type(data_type)
payload = {'chat_id': chat_id}
files = None
@ -902,14 +913,14 @@ async def send_data(token, chat_id, data, data_type, reply_to_message_id=None, r
payload['timeout'] = timeout
if caption:
payload['caption'] = caption
if thumb:
if not util.is_string(thumb):
if thumbnail:
if not util.is_string(thumbnail):
if files:
files['thumb'] = thumb
files['thumbnail'] = thumbnail
else:
files = {'thumb': thumb}
files = {'thumbnail': thumbnail}
else:
payload['thumb'] = thumb
payload['thumbnail'] = thumbnail
if caption_entities:
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
@ -920,6 +931,8 @@ async def send_data(token, chat_id, data, data_type, reply_to_message_id=None, r
payload['disable_content_type_detection'] = disable_content_type_detection
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if emoji:
payload['emoji'] = emoji
return await _process_request(token, method_url, params=payload, files=files, method='post')
@ -951,31 +964,13 @@ async def unban_chat_member(token, chat_id, user_id, only_if_banned):
async def restrict_chat_member(
token, chat_id, user_id, until_date=None,
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):
token, chat_id, user_id, permissions, until_date=None,
use_independent_chat_permissions=None):
method_url = 'restrictChatMember'
permissions = {}
if can_send_messages is not None:
permissions['can_send_messages'] = can_send_messages
if can_send_media_messages is not None:
permissions['can_send_media_messages'] = can_send_media_messages
if can_send_polls is not None:
permissions['can_send_polls'] = can_send_polls
if can_send_other_messages is not None:
permissions['can_send_other_messages'] = can_send_other_messages
if can_add_web_page_previews is not None:
permissions['can_add_web_page_previews'] = can_add_web_page_previews
if can_change_info is not None:
permissions['can_change_info'] = can_change_info
if can_invite_users is not None:
permissions['can_invite_users'] = can_invite_users
if can_pin_messages is not None:
permissions['can_pin_messages'] = can_pin_messages
permissions_json = json.dumps(permissions)
payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions_json}
payload = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions.to_json()}
if use_independent_chat_permissions is not None:
payload['use_independent_chat_permissions'] = use_independent_chat_permissions
if until_date is not None:
if isinstance(until_date, datetime):
payload['until_date'] = until_date.timestamp()
@ -1037,12 +1032,14 @@ async def unban_chat_sender_chat(token, chat_id, sender_chat_id):
payload = {'chat_id': chat_id, 'sender_chat_id': sender_chat_id}
return await _process_request(token, method_url, params=payload, method='post')
async def set_chat_permissions(token, chat_id, permissions):
async def set_chat_permissions(token, chat_id, permissions, use_independent_chat_permissions=None):
method_url = 'setChatPermissions'
payload = {
'chat_id': chat_id,
'permissions': permissions.to_json()
}
if use_independent_chat_permissions is not None:
payload['use_independent_chat_permissions'] = use_independent_chat_permissions
return await _process_request(token, method_url, params=payload, method='post')
@ -1145,6 +1142,37 @@ async def set_chat_title(token, chat_id, title):
payload = {'chat_id': chat_id, 'title': title}
return await _process_request(token, method_url, params=payload, method='post')
async def set_my_description(token, description=None, language_code=None):
method_url = r'setMyDescription'
payload = {}
if description is not None:
payload['description'] = description
if language_code is not None:
payload['language_code'] = language_code
return await _process_request(token, method_url, params=payload, method='post')
async def get_my_description(token, language_code=None):
method_url = r'getMyDescription'
payload = {}
if language_code:
payload['language_code'] = language_code
return await _process_request(token, method_url, params=payload)
async def set_my_short_description(token, short_description=None, language_code=None):
method_url = r'setMyShortDescription'
payload = {}
if short_description is not None:
payload['short_description'] = short_description
if language_code is not None:
payload['language_code'] = language_code
return await _process_request(token, method_url, params=payload, method='post')
async def get_my_short_description(token, language_code=None):
method_url = r'getMyShortDescription'
payload = {}
if language_code:
payload['language_code'] = language_code
return await _process_request(token, method_url, params=payload)
async def get_my_commands(token, scope=None, language_code=None):
method_url = r'getMyCommands'
@ -1155,6 +1183,23 @@ async def get_my_commands(token, scope=None, language_code=None):
payload['language_code'] = language_code
return await _process_request(token, method_url, params=payload)
async def set_my_name(token, name=None, language_code=None):
method_url = r'setMyName'
payload = {}
if name is not None:
payload['name'] = name
if language_code is not None:
payload['language_code'] = language_code
return await _process_request(token, method_url, params=payload, method='post')
async def get_my_name(token, language_code=None):
method_url = r'getMyName'
payload = {}
if language_code is not None:
payload['language_code'] = language_code
return await _process_request(token, method_url, params=payload)
async def set_chat_menu_button(token, chat_id=None, menu_button=None):
method_url = r'setChatMenuButton'
payload = {}
@ -1407,8 +1452,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,
message_thread_id=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)
@ -1440,7 +1485,8 @@ async def send_invoice(
:param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest units of the currency.
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
:param protect_content:
:param protect_content: Protects the contents of the sent message from forwarding and saving
:param message_thread_id: Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
:return:
"""
method_url = r'sendInvoice'
@ -1558,7 +1604,7 @@ async def answer_callback_query(token, callback_query_id, text=None, show_alert=
async def answer_inline_query(token, inline_query_id, results, cache_time=None, is_personal=None, next_offset=None,
switch_pm_text=None, switch_pm_parameter=None):
button=None):
method_url = 'answerInlineQuery'
payload = {'inline_query_id': inline_query_id, 'results': await _convert_list_json_serializable(results)}
if cache_time is not None:
@ -1567,10 +1613,10 @@ async def answer_inline_query(token, inline_query_id, results, cache_time=None,
payload['is_personal'] = is_personal
if next_offset is not None:
payload['next_offset'] = next_offset
if switch_pm_text:
payload['switch_pm_text'] = switch_pm_text
if switch_pm_parameter:
payload['switch_pm_parameter'] = switch_pm_parameter
if button is not None:
payload["button"] = button.to_json()
return await _process_request(token, method_url, params=payload, method='post')
@ -1580,62 +1626,85 @@ async def get_sticker_set(token, name):
async def get_custom_emoji_stickers(token, custom_emoji_ids):
method_url = r'getCustomEmojiStickers'
return await _process_request(token, method_url, params={'custom_emoji_ids': custom_emoji_ids})
return await _process_request(token, method_url, params={'custom_emoji_ids': json.dumps(custom_emoji_ids)})
async def upload_sticker_file(token, user_id, png_sticker):
async def set_sticker_keywords(token, sticker, keywords=None):
method_url = 'setStickerKeywords'
payload = {'sticker': sticker}
if keywords:
payload['keywords'] = json.dumps(keywords)
return await _process_request(token, method_url, params=payload, method='post')
async def set_sticker_mask_position(token, sticker, mask_position=None):
method_url = 'setStickerMaskPosition'
payload = {'sticker': sticker}
if mask_position:
payload['mask_position'] = mask_position.to_json()
return await _process_request(token, method_url, params=payload, method='post')
async def upload_sticker_file(token, user_id, sticker, sticker_format):
method_url = 'uploadStickerFile'
payload = {'user_id': user_id}
files = {'png_sticker': png_sticker}
payload = {'user_id': user_id, 'sticker_format': sticker_format}
files = {'sticker': sticker}
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def set_sticker_emoji_list(token, sticker, emoji_list):
method_url = 'setStickerEmojiList'
payload = {'sticker': sticker, 'emoji_list': json.dumps(emoji_list)}
return await _process_request(token, method_url, params=payload, method='post')
async def delete_sticker_set(token, name):
method_url = 'deleteStickerSet'
payload = {'name': name}
return await _process_request(token, method_url, params=payload, method='post')
async def set_custom_emoji_sticker_set_thumbnail(token, name, custom_emoji_id=None):
method_url = 'setCustomEmojiStickerSetThumbnail'
payload = {'name': name}
if custom_emoji_id is not None:
payload['custom_emoji_id'] = custom_emoji_id
return await _process_request(token, method_url, params=payload, method='post')
async def set_sticker_set_title(token, name, title):
method_url = 'setStickerSetTitle'
payload = {'name': name, 'title': title}
return await _process_request(token, method_url, params=payload, method='post')
async def create_new_sticker_set(
token, user_id, name, title, emojis, png_sticker, tgs_sticker,
mask_position=None, webm_sticker=None, sticker_type=None):
token, user_id, name, title, stickers, sticker_format, sticker_type=None, needs_repainting=None):
method_url = 'createNewStickerSet'
payload = {'user_id': user_id, 'name': name, 'title': title, 'emojis': emojis}
if png_sticker:
stype = 'png_sticker'
elif webm_sticker:
stype = 'webm_sticker'
else:
stype = 'tgs_sticker'
sticker = png_sticker or tgs_sticker or webm_sticker
files = None
if not util.is_string(sticker):
files = {stype: sticker}
else:
payload[stype] = sticker
if mask_position:
payload['mask_position'] = mask_position.to_json()
if webm_sticker:
payload['webm_sticker'] = webm_sticker
payload = {'user_id': user_id, 'name': name, 'title': title, 'sticker_format': sticker_format}
if sticker_type:
payload['sticker_type'] = sticker_type
if needs_repainting:
payload['needs_repainting'] = needs_repainting
files = {}
lst = []
for sticker in stickers:
json_dict, file = sticker.convert_input_sticker()
json_dict = sticker.to_dict()
if file:
list_keys = list(file.keys())
files[list_keys[0]] = file[list_keys[0]]
lst.append(json_dict)
payload['stickers'] = json.dumps(lst)
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def add_sticker_to_set(token, user_id, name, emojis, png_sticker, tgs_sticker, mask_position, webm_sticker):
async def add_sticker_to_set(token, user_id, name, sticker):
method_url = 'addStickerToSet'
payload = {'user_id': user_id, 'name': name, 'emojis': emojis}
if png_sticker:
stype = 'png_sticker'
elif webm_sticker:
stype = 'webm_sticker'
else:
stype = 'tgs_sticker'
files = None
sticker = png_sticker or tgs_sticker or webm_sticker
json_dict, files = sticker.convert_input_sticker()
payload = {'user_id': user_id, 'name': name, 'sticker': json_dict}
if not util.is_string(sticker):
files = {stype: sticker}
else:
payload[stype] = sticker
if mask_position:
payload['mask_position'] = mask_position.to_json()
if webm_sticker:
payload['webm_sticker'] = webm_sticker
return await _process_request(token, method_url, params=payload, files=files, method='post')
@ -1757,9 +1826,13 @@ async def create_forum_topic(token, chat_id, name, icon_color=None, icon_custom_
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, icon_custom_emoji_id):
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, 'name': name, 'icon_custom_emoji_id': icon_custom_emoji_id}
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):
@ -1786,6 +1859,31 @@ 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):
ret = ''
for r in results:
@ -1876,10 +1974,10 @@ class ApiHTTPException(ApiException):
This class represents an Exception thrown when a call to the
Telegram API server returns HTTP code that is not 200.
"""
def __init__(self, function_name, result):
def __init__(self, function_name, result: aiohttp.ClientResponse):
super(ApiHTTPException, self).__init__(
"The server returned HTTP {0} {1}. Response body:\n[{2}]" \
.format(result.status_code, result.reason, result),
.format(result.status, result.reason, result.request_info),
function_name,
result)

View File

@ -28,7 +28,7 @@ class StatePickleStorage(StateStorageBase):
"""
Create directory .save-handlers.
"""
dirs = self.file_path.rsplit('/', maxsplit=1)[0]
dirs, filename = os.path.split(self.file_path)
os.makedirs(dirs, exist_ok=True)
if not os.path.isfile(self.file_path):
with open(self.file_path,'wb') as file:

View File

@ -1,10 +1,11 @@
from telebot.asyncio_storage.base_storage import StateStorageBase, StateContext
import json
redis_installed = True
is_actual_aioredis = False
try:
import aioredis
is_actual_aioredis = True
except ImportError:
try:
from redis import asyncio as aioredis
@ -23,10 +24,10 @@ class StateRedisStorage(StateStorageBase):
if not redis_installed:
raise ImportError('AioRedis is not installed. Install it via "pip install aioredis"')
aioredis_version = tuple(map(int, aioredis.__version__.split(".")[0]))
if aioredis_version < (2,):
raise ImportError('Invalid aioredis version. Aioredis version should be >= 2.0.0')
if is_actual_aioredis:
aioredis_version = tuple(map(int, aioredis.__version__.split(".")[0]))
if aioredis_version < (2,):
raise ImportError('Invalid aioredis version. Aioredis version should be >= 2.0.0')
self.redis = aioredis.Redis(host=host, port=port, db=db, password=password)
self.prefix = prefix
@ -170,6 +171,6 @@ class StateRedisStorage(StateStorageBase):
user_id = str(user_id)
if response:
if user_id in response:
response[user_id]['data'] = dict(data, **response[user_id]['data'])
response[user_id]['data'] = data
await self.set_record(chat_id, response)
return True

View File

@ -25,7 +25,8 @@ 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,

View File

@ -18,8 +18,14 @@ def restart_file():
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
os.execl(python, python, *sys.argv)
if os.name == 'nt':
os.execv(sys.executable, ['python'] + sys.argv)
else:
os.execl(python, python, *sys.argv)

View File

@ -21,7 +21,8 @@ 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,

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

@ -185,13 +185,20 @@ class StatesGroup:
my_state = State() # returns my_state:State string.
"""
def __init_subclass__(cls) -> None:
state_list = []
for name, value in cls.__dict__.items():
if not name.startswith('__') and not callable(value) and isinstance(value, State):
# change value of that variable
value.name = ':'.join((cls.__name__, name))
value.group = cls
state_list.append(value)
cls._state_list = state_list
@property
def state_list(self):
return self._state_list
class BaseMiddleware:
"""
Base class for middleware.

84
telebot/service_utils.py Normal file
View File

@ -0,0 +1,84 @@
import random
import string
from io import BytesIO
try:
# noinspection PyPackageRequirements
from PIL import Image
pil_imported = True
except ImportError:
pil_imported = False
def is_string(var) -> bool:
"""
Returns True if the given object is a string.
"""
return isinstance(var, str)
def is_dict(var) -> bool:
"""
Returns True if the given object is a dictionary.
:param var: object to be checked
:type var: :obj:`object`
:return: True if the given object is a dictionary.
:rtype: :obj:`bool`
"""
return isinstance(var, dict)
def is_bytes(var) -> bool:
"""
Returns True if the given object is a bytes object.
:param var: object to be checked
:type var: :obj:`object`
:return: True if the given object is a bytes object.
:rtype: :obj:`bool`
"""
return isinstance(var, bytes)
def is_pil_image(var) -> bool:
"""
Returns True if the given object is a PIL.Image.Image object.
:param var: object to be checked
:type var: :obj:`object`
:return: True if the given object is a PIL.Image.Image object.
:rtype: :obj:`bool`
"""
return pil_imported and isinstance(var, Image.Image)
def pil_image_to_file(image, extension='JPEG', quality='web_low'):
if pil_imported:
photoBuffer = BytesIO()
image.convert('RGB').save(photoBuffer, extension, quality=quality)
photoBuffer.seek(0)
return photoBuffer
else:
raise RuntimeError('PIL module is not imported')
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
# https://stackoverflow.com/a/312464/9935473
for i in range(0, len(lst), n):
yield lst[i:i + n]
def generate_random_token() -> str:
"""
Generates a random token consisting of letters and digits, 16 characters long.
:return: a random token
:rtype: :obj:`str`
"""
return ''.join(random.sample(string.ascii_letters, 16))

View File

@ -34,7 +34,7 @@ class StatePickleStorage(StateStorageBase):
"""
Create directory .save-handlers.
"""
dirs = self.file_path.rsplit('/', maxsplit=1)[0]
dirs, filename = os.path.split(self.file_path)
os.makedirs(dirs, exist_ok=True)
if not os.path.isfile(self.file_path):
with open(self.file_path,'wb') as file:

View File

@ -174,7 +174,7 @@ class StateRedisStorage(StateStorageBase):
user_id = str(user_id)
if response:
if user_id in response:
response[user_id]['data'] = dict(data, **response[user_id]['data'])
response[user_id]['data'] = data
self.set_record(chat_id, response)
return True

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
import random
import re
import string
import threading
import traceback
from typing import Any, Callable, List, Dict, Optional, Union
@ -14,21 +12,13 @@ import queue as Queue
import logging
from telebot import types
from telebot.service_utils import is_pil_image, is_dict, is_string, is_bytes, chunks, generate_random_token, pil_image_to_file
try:
import ujson as json
except ImportError:
import json
try:
# noinspection PyPackageRequirements
from PIL import Image
from io import BytesIO
pil_imported = True
except:
pil_imported = False
MAX_MESSAGE_LENGTH = 4096
logger = logging.getLogger('TeleBot')
@ -44,11 +34,11 @@ content_type_media = [
#: Contains all service content types such as `User joined the group`.
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', 'forum_topic_created', 'forum_topic_closed',
'forum_topic_reopened',
'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', 'forum_topic_created',
'forum_topic_closed', 'forum_topic_reopened', 'user_shared', 'chat_shared',
]
#: All update types, should be used for allowed_updates parameter in polling.
@ -129,6 +119,7 @@ class ThreadPool:
"""
:meta private:
"""
def __init__(self, telebot, num_threads=2):
self.telebot = telebot
self.tasks = Queue.Queue()
@ -162,13 +153,15 @@ class ThreadPool:
for worker in self.workers:
worker.stop()
for worker in self.workers:
worker.join()
if worker != threading.current_thread():
worker.join()
class AsyncTask:
"""
:meta private:
"""
def __init__(self, target, *args, **kwargs):
self.target = target
self.args = args
@ -198,7 +191,8 @@ class CustomRequestResponse():
"""
:meta private:
"""
def __init__(self, json_text, status_code = 200, reason = ""):
def __init__(self, json_text, status_code=200, reason=""):
self.status_code = status_code
self.text = json_text
self.reason = reason
@ -211,6 +205,7 @@ def async_dec():
"""
:meta private:
"""
def decorator(fn):
def wrapper(*args, **kwargs):
return AsyncTask(fn, *args, **kwargs)
@ -220,63 +215,6 @@ def async_dec():
return decorator
def is_string(var) -> bool:
"""
Returns True if the given object is a string.
"""
return isinstance(var, str)
def is_dict(var) -> bool:
"""
Returns True if the given object is a dictionary.
:param var: object to be checked
:type var: :obj:`object`
:return: True if the given object is a dictionary.
:rtype: :obj:`bool`
"""
return isinstance(var, dict)
def is_bytes(var) -> bool:
"""
Returns True if the given object is a bytes object.
:param var: object to be checked
:type var: :obj:`object`
:return: True if the given object is a bytes object.
:rtype: :obj:`bool`
"""
return isinstance(var, bytes)
def is_pil_image(var) -> bool:
"""
Returns True if the given object is a PIL.Image.Image object.
:param var: object to be checked
:type var: :obj:`object`
:return: True if the given object is a PIL.Image.Image object.
:rtype: :obj:`bool`
"""
return pil_imported and isinstance(var, Image.Image)
def pil_image_to_file(image, extension='JPEG', quality='web_low'):
if pil_imported:
photoBuffer = BytesIO()
image.convert('RGB').save(photoBuffer, extension, quality=quality)
photoBuffer.seek(0)
return photoBuffer
else:
raise RuntimeError('PIL module is not imported')
def is_command(text: str) -> bool:
r"""
Checks if `text` is a command. Telegram chat commands start with the '/' character.
@ -335,6 +273,39 @@ def extract_arguments(text: str) -> str or None:
result = regexp.match(text)
return result.group(2) if is_command(text) else None
def extract_entity(text: str, e: types.MessageEntity) -> str:
"""
Returns the content of the entity.
:param text: The text of the message the entity belongs to
:type text: :obj:`str`
:param e: The entity to extract
:type e: :obj:`MessageEntity`
:return: The content of the entity
:rtype: :obj:`str`
"""
offset = 0
start = 0
encoded_text = text.encode()
end = len(encoded_text)
i = 0
for byte in encoded_text:
if (byte & 0xc0) != 0x80:
if offset == e.offset:
start = i
elif offset - e.offset == e.length:
end = i
break
if byte >= 0xf0:
offset += 2
else:
offset += 1
i += 1
return encoded_text[start:end].decode()
def split_string(text: str, chars_per_string: int) -> List[str]:
"""
@ -353,7 +324,7 @@ def split_string(text: str, chars_per_string: int) -> List[str]:
return [text[i:i + chars_per_string] for i in range(0, len(text), chars_per_string)]
def smart_split(text: str, chars_per_string: int=MAX_MESSAGE_LENGTH) -> List[str]:
def smart_split(text: str, chars_per_string: int = MAX_MESSAGE_LENGTH) -> List[str]:
r"""
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.
@ -383,9 +354,12 @@ def smart_split(text: str, chars_per_string: int=MAX_MESSAGE_LENGTH) -> List[str
part = text[:chars_per_string]
if "\n" in part: part = _text_before_last("\n")
elif ". " in part: part = _text_before_last(". ")
elif " " in part: part = _text_before_last(" ")
if "\n" in part:
part = _text_before_last("\n")
elif ". " in part:
part = _text_before_last(". ")
elif " " in part:
part = _text_before_last(" ")
parts.append(part)
text = text[len(part):]
@ -399,11 +373,14 @@ 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
def user_link(user: types.User, include_id: bool=False) -> str:
def user_link(user: types.User, include_id: bool = False) -> str:
"""
Returns an HTML user link. This is useful for reports.
Attention: Don't forget to set parse_mode to 'HTML'!
@ -430,10 +407,10 @@ def user_link(user: types.User, include_id: bool=False) -> str:
"""
name = escape(user.first_name)
return (f"<a href='tg://user?id={user.id}'>{name}</a>"
+ (f" (<pre>{user.id}</pre>)" if include_id else ""))
+ (f" (<pre>{user.id}</pre>)" if include_id else ""))
def quick_markup(values: Dict[str, Dict[str, Any]], row_width: int=2) -> types.InlineKeyboardMarkup:
def quick_markup(values: Dict[str, Dict[str, Any]], row_width: int = 2) -> types.InlineKeyboardMarkup:
"""
Returns a reply markup from a dict in this format: {'text': kwargs}
This is useful to avoid always typing 'btn1 = InlineKeyboardButton(...)' 'btn2 = InlineKeyboardButton(...)'
@ -443,11 +420,13 @@ def quick_markup(values: Dict[str, Dict[str, Any]], row_width: int=2) -> types.I
.. code-block:: python3
:caption: Using quick_markup:
quick_markup({
from telebot.util import quick_markup
markup = quick_markup({
'Twitter': {'url': 'https://twitter.com'},
'Facebook': {'url': 'https://facebook.com'},
'Back': {'callback_data': 'whatever'}
}, row_width=2):
}, row_width=2)
# returns an InlineKeyboardMarkup with two buttons in a row, one leading to Twitter, the other to facebook
# and a back button below
@ -466,7 +445,7 @@ def quick_markup(values: Dict[str, Dict[str, Any]], row_width: int=2) -> types.I
:param values: a dict containing all buttons to create in this format: {text: kwargs} {str:}
:type values: :obj:`dict`
:param row_width: int row width
:param row_width: number of :class:`telebot.types.InlineKeyboardButton` objects on each row
:type row_width: :obj:`int`
:return: InlineKeyboardMarkup
@ -548,24 +527,7 @@ def per_thread(key, construct_value, reset=False):
return getattr(thread_local, key)
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
# https://stackoverflow.com/a/312464/9935473
for i in range(0, len(lst), n):
yield lst[i:i + n]
def generate_random_token() -> str:
"""
Generates a random token consisting of letters and digits, 16 characters long.
:return: a random token
:rtype: :obj:`str`
"""
return ''.join(random.sample(string.ascii_letters, 16))
def deprecated(warn: bool=True, alternative: Optional[Callable]=None, deprecation_text=None):
def deprecated(warn: bool = True, alternative: Optional[Callable] = None, deprecation_text=None):
"""
Use this decorator to mark functions as deprecated.
When the function is used, an info (or warning if `warn` is True) is logged.
@ -583,6 +545,7 @@ def deprecated(warn: bool=True, alternative: Optional[Callable]=None, deprecatio
:return: The decorated function
"""
def decorator(function):
def wrapper(*args, **kwargs):
info = f"`{function.__name__}` is deprecated."
@ -595,7 +558,9 @@ def deprecated(warn: bool=True, alternative: Optional[Callable]=None, deprecatio
else:
logger.warning(info)
return function(*args, **kwargs)
return wrapper
return decorator
@ -625,7 +590,7 @@ def webhook_google_functions(bot, request):
return 'Bot ON'
def antiflood(function: Callable, *args, **kwargs):
def antiflood(function: Callable, *args, number_retries=5, **kwargs):
"""
Use this function inside loops in order to avoid getting TooManyRequests error.
Example:
@ -639,6 +604,9 @@ def antiflood(function: Callable, *args, **kwargs):
:param function: The function to call
:type function: :obj:`Callable`
:param number_retries: Number of retries to send
:type function: :obj:int
:param args: The arguments to pass to the function
:type args: :obj:`tuple`
@ -650,16 +618,18 @@ def antiflood(function: Callable, *args, **kwargs):
from telebot.apihelper import ApiTelegramException
from time import sleep
try:
return function(*args, **kwargs)
except ApiTelegramException as ex:
if ex.error_code == 429:
sleep(ex.result_json['parameters']['retry_after'])
for _ in range(number_retries - 1):
try:
return function(*args, **kwargs)
else:
raise
except ApiTelegramException as ex:
if ex.error_code == 429:
sleep(ex.result_json['parameters']['retry_after'])
else:
raise
else:
return function(*args, **kwargs)
def parse_web_app_data(token: str, raw_init_data: str):
"""
Parses web app data.
@ -712,4 +682,16 @@ def validate_web_app_data(token: str, raw_init_data: str):
return hmac.new(secret_key.digest(), data_check_string.encode(), sha256).hexdigest() == init_data_hash
__all__ = (
"content_type_media", "content_type_service", "update_types",
"WorkerThread", "AsyncTask", "CustomRequestResponse",
"async_dec", "deprecated",
"is_bytes", "is_string", "is_dict", "is_pil_image",
"chunks", "generate_random_token", "pil_image_to_file",
"is_command", "extract_command", "extract_arguments",
"split_string", "smart_split", "escape", "user_link", "quick_markup",
"antiflood", "parse_web_app_data", "validate_web_app_data",
"or_set", "or_clear", "orify", "OrEvent", "per_thread",
"webhook_google_functions"
)

View File

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

View File

@ -470,6 +470,53 @@ class TestTeleBot:
for i in range(0,200):
util.antiflood(tb.send_message, CHAT_ID, text)
assert i == 199
def test_extract_entity(self):
entities_map = {"https://core.telegram.org/api/entities": "https://core.telegram.org/api/entities",
"https://github.com/eternnoir/pyTelegramBotAPI": "https://github.com/eternnoir/pyTelegramBotAPI",
"*粗 bold text体*": "粗 bold text体",
"_斜体 italic text_": "斜体 italic text",
"[谷歌](http://www.google.com/)": "谷歌",
'`std::cout<<"test"<<std::endl;`': 'std::cout<<"test"<<std::endl;',
'''```rust
let number = loop {
println!("Pick a pattern from 0-2:");
stdin.read_line(&mut option).unwrap();
match option.lines().next().unwrap().parse::<usize>() {
Ok(number @ 0..=2) => break number,
_ => {
println!("invalid input!");
option = String::new();
continue;
}
};
};```''': '''let number = loop {
println!("Pick a pattern from 0-2:");
stdin.read_line(&mut option).unwrap();
match option.lines().next().unwrap().parse::<usize>() {
Ok(number @ 0..=2) => break number,
_ => {
println!("invalid input!");
option = String::new();
continue;
}
};
};''',
"@username": "@username",
"#hashtag索引标签": "#hashtag索引标签",
"do-not-reply@telegram.org": "do-not-reply@telegram.org",
"+12125550123": "+12125550123"}
entites = list(entities_map.keys())
contents = list(entities_map.values())
contents.sort()
text = '\n'.join(entites)
bot = telebot.TeleBot(TOKEN)
message = bot.send_message(CHAT_ID, text, parse_mode="Markdown")
extracted_contents = [util.extract_entity(
message.text, e) for e in message.entities]
extracted_contents.sort()
assert contents == extracted_contents
@staticmethod
def create_text_message(text):

View File

@ -67,9 +67,9 @@ def test_json_GroupChat():
def test_json_Document():
json_string = r'{"file_name":"Text File","thumb":{},"file_id":"BQADBQADMwIAAsYifgZ_CEh0u682xwI","file_unique_id": "AgADJQEAAqfhOEY","file_size":446}'
json_string = r'{"file_name":"Text File","thumbnail":{},"file_id":"BQADBQADMwIAAsYifgZ_CEh0u682xwI","file_unique_id": "AgADJQEAAqfhOEY","file_size":446}'
doc = types.Document.de_json(json_string)
assert doc.thumb is None
assert doc.thumbnail is None
assert doc.file_name == 'Text File'
@ -83,23 +83,23 @@ def test_json_Message_Audio():
def test_json_Message_Sticker():
json_string = r'{"message_id": 21552, "from": {"id": 590740002, "is_bot": false, "first_name": "⚜️ Ƥυrуα ⚜️", "username": "Purya", "language_code": "en"}, "chat": {"id": -1001309982000, "title": "123", "type": "supergroup"}, "date": 1594068909, "sticker": {"type": "regular", "width": 368, "height": 368, "emoji": "🤖", "set_name": "ipuryapack", "is_animated": false, "is_video": true, "thumb": {"file_id": "AAMCBAADHQJOFL7mAAJUMF8Dj62hpmDhpRAYvkc8CtIqipolAAJ8AAPA-8cF9yxjgjkLS97A0D4iXQARtQAHbQADHy4AAhoE", "file_unique_id": "AQADwNA-Il0AAx8uAAI", "file_size": 7776, "width": 60, "height": 60}, "file_id": "CAACAgQAAx0CThS-5gACVDBfA4-toaZg4aUQGL5HWerSKoqaJQACArADwPvHBfcsY4I5C3feGgQ", "file_unique_id": "AgADfAADsPvHWQ", "file_size": 14602}}'
json_string = r'{"message_id": 21552, "from": {"id": 590740002, "is_bot": false, "first_name": "⚜️ Ƥυrуα ⚜️", "username": "Purya", "language_code": "en"}, "chat": {"id": -1001309982000, "title": "123", "type": "supergroup"}, "date": 1594068909, "sticker": {"type": "regular", "width": 368, "height": 368, "emoji": "🤖", "set_name": "ipuryapack", "is_animated": false, "is_video": true, "thumbnail": {"file_id": "AAMCBAADHQJOFL7mAAJUMF8Dj62hpmDhpRAYvkc8CtIqipolAAJ8AAPA-8cF9yxjgjkLS97A0D4iXQARtQAHbQADHy4AAhoE", "file_unique_id": "AQADwNA-Il0AAx8uAAI", "file_size": 7776, "width": 60, "height": 60}, "file_id": "CAACAgQAAx0CThS-5gACVDBfA4-toaZg4aUQGL5HWerSKoqaJQACArADwPvHBfcsY4I5C3feGgQ", "file_unique_id": "AgADfAADsPvHWQ", "file_size": 14602}}'
msg = types.Message.de_json(json_string)
assert msg.sticker.height == 368
assert msg.sticker.thumb.height == 60
assert msg.sticker.thumbnail.height == 60
assert msg.content_type == 'sticker'
def test_json_Message_Sticker_without_thumb():
def test_json_Message_Sticker_without_thumbnail():
json_string = r'{"message_id": 21552, "from": {"id": 590740002, "is_bot": false, "first_name": "⚜️ Ƥυrуα ⚜️", "username": "Purya", "language_code": "en"}, "chat": {"id": -1001309982000, "title": "123", "type": "supergroup"}, "date": 1594068909, "sticker": {"type": "regular", "width": 368, "height": 368, "emoji": "🤖", "set_name": "ipuryapack", "is_animated": false, "is_video": true, "file_id": "CAACAgQAAx0CThS-5gACVDBfA4-toaZg4aUQGL5HWerSKoqaJQACArADwPvHBfcsY4I5C3feGgQ", "file_unique_id": "AgADfAADsPvHWQ", "file_size": 14602}}'
msg = types.Message.de_json(json_string)
assert msg.sticker.height == 368
assert msg.sticker.thumb is None
assert msg.sticker.thumbnail is None
assert msg.content_type == 'sticker'
def test_json_Message_Document():
json_string = r'{"message_id":97,"from":{"id":10734,"first_name":"Fd","last_name":"Wd","username":"dd","is_bot":true },"chat":{"id":10,"first_name":"Fd","type":"private","last_name":"Wd","username":"dd"},"date":1435478744,"document":{"file_name":"Text File","thumb":{},"file_id":"BQADBQADMwIAAsYifgZ_CEh0u682xwI","file_unique_id": "AQAD_QIfa3QAAyA4BgAB","file_size":446}}'
json_string = r'{"message_id":97,"from":{"id":10734,"first_name":"Fd","last_name":"Wd","username":"dd","is_bot":true },"chat":{"id":10,"first_name":"Fd","type":"private","last_name":"Wd","username":"dd"},"date":1435478744,"document":{"file_name":"Text File","thumbnail":{},"file_id":"BQADBQADMwIAAsYifgZ_CEh0u682xwI","file_unique_id": "AQAD_QIfa3QAAyA4BgAB","file_size":446}}'
msg = types.Message.de_json(json_string)
assert msg.document.file_name == 'Text File'
assert msg.content_type == 'document'
@ -113,11 +113,11 @@ def test_json_Message_Photo():
def test_json_Message_Video():
json_string = r'{"message_id":101,"from":{"id":109734,"first_name":"dd","last_name":"dd","username":"dd","is_bot":true },"chat":{"id":109734,"first_name":"dd","type":"private","last_name":"dd","username":"dd"},"date":1435481960,"video":{"duration":3,"caption":"","width":360,"height":640,"thumb":{"file_id":"AAQFABPiYnBjkDwMAAIC","file_unique_id": "AQADTeisa3QAAz1nAAI","file_size":1597,"width":50,"height":90},"file_id":"BAADBQADNifgb_TOPEKErGoQI","file_unique_id": "AgADbgEAAn8VSFY","file_size":260699}}'
json_string = r'{"message_id":101,"from":{"id":109734,"first_name":"dd","last_name":"dd","username":"dd","is_bot":true },"chat":{"id":109734,"first_name":"dd","type":"private","last_name":"dd","username":"dd"},"date":1435481960,"video":{"duration":3,"caption":"","width":360,"height":640,"thumbnail":{"file_id":"AAQFABPiYnBjkDwMAAIC","file_unique_id": "AQADTeisa3QAAz1nAAI","file_size":1597,"width":50,"height":90},"file_id":"BAADBQADNifgb_TOPEKErGoQI","file_unique_id": "AgADbgEAAn8VSFY","file_size":260699}}'
msg = types.Message.de_json(json_string)
assert msg.video
assert msg.video.duration == 3
assert msg.video.thumb.width == 50
assert msg.video.thumbnail.width == 50
assert msg.content_type == 'video'
@ -271,5 +271,33 @@ def test_sent_web_app_message():
assert sent_web_app_message.inline_message_id == '29430'
def test_message_entity():
# TODO: Add support for nesting entities
sample_string_1 = r'{"update_id":934522126,"message":{"message_id":1374510,"from":{"id":927266710,"is_bot":false,"first_name":">_run","username":"coder2020","language_code":"en","is_premium":true},"chat":{"id":927266710,"first_name":">_run","username":"coder2020","type":"private"},"date":1682177590,"text":"b b b","entities":[{"offset":0,"length":2,"type":"bold"},{"offset":0,"length":1,"type":"italic"},{"offset":2,"length":2,"type":"bold"},{"offset":2,"length":1,"type":"italic"},{"offset":4,"length":1,"type":"bold"},{"offset":4,"length":1,"type":"italic"}]}}'
update = types.Update.de_json(sample_string_1)
message: types.Message = update.message
assert message.html_text == "<i><b>b </b></i><i><b>b </b></i><i><b>b</b></i>"
sample_string_2 = r'{"update_id":934522166,"message":{"message_id":1374526,"from":{"id":927266710,"is_bot":false,"first_name":">_run","username":"coder2020","language_code":"en","is_premium":true},"chat":{"id":927266710,"first_name":">_run","username":"coder2020","type":"private"},"date":1682179716,"text":"b b b","entities":[{"offset":0,"length":1,"type":"bold"},{"offset":2,"length":1,"type":"bold"},{"offset":4,"length":1,"type":"italic"}]}}'
message_2 = types.Update.de_json(sample_string_2).message
assert message_2.html_text == "<b>b</b> <b>b</b> <i>b</i>"
sample_string_3 = r'{"update_id":934522172,"message":{"message_id":1374530,"from":{"id":927266710,"is_bot":false,"first_name":">_run","username":"coder2020","language_code":"en","is_premium":true},"chat":{"id":927266710,"first_name":">_run","username":"coder2020","type":"private"},"date":1682179968,"text":"This is a bold text with a nested italic and bold text.","entities":[{"offset":10,"length":4,"type":"bold"},{"offset":27,"length":7,"type":"italic"},{"offset":34,"length":15,"type":"bold"},{"offset":34,"length":15,"type":"italic"}]}}'
message_3 = types.Update.de_json(sample_string_3).message
assert message_3.html_text == "This is a <b>bold</b> text with a <i>nested </i><i><b>italic and bold</b></i> text."
sample_string_4 = r'{"update_id":934522437,"message":{"message_id":1374619,"from":{"id":927266710,"is_bot":false,"first_name":">_run","username":"coder2020","language_code":"en","is_premium":true},"chat":{"id":927266710,"first_name":">_run","username":"coder2020","type":"private"},"date":1682189507,"forward_from":{"id":927266710,"is_bot":false,"first_name":">_run","username":"coder2020","language_code":"en","is_premium":true},"forward_date":1682189124,"text":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa😋😋","entities":[{"offset":0,"length":76,"type":"bold"},{"offset":0,"length":76,"type":"italic"},{"offset":0,"length":76,"type":"underline"},{"offset":0,"length":76,"type":"strikethrough"},{"offset":76,"length":2,"type":"custom_emoji","custom_emoji_id":"5456188142006575553"},{"offset":78,"length":2,"type":"custom_emoji","custom_emoji_id":"5456188142006575553"}]}}'
message_4 = types.Update.de_json(sample_string_4).message
assert message_4.html_text == '<s><u><i><b>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</b></i></u></s><tg-emoji emoji-id="5456188142006575553">😋</tg-emoji><tg-emoji emoji-id="5456188142006575553">😋</tg-emoji>'