mirror of
https://github.com/eternnoir/pyTelegramBotAPI.git
synced 2023-08-10 21:12:57 +03:00
Compare commits
61 Commits
Author | SHA1 | Date | |
---|---|---|---|
31c3b3b28e | |||
b95ab104e3 | |||
a54e4c22a8 | |||
7913e25be2 | |||
63cbda8890 | |||
38851bce22 | |||
74835c40ea | |||
97e99b4910 | |||
4ced4d29f5 | |||
239a90de14 | |||
c86af0496b | |||
4071ab9124 | |||
5c715dabc3 | |||
43d2d8583e | |||
cf78234e3a | |||
5f4cd09490 | |||
8534804c0c | |||
cf75e76e5c | |||
7d5e9e5111 | |||
1ceec3cb54 | |||
5f8c75816e | |||
4e37662ab3 | |||
a97a917522 | |||
88f91518c7 | |||
e89acc8ba6 | |||
5d611ea7f3 | |||
5c80f11261 | |||
f2202b44fe | |||
2da48c0adc | |||
389407e3ee | |||
14be2b8c18 | |||
df7808264f | |||
9d37503442 | |||
dd6f39c3cd | |||
8e4d70b9c6 | |||
87fb30d57b | |||
8f3371dcd5 | |||
ec8975c9e3 | |||
16edfbb9dc | |||
f70b135359 | |||
78fb69ded1 | |||
0f7eb1571e | |||
ac54b7abd4 | |||
0f3a6393fc | |||
de6f339cdf | |||
d0969bd5f3 | |||
4035a38507 | |||
944b077c65 | |||
644c6b9082 | |||
dc9f8db556 | |||
07ebdeab25 | |||
e8738cce7d | |||
d9e638a7df | |||
08b1dd31c8 | |||
b4f0a6d546 | |||
4eb28df1ab | |||
50e5e96bb1 | |||
bd3a9bc350 | |||
06923c8274 | |||
3efc2cf869 | |||
f5de0eeacf |
226
README.md
226
README.md
@ -10,7 +10,7 @@
|
||||
|
||||
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#june-25-2021">5.3</a>!
|
||||
|
||||
##Contents
|
||||
## Contents
|
||||
|
||||
* [Getting started.](#getting-started)
|
||||
* [Writing your first bot](#writing-your-first-bot)
|
||||
@ -21,12 +21,27 @@
|
||||
* [Methods](#methods)
|
||||
* [General use of the API](#general-use-of-the-api)
|
||||
* [Message handlers](#message-handlers)
|
||||
* [Edited Message handler](#edited-message-handler)
|
||||
* [Channel Post handler](#channel-post-handler)
|
||||
* [Edited Channel Post handler](#edited-channel-post-handler)
|
||||
* [Callback Query handlers](#callback-query-handler)
|
||||
* [Middleware handlers](#middleware-handler)
|
||||
* [Shipping Query Handler](#shipping-query-handler)
|
||||
* [Pre Checkout Query Handler](#pre-checkout-query-handler)
|
||||
* [Poll Handler](#poll-handler)
|
||||
* [Poll Answer Handler](#poll-answer-handler)
|
||||
* [My Chat Member Handler](#my-chat-member-handler)
|
||||
* [Chat Member Handler](#chat-member-handler)
|
||||
* [Inline Mode](#inline-mode)
|
||||
* [Inline handler](#inline-handler)
|
||||
* [Chosen Inline handler](#chosen-inline-handler)
|
||||
* [Answer Inline Query](#answer-inline-query)
|
||||
* [Additional API features](#additional-api-features)
|
||||
* [Middleware handlers](#middleware-handlers)
|
||||
* [Custom filters](#custom-filters)
|
||||
* [TeleBot](#telebot)
|
||||
* [Reply markup](#reply-markup)
|
||||
* [Inline Mode](#inline-mode)
|
||||
* [Advanced use of the API](#advanced-use-of-the-api)
|
||||
* [Using local Bot API Server](#using-local-bot-api-sever)
|
||||
* [Asynchronous delivery of messages](#asynchronous-delivery-of-messages)
|
||||
* [Sending large text messages](#sending-large-text-messages)
|
||||
* [Controlling the amount of Threads used by TeleBot](#controlling-the-amount-of-threads-used-by-telebot)
|
||||
@ -35,9 +50,7 @@
|
||||
* [Logging](#logging)
|
||||
* [Proxy](#proxy)
|
||||
* [API conformance](#api-conformance)
|
||||
* [Change log](#change-log)
|
||||
* [F.A.Q.](#faq)
|
||||
* [Bot 2.0](#bot-20)
|
||||
* [How can I distinguish a User and a GroupChat in message.chat?](#how-can-i-distinguish-a-user-and-a-groupchat-in-messagechat)
|
||||
* [How can I handle reocurring ConnectionResetErrors?](#how-can-i-handle-reocurring-connectionreseterrors)
|
||||
* [The Telegram Chat Group](#the-telegram-chat-group)
|
||||
@ -46,7 +59,7 @@
|
||||
|
||||
## Getting started.
|
||||
|
||||
This API is tested with Python Python 3.6-3.9 and Pypy 3.
|
||||
This API is tested with Python 3.6-3.9 and Pypy 3.
|
||||
There are two ways to install the library:
|
||||
|
||||
* Installation using pip (a Python package manager)*:
|
||||
@ -167,8 +180,9 @@ TeleBot supports the following filters:
|
||||
|content_types|list of strings (default `['text']`)|`True` if message.content_type is in the list of strings.|
|
||||
|regexp|a regular expression as a string|`True` if `re.search(regexp_arg)` returns `True` and `message.content_type == 'text'` (See [Python Regular Expressions](https://docs.python.org/2/library/re.html))|
|
||||
|commands|list of strings|`True` if `message.content_type == 'text'` and `message.text` starts with a command that is in the list of strings.|
|
||||
|chat_types|list of chat types|`True` if `message.chat.type` in your filter
|
||||
|func|a function (lambda or function reference)|`True` if the lambda or function reference returns `True`
|
||||
|
||||
|
||||
Here are some examples of using the filters and message handlers:
|
||||
|
||||
```python
|
||||
@ -212,15 +226,15 @@ def send_something(message):
|
||||
```
|
||||
**Important: all handlers are tested in the order in which they were declared**
|
||||
|
||||
#### Edited Message handlers
|
||||
#### Edited Message handler
|
||||
Handle edited messages
|
||||
`@bot.edited_message_handler(filters) # <- passes a Message type object to your function`
|
||||
|
||||
#### channel_post_handler
|
||||
#### Channel Post handler
|
||||
Handle channel post messages
|
||||
`@bot.channel_post_handler(filters) # <- passes a Message type object to your function`
|
||||
|
||||
#### edited_channel_post_handler
|
||||
#### Edited Channel Post handler
|
||||
Handle edited channel post messages
|
||||
`@bot.edited_channel_post_handler(filters) # <- passes a Message type object to your function`
|
||||
|
||||
@ -232,14 +246,6 @@ def test_callback(call): # <- passes a CallbackQuery type object to your functi
|
||||
logger.info(call)
|
||||
```
|
||||
|
||||
#### Inline Handler
|
||||
Handle inline queries
|
||||
`@bot.inline_handler() # <- passes a InlineQuery type object to your function`
|
||||
|
||||
#### Chosen Inline Handler
|
||||
Handle chosen inline results
|
||||
`@bot.chosen_inline_handler() # <- passes a ChosenInlineResult type object to your function`
|
||||
|
||||
#### Shipping Query Handler
|
||||
Handle shipping queries
|
||||
`@bot.shipping_query_handeler() # <- passes a ShippingQuery type object to your function`
|
||||
@ -265,8 +271,51 @@ Handle updates of a chat member's status in a chat
|
||||
`@bot.chat_member_handler() # <- passes a ChatMemberUpdated type object to your function`
|
||||
*Note: "chat_member" updates are not requested by default. If you want to allow all update types, set `allowed_updates` in `bot.polling()` / `bot.infinity_polling()` to `util.update_types`*
|
||||
|
||||
### Inline Mode
|
||||
|
||||
#### Middleware Handler
|
||||
More information about [Inline mode](https://core.telegram.org/bots/inline).
|
||||
|
||||
#### Inline handler
|
||||
|
||||
Now, you can use inline_handler to get inline queries in telebot.
|
||||
|
||||
```python
|
||||
|
||||
@bot.inline_handler(lambda query: query.query == 'text')
|
||||
def query_text(inline_query):
|
||||
# Query message is text
|
||||
```
|
||||
|
||||
#### Chosen Inline handler
|
||||
|
||||
Use chosen_inline_handler to get chosen_inline_result in telebot. Don't forgot add the /setinlinefeedback
|
||||
command for @Botfather.
|
||||
|
||||
More information : [collecting-feedback](https://core.telegram.org/bots/inline#collecting-feedback)
|
||||
|
||||
```python
|
||||
@bot.chosen_inline_handler(func=lambda chosen_inline_result: True)
|
||||
def test_chosen(chosen_inline_result):
|
||||
# Process all chosen_inline_result.
|
||||
```
|
||||
|
||||
#### Answer Inline Query
|
||||
|
||||
```python
|
||||
@bot.inline_handler(lambda query: query.query == 'text')
|
||||
def query_text(inline_query):
|
||||
try:
|
||||
r = types.InlineQueryResultArticle('1', 'Result', types.InputTextMessageContent('Result message.'))
|
||||
r2 = types.InlineQueryResultArticle('2', 'Result2', types.InputTextMessageContent('Result message2.'))
|
||||
bot.answer_inline_query(inline_query.id, [r, r2])
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
```
|
||||
|
||||
### Additional API features
|
||||
|
||||
#### Middleware Handlers
|
||||
|
||||
A middleware handler is a function that allows you to modify requests or the bot context as they pass through the
|
||||
Telegram to the bot. You can imagine middleware as a chain of logic connection handled before any other handlers are
|
||||
@ -286,6 +335,43 @@ def start(message):
|
||||
assert message.another_text == message.text + ':changed'
|
||||
```
|
||||
There are other examples using middleware handler in the [examples/middleware](examples/middleware) directory.
|
||||
|
||||
|
||||
#### Custom filters
|
||||
Also, you can use built-in custom filters. Or, you can create your own filter.
|
||||
|
||||
[Example of custom filter](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/custom_filters/general_custom_filters.py)
|
||||
|
||||
Also, we have examples on them. Check this links:
|
||||
|
||||
You can check some built-in filters in source [code](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/telebot/custom_filters.py)
|
||||
|
||||
Example of [filtering by id](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/custom_filters/id_filter_example.py)
|
||||
|
||||
Example of [filtering by text](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/custom_filters/text_filter_example.py)
|
||||
|
||||
If you want to add some built-in filter, you are welcome to add it in custom_filters.py file.
|
||||
|
||||
Here is example of creating filter-class:
|
||||
|
||||
```python
|
||||
class IsAdmin(telebot.custom_filters.SimpleCustomFilter):
|
||||
# Class will check whether the user is admin or creator in group or not
|
||||
key='is_admin'
|
||||
@staticmethod
|
||||
def check(message: telebot.types.Message):
|
||||
return bot.get_chat_member(message.chat.id,message.from_user.id).status in ['administrator','creator']
|
||||
|
||||
# To register filter, you need to use method add_custom_filter.
|
||||
bot.add_custom_filter(IsAdmin())
|
||||
|
||||
# Now, you can use it in handler.
|
||||
@bot.message_handler(is_admin=True)
|
||||
def admin_of_group(message):
|
||||
bot.send_message(message.chat.id, 'You are admin of this group'!)
|
||||
|
||||
```
|
||||
|
||||
|
||||
#### TeleBot
|
||||
```python
|
||||
@ -433,49 +519,8 @@ ForceReply:
|
||||
|
||||

|
||||
|
||||
### Inline Mode
|
||||
|
||||
More information about [Inline mode](https://core.telegram.org/bots/inline).
|
||||
|
||||
#### inline_handler
|
||||
|
||||
Now, you can use inline_handler to get inline queries in telebot.
|
||||
|
||||
```python
|
||||
|
||||
@bot.inline_handler(lambda query: query.query == 'text')
|
||||
def query_text(inline_query):
|
||||
# Query message is text
|
||||
```
|
||||
|
||||
|
||||
#### chosen_inline_handler
|
||||
|
||||
Use chosen_inline_handler to get chosen_inline_result in telebot. Don't forgot add the /setinlinefeedback
|
||||
command for @Botfather.
|
||||
|
||||
More information : [collecting-feedback](https://core.telegram.org/bots/inline#collecting-feedback)
|
||||
|
||||
```python
|
||||
@bot.chosen_inline_handler(func=lambda chosen_inline_result: True)
|
||||
def test_chosen(chosen_inline_result):
|
||||
# Process all chosen_inline_result.
|
||||
```
|
||||
|
||||
#### answer_inline_query
|
||||
|
||||
```python
|
||||
@bot.inline_handler(lambda query: query.query == 'text')
|
||||
def query_text(inline_query):
|
||||
try:
|
||||
r = types.InlineQueryResultArticle('1', 'Result', types.InputTextMessageContent('Result message.'))
|
||||
r2 = types.InlineQueryResultArticle('2', 'Result2', types.InputTextMessageContent('Result message2.'))
|
||||
bot.answer_inline_query(inline_query.id, [r, r2])
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
```
|
||||
### Working with entities:
|
||||
### Working with entities
|
||||
This object represents one special entity in a text message. For example, hashtags, usernames, URLs, etc.
|
||||
Attributes:
|
||||
* `type`
|
||||
@ -636,23 +681,8 @@ apihelper.proxy = {'https':'socks5://userproxy:password@proxy_address:port'}
|
||||
* ✔ [Bot API 2.0](https://core.telegram.org/bots/api-changelog#april-9-2016)
|
||||
|
||||
|
||||
## Change log
|
||||
|
||||
27.04.2020 - Poll and Dice are up to date.
|
||||
Python2 conformance is not checked any more due to EOL.
|
||||
|
||||
11.04.2020 - Refactoring. new_chat_member is out of support. Bugfix in html_text. Started Bot API conformance checking.
|
||||
|
||||
06.06.2019 - Added polls support (Poll). Added functions send_poll, stop_poll
|
||||
|
||||
## F.A.Q.
|
||||
|
||||
### Bot 2.0
|
||||
|
||||
April 9,2016 Telegram release new bot 2.0 API, which has a drastic revision especially for the change of method's interface.If you want to update to the latest version, please make sure you've switched bot's code to bot 2.0 method interface.
|
||||
|
||||
[More information about pyTelegramBotAPI support bot2.0](https://github.com/eternnoir/pyTelegramBotAPI/issues/130)
|
||||
|
||||
### How can I distinguish a User and a GroupChat in message.chat?
|
||||
Telegram Bot API support new type Chat for message.chat.
|
||||
|
||||
@ -682,7 +712,6 @@ Bot instances that were idle for a long time might be rejected by the server whe
|
||||
Get help. Discuss. Chat.
|
||||
|
||||
* Join the [pyTelegramBotAPI Telegram Chat Group](https://telegram.me/joinchat/Bn4ixj84FIZVkwhk2jag6A)
|
||||
* We now have a Telegram Channel as well! Keep yourself up to date with API changes, and [join it](https://telegram.me/pytelegrambotapi).
|
||||
|
||||
## More examples
|
||||
|
||||
@ -693,72 +722,43 @@ Get help. Discuss. Chat.
|
||||
## Bots using this API
|
||||
* [SiteAlert bot](https://telegram.me/SiteAlert_bot) ([source](https://github.com/ilteoood/SiteAlert-Python)) by *ilteoood* - Monitors websites and sends a notification on changes
|
||||
* [TelegramLoggingBot](https://github.com/aRandomStranger/TelegramLoggingBot) by *aRandomStranger*
|
||||
* [Send to Kindle Bot](https://telegram.me/Send2KindleBot) by *GabrielRF* - Send to Kindle files or links to files.
|
||||
* [Telegram LMGTFY_bot](https://github.com/GabrielRF/telegram-lmgtfy_bot) ([source](https://github.com/GabrielRF/telegram-lmgtfy_bot)) by *GabrielRF* - Let me Google that for you.
|
||||
* [Telegram UrlProBot](https://github.com/GabrielRF/telegram-urlprobot) ([source](https://github.com/GabrielRF/telegram-urlprobot)) by *GabrielRF* - URL shortener and URL expander.
|
||||
* [Telegram Proxy Bot](https://github.com/mrgigabyte/proxybot) by *mrgigabyte* - `Credits for the original version of this bot goes to` **Groosha** `, simply added certain features which I thought were needed`.
|
||||
* [Telegram LMGTFY_bot](https://github.com/GabrielRF/telegram-lmgtfy_bot) by *GabrielRF* - Let me Google that for you.
|
||||
* [Telegram Proxy Bot](https://github.com/mrgigabyte/proxybot) by *mrgigabyte*
|
||||
* [RadRetroRobot](https://github.com/Tronikart/RadRetroRobot) by *Tronikart* - Multifunctional Telegram Bot RadRetroRobot.
|
||||
* [League of Legends bot](https://telegram.me/League_of_Legends_bot) ([source](https://github.com/i32ropie/lol)) by *i32ropie*
|
||||
* [NeoBot](https://github.com/neoranger/NeoBot) by [@NeoRanger](https://github.com/neoranger)
|
||||
* [TagAlertBot](https://github.com/pitasi/TagAlertBot) by *pitasi*
|
||||
* [ColorCodeBot](https://t.me/colorcodebot) ([source](https://github.com/andydecleyre/colorcodebot)) - Share code snippets as beautifully syntax-highlighted HTML and/or images.
|
||||
* [ComedoresUGRbot](http://telegram.me/ComedoresUGRbot) ([source](https://github.com/alejandrocq/ComedoresUGRbot)) by [*alejandrocq*](https://github.com/alejandrocq) - Telegram bot to check the menu of Universidad de Granada dining hall.
|
||||
* [picpingbot](https://web.telegram.org/#/im?p=%40picpingbot) - Fun anonymous photo exchange by Boogie Muffin.
|
||||
* [TheZigZagProject](https://github.com/WebShark025/TheZigZagProject) - The 'All In One' bot for Telegram! by WebShark025
|
||||
* [proxybot](https://github.com/p-hash/proxybot) - Simple Proxy Bot for Telegram. by p-hash
|
||||
* [DonantesMalagaBot](https://github.com/vfranch/DonantesMalagaBot)- DonantesMalagaBot facilitates information to Malaga blood donors about the places where they can donate today or in the incoming days. It also records the date of the last donation so that it helps the donors to know when they can donate again. - by vfranch
|
||||
* [DonantesMalagaBot](https://github.com/vfranch/DonantesMalagaBot) - DonantesMalagaBot facilitates information to Malaga blood donors about the places where they can donate today or in the incoming days. It also records the date of the last donation so that it helps the donors to know when they can donate again. - by vfranch
|
||||
* [DuttyBot](https://github.com/DmytryiStriletskyi/DuttyBot) by *Dmytryi Striletskyi* - Timetable for one university in Kiev.
|
||||
* [dailypepebot](https://telegram.me/dailypepebot) by [*Jaime*](https://github.com/jiwidi/Dailypepe) - Get's you random pepe images and gives you their id, then you can call this image with the number.
|
||||
* [DailyQwertee](https://t.me/DailyQwertee) by [*Jaime*](https://github.com/jiwidi/DailyQwertee) - Bot that manages a channel that sends qwertee daily tshirts every day at 00:00
|
||||
* [wat-bridge](https://github.com/rmed/wat-bridge) by [*rmed*](https://github.com/rmed) - Send and receive messages to/from WhatsApp through Telegram
|
||||
* [flibusta_bot](https://github.com/Kurbezz/flibusta_bot) by [*Kurbezz*](https://github.com/Kurbezz)
|
||||
* [EmaProject](https://github.com/halkliff/emaproject) by [*halkliff*](https://github.com/halkliff) - Ema - Eastern Media Assistant was made thinking on the ease-to-use feature. Coding here is simple, as much as is fast and powerful.
|
||||
* [filmratingbot](http://t.me/filmratingbot)([source](https://github.com/jcolladosp/film-rating-bot)) by [*jcolladosp*](https://github.com/jcolladosp) - Telegram bot using the Python API that gets films rating from IMDb and metacritic
|
||||
* [you2mp3bot](http://t.me/you2mp3bot)([link](https://storebot.me/bot/you2mp3bot)) - This bot can convert a Youtube video to Mp3. All you need is send the URL video.
|
||||
* [Send2Kindlebot](http://t.me/Send2KindleBot) ([source](https://github.com/GabrielRF/Send2KindleBot)) by *GabrielRF* - Send to Kindle service.
|
||||
* [RastreioBot](http://t.me/RastreioBot) ([source](https://github.com/GabrielRF/RastreioBot)) by *GabrielRF* - Bot used to track packages on the Brazilian Mail Service.
|
||||
* [filex_bot](http://t.me/filex_bot)([link](https://github.com/victor141516/FileXbot-telegram))
|
||||
* [Spbu4UBot](http://t.me/Spbu4UBot)([link](https://github.com/EeOneDown/spbu4u)) by *EeOneDown* - Bot with timetables for SPbU students.
|
||||
* [SmartySBot](http://t.me/ZDU_bot)([link](https://github.com/0xVK/SmartySBot)) by *0xVK* - Telegram timetable bot, for Zhytomyr Ivan Franko State University students.
|
||||
* [yandex_music_bot](http://t.me/yandex_music_bot)- Downloads tracks/albums/public playlists from Yandex.Music streaming service for free.
|
||||
* [LearnIt](https://t.me/LearnItbot)([link](https://github.com/tiagonapoli/LearnIt)) - A Telegram Bot created to help people to memorize other languages’ vocabulary.
|
||||
* [MusicQuiz_bot](https://t.me/MusicQuiz_bot) by [Etoneja](https://github.com/Etoneja) - Listen to audio samples and try to name the performer of the song.
|
||||
* [Bot-Telegram-Shodan ](https://github.com/rubenleon/Bot-Telegram-Shodan) by [rubenleon](https://github.com/rubenleon)
|
||||
* [MandangoBot](https://t.me/MandangoBot) by @Alvaricias - Bot for managing Marvel Strike Force alliances (only in spanish, atm).
|
||||
* [ManjaroBot](https://t.me/ManjaroBot) by [@NeoRanger](https://github.com/neoranger) - Bot for Manjaro Linux Spanish group with a lot of info for Manjaro Newbies.
|
||||
* [VigoBusTelegramBot](https://t.me/vigobusbot) ([GitHub](https://github.com/Pythoneiro/VigoBus-TelegramBot)) - Bot that provides buses coming to a certain stop and their remaining time for the city of Vigo (Galicia - Spain)
|
||||
* [kaishnik-bot](https://t.me/kaishnik_bot) ([source](https://github.com/airatk/kaishnik-bot)) by *airatk* - bot which shows all the necessary information to KNTRU-KAI students.
|
||||
* [Creation Date](https://t.me/creationdatebot) by @karipov - interpolates account creation dates based on telegram given ID’s
|
||||
* [m0xbot](https://t.me/m0xbot) by [kor0p](https://github.com/kor0p) - tic-tac-toe.
|
||||
* [kboardbot](https://t.me/kboardbot) by [kor0p](https://github.com/kor0p) - inline switches keyboard layout (English, Hebrew, Ukrainian, Russian).
|
||||
* [Robbie](https://t.me/romdeliverybot) ([source](https://github.com/FacuM/romdeliverybot_support)) by @FacuM - Support Telegram bot for developers and maintainers.
|
||||
* [AsadovBot](https://t.me/asadov_bot) ([source](https://github.com/desexcile/BotApi)) by @DesExcile - Сatalog of poems by Eduard Asadov.
|
||||
* [thesaurus_com_bot](https://t.me/thesaurus_com_bot) ([source](https://github.com/LeoSvalov/words-i-learn-bot)) by @LeoSvalov - words and synonyms from [dictionary.com](https://www.dictionary.com) and [thesaurus.com](https://www.thesaurus.com) in the telegram.
|
||||
* [InfoBot](https://t.me/info2019_bot) ([source](https://github.com/irevenko/info-bot)) by @irevenko - An all-round bot that displays some statistics (weather, time, crypto etc...)
|
||||
* [FoodBot](https://t.me/ChensonUz_bot) ([source](https://github.com/Fliego/old_restaurant_telegram_chatbot)) by @Fliego - a simple bot for food ordering
|
||||
* [Sporty](https://t.me/SportydBot) ([source](https://github.com/0xnu/sporty)) by @0xnu - Telegram bot for displaying the latest news, sports schedules and injury updates.
|
||||
* [Neural style transfer](https://t.me/ebanyivolshebnikBot) ([source](https://github.com/timbyxty/StyleTransfer-tgbot)) by @timbyxty - bot for transferring style from one picture to another based on neural network.
|
||||
* [JoinGroup Silencer Bot](https://t.me/joingroup_silencer_bot) ([source](https://github.com/zeph1997/Telegram-Group-Silencer-Bot)) by [@zeph1997](https://github.com/zeph1997) - A Telegram Bot to remove "join group" and "removed from group" notifications.
|
||||
* [AdviceBook](https://t.me/adviceokbot) by [@barbax7](https://github.com/barbax7) - A Telegram Bot that allows you to receive random reading tips when you don't know which book to read.
|
||||
* [Blue_CC_Bot](https://t.me/Blue_CC_Bot) by [@Akash](https://github.com/BLUE-DEVIL1134) - A Telegram Bot Which Checks Your Given Credit Cards And Says Which Is A Real,Card And Which Is Fake.
|
||||
* [RandomInfoBot](https://t.me/RandomInfoBot) by [@Akash](https://github.com/BLUE-DEVIL1134) - A Telegram Bot Which Generates Random Information Of Humans Scraped From Over 13 Websites.
|
||||
* [TasksListsBot](https://t.me/TasksListsBot) ([source](https://github.com/Pablo-Davila/TasksListsBot)) by [@Pablo-Davila](https://github.com/Pablo-Davila) - A (tasks) lists manager bot for Telegram.
|
||||
* [MyElizaPsychologistBot](https://t.me/TasksListsBot) ([source](https://github.com/Pablo-Davila/MyElizaPsychologistBot)) by [@Pablo-Davila](https://github.com/Pablo-Davila) - An implementation of the famous Eliza psychologist chatbot.
|
||||
* [Evdembot](https://t.me/Evdembot) by Adem Kavak. A bot that informs you about everything you want.
|
||||
* [Frcstbot](https://t.me/frcstbot) ([source](https://github.com/Mrsqd/frcstbot_public)) by [Mrsqd](https://github.com/Mrsqd). A Telegram bot that will always be happy to show you the weather forecast.
|
||||
* [Bot Hour](https://t.me/roadtocode_bot) a little bot that say the time in different countries by [@diegop384](https://github.com/diegop384) [repo](https://github.com/diegop384/telegrambothour)
|
||||
* [moodforfood_bot](https://t.me/moodforfood_bot) This bot will provide you with a list of food place(s) near your current Telegram location, which you are prompted to share. The API for all this info is from https://foursquare.com/. by [@sophiamarani](https://github.com/sophiamarani)
|
||||
* [Donation with Amazon](https://t.me/donamazonbot) by [@barbax7](https://github.com/barbax7) This bot donates amazon advertising commissions to the non-profit organization chosen by the user.
|
||||
* [COVID-19 Galicia Bot](https://t.me/covid19_galicia_bot) by [@dgarcoe](https://github.com/dgarcoe) This bot provides daily data related to the COVID19 crisis in Galicia (Spain) obtained from official government sources.
|
||||
* [MineGramBot](https://github.com/ModischFabrications/MineGramBot) by [ModischFabrications](https://github.com/ModischFabrications). This bot can start, stop and monitor a minecraft server.
|
||||
* [Tabletop DiceBot](https://github.com/dexpiper/tabletopdicebot) by [dexpiper](https://github.com/dexpiper). This bot can roll multiple dices for RPG-like games, add positive and negative modifiers and show short descriptions to the rolls.
|
||||
* [BarnameKon](https://t.me/BarnameKonBot) by [Anvaari](https://github.com/anvaari). This Bot make "Add to google calendar" link for your events. It give information about event and return link. It work for Jalali calendar and in Tehran Time. [Source code](https://github.com/anvaari/BarnameKon)
|
||||
* [Price Tracker](https://t.me/trackokbot) by [@barbax7](https://github.com/barbax7). This bot tracks amazon.it product's prices the user is interested to and notify him when one price go down.
|
||||
* [Torrent Hunt](https://t.me/torrenthuntbot) by [@Hemantapkh](https://github.com/hemantapkh/torrenthunt). Torrent Hunt bot is a multilingual bot with inline mode support to search and explore torrents from 1337x.to.
|
||||
* Translator bot by [Areeg Fahad (source)](https://github.com/AREEG94FAHAD/translate_text_bot). This bot can be use to translate texts.
|
||||
* Digital Cryptocurrency bot by [Areeg Fahad (source)](https://github.com/AREEG94FAHAD/currencies_bot). With this bot, you can now monitor the prices of more than 12 digital Cryptocurrency.
|
||||
* [Anti-Tracking Bot](https://t.me/AntiTrackingBot) by [Leon Heess (source)](https://github.com/leonheess/AntiTrackingBot). Send any link, and the bot tries its best to remove all tracking from the link you sent.
|
||||
* [Translator bot](https://github.com/AREEG94FAHAD/translate_text_bot) by Areeg Fahad. This bot can be used to translate texts.
|
||||
* [Digital Cryptocurrency bot](https://github.com/AREEG94FAHAD/currencies_bot) by Areeg Fahad. With this bot, you can now monitor the prices of more than 12 digital Cryptocurrency.
|
||||
* [Anti-Tracking Bot](https://t.me/AntiTrackingBot) by Leon Heess [(source)](https://github.com/leonheess/AntiTrackingBot). Send any link, and the bot tries its best to remove all tracking from the link you sent.
|
||||
* [Developer Bot](https://t.me/IndDeveloper_bot) by [Vishal Singh](https://github.com/vishal2376) [(source code)](https://github.com/vishal2376/telegram-bot) This telegram bot can do tasks like GitHub search & clone,provide c++ learning resources ,Stackoverflow search, Codeforces(profile visualizer,random problems)
|
||||
* [oneIPO bot](https://github.com/aaditya2200/IPO-proj) by [Aadithya](https://github.com/aaditya2200) & [Amol Soans](https://github.com/AmolDerickSoans) This Telegram bot provides live updates , data and documents on current and upcoming IPOs(Initial Public Offerings)
|
||||
|
||||
**Want to have your bot listed here? Just make a pull request.**
|
||||
**Want to have your bot listed here? Just make a pull request. Only bots with public source code are accepted.**
|
||||
|
42
examples/custom_filters/general_custom_filters.py
Normal file
42
examples/custom_filters/general_custom_filters.py
Normal file
@ -0,0 +1,42 @@
|
||||
import telebot
|
||||
|
||||
bot = telebot.TeleBot('TOKEN')
|
||||
|
||||
|
||||
# AdvancedCustomFilter is for list, string filter values
|
||||
class MainFilter(telebot.custom_filters.AdvancedCustomFilter):
|
||||
key='text'
|
||||
@staticmethod
|
||||
def check(message, text):
|
||||
return message.text in text
|
||||
|
||||
# SimpleCustomFilter is for boolean values, such as is_admin=True
|
||||
class IsAdmin(telebot.custom_filters.SimpleCustomFilter):
|
||||
key='is_admin'
|
||||
@staticmethod
|
||||
def check(message: telebot.types.Message):
|
||||
return bot.get_chat_member(message.chat.id,message.from_user.id).status in ['administrator','creator']
|
||||
|
||||
|
||||
@bot.message_handler(is_admin=True, commands=['admin']) # Check if user is admin
|
||||
def admin_rep(message):
|
||||
bot.send_message(message.chat.id, "Hi admin")
|
||||
|
||||
@bot.message_handler(is_admin=False, commands=['admin']) # If user is not admin
|
||||
def not_admin(message):
|
||||
bot.send_message(message.chat.id, "You are not admin")
|
||||
|
||||
@bot.message_handler(text=['hi']) # Response to hi message
|
||||
def welcome_hi(message):
|
||||
bot.send_message(message.chat.id, 'You said hi')
|
||||
|
||||
@bot.message_handler(text=['bye']) # Response to bye message
|
||||
def bye_user(message):
|
||||
bot.send_message(message.chat.id, 'You said bye')
|
||||
|
||||
|
||||
# Do not forget to register filters
|
||||
bot.add_custom_filter(MainFilter())
|
||||
bot.add_custom_filter(IsAdmin())
|
||||
|
||||
bot.polling(skip_pending=True,non_stop=True) # Skip old updates
|
22
examples/custom_filters/id_filter_example.py
Normal file
22
examples/custom_filters/id_filter_example.py
Normal file
@ -0,0 +1,22 @@
|
||||
import telebot
|
||||
from telebot import custom_filters
|
||||
|
||||
bot = telebot.TeleBot('token')
|
||||
|
||||
|
||||
# Chat id can be private or supergroups.
|
||||
@bot.message_handler(chat_id=[12345678], commands=['admin']) # chat_id checks id corresponds to your list or not.
|
||||
def admin_rep(message):
|
||||
bot.send_message(message.chat.id, "You are allowed to use this command.")
|
||||
|
||||
@bot.message_handler(commands=['admin'])
|
||||
def not_admin(message):
|
||||
bot.send_message(message.chat.id, "You are not allowed to use this command")
|
||||
|
||||
|
||||
# Do not forget to register
|
||||
bot.add_custom_filter(custom_filters.ChatFilter())
|
||||
|
||||
|
||||
bot.polling(non_stop=True)
|
||||
|
21
examples/custom_filters/text_filter_example.py
Normal file
21
examples/custom_filters/text_filter_example.py
Normal file
@ -0,0 +1,21 @@
|
||||
import telebot
|
||||
from telebot import custom_filters
|
||||
|
||||
bot = telebot.TeleBot('TOKEN')
|
||||
|
||||
|
||||
# Check if message starts with @admin tag
|
||||
@bot.message_handler(text_startswith="@admin")
|
||||
def start_filter(message):
|
||||
bot.send_message(message.chat.id, "Looks like you are calling admin, wait...")
|
||||
|
||||
# Check if text is hi or hello
|
||||
@bot.message_handler(text=['hi','hello'])
|
||||
def text_filter(message):
|
||||
bot.send_message(message.chat.id, "Hi, {name}!".format(name=message.from_user.first_name))
|
||||
|
||||
# Do not forget to register filters
|
||||
bot.add_custom_filter(custom_filters.TextMatchFilter())
|
||||
bot.add_custom_filter(custom_filters.TextStartsFilter())
|
||||
|
||||
bot.polling(non_stop=True)
|
@ -12,7 +12,7 @@ from typing import Any, Callable, List, Optional, Union
|
||||
# this imports are used to avoid circular import error
|
||||
import telebot.util
|
||||
import telebot.types
|
||||
|
||||
from telebot.custom_filters import SimpleCustomFilter, AdvancedCustomFilter
|
||||
|
||||
|
||||
logger = logging.getLogger('TeleBot')
|
||||
@ -185,6 +185,7 @@ class TeleBot:
|
||||
self.poll_answer_handlers = []
|
||||
self.my_chat_member_handlers = []
|
||||
self.chat_member_handlers = []
|
||||
self.custom_filters = {}
|
||||
|
||||
if apihelper.ENABLE_MIDDLEWARE:
|
||||
self.typed_middleware_handlers = {
|
||||
@ -2425,7 +2426,9 @@ class TeleBot:
|
||||
"""
|
||||
return {
|
||||
'function': handler,
|
||||
'filters': filters
|
||||
'filters': {ftype: fvalue for ftype, fvalue in filters.items() if fvalue is not None}
|
||||
# Remove None values, they are skipped in _test_filter anyway
|
||||
#'filters': filters
|
||||
}
|
||||
|
||||
def middleware_handler(self, update_types=None):
|
||||
@ -2476,7 +2479,7 @@ class TeleBot:
|
||||
else:
|
||||
self.default_middleware_handlers.append(handler)
|
||||
|
||||
def message_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
|
||||
def message_handler(self, commands=None, regexp=None, func=None, content_types=None, chat_types=None, **kwargs):
|
||||
"""
|
||||
Message handler decorator.
|
||||
This decorator can be used to decorate functions that must handle certain types of messages.
|
||||
@ -2491,6 +2494,11 @@ class TeleBot:
|
||||
def command_help(message):
|
||||
bot.send_message(message.chat.id, 'Did someone call for help?')
|
||||
|
||||
# Handles messages in private chat
|
||||
@bot.message_handler(chat_types=['private']) # You can add more chat types
|
||||
def command_help(message):
|
||||
bot.send_message(message.chat.id, 'Private chat detected, sir!')
|
||||
|
||||
# Handle all sent documents of type 'text/plain'.
|
||||
@bot.message_handler(func=lambda message: message.document.mime_type == 'text/plain',
|
||||
content_types=['document'])
|
||||
@ -2508,13 +2516,23 @@ class TeleBot:
|
||||
:param func: Optional lambda function. The lambda receives the message to test as the first parameter.
|
||||
It must return True if the command should handle the message.
|
||||
:param content_types: Supported message content types. Must be a list. Defaults to ['text'].
|
||||
:param chat_types: list of chat types
|
||||
"""
|
||||
|
||||
if content_types is None:
|
||||
content_types = ["text"]
|
||||
|
||||
if isinstance(commands, str):
|
||||
logger.warning("message_handler: 'commands' filter should be List of strings (commands), not string.")
|
||||
commands = [commands]
|
||||
|
||||
if isinstance(content_types, str):
|
||||
logger.warning("message_handler: 'content_types' filter should be List of strings (content types), not string.")
|
||||
content_types = [content_types]
|
||||
|
||||
def decorator(handler):
|
||||
handler_dict = self._build_handler_dict(handler,
|
||||
chat_types=chat_types,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
@ -2533,7 +2551,7 @@ class TeleBot:
|
||||
"""
|
||||
self.message_handlers.append(handler_dict)
|
||||
|
||||
def register_message_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, **kwargs):
|
||||
def register_message_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, chat_types=None, **kwargs):
|
||||
"""
|
||||
Registers message handler.
|
||||
:param callback: function to be called
|
||||
@ -2541,22 +2559,34 @@ class TeleBot:
|
||||
:param commands: list of commands
|
||||
:param regexp:
|
||||
:param func:
|
||||
:param chat_types: True for private chat
|
||||
:return: decorated function
|
||||
"""
|
||||
if isinstance(commands, str):
|
||||
logger.warning("register_message_handler: 'commands' filter should be List of strings (commands), not string.")
|
||||
commands = [commands]
|
||||
|
||||
if isinstance(content_types, str):
|
||||
logger.warning("register_message_handler: 'content_types' filter should be List of strings (content types), not string.")
|
||||
content_types = [content_types]
|
||||
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
**kwargs)
|
||||
chat_types=chat_types,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
**kwargs)
|
||||
self.add_message_handler(handler_dict)
|
||||
def edited_message_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
|
||||
|
||||
def edited_message_handler(self, commands=None, regexp=None, func=None, content_types=None, chat_types=None, **kwargs):
|
||||
"""
|
||||
Edit message handler decorator
|
||||
:param commands:
|
||||
:param regexp:
|
||||
:param func:
|
||||
:param content_types:
|
||||
:param chat_types: list of chat types
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
@ -2564,12 +2594,21 @@ class TeleBot:
|
||||
if content_types is None:
|
||||
content_types = ["text"]
|
||||
|
||||
if isinstance(commands, str):
|
||||
logger.warning("edited_message_handler: 'commands' filter should be List of strings (commands), not string.")
|
||||
commands = [commands]
|
||||
|
||||
if isinstance(content_types, str):
|
||||
logger.warning("edited_message_handler: 'content_types' filter should be List of strings (content types), not string.")
|
||||
content_types = [content_types]
|
||||
|
||||
def decorator(handler):
|
||||
handler_dict = self._build_handler_dict(handler,
|
||||
chat_types=chat_types,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
content_types=content_types,
|
||||
**kwargs)
|
||||
self.add_edited_message_handler(handler_dict)
|
||||
return handler
|
||||
@ -2584,7 +2623,7 @@ class TeleBot:
|
||||
"""
|
||||
self.edited_message_handlers.append(handler_dict)
|
||||
|
||||
def register_edited_message_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, **kwargs):
|
||||
def register_edited_message_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, chat_types=None, **kwargs):
|
||||
"""
|
||||
Registers edited message handler.
|
||||
:param callback: function to be called
|
||||
@ -2592,15 +2631,26 @@ class TeleBot:
|
||||
:param commands: list of commands
|
||||
:param regexp:
|
||||
:param func:
|
||||
:param chat_types: True for private chat
|
||||
:return: decorated function
|
||||
"""
|
||||
if isinstance(commands, str):
|
||||
logger.warning("register_edited_message_handler: 'commands' filter should be List of strings (commands), not string.")
|
||||
commands = [commands]
|
||||
|
||||
if isinstance(content_types, str):
|
||||
logger.warning("register_edited_message_handler: 'content_types' filter should be List of strings (content types), not string.")
|
||||
content_types = [content_types]
|
||||
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
**kwargs)
|
||||
chat_types=chat_types,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
**kwargs)
|
||||
self.add_edited_message_handler(handler_dict)
|
||||
|
||||
def channel_post_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
|
||||
"""
|
||||
Channel post handler decorator
|
||||
@ -2611,16 +2661,23 @@ class TeleBot:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if content_types is None:
|
||||
content_types = ["text"]
|
||||
|
||||
if isinstance(commands, str):
|
||||
logger.warning("channel_post_handler: 'commands' filter should be List of strings (commands), not string.")
|
||||
commands = [commands]
|
||||
|
||||
if isinstance(content_types, str):
|
||||
logger.warning("channel_post_handler: 'content_types' filter should be List of strings (content types), not string.")
|
||||
content_types = [content_types]
|
||||
|
||||
def decorator(handler):
|
||||
handler_dict = self._build_handler_dict(handler,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
content_types=content_types,
|
||||
**kwargs)
|
||||
self.add_channel_post_handler(handler_dict)
|
||||
return handler
|
||||
@ -2645,13 +2702,22 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
if isinstance(commands, str):
|
||||
logger.warning("register_channel_post_handler: 'commands' filter should be List of strings (commands), not string.")
|
||||
commands = [commands]
|
||||
|
||||
if isinstance(content_types, str):
|
||||
logger.warning("register_channel_post_handler: 'content_types' filter should be List of strings (content types), not string.")
|
||||
content_types = [content_types]
|
||||
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
**kwargs)
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
**kwargs)
|
||||
self.add_channel_post_handler(handler_dict)
|
||||
|
||||
def edited_channel_post_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
|
||||
"""
|
||||
Edit channel post handler decorator
|
||||
@ -2662,16 +2728,23 @@ class TeleBot:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if content_types is None:
|
||||
content_types = ["text"]
|
||||
|
||||
if isinstance(commands, str):
|
||||
logger.warning("edited_channel_post_handler: 'commands' filter should be List of strings (commands), not string.")
|
||||
commands = [commands]
|
||||
|
||||
if isinstance(content_types, str):
|
||||
logger.warning("edited_channel_post_handler: 'content_types' filter should be List of strings (content types), not string.")
|
||||
content_types = [content_types]
|
||||
|
||||
def decorator(handler):
|
||||
handler_dict = self._build_handler_dict(handler,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
content_types=content_types,
|
||||
**kwargs)
|
||||
self.add_edited_channel_post_handler(handler_dict)
|
||||
return handler
|
||||
@ -2696,12 +2769,20 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
if isinstance(commands, str):
|
||||
logger.warning("register_edited_channel_post_handler: 'commands' filter should be List of strings (commands), not string.")
|
||||
commands = [commands]
|
||||
|
||||
if isinstance(content_types, str):
|
||||
logger.warning("register_edited_channel_post_handler: 'content_types' filter should be List of strings (content types), not string.")
|
||||
content_types = [content_types]
|
||||
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
**kwargs)
|
||||
content_types=content_types,
|
||||
commands=commands,
|
||||
regexp=regexp,
|
||||
func=func,
|
||||
**kwargs)
|
||||
self.add_edited_channel_post_handler(handler_dict)
|
||||
|
||||
def inline_handler(self, func, **kwargs):
|
||||
@ -2734,9 +2815,7 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_inline_handler(handler_dict)
|
||||
|
||||
def chosen_inline_handler(self, func, **kwargs):
|
||||
@ -2769,12 +2848,9 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_chosen_inline_handler(handler_dict)
|
||||
|
||||
|
||||
def callback_query_handler(self, func, **kwargs):
|
||||
"""
|
||||
Callback request handler decorator
|
||||
@ -2805,9 +2881,7 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_callback_query_handler(handler_dict)
|
||||
|
||||
def shipping_query_handler(self, func, **kwargs):
|
||||
@ -2840,9 +2914,7 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_shipping_query_handler(handler_dict)
|
||||
|
||||
def pre_checkout_query_handler(self, func, **kwargs):
|
||||
@ -2875,9 +2947,7 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_pre_checkout_query_handler(handler_dict)
|
||||
|
||||
def poll_handler(self, func, **kwargs):
|
||||
@ -2910,9 +2980,7 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_poll_handler(handler_dict)
|
||||
|
||||
def poll_answer_handler(self, func=None, **kwargs):
|
||||
@ -2945,9 +3013,7 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_poll_answer_handler(handler_dict)
|
||||
|
||||
def my_chat_member_handler(self, func=None, **kwargs):
|
||||
@ -2980,9 +3046,7 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_my_chat_member_handler(handler_dict)
|
||||
|
||||
def chat_member_handler(self, func=None, **kwargs):
|
||||
@ -3015,9 +3079,7 @@ class TeleBot:
|
||||
:param func:
|
||||
:return: decorated function
|
||||
"""
|
||||
handler_dict = self._build_handler_dict(callback,
|
||||
func=func,
|
||||
**kwargs)
|
||||
handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
|
||||
self.add_chat_member_handler(handler_dict)
|
||||
|
||||
def _test_message_handler(self, message_handler, message):
|
||||
@ -3036,23 +3098,55 @@ class TeleBot:
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def _test_filter(message_filter, filter_value, message):
|
||||
def add_custom_filter(self, custom_filter):
|
||||
"""
|
||||
Create custom filter.
|
||||
custom_filter: Class with check(message) method.
|
||||
"""
|
||||
self.custom_filters[custom_filter.key] = custom_filter
|
||||
|
||||
def _test_filter(self, message_filter, filter_value, message):
|
||||
"""
|
||||
Test filters
|
||||
:param message_filter:
|
||||
:param filter_value:
|
||||
:param message:
|
||||
:return:
|
||||
:param message_filter: Filter type passed in handler
|
||||
:param filter_value: Filter value passed in handler
|
||||
:param message: Message to test
|
||||
:return: True if filter conforms
|
||||
"""
|
||||
test_cases = {
|
||||
'content_types': lambda msg: msg.content_type in filter_value,
|
||||
'regexp': lambda msg: msg.content_type == 'text' and re.search(filter_value, msg.text, re.IGNORECASE),
|
||||
'commands': lambda msg: msg.content_type == 'text' and util.extract_command(msg.text) in filter_value,
|
||||
'func': lambda msg: filter_value(msg)
|
||||
}
|
||||
# test_cases = {
|
||||
# 'content_types': lambda msg: msg.content_type in filter_value,
|
||||
# 'regexp': lambda msg: msg.content_type == 'text' and re.search(filter_value, msg.text, re.IGNORECASE),
|
||||
# 'commands': lambda msg: msg.content_type == 'text' and util.extract_command(msg.text) in filter_value,
|
||||
# 'func': lambda msg: filter_value(msg)
|
||||
# }
|
||||
# return test_cases.get(message_filter, lambda msg: False)(message)
|
||||
|
||||
if message_filter == 'content_types':
|
||||
return message.content_type in filter_value
|
||||
elif message_filter == 'regexp':
|
||||
return message.content_type == 'text' and re.search(filter_value, message.text, re.IGNORECASE)
|
||||
elif message_filter == 'commands':
|
||||
return message.content_type == 'text' and util.extract_command(message.text) in filter_value
|
||||
elif message_filter == 'chat_types':
|
||||
return message.chat.type in filter_value
|
||||
elif message_filter == 'func':
|
||||
return filter_value(message)
|
||||
elif self.custom_filters and message_filter in self.custom_filters:
|
||||
return self._check_filter(message_filter,filter_value,message)
|
||||
else:
|
||||
return False
|
||||
|
||||
return test_cases.get(message_filter, lambda msg: False)(message)
|
||||
def _check_filter(self, message_filter, filter_value, message):
|
||||
filter_check = self.custom_filters.get(message_filter)
|
||||
if not filter_check:
|
||||
return False
|
||||
elif isinstance(filter_check, SimpleCustomFilter):
|
||||
return filter_value == filter_check.check(message)
|
||||
elif isinstance(filter_check, AdvancedCustomFilter):
|
||||
return filter_check.check(message, filter_value)
|
||||
else:
|
||||
logger.error("Custom filter: wrong type. Should be SimpleCustomFilter or AdvancedCustomFilter.")
|
||||
return False
|
||||
|
||||
def _notify_command_handlers(self, handlers, new_messages):
|
||||
"""
|
||||
|
@ -33,7 +33,7 @@ READ_TIMEOUT = 30
|
||||
|
||||
LONG_POLLING_TIMEOUT = 10 # Should be positive, short polling should be used for testing purposes only (https://core.telegram.org/bots/api#getupdates)
|
||||
|
||||
SESSION_TIME_TO_LIVE = None # In seconds. None - live forever, 0 - one-time
|
||||
SESSION_TIME_TO_LIVE = 600 # In seconds. None - live forever, 0 - one-time
|
||||
|
||||
RETRY_ON_ERROR = False
|
||||
RETRY_TIMEOUT = 2
|
||||
@ -973,8 +973,8 @@ def create_chat_invite_link(token, chat_id, expire_date, member_limit):
|
||||
}
|
||||
|
||||
if expire_date is not None:
|
||||
if isinstance(payload['expire_date'], datetime):
|
||||
payload['expire_date'] = payload['expire_date'].timestamp()
|
||||
if isinstance(expire_date, datetime):
|
||||
payload['expire_date'] = expire_date.timestamp()
|
||||
else:
|
||||
payload['expire_date'] = expire_date
|
||||
if member_limit:
|
||||
@ -991,8 +991,8 @@ def edit_chat_invite_link(token, chat_id, invite_link, expire_date, member_limit
|
||||
}
|
||||
|
||||
if expire_date is not None:
|
||||
if isinstance(payload['expire_date'], datetime):
|
||||
payload['expire_date'] = payload['expire_date'].timestamp()
|
||||
if isinstance(expire_date, datetime):
|
||||
payload['expire_date'] = expire_date.timestamp()
|
||||
else:
|
||||
payload['expire_date'] = expire_date
|
||||
|
||||
|
132
telebot/custom_filters.py
Normal file
132
telebot/custom_filters.py
Normal file
@ -0,0 +1,132 @@
|
||||
from abc import ABC
|
||||
|
||||
class SimpleCustomFilter(ABC):
|
||||
"""
|
||||
Simple Custom Filter base class.
|
||||
Create child class with check() method.
|
||||
Accepts only message, returns bool value, that is compared with given in handler.
|
||||
"""
|
||||
|
||||
def check(self, message):
|
||||
"""
|
||||
Perform a check.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class AdvancedCustomFilter(ABC):
|
||||
"""
|
||||
Simple Custom Filter base class.
|
||||
Create child class with check() method.
|
||||
Accepts two parameters, returns bool: True - filter passed, False - filter failed.
|
||||
message: Message class
|
||||
text: Filter value given in handler
|
||||
"""
|
||||
|
||||
def check(self, message, text):
|
||||
"""
|
||||
Perform a check.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class TextMatchFilter(AdvancedCustomFilter):
|
||||
"""
|
||||
Filter to check Text message.
|
||||
key: text
|
||||
|
||||
Example:
|
||||
@bot.message_handler(text=['account'])
|
||||
"""
|
||||
|
||||
key = 'text'
|
||||
|
||||
def check(self, message, text):
|
||||
if type(text) is list:return message.text in text
|
||||
else: return text == message.text
|
||||
|
||||
class TextContainsFilter(AdvancedCustomFilter):
|
||||
"""
|
||||
Filter to check Text message.
|
||||
key: text
|
||||
|
||||
Example:
|
||||
# Will respond if any message.text contains word 'account'
|
||||
@bot.message_handler(text_contains=['account'])
|
||||
"""
|
||||
|
||||
key = 'text_contains'
|
||||
|
||||
def check(self, message, text):
|
||||
return text in message.text
|
||||
|
||||
class TextStartsFilter(AdvancedCustomFilter):
|
||||
"""
|
||||
Filter to check whether message starts with some text.
|
||||
|
||||
Example:
|
||||
# Will work if message.text starts with 'Sir'.
|
||||
@bot.message_handler(text_startswith='Sir')
|
||||
"""
|
||||
|
||||
key = 'text_startswith'
|
||||
def check(self, message, text):
|
||||
return message.text.startswith(text)
|
||||
|
||||
class ChatFilter(AdvancedCustomFilter):
|
||||
"""
|
||||
Check whether chat_id corresponds to given chat_id.
|
||||
|
||||
Example:
|
||||
@bot.message_handler(chat_id=[99999])
|
||||
"""
|
||||
|
||||
key = 'chat_id'
|
||||
def check(self, message, text):
|
||||
return message.chat.id in text
|
||||
|
||||
class ForwardFilter(SimpleCustomFilter):
|
||||
"""
|
||||
Check whether message was forwarded.
|
||||
|
||||
Example:
|
||||
|
||||
@bot.message_handler(is_forwarded=True)
|
||||
"""
|
||||
|
||||
key = 'is_forwarded'
|
||||
|
||||
def check(self, message):
|
||||
return message.forward_from_chat is not None
|
||||
|
||||
class IsReplyFilter(SimpleCustomFilter):
|
||||
"""
|
||||
Check whether message is a reply.
|
||||
|
||||
Example:
|
||||
|
||||
@bot.message_handler(is_reply=True)
|
||||
"""
|
||||
|
||||
key = 'is_reply'
|
||||
|
||||
def check(self, message):
|
||||
return message.reply_to_message is not None
|
||||
|
||||
|
||||
|
||||
class LanguageFilter(AdvancedCustomFilter):
|
||||
"""
|
||||
Check users language_code.
|
||||
|
||||
Example:
|
||||
|
||||
@bot.message_handler(language_code=['ru'])
|
||||
"""
|
||||
|
||||
key = 'language_code'
|
||||
|
||||
def check(self, message, text):
|
||||
if type(text) is list:return message.from_user.language_code in text
|
||||
else: return message.from_user.language_code == text
|
||||
|
@ -27,7 +27,7 @@ logger = logging.getLogger('TeleBot')
|
||||
thread_local = threading.local()
|
||||
|
||||
content_type_media = [
|
||||
'text', 'audio', 'document', 'photo', 'sticker', 'video', 'video_note', 'voice', 'contact', 'dice', 'poll',
|
||||
'text', 'audio', 'animation', 'document', 'photo', 'sticker', 'video', 'video_note', 'voice', 'contact', 'dice', 'poll',
|
||||
'venue', 'location'
|
||||
]
|
||||
|
||||
@ -440,3 +440,18 @@ def deprecated(warn: bool=False, alternative: Optional[Callable]=None):
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# Cloud helpers
|
||||
def webhook_google_functions(bot, request):
|
||||
"""A webhook endpoint for Google Cloud Functions FaaS."""
|
||||
if request.is_json:
|
||||
try:
|
||||
request_json = request.get_json()
|
||||
update = types.Update.de_json(request_json)
|
||||
bot.process_new_updates([update])
|
||||
return ''
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return 'Bot FAIL', 400
|
||||
else:
|
||||
return 'Bot ON'
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Versions should comply with PEP440.
|
||||
# This line is parsed in setup.py:
|
||||
__version__ = '3.8.3'
|
||||
__version__ = '4.0.1'
|
||||
|
Reference in New Issue
Block a user