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

Compare commits

...

684 Commits
0.3.4 ... 3.6.7

Author SHA1 Message Date
b1e5d00821 Merge pull request #728 from Badiboy/master
Design updates from #711
2020-01-08 20:29:12 +03:00
aa02ddb573 TAB fix
TAB fix
2020-01-08 20:17:25 +03:00
760ea5a2f0 Design updates from #711
Significant design updated from
https://github.com/eternnoir/pyTelegramBotAPI/pull/711
2020-01-08 20:06:40 +03:00
9b279dc562 Merge pull request #726 from Badiboy/master
Update test_types.py
2020-01-03 19:31:39 +03:00
5cd97ebc96 Update detailed_example.py
Vulgarity replaced.
2020-01-03 19:24:10 +03:00
b5ba2445d3 Update test_types.py
Updated test vectors for stickers.
2020-01-03 19:18:18 +03:00
7adec8bd90 Merge pull request #673 from TahaPY/master
Added Animation and is_animated for stickers
2020-01-03 17:51:53 +03:00
0603a0df4c Update types.py
Animation is moved before document to save backward compatibility. content_type = 'document' should override content_type = 'animation' to save previous behaviour.
2020-01-03 17:51:05 +03:00
59810b5e2a Merge pull request #620 from nev3rfail/send_animation
Added reduced version of sendAnimation (no width/height/thumb).
2020-01-03 17:12:29 +03:00
b999fea2ac Merge pull request #703 from voskresla/patch-1
Using Azure Functions for serverless bots.
2020-01-03 16:59:09 +03:00
a41dabf73c Merge pull request #725 from cclauss/patch-1
Travis CI: Drop EOL Py34 and add current Py38
2020-01-03 16:53:18 +03:00
5407801f62 Merge pull request #708 from xxsokolov/patch-1
Remove unused base_url from _make_request. Fixed misc error.
2020-01-03 16:52:47 +03:00
2efb33fc29 Merge branch 'master' into patch-1 2020-01-03 16:45:43 +03:00
620ea5dee0 Travis CI: Drop EOL Py34 and add current Py38 2020-01-03 14:36:08 +01:00
eaf44f1a6b Merge pull request #724 from Badiboy/master
Update version list in travis.yml
2020-01-03 02:08:00 +03:00
8c62b99057 Update .travis.yml
Travis: removed 2.6 and 3.3 (not supported). Added 3.7. Also added 3.8 (for experiment)
2020-01-03 02:05:32 +03:00
e3b126807e Merge pull request #713 from dtalkachou/patch-1
Correct work with empty base_url in make_request
2020-01-03 01:33:27 +03:00
769ff8008e Merge pull request #599 from KanerL/KanerL-patch-shipping-option
ShippingOption.add_price returns "self" (for chaining etc.).
2020-01-03 01:28:37 +03:00
0e0e2d97c0 Merge pull request #715 from Pablohn26/patch-1
Change chatid to chat_id to be the same as other examples
2020-01-03 01:19:47 +03:00
bb199024fd Merge pull request #593 from neoranger/patch-2
Update README.md
2020-01-03 01:02:35 +03:00
86644c05f7 Merge pull request #539 from Badiboy/master
"timeout" parameter for send_message
Fix kick_chat_member return type
HTML symbols not replaced
2020-01-03 00:50:24 +03:00
3a3bab5b92 Merge pull request #480 from SkymanOne/patch-1
create field forward_from_message_id in Message
2020-01-03 00:46:27 +03:00
bf844ed202 HTML symbols not replaced
HTML symbols not replaced because return is before replace.
2020-01-01 13:46:18 +03:00
fefb9d4555 Merge pull request #723 from LeoSvalov/master
Update README
2019-12-28 12:34:14 +08:00
a413a51221 Update README
Adding another bot that user pyTelegramBotAPI.
2019-12-24 16:25:58 +05:00
a71030dcdd Change chatid to chat_id to be the same as other examples
Change in README.md chatid to chat_id to be the same as other examples
2019-11-30 05:51:56 +01:00
68db599790 Delete duplicate string 2019-11-23 21:25:29 +03:00
a749acde15 Update apihelper.py #2
Merge Fixes # 684
2019-11-05 17:37:53 +03:00
5935a378ca Merge pull request #685 from cclauss/patch-1
Use ==/!= to compare str, bytes, and int literals
2019-10-30 21:26:00 +08:00
1dd94d6e6d Merge pull request #667 from desexcile/patch-2
Update Readme
2019-10-30 21:25:11 +08:00
2fb0f3fb4b Merge pull request #684 from xxsokolov/patch-1
Update apihelper.py
2019-10-30 21:24:51 +08:00
575fb9da7f Merge branch 'master' into patch-1 2019-10-30 21:24:43 +08:00
c6358f35d2 Merge pull request #688 from vryazanov/master
New content type related to Telegram Passport
2019-10-30 21:22:36 +08:00
20b87f2242 Merge pull request #701 from eternnoir/dependabot/pip/requests-2.20.0
Bump requests from 2.7.0 to 2.20.0
2019-10-30 21:22:16 +08:00
f4c215b0b8 Merge pull request #705 from keshamin/fix-578
Fixed #578
2019-10-30 21:21:49 +08:00
1a30a9a249 Fixed #578 2019-10-30 14:02:00 +03:00
e644ed910a Using Azure Functions for serverless bots.
Simple echo bot using Azure Functions as webhook.
2019-10-13 23:49:43 +03:00
8cb2da3775 Bump requests from 2.7.0 to 2.20.0
Bumps [requests](https://github.com/requests/requests) from 2.7.0 to 2.20.0.
- [Release notes](https://github.com/requests/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/master/HISTORY.md)
- [Commits](https://github.com/requests/requests/compare/v2.7.0...v2.20.0)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-05 11:55:18 +00:00
f8e7c0f819 Merge branch 'master' into patch-2 2019-09-23 10:25:18 -03:00
f241ef1eac passport_data content type added 2019-08-27 11:55:14 +03:00
8f8276314e Merge pull request #1 from cmd410/master
Support for animated stickers
2019-08-16 20:42:08 +00:00
9e30cfbda6 Use ==/!= to compare str, bytes, and int literals
Identity is not the same thing as equality in Python.
2019-08-12 22:47:59 +02:00
6fb9e18385 Update apihelper.py
Hi, to indicate a third-party api-url (reverse proxy) added conditions.
Perhaps not the most elegant solution, but this functionality is very lacking.


apihelper.API_URL = "http://reverseproxy.example.com/bot{0}/{1}"
2019-08-12 17:09:52 +03:00
f0835a1a14 Support for animated stickers 2019-07-30 12:46:39 +03:00
be3b6f88e8 Added Animation 2019-07-14 18:53:59 +04:30
87e811ce3e Update Readme
Fixed source link
2019-06-29 09:39:14 +03:00
151880f391 Merge pull request #659 from OslikAi/master
Add Poll
2019-06-28 21:02:23 +08:00
bf91829088 Merge pull request #664 from vovawed/master
Added LoginUrl to types
2019-06-28 21:02:04 +08:00
56f0b0a0d4 Merge pull request #603 from nailerNAS/master
infinity_polling fix
2019-06-28 20:57:28 +08:00
2b8e77f749 Merge pull request #616 from painca/patch-1
edit message_handler doc
2019-06-28 20:56:47 +08:00
fba425265e Merge pull request #645 from setazer/patch-1
remove unnecessary f-strings
2019-06-28 20:56:29 +08:00
23069ac729 Merge pull request #644 from David-Lor/master
update bot list
2019-06-28 20:56:15 +08:00
7ab93f55a6 Merge pull request #666 from desexcile/patch-1
Update Readme
2019-06-28 20:55:46 +08:00
ba2705dc82 Merge remote-tracking branch 'origin/master' 2019-06-27 15:07:54 +03:00
3a1bdc2899 add Poll, sendPoll, stopPoll 2019-06-27 15:07:41 +03:00
4e57adbcb6 Update Readme
added @asadov_bot to Bot list using this Api
2019-06-26 10:54:59 +03:00
600002e158 Fixed bug with LoginUrl 2019-06-15 23:09:59 +03:00
3c62e9d391 Added LoginUrl to types 2019-06-15 22:59:41 +03:00
63df69aeb8 Delete my_tests.py 2019-06-06 22:23:11 +03:00
a8cf9f4ae5 Update README.md 2019-06-06 21:54:06 +03:00
b10e45f714 add Poll, sendPoll, stopPoll 2019-06-06 21:49:06 +03:00
9624b45314 add Poll, sendPoll, stopPoll 2019-06-06 21:47:08 +03:00
e26ad07965 Merge pull request #658 from FacuM/add_bot_patch
Update README.md
2019-05-31 11:24:14 +08:00
55c7b6373c Update README.md 2019-05-30 00:35:57 -03:00
ceceeb7d8c Update README.md 2019-05-24 15:05:20 +08:00
b76a69e036 Merge pull request #624 from kor0p/editMessageText
Add 'method' parameter to methods that edit message
2019-05-18 07:58:56 +08:00
e5700380bd Merge branch 'master' into master 2019-05-18 07:56:53 +08:00
47b53b8812 Merge pull request #649 from karipov/master
added creationdatebot to bots api list
2019-04-24 17:41:43 +08:00
2d0ebde481 added creationdatebot to bots api list 2019-04-24 11:29:52 +02:00
271b7e0642 Merge pull request #646 from airatk/master
Update README.md
2019-04-23 10:15:02 +08:00
f516438360 Update README.md 2019-04-21 18:34:10 +03:00
7dc9abffc6 remove unnecessary f-strings 2019-04-16 07:38:50 +07:00
2285d0466e update bot list
Remove areajugonesbot; add vigobustelegrambot
2019-04-09 11:32:15 +02:00
31dbe30489 Merge pull request #629 from iv8/patch-1
fix errors
2019-04-07 21:43:41 +08:00
iv8
c77307881d fix errors 2019-03-04 15:24:55 +08:00
1a58731fb7 Add 'method' parameter to methods that edit message 2019-02-23 16:15:20 +02:00
99df992a66 Added the method sendAnimation, which can be used instead of sendDocument to send animations, specifying their duration. 2019-02-15 18:46:18 +00:00
79e6a3166d edit message_handler doc 2019-01-20 23:04:11 +05:00
8005ca2f6c Update example for api server check webhook alive. 2018-12-29 23:49:10 +08:00
b82ed70ec9 fix syntax errors 2018-11-17 13:19:09 +02:00
18e37f3d20 sleep time timeout time instead of 5 seconds always 2018-11-17 12:58:56 +02:00
ceea457cf1 Update shipping option
Setting list of ShippingOptions like in payments_example.py
shipping_options = [
    ShippingOption(id='instant', title='WorldWide Teleporter').add_price(LabeledPrice('Teleporter', 1000)),
    ShippingOption(id='pickup', title='Local pickup').add_price(LabeledPrice('Pickup', 300))]
gives us [None,None],so It's better add_price to return self
2018-11-12 01:43:00 +02:00
4131b05733 Update README.md
Adding another bot that user pyTelegramBotAPI.
2018-11-05 15:11:31 -03:00
ad4be5c0ae Merge branch 'master' of https://github.com/eternnoir/pyTelegramBotAPI 2018-10-19 13:40:14 +03:00
a946b79839 Merge pull request #586 from khode-mohsen/patch-2
Update deep_linking.py
2018-10-19 10:08:05 +08:00
4eeca78f2f Merge pull request #585 from khode-mohsen/patch-1
Update echo_bot.py
2018-10-19 10:07:55 +08:00
2d6c2a345f Merge pull request #577 from rmed/master
Add check for parse_mode in BaseInlineQueryResultCached
2018-10-19 10:07:40 +08:00
e62eeb7ff2 Merge pull request #565 from uburuntu/analyzer-fixes
Some analyzer fixes
2018-10-19 10:06:37 +08:00
76fc8fbe5e Update deep_linking.py
add '#!/usr/bin/python' for direct execute
2018-10-19 03:47:19 +03:30
584955962e Update echo_bot.py
add '#!/usr/bin/env' for direct execute
2018-10-19 03:38:03 +03:30
b8f442d06b Update Bots using this API 2018-10-09 17:32:27 +08:00
891988be93 Added check for parse_mode in BaseInlineQueryResultCached. Should fix #571 2018-09-15 20:25:06 +02:00
8636b282d7 Merge branch 'master' into analyzer-fixes 2018-09-07 18:07:37 +03:00
2c57c5c01c Update version. 2018-09-07 16:02:03 +08:00
07b82dc9b0 Merge pull request #575 from uburuntu/reset_session
Reset requests.Session feature
2018-09-07 15:56:59 +08:00
a850a0d94f Merge pull request #554 from uburuntu/patch-1
Pretty formatted docs for PyPI
2018-09-07 15:55:23 +08:00
d4f1444503 Merge pull request #574 from setazer/master
fix typo + add inline keyboard example
2018-09-07 15:54:11 +08:00
bab9f7bbb9 enh: reset requests.Session feature
Need for proxy changing and other reconnection stuff
2018-09-06 12:48:08 +03:00
d9ace2adc8 fix typo + add inline keyboard example 2018-09-05 12:34:19 +07:00
36621bb22a fix: some intendation 2018-08-17 13:01:03 +03:00
99466017c5 enh: optimize imports 2018-08-17 12:54:26 +03:00
feec1dde56 fix: little style fixes 2018-08-17 12:49:37 +03:00
54eba946be fix: wrong arguments usage (fix fa038c2) 2018-08-17 12:48:59 +03:00
65a272b901 fix: python 2/3 compatibility in examples 2018-08-17 12:47:44 +03:00
6a4c7e731b fix: delete doubled Sticker class (left a new one) 2018-08-17 12:46:40 +03:00
2b3c86b647 Merge pull request #562 from uburuntu/InputMedia
fix: python2 positional argument specifiers
2018-08-14 22:37:39 +08:00
e419214b49 fix: python2 positional argument specifiers 2018-08-14 17:29:35 +03:00
fe6959c38e Merge pull request #561 from uburuntu/InputMedia
fix: support python2 super()
2018-08-14 21:58:48 +08:00
7dd53b1396 fix: support python2 super() 2018-08-14 12:23:15 +03:00
421118d9d8 Merge pull request #558 from uburuntu/InputMedia
v.4.0: InputMediaAnimation, InputMediaAudio, InputMediaDocument, editMessageMedia
2018-08-13 23:47:03 +08:00
cf69a06ab8 enh: make code better and enhance test case 2018-08-10 16:48:09 +03:00
8ac6e664c5 new: InputMediaAnimation, InputMediaAudio, InputMediaDocument, editMessageMedia
Added support for editing the media content of messages: added the method editMessageMedia and new types InputMediaAnimation, InputMediaAudio, and InputMediaDocument.
2018-08-09 19:16:38 +03:00
12dbcb56d3 Update README.md 2018-08-09 08:45:07 +08:00
a46975d038 Merge pull request #556 from Andru1999/patch-2
Fix issue When you use threading mode
2018-08-08 10:06:49 +08:00
494b535a91 Fix issue When you use threading mode 2018-08-08 10:46:23 +10:00
74f75884f3 Delete now unused deprecated README.rst 2018-08-06 13:56:38 +03:00
4eae469528 Use last version of README.md for PyPI docs with pretty formatting
https://packaging.python.org/specifications/core-metadata/#description-content-type
https://pypi.org/project/pyTelegramBotAPI/
2018-08-06 13:54:46 +03:00
41f7c07959 Update version. 2018-08-03 08:35:04 +08:00
35ea2a2b7e Fix #548 2018-08-03 08:34:48 +08:00
522b2b487b Merge pull request #551 from heyyyoyy/origin/Bot_Api_3.6
Added parse mode for objects in Inline mode
2018-08-03 08:30:41 +08:00
5035e0ce80 Added parse mode for objects in Inline mode 2018-08-02 21:15:33 +03:00
7061091c1c Update version.
* Fix python 3.7 async
2018-07-31 08:58:04 +08:00
5c199bd246 Update README.md 2018-07-26 22:17:55 +08:00
44dd89881d Update README.md 2018-07-26 21:41:08 +08:00
8634e65249 Fix kick_chat_member decription
Fix kick_chat_member return value type description (should be boolean according to API and is boolean by fact).
2018-07-25 12:44:18 +03:00
76dbb05259 Merge pull request #537 from Andru1999/patch-1
Update __init__.py
2018-07-24 13:05:02 +08:00
578a9383b2 Merge branch 'master' into patch-1 2018-07-24 10:42:04 +08:00
85093bded5 Merge pull request #515 from WaffleWafflerov/master
Saving next step and reply handlers
2018-07-24 10:39:35 +08:00
27d442fabf timeout for send_message
Add optional "timeout" parameter to send_message (the same as exists in all other send_*).

Equal rights for all send functions! :)
2018-07-24 00:33:13 +03:00
f251def304 Merge branch 'master' into master 2018-07-22 04:43:53 +03:00
2b822f782d Update __init__.py
I find bug when I use your library without threading. If call bot.register_next_step_handler in function that register next_handler in next_step_handlers but in function _notify_next_handlers this delete and bot don`t have handler, but in threading mode function self.next_step_handlers.pop(chat_id, None) has time to eval self.next_step_handlers.pop(chat_id, None) and bug disappear. Sorry for my English
2018-07-22 00:31:02 +10:00
8bc5b74495 Remove 3.7 stable. Travis ci not support now. 2018-07-03 22:34:28 +08:00
70426ac274 Merge pull request #526 from skar404/master
rename async -> async_dec
2018-07-03 11:19:29 +08:00
a3a2bd5793 Add python 3.7 in travis ci.
#527
2018-07-03 11:17:44 +08:00
c3b6ee9dc0 bug in travis-ci 2018-07-02 23:41:37 +03:00
4079772fd3 Update .travis.yml 2018-07-02 23:29:07 +03:00
9547a8d7b1 test python 3.7 2018-07-02 23:23:48 +03:00
c8b2b14157 rename async -> async_dec 2018-07-02 18:13:11 +03:00
3d5ef5b1d8 Merge pull request #516 from Badiboy/master
_notify_next_handlers drops messages if empty handler list
2018-05-31 14:04:45 +08:00
776a699a8d _notify_next_handlers skips sequential messages
Is there are several sequential messages and next_step_handlers are set, the _notify_next_handlers will process only every even message dew to execute both .pop(i) and i+=1
2018-05-29 18:55:41 +03:00
78afd045d8 _notify_next_handlers drops messages if empty handler list
After calling
clear_step_handler(...)
code:
self.next_step_handlers[chat_id] = []
left the key in next_step_handlers.
When a next message arrives, the old handler executes nothing (no handlers), but still remove message from message queue:
new_messages.pop(i).

Updated to pop message only when there are real handlers in the list.
2018-05-27 23:24:37 +03:00
06faed887c Merge pull request #509 from Badiboy/master
html_text fix and html_caption
2018-05-27 23:14:37 +08:00
bc855f7610 Fix register_for_reply_by_message_id and register_for_reply doc strings. 2018-05-27 17:05:01 +03:00
893d5386c5 Fix register_for_reply_by_message_id doc strings. 2018-05-27 17:02:04 +03:00
909d570dca Add warning about lambda functions in callbacks 2018-05-27 17:01:07 +03:00
424c77fd2c Remove type hint for 2.x and PyPy python compatibility 2018-05-27 16:54:56 +03:00
333949683f Add doc strings to new TeleBot methods
Update telebot/__init__.py
2018-05-27 01:37:06 +03:00
fa038c2e42 Move del_file_after_loading param to right methods :face_palm:
Update: telebot/__init__.py
2018-05-27 01:30:14 +03:00
d61de35a32 Remove rudiment json things, again!
Update: telebot/__init__.py
2018-05-27 01:23:20 +03:00
13df7b5908 Add enable_save_next_step_handlers and load_next_step_handlers methods to step_example/
Update: examples/step_example.py
2018-05-26 17:21:39 +03:00
1de356dcc3 Change default save directory to "./.handler-saves/".
Add del_file_after_loading param to load methods.

Update: telebot/__init__.py
2018-05-26 17:10:00 +03:00
47e6dfd6bc Remove rudiment json things
Update: telebot/__init__.py
2018-05-26 16:52:30 +03:00
3c890a7846 Remove 2 spaces up to TeleBot class.
Update: telebot/__init__.py
2018-05-26 16:37:25 +03:00
17971ff48b Move from json to pickle.
Update: relebot/__init__.py
2018-05-26 12:19:01 +03:00
b989b7601b Add new class: Handler
Change type of (next step|reply) handlers from dict to Handler [WIP]

update: telebot/__init__.py
2018-05-25 20:57:22 +03:00
8c574a786a Merge branch 'master' of https://github.com/WaffleWafflerov/pyTelegramBotAPI-1 2018-05-25 20:37:36 +03:00
7e5f51e4ab Remove old thing.
Update telebot/__init__.py
2018-05-25 09:44:43 +03:00
018e4597a2 Add del_file_after_loading param to Saver.return_load_handlers and Saver.load_handlers methods.
Update telebot/__init__.py
2018-05-25 09:40:29 +03:00
7df6b3d4c9 Fix situation where delay <= 0.
Update telebot/__init__.py
2018-05-25 09:35:39 +03:00
4facc5f7d7 fix unenabled saving handlers.
Updated telebot/__init__.py
2018-05-25 09:30:10 +03:00
4bcfc34a50 Update _notify_next_handlers and _notify_reply_handlers methods:
Now if there wasn't any handler updates, timer willn't start.
2018-05-25 09:07:59 +03:00
b1d5cb2129 Rewrite.
Add class 'Saver' that provides methods for saving (next step|reply) handlers.
Add methods
enable_save_next_step_handlers,
enable_save_reply_handlers,
disable_save_next_step_handlers,
disable_save_reply_handlers,
load_next_step_handlers,
load_reply_handlers
to Telebot and AsyncTelebot.

update telebot/__init__.py
2018-05-25 08:57:48 +03:00
00c8dcc19b Add async methods 2018-05-25 03:10:40 +03:00
ed7e33b4c6 Fix loadings funcs 2018-05-25 02:48:46 +03:00
74a952846c Merge branch 'master' of https://github.com/CoconutWaffle/pyTelegramBotAPI-1 2018-05-24 18:32:25 +03:00
e99fb8f84f Add methods to save (reply|next step) handlers [WIP] 2018-05-20 23:40:25 +03:00
49aee14fca Make _test_filter method static and a bit clear doc strings 2018-05-19 00:42:06 +03:00
9267da205d Merge pull request #1 from eternnoir/master
Updating fork
2018-05-19 00:35:58 +03:00
9c79ba2f87 html_text fix and html_caption
html_text now works with text_link
html_caption now works for caption/caption_entities
2018-05-14 13:29:34 +03:00
3be21ae361 Update version. 2018-05-14 10:15:05 +08:00
42343c3a7f Merge pull request #490 from CoconutWaffle/master
Fixing and upgrading next step and reply handlers. + minor fixes
2018-05-04 07:20:18 +08:00
5a102ed8fa Merge pull request #492 from sviat9440/master
Bugfixes (message.html_text offset)
2018-05-04 07:19:28 +08:00
e1e109bef1 Merge pull request #502 from fojetin/patch-1
Fix #253 #231 #485
2018-05-04 07:18:57 +08:00
b5a217013a Fix #253 #231 #485 2018-04-30 15:41:12 +03:00
3ba9799b98 Renaming back pytelegrambotapi module to telebot 2018-04-28 13:50:59 +03:00
91f213ff34 Fix #501 2018-04-27 15:47:03 +08:00
8f55460924 Fix cache time is zero. 2018-04-26 09:53:55 +08:00
f6b999053d Merge pull request #497 from khabibr/master
Update apihelper.py
2018-04-24 23:52:45 +08:00
99ff104a3f Update apihelper.py
Correct files downloading when proxy used.
2018-04-24 16:48:39 +06:00
662c2c8797 Merge pull request #495 from BennyThink/master
fix issue #403: UnicodeEncodeError when sending a non-ASCII file in Python 2
2018-04-18 20:05:19 +09:00
72a0199a2f Merge pull request #496 from Jay-T/master
Update README.md
2018-04-18 20:04:27 +09:00
989cae597b Update README.md 2018-04-18 13:10:22 +05:00
5dd88f8223 fix issue #403: UnicodeEncodeError when sending a non-ASCII file in Python 2.7 2018-04-18 15:00:05 +08:00
28111bdf4e Merge pull request #494 from LeoNeeDpk1/patch-1
Update README.md SOCKS5 proxy info
2018-04-18 11:51:44 +09:00
10ec897fb5 Update README.md
Updated and 100% working info in SOCKS5 proxy block.
2018-04-18 10:05:26 +12:00
ffe3a0c3d7 Update types.py
-- Fix encoding bug (emoji shifted offset)
2018-04-15 19:19:29 +03:00
f5f48db6ba Merge pull request #1 from eternnoir/master
Update
2018-04-15 19:17:46 +03:00
183230e927 Update setup.py 2018-04-12 17:24:04 +03:00
7957bc45a8 Fixing and upgrading next step and reply handlers. + minor fixes
Rename telebot package to pytelegrambotapi becouse lib named telebot exists and it raising many errors

Add methods:
|     register_for_reply_by_message_id,
|     register_next_step_handler_by_chat_id,
|     clear_reply_handlers,
|     clear_reply_handlers_by_message_id
2018-04-12 13:45:32 +03:00
373d4d37ff Fix test case. 2018-04-10 14:48:39 +08:00
0d0e37dae5 Merge pull request #487 from sviat9440/master
Bugfixes and minor improvements
2018-04-10 15:25:36 +09:00
36d088dfbf Bugfixes and minor improvements 2018-04-04 10:47:37 +03:00
9ae20b4815 Merge pull request #482 from sviat9440/master
Minor improvements
2018-03-25 21:39:27 +08:00
e761e1e1d9 Update apihelper.py 2018-03-25 14:54:28 +03:00
cb0256b37d Update __init__.py 2018-03-25 13:22:35 +03:00
ff3cbaf45b Update apihelper.py 2018-03-25 13:21:55 +03:00
d231b1fbaa Bump version. 2018-03-23 19:59:42 +08:00
7f47f11444 Fix #481 2018-03-23 19:58:43 +08:00
0422e62f65 Update types.py
Fix
2018-03-21 10:45:34 +03:00
82e252ec46 Update types.py
Fix
2018-03-21 10:44:37 +03:00
c11a9f810c Update types.py
Added 'json' property to class 'Message', to quickly save a message to the database
2018-03-21 07:35:42 +03:00
d17d28a144 create field forward_from_message_id in Message
https://core.telegram.org/bots/api#message
2018-03-20 23:36:29 +03:00
dadcd5a577 Update "Bots using this API" entry. 2018-03-19 15:13:48 +08:00
afc9abc269 Add ci test for python 3.6 2018-03-10 14:48:30 +08:00
e01f17e3a0 Bump version. 2018-03-10 14:46:47 +08:00
48e6757686 Fix import logger problem. 2018-03-10 14:41:34 +08:00
8495229ce1 Update version 3.6.0 2018-03-02 19:28:34 +08:00
3b60f7ca67 Merge pull request #462 from heyyyoyy/Bot_Api_3.6
Bot Api 3.6
2018-02-22 22:11:46 +08:00
a1930e05c2 Merge pull request #463 from dmytrostriletskyi/master
Make the Heroku example actual
2018-02-22 20:52:53 +08:00
bc067662dc Make the Heroku example actual 2018-02-16 17:52:37 +02:00
518c49f23a fixing formatting of caption in the method send_document 2018-02-16 18:29:29 +03:00
903b1dfd50 added parse_mode in edit_message_caption 2018-02-16 14:19:35 +00:00
2e199a5684 Bot Api 3.6 2018-02-14 20:27:55 +00:00
55302cb972 Merge pull request #445 from heyyyoyy/update_send_media_group
Added support for local files in the sendMediaGroup method
2018-02-01 19:24:50 +08:00
f47653d2e4 Update README.md 2018-01-24 19:13:29 +08:00
94b4a25980 Update version. 2018-01-24 19:11:03 +08:00
afac177d7d Fix missing media_group_id in message. 2018-01-24 19:05:38 +08:00
2637e29dbe Updated sendMediaGroup method 2018-01-15 16:08:50 +03:00
6d180e30f0 Merge pull request #443 from reacheight/master
fixed example of usage sendVideoNote method
2018-01-15 10:25:06 +08:00
e2ed4cf065 Merge pull request #387 from fumycat/patch-1
Fix optional parameter
2018-01-15 10:23:26 +08:00
8b2dea1d56 fixed example of usage sendVideoNote method 2018-01-10 00:26:44 +03:00
41e31de034 Merge pull request #429 from JekaFST/master
Fix for SendLocation with live period
2017-12-06 15:50:49 +08:00
ae074fd5c9 Merge pull request #2 from JekaFST/JekaFST-live_location_fixes
Edit and stop live location fixes
2017-12-05 01:32:06 +03:00
60596a95b8 Edit and stop live location fixes
.token was missed in apihelper's methods calls
2017-12-05 01:31:47 +03:00
44531bcedf Merge pull request #1 from JekaFST/JekaFST-FixLiveLocation
Fix for SendLocation with live period
2017-12-05 00:23:32 +03:00
8aa8fa5986 Fix for SendLocation with live period
Fix for payload['live_perion'] typo -> payload['live_period']
2017-12-05 00:21:05 +03:00
f0e64b3653 Merge pull request #428 from 0xVK/patch-1
Added SmartySBot to README
2017-12-04 16:21:41 +08:00
8444ea588a Added SmartySBot to README
Added SmartySBot to README
2017-12-03 20:34:37 +02:00
b2f376a906 Remove debug message. Add content_type 2017-11-30 23:34:07 +08:00
d0b4bb7c69 Bump version. 2017-11-29 14:09:57 +08:00
c300195b49 Add provider_data . 2017-11-29 13:59:47 +08:00
2493b200a4 Add provider_data to sendInvoice. 2017-11-29 13:53:39 +08:00
8528ca9e4e Add some message content type. Fix #426 2017-11-29 13:48:34 +08:00
e1a3ccadb7 Add sendMediaGroup method. 2017-11-29 13:45:25 +08:00
a43f037bc9 Version update. 2017-11-15 00:42:50 +08:00
7ac246b801 Fix inline_query_handler not work. 2017-11-15 00:42:27 +08:00
47624a556e Update version. 2017-11-13 10:26:27 +08:00
8bdbc24014 Fix ShippingOption to_json. #414 2017-11-13 10:25:39 +08:00
e45ced958a Update version to support 3.4. 2017-11-13 10:19:13 +08:00
46c803bf55 Fix shipping_options bug. #414
Update version.
2017-11-13 10:14:10 +08:00
3986f33d3a Fix caption_entities without default value. 2017-11-06 08:42:57 +08:00
c327be5a03 Merge pull request #410 from 0xVK/fix-exec-handlers
#405 - Message has callback function but it exec command handlers too.
2017-11-04 21:28:21 +08:00
d8587419e1 Fixed bug when message has next step handler and exec command handlers. 2017-11-04 15:09:29 +02:00
35d7293ebd Merge pull request #402 from MasterGroosha/master
Bot API 3.4: new methods for live locations, new objects.
2017-10-31 09:51:23 +08:00
8e71a612a6 Added missing methods definitions to __init__.py and Async Telebot 2017-10-22 20:07:51 +03:00
5f8d99664e Bot API 3.4: new methods for live locations, new objects. 2017-10-22 19:50:51 +03:00
aaa968c27f Merge pull request #396 from MasterGroosha/patch-1
Added missing author_signature field to Message object
2017-09-25 16:42:38 +08:00
600c014515 Added missing author_signature field to Message object
`author_signature` field was checked, but never added to `Message` object.
2017-09-22 01:08:54 +03:00
0a80fafd76 Update README.md 2017-09-09 21:32:13 +08:00
4a11bb60b4 Update new_chat_member to new_chat_members 2017-09-08 15:47:16 +08:00
7d37374667 Fix test case. 2017-08-28 12:13:26 +08:00
6ad56eb30f Merge pull request #392 from MasterGroosha/master
Bot API 3.3
2017-08-28 11:50:25 +08:00
211f1c607d Bot API 3.3:
- Added the new field pinned_message to the Chat object.
- Added the new fields author_signature and forward_signature to the Message object.
- Added the new field is_bot to the User object.
2017-08-23 10:30:32 +03:00
be786021dc Merge pull request #389 from mostafaqanbaryan/patch-1
Update __init__.py
2017-08-22 04:06:08 +07:00
15d287919d Update __init__.py
Add clear_step_handler() for resetting bot
2017-08-21 14:40:47 +04:30
af991ea76e Fix optional parameter 2017-08-20 01:36:08 +07:00
064b84ad3d Merge pull request #377 from GabrielRF/master
Update README.md
2017-08-13 00:40:50 +08:00
39b4f0a068 Merge branch 'master' into master 2017-08-10 15:03:39 -03:00
246e7e31d7 Update README.md 2017-08-08 21:50:54 +08:00
48bfb7b84f Update version. 2017-08-06 15:47:59 +08:00
dcddedcd24 Fix file dic. 2017-08-06 15:35:43 +08:00
2e743b4b86 Add v3.2 method. 2017-08-06 15:22:23 +08:00
af70313721 New method for v3.2 2017-08-06 14:25:25 +08:00
aefd666062 Update sticker set. 2017-08-06 12:00:26 +08:00
23d66afbb0 Merge pull request #381 from noirgif/master
change the documentation of TeleBot.polling in readme
2017-08-01 09:31:01 +08:00
ed29f9316f change the documentation of TeleBot.polling in readme 2017-07-30 23:24:30 -07:00
e92dc3717e Update README.md 2017-07-24 14:28:27 -03:00
c91ce6036b Merge pull request #372 from Kylmakalle/master
Async Methods for API v3.1
2017-07-23 15:50:02 +08:00
cb60a1256f Merge pull request #374 from the31k/per_thread_requests_sessions
Per-thread requests sessions
2017-07-23 15:49:42 +08:00
96569cbdac Fix typo 2017-07-19 15:44:10 +03:00
feec19b7f4 Use per-thread requests sessions
Reason is requests.Session is not thread-safe
See: https://github.com/requests/requests/issues/2766
2017-07-19 01:50:12 +03:00
1a80fc5a0e Per-thread singletons 2017-07-19 01:50:04 +03:00
488fb745b7 Merge pull request #359 from Yolley/master
Informative exception message for better exception handling
2017-07-07 10:45:23 +08:00
08d6ab549d Aync Methods for v3.1 2017-07-07 00:54:18 +03:00
f718c36ea7 Merge remote-tracking branch 'refs/remotes/eternnoir/master' 2017-07-07 00:29:40 +03:00
ed88939110 Merge remote-tracking branch 'refs/remotes/eternnoir/master' 2017-07-07 00:25:13 +03:00
0632cfb9b0 Fix new chat members. 2017-07-02 21:24:19 +08:00
4979589faf Fix not require args. #369 2017-07-02 21:08:36 +08:00
d2f694516a Update version. 2017-07-01 11:24:29 +08:00
5f8ed347a1 Add missing arg until_date for kickChatMember. 2017-07-01 11:11:25 +08:00
514880fe22 Merge remote-tracking branch 'origin/proxySupport' 2017-07-01 11:06:05 +08:00
f97bb2f615 FIx missing declare 2017-07-01 11:05:14 +08:00
38af4f441b Merge pull request #368 from MasterGroosha/botapi_v3.1
Bot API v3.1
2017-07-01 10:33:35 +08:00
662a834138 Added missing arguments to restrict_chat_member method 2017-06-30 20:16:51 +03:00
25a37db2bb Bot API v3.1 2017-06-30 19:47:09 +03:00
3e04df7080 Update README.md 2017-06-28 18:01:07 +08:00
6af3067a12 Add proxy to readme. 2017-06-28 17:44:07 +08:00
32c2178b29 Merge pull request #362 from BoberMod/patch-1
Using some content types in one function
2017-06-26 08:28:28 +08:00
6786f87d66 Using some content types in one function 2017-06-23 17:01:05 +03:00
ebdd7d107e Merge pull request #361 from ihoru/master
json.dumps(allowed_updates) before sending request
2017-06-22 14:55:35 +08:00
3713b093b6 json.dumps(allowed_updates) before sending request 2017-06-22 10:35:13 +07:00
242456d92b Update util.py 2017-06-20 15:45:18 +03:00
328cabead6 Update util.py 2017-06-20 15:45:01 +03:00
e834903bc2 Merge pull request #357 from gabolaev/fixDownloadingExample
Added file opening mode
2017-06-16 10:39:39 +08:00
556a04ca8b Added file opening mode 2017-06-16 02:57:12 +03:00
4b165ba3f1 Merge pull request #305 from MonsterDeveloper/patch-2
Added option to disable CherryPy logging
2017-06-02 16:13:56 +08:00
4e1d5b83b6 Merge pull request #349 from MasterGroosha/patch-2
Fixed wrong method call
2017-06-02 16:13:18 +08:00
cb4521f497 Fixed wrong method call
Should be called `apihelper.answer_shipping_query` instead of `apihelper.answer_shippingQuery`
2017-06-02 11:07:35 +03:00
52e50f1286 Merge pull request #347 from denkorzh/patch-1
Update README.md
2017-06-01 17:23:08 +08:00
3f626d37ba Update README.md
Fixed hyperlink formatting in the subtitle
2017-06-01 10:44:46 +03:00
d6aaf0716a Update version.
Change log:
- Fix #314
2017-05-30 17:19:03 +08:00
777a3afaaa Fix #314 2017-05-30 17:18:03 +08:00
0b1ae6ad8b Update version. 2017-05-30 17:18:03 +08:00
7aca24a18b Merge pull request #346 from Kylmakalle/master
Added payments example
2017-05-26 11:05:40 +08:00
754ca77394 Add payments bot example 2017-05-25 21:00:48 +03:00
5ffd9c5755 Merge remote-tracking branch 'refs/remotes/eternnoir/master' 2017-05-25 20:46:10 +03:00
639218b3bf New fields gif_duration in InlineQueryResultGif and mpeg4_duration in
InlineQueryResultMpeg4Gif.
2017-05-25 13:27:13 +08:00
b2449e64c2 Add pay in inline keyboard btn, 2017-05-25 11:48:16 +08:00
708635e420 Fix handler. 2017-05-25 11:45:44 +08:00
84b1aca939 Fix method name. 2017-05-25 11:23:37 +08:00
9025be0ef2 Add handlers. 2017-05-25 11:22:40 +08:00
a8e60b28e0 Fix requirement params. 2017-05-25 11:14:08 +08:00
cf287af549 Add payment method. PEP8. Refactor. 2017-05-25 10:56:58 +08:00
2d10793686 Merge pull request #343 from Kylmakalle/feature-BotAPIV3
Payments methods
2017-05-24 14:31:11 +08:00
3a10c90799 Payments methods 2017-05-24 01:23:52 +03:00
f8fed5c942 Merge remote-tracking branch 'refs/remotes/eternnoir/feature-BotAPIV3' into feature-BotAPIV3 2017-05-23 23:37:33 +03:00
12791e1366 Add payments type to update and message. 2017-05-21 21:52:56 +08:00
5ed333492b All payment type done. 2017-05-21 21:45:12 +08:00
9134e8dd1a Add send video note test case. 2017-05-21 19:58:00 +08:00
43a30e7777 Merge pull request #338 from Kylmakalle/feature-BotAPIV3
Video Note support.
2017-05-21 19:47:30 +08:00
3f5596ddce new_chat_members content type and new send_action actions 2017-05-21 14:27:31 +03:00
443d81d4db FIX: Can't edit file bytes 2017-05-19 18:08:07 +03:00
6cda8d052c VideoNote support
Send and recieve round video messages.
Support for send_video_note metod and video_note content type.
2017-05-19 17:19:15 +03:00
5969a6644c Merge pull request #1 from eternnoir/master
Merging to master
2017-05-19 16:22:07 +03:00
791a183af5 Merge pull request #336 from i32ropie/master
Added language code for users
2017-05-19 10:04:30 +08:00
35214b1270 Added language code for users 2017-05-18 23:40:10 +02:00
50ea288c9e Merge pull request #333 from Kurbezz/master
Add methods to AsyncTeleBot
2017-05-18 21:52:18 +08:00
34047c0121 Add methods to AsyncTeleBot 2017-05-18 13:55:55 +04:00
1a70c2d613 Merge pull request #319 from Artom-Kozincev/master
Add more accurate control over threads count
2017-05-17 14:48:18 +08:00
6d18a2c22f Merge pull request #325 from Kylmakalle/master
Added option to delete messages.
2017-05-16 16:54:34 +08:00
89f515b120 deleteMessage returns Ok on success, not Message type 2017-05-12 01:13:40 +03:00
11f0733974 Merge pull request #326 from jiwidi/master
Update readme
2017-05-08 10:25:54 +08:00
b91eeb2752 Update readme 2017-05-07 18:27:04 +02:00
f7cfb98b60 Added option to delete messages.
Added option to delete messages.

Some bots do not support this method now, waiting for an official api
release.
2017-05-07 17:37:03 +03:00
8bf226e6bf Bump version. 2017-04-30 20:37:55 +08:00
450ef42a83 Fix typo. 2017-04-30 19:40:27 +08:00
4fc83a85ee Merge pull request #321 from bryant1410/master
Fix broken headings in Markdown files
2017-04-18 13:31:55 +08:00
8dca85b1f2 Fix broken Markdown headings 2017-04-18 01:38:53 -03:00
fc65b30e3a Update README.md 2017-04-15 23:27:07 +08:00
e138d2e1ef Add more accurate control over threads count 2017-04-06 22:12:17 +03:00
d29c816b79 Merge pull request #318 from ihoru/master
RecursionError fix during sending files
2017-04-05 14:13:22 +08:00
f220a68c00 Merge pull request #312 from MonsterDeveloper/patch-3
Added webhook example with Tornado
2017-04-05 14:12:45 +08:00
94d723cf7b Merge pull request #317 from MonsterDeveloper/patch-4
Added IGNORECASE flag to message_handler
2017-04-05 14:12:07 +08:00
662c69e09c RecursionError fix during sending files 2017-04-02 14:56:53 +07:00
43f026dc64 Added IGNORECASE flag to message_handler
Added re.IGNORECASE flag to message_handler, so it matches without chars case.
2017-03-28 16:24:28 +03:00
2c631b2973 Added webhook example with Tornado 2017-03-23 15:34:33 +03:00
401a848927 Added option to disable CherryPy logging 2017-03-07 21:43:14 +03:00
7f31f8dde8 Merge pull request #294 from bace1996/patch-1
Fixed README.MD
2017-03-05 20:18:07 +08:00
19b8b4d2bf Fix readme image url link 2017-03-05 20:17:46 +08:00
6515c7c494 Update version. 2017-03-04 21:30:35 +08:00
76a48ffe82 Bug fix for edited_channel_post_handler. 2017-03-04 21:30:07 +08:00
f8f0e0c343 Update Bots using this API list 2017-03-03 11:00:03 +08:00
8129b95118 Fixed README.MD
Fixed a problem that could not jump to "Using web hooks" correctly
2017-02-15 21:31:52 +08:00
2b7e9a6180 Merge pull request #293 from MonsterDeveloper/patch-1
Fixed typo: from plan to plain
2017-02-10 15:33:03 +08:00
a84c0b984b Fixed typo: from plan to plain
Line 184: from `return message.document.mime_type == 'text/plan'` to `return message.document.mime_type == 'text/plain'`
2017-02-09 16:49:15 +03:00
a356c9a325 Merge pull request #283 from roboxv/master
Extend examples with aiohttp
2017-02-02 10:45:49 +08:00
4c4e8deaee Merge pull request #284 from Kuznitsin/master
Non-ASCII chars for filename.
2017-02-02 10:45:19 +08:00
f7fc538bd8 Non-ASCII chars for filename. Telegram doesn't accept rfc2231 styled filename. Using utf-8 directly. 2017-01-30 17:40:18 +03:00
6c770d81f9 Extend examples with aiohttp 2017-01-30 01:54:49 +06:00
d6af33fef7 Merge pull request #277 from i32ropie/master
Updated from ReplyKeyboardHide() methode to ReplyKeyboardRemove()
2017-01-23 11:21:10 +08:00
b6fee07089 Updated from ReplyKeyboardHide() methode to ReplyKeyboardRemove() 2017-01-20 10:55:34 +01:00
a5d6b541a5 Update README.md 2017-01-15 00:57:05 +08:00
ecad88ad00 Merge pull request #275 from mefuckin/patch-1
Fix error in webhook flask example
2017-01-05 11:02:10 +08:00
be87e4b2b9 Fix error in webhook flask example 2017-01-04 21:50:09 +03:00
1215eee167 Merge pull request #272 from mymedia2/persistent-connection
Use session to ensure persistent connection to api.telegram.org
2016-12-20 00:57:22 +08:00
9fe8565d53 Use session to ensure persistent connection to api.telegram.org 2016-12-17 09:03:00 +03:00
1058822f85 Merge pull request #266 from Yolley/patch-1
Added isinstance for bytes to function 'add' in ReplyKeyboardMarkup
2016-12-13 10:02:58 +08:00
57a57c8aca Merge pull request #268 from MasterGroosha/patch-1
Added max_connections and allowed updates to WebhookInfo
2016-12-13 09:45:55 +08:00
12e7879325 Added max_connections and allowed updates to WebhookInfo 2016-12-12 19:29:57 +03:00
d14bd9a36b Add isinstance for bytes to function 'add' in ReplyKeyboardMarkup
All explanation is here https://github.com/eternnoir/pyTelegramBotAPI/issues/265
2016-12-06 17:12:28 +03:00
c168feea32 Version update:
Change log:
- Telegram bot api 20161121 new feature.
- Telegram bot api 20161204 new feature.
2016-12-06 12:09:28 +08:00
a06551daaf Add delete webhook. 2016-12-06 11:52:16 +08:00
eadff07f79 Add allowed_updates to get_updates. 2016-12-06 11:44:30 +08:00
b5e27d0fea Add max_connections and allowed_updates to set_webhook. 2016-12-06 11:42:15 +08:00
509fae6792 Bug fix. 2016-12-03 15:17:06 +08:00
b0bc49c803 Update readme. 2016-12-03 13:56:22 +08:00
e555da86dd Add cache_time to answerCallbackQuery 2016-12-03 13:38:30 +08:00
9a5e8302be Add force params in setGameScore method. 2016-12-03 13:31:55 +08:00
30ed6e37d3 Add channel_post, edited_channel_post support. 2016-12-03 13:28:22 +08:00
27a79c4be5 Merge pull request #254 from Kondra007/patch-2
Bot API November updates
2016-11-25 08:27:15 +08:00
c99bb16619 Updated set_game_score
• New field `force`
• Changed `edit_message` to `disable_edit_message`
2016-11-21 09:28:32 +03:00
856af72599 Added cache_time to answer_callback_query 2016-11-21 09:19:59 +03:00
8c8be81bb9 Added optional forward_from_message_id
And changed `forward_date` to optional (as it should be)
2016-11-21 09:10:51 +03:00
b2cd3c9716 Added channel_post and edited_channel_post to Update object 2016-11-21 09:06:36 +03:00
1c9a9b9622 hide_keyboard -> remove_keyboard 2016-11-21 08:57:38 +03:00
f413ccf3fb Merge pull request #257 from rmed/wat-bridge
Added wat-bridge to the list of bots
2016-11-21 10:37:01 +08:00
9aaa00c8fd Added wat-bridge to the list of bots 2016-11-20 19:04:21 +00:00
11c2505d50 Update readme. 2016-11-18 19:37:29 +08:00
91076d0b59 Add dailypepebot to list. 2016-11-18 19:37:00 +08:00
1691e84d01 ReplyKeyboardHide -> ReplyKeyboardRemove
Since Telegram changed object name in API docs: https://core.telegram.org/bots/api#replykeyboardremove
2016-11-16 14:18:39 +03:00
903de2a72c Merge pull request #252 from DmytryiStriletskyi/striletskyi
Update README.md
2016-11-11 15:03:15 +08:00
9ddc529b28 Update README.md 2016-11-09 20:24:27 +02:00
d9ca776e2c Update README.md 2016-11-09 20:03:28 +02:00
2c497edca6 Update README.md 2016-11-03 16:43:46 +08:00
bf6634bc36 Version update.
Chnage log:
- Fix InlineQueryResultGame's reply_makrup bug.
- Remove type param from InlineQueryResultGame contractor.
2016-11-01 01:23:51 +08:00
2455d7013c Merge branch 'bug-fixInlineQueryResultGame' 2016-11-01 01:23:21 +08:00
7a6bb4dcc8 Remove type in InlineQueryResultGame. 2016-11-01 01:14:28 +08:00
e342b9fa6b Fix InlineQueryResultGame replymarkup do not to_dic. 2016-11-01 01:10:06 +08:00
2e8151cb7d Version update. 2016-10-31 00:35:07 +08:00
2af9209005 Fixed KeyError when data field is None in CallbackQuery
obj['data'] raises KeyError when `data` is None, while obj.get('data') returns None
2016-10-30 18:23:57 +08:00
34b0a2404e Version change.
Change log:
- bug fix.
2016-10-30 07:05:15 +08:00
f6d5358d1a Merge pull request #245 from Kondra007/patch-11
Fixed API object type mismatch
2016-10-30 07:03:53 +08:00
d2e1acde6a Fixed API object type mismatch 2016-10-29 23:23:39 +03:00
aad9251d48 Version update.
Change log:
* Gaming platform new methods.
* Other change in October 3, 2016 update.
(https://core.telegram.org/bots/api/#recent-changes)
2016-10-29 21:44:02 +08:00
54ed2038aa New methods setGameScore and getGameHighScores. 2016-10-29 21:22:46 +08:00
1b767215b5 Merge pull request #243 from Kondra007/patch-10
Added setGameScore and getGameHighScores
2016-10-27 10:41:47 +08:00
6f8ebbae89 Added setGameScore and getGameHighScores
1. https://core.telegram.org/bots/api#setgamescore
2. https://core.telegram.org/bots/api#getgamehighscores
2016-10-26 16:19:04 +03:00
d1498979d4 Merge branch 'JrooTJunior-master' into feature-20161003update 2016-10-20 20:09:07 +08:00
702763edd6 Get webhook info
https://core.telegram.org/bots/api#getwebhookinfo
2016-10-20 10:52:38 +03:00
ffa0ea449b Fix test case. 2016-10-12 15:52:34 +08:00
d53a881ac4 Merge pull request #238 from Kondra007/patch-6
Added "all_members_are_administrators" field to Chat object
2016-10-12 12:01:46 +08:00
67583d3639 Merge pull request #240 from Kondra007/patch-9
Added caption field to several objects
2016-10-12 12:00:32 +08:00
0f3398ed2f Merge pull request #239 from Kondra007/patch-7
Added Caption field to sendAudio & sendVoice
2016-10-12 11:59:15 +08:00
08dd7d1593 Added caption field to several objects
InlineQueryResultAudio, InlineQueryResultVoice, InlineQueryResultCachedAudio, InlineQueryResultCachedVoice
2016-10-11 22:57:16 +03:00
7e94810ece Added Caption field to sendAudio & sendVoice 2016-10-11 22:51:20 +03:00
11aa5fcb85 Added "all_members_are_administrators" field to Chat object 2016-10-11 22:43:44 +03:00
8d65856dec New field callback_game in InlineKeyboardButton, new fields
game_short_name and chat_instance in CallbackQuery.
2016-10-08 22:04:44 +08:00
740d7f44cf Add url param in answer inline query. 2016-10-08 21:55:28 +08:00
b8e5c43598 Add send game method. 2016-10-08 20:36:48 +08:00
795a00f92c Add game in Message. InlineQueryResultGame 2016-10-08 20:06:08 +08:00
de740be506 Add class Game,Animation,GameHighScore. For Game feature. 2016-10-08 19:50:29 +08:00
cd89de5a9a Update README.md 2016-09-29 13:35:42 +08:00
4dc2d5f1db Update README.md 2016-09-29 13:25:01 +08:00
1b0a872619 return statement added to callback_query_handler in decorator 2016-09-28 20:07:15 +08:00
82cf5535dd Merge pull request #230 from Kondra007/patch-6
Update Readme.md
2016-09-19 10:59:01 +08:00
48002f280b Update Readme.md
Added new content_types names in documentation.
2016-09-18 20:36:40 +03:00
057d130baa Update README.md 2016-09-17 20:32:54 +08:00
88e49bdaef Update test case. 2016-09-17 07:55:25 +08:00
acdc2058c5 Version change.
Change log:
- Fix venue's location not dejson to Location object.
2016-09-17 07:49:05 +08:00
a5ed76018d Fix venue Loacation dejson. 2016-09-17 07:38:18 +08:00
bac269d48a Update pytest. 2016-09-12 17:13:48 +08:00
e69790a8fc CI support py3.5. 2016-09-12 16:53:48 +08:00
590b27ca8a Add ujson support. 2016-09-12 16:38:54 +08:00
404f81fd43 Version update.
Change log:
- bugs fix.
2016-08-29 21:50:26 +08:00
89cf2658ae Fix edit reply markup return bool. 2016-08-29 20:50:27 +08:00
ea92e8696e Fix test case. 2016-08-29 20:48:09 +08:00
6da88c9751 FIx #225 2016-08-29 20:21:56 +08:00
ff5f6f727a Fix document #220 2016-08-11 22:46:40 +08:00
315400de47 Merge pull request #219 from olshevskiy87/t1
fix relative link for "callback query handlers" in readme
2016-08-10 10:37:36 +08:00
ca33801565 fix relative link for "callback query handlers" in readme 2016-08-09 16:17:45 +03:00
c61b82ace6 Update create_threads to threads. #198 2016-07-17 23:38:37 +08:00
8a4d2000d2 Update message's content_type doc. #199 2016-07-17 23:36:43 +08:00
f9d7f6905b Merge pull request #209 from QtRoS/master
Example of inline bot fixed
2016-07-17 23:15:34 +08:00
124b550de5 Merge pull request #1 from QtRoS/QtRoS-inline-bot-fix
Example of inline bot fixed
2016-07-17 15:55:11 +03:00
653c892b33 Example of inline bot fixed 2016-07-17 15:54:26 +03:00
b79c3165a1 Add issue templaate. 2016-07-11 21:45:52 +08:00
303406020b Update version. 2016-07-11 21:45:52 +08:00
3dcd59c22e Fix example 2016-07-11 21:29:25 +08:00
d847cfb9fa Merge branch 'bug-fix#202' 2016-07-06 10:22:55 +08:00
4205e46608 Fix missing location object in InlineQuery. 2016-07-06 10:13:42 +08:00
2044fba29a Update version. 2016-06-17 17:55:53 +08:00
29ef0e74af Fix typo. 2016-06-17 17:50:06 +08:00
46fc8da79e Merge pull request #197 from aivel/master
+ More flexibility for different handlers(callback_query_handler and etc.)
2016-06-17 01:22:07 +08:00
Max
b9a0c3e511 + More flexibility for different handlers(callback_query_handler and
etc.): now they are not limited in input arguments so can be easily
extended by subclassing

arguments
2016-06-16 11:49:51 +03:00
a4ac83aec2 Merge pull request #196 from auveele/patch-1
Update README.md
2016-06-15 20:03:22 +08:00
70fa5b405a Update README.md 2016-06-15 13:30:57 +02:00
c7d2731559 Merge pull request #195 from aivel/master
Some changes to make the library more flexible in terms of extensibility
2016-06-13 22:33:42 +08:00
Max
527351385b + Don't check filters against NoneType values;
+ More flexibility for subclassing:
	- __exec_task is protected now(was private)
	- _test_message_handler and _test_filter are class members
	  now(used to be static methods)
+ More flexibility on extention of message_handler(**kwargs for
additional parameters)
2016-06-13 16:47:15 +03:00
Max
1b47e5cc62 code duplication lessened 2016-06-13 14:24:27 +03:00
Max
eb4d58bec1 little optimization on handler dictionary building: code duplication lessened 2016-06-13 14:15:15 +03:00
57486b18cd Remove download count from readme. 2016-06-07 20:04:19 +08:00
25ad3f055f Update version.
Change log:
- Added new methods: getChat, leaveChat, getChatAdministrators,
  getChatMember, getChatMembersCount.
- New fields: edited_message in Update, edit_date in Message, user in
  MessageEntity. New value text_mention for the type field in
MessageEntity.
2016-06-07 19:57:40 +08:00
cdb6d6760d Add some comment. 2016-06-07 19:44:30 +08:00
5bd8e9d3f5 Update readme. 2016-06-07 19:40:35 +08:00
fab2f324d0 Fix test case. 2016-06-07 19:34:46 +08:00
9bf4be2caf fix test case. 2016-06-07 19:32:12 +08:00
d701fd6e1d Merge remote-tracking branch 'origin/feature-changes20160522' into api2.1 2016-06-07 19:30:01 +08:00
8e3c9d8d24 Add edited message handler. 2016-06-07 19:29:12 +08:00
0b9f91c6fb Add new method test case. 2016-06-07 19:16:17 +08:00
468a535257 Fix de_json. 2016-06-07 19:08:52 +08:00
d2e7f4d8f2 Add 2.1 new method. 2016-06-07 19:00:44 +08:00
ddd3664329 Merge pull request #192 from alejandrocq/comedoresugrbot
Add ComedoresUGRbot to bots list.
2016-06-06 01:32:45 +08:00
9e397c41cf ComedoresUGRbot added to bots list. 2016-06-05 19:20:17 +02:00
b528b0bcf0 Merge pull request #191 from Ledokol/uni-json
unicode strings for check_json
2016-06-05 18:36:36 +08:00
2f20d70e89 unicode strings for check_json 2016-06-04 21:18:09 +05:00
ac740e4755 Change public link to invite link. 2016-06-03 17:21:33 +08:00
2cf8ffcbc0 Update group link. 2016-06-03 14:45:25 +08:00
87ad4a62ff Merge pull request #187 from GabrielRF/master
Added Send2KindleBot
2016-06-03 00:06:10 +08:00
6b255deed7 Added Send2KindleBot
Also added description of urlprobot and lmgtfy_bot
2016-06-02 12:04:04 -03:00
ce24aa25f2 Fix #179. 2016-06-02 13:25:50 +08:00
a0f25089e0 Merge pull request #177 from qwidim/master
heroku webhook example
2016-06-02 13:17:12 +08:00
1bfdf7cf35 Merge pull request #173 from dmcelectrico/master
Added optional connection (aka sending) timeouts to methods that may …
2016-05-31 02:11:31 +08:00
5b1de9f339 Merge pull request #181 from PowerInside/patch-1
Fix inline demo code in readme.md
2016-05-29 22:29:21 +08:00
e956800e34 Fix inline demo code in readme.md 2016-05-29 19:25:36 +05:30
b9a57f630a Merge pull request #178 from Kondra007/patch-5
Update Readme.md
2016-05-26 11:02:30 +08:00
851d76888b Update Readme.md
Added `user` to attributes list
2016-05-26 00:44:39 +03:00
05f1c87c7d Update webhook_flask_heroku_echo.py 2016-05-25 19:25:46 +06:00
59b19fbbc1 Update webhook_flask_heroku_echo.py 2016-05-25 19:15:13 +06:00
e87907f0b8 Update webhook_flask_heroku_echo.py 2016-05-25 01:44:09 +06:00
d84aa796c0 Add files via upload 2016-05-25 01:42:25 +06:00
8c20f63022 Add user to MessageEntity. 2016-05-23 11:12:20 +08:00
f9c7497c5c Merge branch 'Kondra007-patch-3' into feature-changes20160522 2016-05-23 11:05:14 +08:00
3413669a23 Added optional connection (aka sending) timeouts to methods that may upload big chunks of data: send_audio, send_voice, send_document, send_sticker and send_video. 2016-05-22 18:35:20 +02:00
1a45b4844a Fixed Travis build (again)
Yeah, I'm really sorry for all this errors, maybe tired a little bit.
2016-05-22 15:47:44 +03:00
8a9d89591b Fixed Travis build errors 2016-05-22 15:44:04 +03:00
234dd8cf9f Edited edit_date field
It's integer, not `Message`
2016-05-22 13:55:54 +03:00
6a98d27f1a Added edited_message to Update object
As of Bot API update 2.1, Update object now has optional edited_message field.
2016-05-22 13:35:21 +03:00
04df139efb Added edit_date to Message object
As of Bot API update 2.1, `Message` object now has optional `edit_date` field.
2016-05-22 13:32:53 +03:00
747f14216b Merge pull request #166 from Kondra007/patch-1
Changed "Process_new_message" to "Process_new_update"
2016-05-20 23:23:10 +08:00
aee9255568 Changed "Process_new_message" to "Process_new_update"
This way all types of queries (Message, Inline query, Callback query) are supported.
2016-05-20 17:40:22 +03:00
fbaf88c237 Update version. 2016-05-20 14:41:00 +08:00
3ebc47de8b Add missing title in InlineQueryResultVenue. #165 2016-05-20 14:39:34 +08:00
8017c8d919 Fix failing build for python 3.3, 3.4 and pypy3 2016-05-19 10:18:00 +02:00
2545724a6f Fix #164 2016-05-19 10:02:59 +02:00
b8770e2c04 Merge pull request #163 from agentik-007/patch-1
Update webhook_flask_echo_bot.py
2016-05-17 08:41:34 +08:00
1da5d1e0e2 Update webhook_flask_echo_bot.py 2016-05-16 14:31:36 +03:00
bc73f345b2 Update README.md 2016-05-15 09:40:56 +08:00
a824ff967b Version update. 2016-05-12 11:39:50 +08:00
0c420ee5e4 Add missing title to InlineQueryResultLocation to_json.
Fix #160
2016-05-12 11:09:21 +08:00
16838c30b6 Update version.
Change log:
- Added the field emoji to the Sticker.
- Added the field forward_from_chat to the Message object for messages
  forwarded from channels.
2016-05-08 18:45:21 +08:00
022cdada49 Merge pull request #157 from Kondra007/patch-6
Added 06.05.16 updates
2016-05-08 10:45:28 +08:00
fb1052824c Added 06.05.16 updates
* Added the field emoji to the Sticker object. Your bot can now know the emoji a sticker corresponds to.
* Added the field forwarded_from_chat to the Message object for messages forwarded from channels.
2016-05-07 20:24:16 +03:00
769bb55bbe Update test. 2016-05-03 21:05:11 +08:00
655940dcf8 Update version. 2016-05-03 21:02:46 +08:00
3b52e5c49b ReplyKeyboardMarkup support string. 2016-05-03 21:02:46 +08:00
700b869555 Merge pull request #154 from tp6vup54/master
Fix the bug that the return of request.get_data() is not string.
2016-05-02 21:12:29 +08:00
5906d632d6 Fix the bug that the return of request.get_data() is not string. 2016-05-02 11:07:23 +00:00
bd513cd343 Merge branch 'master' of github.com:eternnoir/pyTelegramBotAPI 2016-05-01 00:25:28 +08:00
0cb99b42e4 Update version. 2016-05-01 00:25:10 +08:00
dc1869167d Fix #153 2016-05-01 00:24:54 +08:00
ef22fafa7e Merge pull request #146 from rmed/fix-regexp
Added missing import for extract_arguments()
2016-04-26 23:14:38 +08:00
94d1b3f7a8 Added missing import for extract_arguments() 2016-04-26 11:16:49 +02:00
ef68bed01f Version update. 2016-04-25 23:55:03 +08:00
0eb21aa673 Fix #138. 2016-04-25 23:54:30 +08:00
e6105d851c Merge pull request #142 from Pitasi/master
Fixed new/left_chat_member content types
2016-04-25 23:32:44 +08:00
7ec33d43b3 Fixed supper for new/left_chat_member content types 2016-04-24 17:53:13 +02:00
0a856f4e83 Fix test case. 2016-04-23 09:29:48 +08:00
bbe53b5e17 Fix #136 and Update version. 2016-04-23 01:24:50 +08:00
84257b6ba9 Fix typo. 2016-04-23 01:21:45 +08:00
5b234920c7 Version Update.
Change log:
- duplicated code remove.
2016-04-19 08:19:20 +08:00
16d4c64b00 Remove duplicated method. 2016-04-19 08:13:37 +08:00
4fb85e25f6 Update rst readme. 2016-04-18 13:39:00 +08:00
0ae20e1a49 Update version. 2016-04-18 13:37:24 +08:00
e913635755 fix next_offset is empty will not set bug. 2016-04-17 23:28:47 +08:00
225cbf2c61 Update switch_inline_query is empty not set bug. 2016-04-17 23:21:11 +08:00
ae63b8029f Merge pull request #134 from Kondra007/patch-5
Fixed typo in types.py
2016-04-17 22:58:37 +08:00
e47790ded8 Fixed typo in types.py
"switch_inline_quer" -> "switch_inline_query"
2016-04-17 17:54:01 +03:00
d0666071d8 Fix edit inlinemessage will return bool not Message object. 2016-04-17 10:24:37 +08:00
eb8e87fdec Merge pull request #133 from Kondra007/patch-4
Fix Readme.md
2016-04-17 10:24:15 +08:00
1c98e1108c Fix Readme.md
Fixed Readme so "Bot 2.0" link leads to proper paragraph
2016-04-16 22:24:48 +03:00
8a0bf8ca7e Update readme. 2016-04-16 15:08:01 +08:00
7490f63f25 Add send_contact 2016-04-16 15:07:52 +08:00
22ab50989e Add answer_callback_query. 2016-04-16 14:53:41 +08:00
1e320a5b0d Add callback query handler. 2016-04-16 14:18:19 +08:00
96e06c248b Merge pull request #131 from Kondra007/patch-4
Fixed typo in InlineQueryResultAudio
2016-04-16 11:22:33 +08:00
ae92d1998e Fixed typo in InlineQueryResultArticle 2016-04-15 21:04:08 +03:00
d87e0821c9 Fix type test. 2016-04-14 17:45:57 +08:00
ee52241cc2 Update inline example. 2016-04-14 17:43:45 +08:00
a6d35fd1de Add all inquery types. 2016-04-14 17:09:12 +08:00
016819cd44 Add inline query classes. 2016-04-14 16:57:23 +08:00
036441b8f6 Add new inline type. 2016-04-14 15:50:55 +08:00
228683aeda Add new param for anser inline query. 2016-04-14 15:32:08 +08:00
4fe4061a0f All Updating messages methods done. 2016-04-14 15:17:53 +08:00
f873658aac Fix edit message error. 2016-04-14 15:06:46 +08:00
13327c371a Add editMessageText. 2016-04-14 15:03:07 +08:00
4dc7af71a0 Add bot2.0 new methods. 2016-04-14 14:48:26 +08:00
209764a5d7 Add connect timeout. Fix #108 2016-04-14 14:34:37 +08:00
c1247249c7 Add send venu method. 2016-04-14 13:55:28 +08:00
a6b0e9598c Add inline keyboard test. 2016-04-14 13:35:18 +08:00
7958264d64 Add bot 2.0 markup. 2016-04-14 12:01:17 +08:00
74c3a3545d Update type message to bot2.0 define. 2016-04-14 11:15:58 +08:00
7b007dab99 Add venue to message type. 2016-04-14 11:02:19 +08:00
8316a57845 Add type Venue. 2016-04-14 11:00:33 +08:00
2eb914d329 Add message entity to message. 2016-04-14 10:57:18 +08:00
2449a3ea64 Add MessageEntity. 2016-04-14 10:51:05 +08:00
a2d91808ef Remove pytest. 2016-04-09 10:37:34 +08:00
23dd31752b Update README.md 2016-04-04 10:51:27 +08:00
7770fcbb33 Update README.md 2016-03-29 11:34:37 +08:00
c64fdf149e Merge pull request #121 from DrBomb/patch-1
extract_argument
2016-03-18 15:09:21 +08:00
17184697ea Update util.py
Another typo
2016-03-17 22:17:06 -04:30
78d86752fb Update util.py
Typo
2016-03-17 00:51:02 -04:30
7669781737 Update util.py
Added a regexp method that returns all the text after the command.
2016-03-17 00:48:08 -04:30
ddc1a4d66f Version Update.
Change log:
- Add disable_notification parameter.
- Added setters for message/inline/chosen-inline handlers.
2016-02-27 11:47:01 +08:00
3d9e012c40 Merge pull request #120 from eternnoir/feature-disable_notification
Feature disable notification
2016-02-27 11:45:23 +08:00
9b9c0287ec Add test case. 2016-02-27 11:36:53 +08:00
292191038f Add disable_notification 2016-02-27 11:17:35 +08:00
f0e157213c Merge pull request #119 from Kondra007/patch-4
Update README.md
2016-02-26 20:45:54 +08:00
18330275bd Corrected author of Proxy Bot 2016-02-26 15:34:14 +03:00
d173681a7c Update README.md 2016-02-25 20:49:45 +08:00
0830f2a0f9 Update README.md 2016-02-23 21:16:35 +08:00
45d6f8980c Merge pull request #117 from Dejust/add-handler-setters
Added setters for message/inline/chosen-inline handlers.
2016-02-21 10:56:22 +08:00
28417d18af Added ability to set message handler, inline handler, chosen inline handler with method calling 2016-02-20 17:51:14 +05:00
e0ae119512 Merge pull request #116 from idlesign/patch-1
answer_inline_query() made POST
2016-02-15 16:19:55 +08:00
e851f37712 answer_inline_query made POST
The default GET produces `414 Request-URI Too Large` response.
2016-02-14 00:08:37 +05:00
40cf8d6903 Update README.md 2016-02-14 02:00:00 +08:00
e507463741 Update README.md 2016-02-14 01:59:31 +08:00
3a055734f9 Update README.md 2016-02-14 01:52:46 +08:00
16ec573c9e Add more example. 2016-02-11 21:42:07 +08:00
2cd19a1a39 Merge pull request #113 from ratijas/master
__retrieve_updates split into process_new_updates
2016-02-08 23:09:15 +08:00
5f9cf881e6 __retrieve_updates split into process_new_updates 2016-02-07 23:45:54 +08:00
baacafe3c0 Update examples. 2016-02-01 22:50:47 +08:00
734767177d Merge pull request #110 from Kondra007/patch-4
Updated README
2016-01-25 09:50:18 +08:00
1e7f71029c Updated README
Added "supergroup" to message.chat examples.  
via https://core.telegram.org/bots/api-changelog#november-2015
2016-01-24 20:51:52 +03:00
02c22c990b Add chosen_inline_handler doc. 2016-01-19 13:56:44 +08:00
00d6481818 Version Update.
Change log:
- All Message's attributes default to None. Don't need hasattr to check
  attribute.
- Inline mode support.
- Add InlineQueryResultArticle InlineQueryResultPhoto
  InlineQueryResultGif InlineQueryResultMpeg4Gif InlineQueryResultVideo
- Add new method answer_inline_query
- Add new inline_handler
2016-01-06 21:26:28 +08:00
a74ed6e3ab Update some comment. 2016-01-06 16:59:42 +08:00
38eb2ba833 Add comment. 2016-01-06 15:53:35 +08:00
93dc1cd92e Add comment. 2016-01-06 14:31:21 +08:00
a7469e6b14 Merge branch 'master' of github.com:eternnoir/pyTelegramBotAPI 2016-01-05 22:25:02 +08:00
b8f251140d Fix thumb_url must have value. 2016-01-05 22:23:00 +08:00
e2e6b07fdb Update README.md 2016-01-05 22:00:34 +08:00
a2ceffecc8 Update README.md 2016-01-05 21:59:34 +08:00
805e3554de Update readme. 2016-01-05 21:54:47 +08:00
94d34747d1 Merge branch 'inline-mode' into develop 2016-01-05 15:35:45 +08:00
8278eef7f3 Add inline bot example. 2016-01-05 14:58:19 +08:00
94f1bbd402 Almost done. 2016-01-05 14:07:47 +08:00
c706a7aba3 Handler done. 2016-01-05 13:18:32 +08:00
c214f8000e Add InlineQueryResultVideo class. 2016-01-05 11:03:05 +08:00
81a201f19f Add InlineQueryResultMpeg4Gif class. 2016-01-05 10:51:33 +08:00
0f0d76ca82 Add InlineQueryResultGif class. 2016-01-05 10:41:32 +08:00
fa6f16ca5e Add InlineQueryResultPhoto class. 2016-01-05 10:24:21 +08:00
a1267a7670 Add InlineQueryResultArticle class. 2016-01-05 09:57:25 +08:00
79c46bccae inline_hanlder done. 2016-01-04 23:10:32 +08:00
e912546680 Add ChosenInlineResult class. 2016-01-04 22:53:08 +08:00
7eeda3bc4d Update update object. 2016-01-04 22:29:04 +08:00
b5680a1c1f Add InlineQuery class. 2016-01-04 22:24:18 +08:00
7514c617fc Merge branch 'master' into develop 2015-12-24 13:42:02 +08:00
32f3a64720 Update README.md 2015-12-24 11:25:19 +08:00
3a08111f10 Fix hasattr. 2015-12-22 14:26:08 +08:00
eeff4e7bf8 Let message all attribute default be None. #100 2015-12-22 14:18:23 +08:00
c37b3625aa Merge branch 'develop' of github.com:eternnoir/pyTelegramBotAPI into develop 2015-12-22 14:12:51 +08:00
a3519ff539 Merge pull request #97 from askainet/skip_pending_update
Get and discard all pending updates sent before first poll of the bot
2015-12-02 09:16:00 +08:00
43ad415320 Get and discard all pending updates sent before the first poll of the bot 2015-12-01 15:05:52 +01:00
fb7c79fdfb Merge pull request #95 from ratijas/master
style unification for method_url in apihelper.py.
2015-11-09 13:17:36 +08:00
413f081b19 style unification for method_url in apihelper.py. 2015-11-08 10:30:09 +08:00
cea0604ede Merge pull request #94 from Kondra007/patch-4
Added 'voice' to content_types + some small fixes
2015-11-06 22:01:36 +08:00
be639ef4dd Added 'voice' to content_types + some small fixes 2015-11-04 18:37:51 +03:00
528b23770f Update README.md 2015-10-26 22:36:32 +08:00
4e472dda48 Update README.md 2015-10-26 22:32:10 +08:00
17dec34923 Update README.md 2015-10-26 22:31:55 +08:00
a17b301f1c Jump to release version. 2015-10-26 22:26:04 +08:00
cf830a0fb4 Version update:
Change log:
- Code clean up
- Bugs fix
2015-10-26 22:15:03 +08:00
7e9f5b09cf Bug #92 fix. 2015-10-26 21:55:04 +08:00
969c5e76ef Fix bytes not string. 2015-10-18 22:03:29 +08:00
7346326bc3 Fix video's thumb type forgot de_json. 2015-10-17 02:30:22 +08:00
f355796b01 Merge pull request #88 from mabitte/develop
Little code cleanup
2015-10-17 02:08:34 +08:00
5175803d0b * dict.get(key) returns None if key is not in the dictionary
* used the class method's class reference to instantiate type classes
2015-10-15 16:53:59 +02:00
bf9939d40e Fix queue default value. #86 2015-10-13 13:05:38 +08:00
07960fe348 Update new type chat document. 2015-10-12 23:00:25 +08:00
f4be18e082 Update Version.
Change log:
- New type Chat support.
- Bugs fix.
2015-10-12 22:45:01 +08:00
8e9837a587 Merge branch 'develop' 2015-10-12 22:37:17 +08:00
361c043872 Fix test data error. 2015-10-12 11:02:10 +08:00
50432dbef1 Fix test data error. 2015-10-12 10:54:33 +08:00
37277d74cc Fix testing error. 2015-10-12 10:51:29 +08:00
9ee341f5e6 Add Chat test for telebot. 2015-10-12 10:46:20 +08:00
0bd284afc7 Format. 2015-10-12 10:37:41 +08:00
4ffdada427 Add Chat json test. 2015-10-12 10:37:25 +08:00
d8effd3f9f New type Chat supported. 2015-10-12 10:36:58 +08:00
303e15b88d Merge pull request #84 from AndydeCleyre/patch-1
Fix AttributeError on Python 3
2015-10-09 21:57:05 +08:00
3273aa9afa Merge pull request #85 from AndydeCleyre/patch-2
Fix NameError in Python 3
2015-10-09 12:21:23 +08:00
9e8b11051c Fix NameError in Python 3 2015-10-08 16:46:15 -04:00
b9d458e643 Fix AttributeError on Python 3 2015-10-08 16:39:22 -04:00
1e6361dd57 Fix #83
Added a `encode('utf8')` statement to support non-ASCII symbols in error log messages.
2015-10-06 22:36:57 +02:00
ca2019b8f1 Merge pull request #82 from skgsergio/webhook-examples
Add Webhook examples (CPython, Flask, CherryPy)
2015-10-06 13:17:10 +02:00
a230665424 Update README.rst 2015-10-06 12:19:20 +02:00
8eb6e034fe Update README with webhooks information. 2015-10-06 12:11:42 +02:00
d6552eb4c6 Add webhook examples 2015-10-06 12:06:23 +02:00
117c5a1141 Minor CPU optimization 2015-10-03 12:48:56 +02:00
3f335c37ce Update version.
Change log:
- Add webhook support.
- Better error handling.
- Add threaded parameter for telebot constructor. Allowing users to decide telebot to use thread for polling method.
2015-10-03 16:33:17 +08:00
e7e681928d Fix polling stuch problem. 2015-10-02 23:24:54 +08:00
855ff40070 Fix python3 raise exception error. 2015-10-02 17:08:05 +08:00
29a42a398b Restored the non-threaded variant 2015-10-02 00:00:54 +02:00
b801728924 Fix unnecessary raise 2015-10-01 22:43:18 +02:00
d14e9051d4 Better error handling.
Errors now are re-raised in the Thread polling() was called from.
If none_stop is *not* set, ApiExceptions will cause the calling Thread to halt.
2015-10-01 22:03:54 +02:00
60ca1751ca WorkerThreads now log ApiExceptions 2015-10-01 11:33:23 +02:00
941b8ac5d0 Added webhooks support with set_webhook and remove_webhook in the TeleBot class 2015-09-30 18:19:31 +02:00
7a08102fad Merge branch 'master' of https://github.com/eternnoir/pyTelegramBotAPI into develop 2015-09-30 17:51:45 +02:00
325061ee96 Added "Bots using this API" section to docs
Added Channel link to docs
2015-09-30 17:50:40 +02:00
8839f36706 Update version.
Change log:
- Bug fix : fix race-condition for register_for_reply.
- Add timeout parameter for polling method.
2015-09-30 23:34:37 +08:00
1c53955d5a Add timeout para for polling method. 2015-09-30 23:18:26 +08:00
9cd28b88be Merge pull request #79 from huiyiqun/master
fix race-condition for register_for_reply
2015-09-30 22:50:08 +08:00
2fb2cd6f20 fix race-condition for message_subscribers 2015-09-30 20:46:37 +08:00
036d000b95 Remove 3.2/3.5 2015-09-22 20:34:06 +08:00
11d4bb02a8 Add Test python version 2015-09-22 20:25:35 +08:00
f4b0b61b9d Update version.
Change log:
- Support File type.
- New method getFile supported.
2015-09-19 23:06:47 +08:00
4b8989f3d2 Merge pull request #74 from eternnoir/develop
Add getFile method and File type
2015-09-19 10:55:44 +08:00
19b4e35ee5 Attempt to fix failing test case 2015-09-18 21:11:56 +02:00
61b4ca8a37 Added download_file and created an example 2015-09-18 20:54:22 +02:00
1038d4fafa Added download_file 2015-09-18 20:53:10 +02:00
fd1f16598b Added File & getFile, including testing 2015-09-18 20:31:29 +02:00
07c28830db Update version.
Change log:
- Hotfix handler lambda bug.
2015-09-10 21:51:51 +08:00
a8fccdbeb3 Add test. 2015-09-10 21:44:14 +08:00
c213b7732b Add lambda text. 2015-09-10 21:38:09 +08:00
2ca5c0d6f3 Hotfix lambda bug. 2015-09-10 21:27:37 +08:00
29 changed files with 6102 additions and 944 deletions

7
.github/ISSUE_TEMPLATE vendored Normal file
View File

@ -0,0 +1,7 @@
Please answer these questions before submitting your issue. Thanks!
1. What version of pyTelegramBotAPI are you using?
2. What OS are you using?
3. What version of python are you using?

View File

@ -1,8 +1,10 @@
language: python
python:
- "2.6"
- "2.7"
- "3.4"
- "3.5"
- "3.6"
- "3.7"
- "3.8"
- "pypy"
- "pypy3"
install: "pip install -r requirements.txt"

273
README.md
View File

@ -1,9 +1,9 @@
# <p align="center">pyTelegramBotAPI
<p align="center">A simple, but extensible Python implementation for the [Telegram Bot API](https://core.telegram.org/bots/api).
<p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.
<p align="center">[![Build Status](https://travis-ci.org/eternnoir/pyTelegramBotAPI.svg?branch=master)](https://travis-ci.org/eternnoir/pyTelegramBotAPI)
[![Download Month](https://img.shields.io/pypi/v/pyTelegramBotAPI.svg)](https://pypi.python.org/pypi/pyTelegramBotAPI)
[![Build Status](https://travis-ci.org/eternnoir/pyTelegramBotAPI.svg?branch=master)](https://travis-ci.org/eternnoir/pyTelegramBotAPI)
* [Getting started.](#getting-started)
* [Writing your first bot](#writing-your-first-bot)
@ -14,8 +14,10 @@
* [Methods](#methods)
* [General use of the API](#general-use-of-the-api)
* [Message handlers](#message-handlers)
* [Callback Query handlers](#callback-query-handler)
* [TeleBot](#telebot)
* [Reply markup](#reply-markup)
* [Inline Mode](#inline-mode)
* [Advanced use of the API](#advanced-use-of-the-api)
* [Asynchronous delivery of messages](#asynchronous-delivery-of-messages)
* [Sending large text messages](#sending-large-text-messages)
@ -23,10 +25,14 @@
* [The listener mechanism](#the-listener-mechanism)
* [Using web hooks](#using-web-hooks)
* [Logging](#logging)
* [Proxy](#proxy)
* [New in library](#new-in-library)
* [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)
* [The Telegram Chat Group](#the-telegram-chat-group)
* [More examples](#more-examples)
* [Bots using this API](#bots-using-this-api)
## Getting started.
@ -118,8 +124,12 @@ To start the bot, simply open up a terminal and enter `python echo_bot.py` to ru
All types are defined in types.py. They are all completely in line with the [Telegram API's definition of the types](https://core.telegram.org/bots/api#available-types), except for the Message's `from` field, which is renamed to `from_user` (because `from` is a Python reserved token). Thus, attributes such as `message_id` can be accessed directly with `message.message_id`. Note that `message.chat` can be either an instance of `User` or `GroupChat` (see [How can I distinguish a User and a GroupChat in message.chat?](#how-can-i-distinguish-a-user-and-a-groupchat-in-messagechat)).
The Message object also has a `content_type`attribute, which defines the type of the Message. `content_type` can be one of the following strings:
'text', 'audio', 'document', 'photo', 'sticker', 'video', 'location', 'contact', 'new_chat_participant', 'left_chat_participant', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created'.
The Message object also has a `content_type`attribute, which defines the type of the Message. `content_type` can be one of the following strings:
`text`, `audio`, `document`, `photo`, `sticker`, `video`, `video_note`, `voice`, `location`, `contact`, `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`.
You can use some types in one function. Example:
```content_types=["text", "sticker", "pinned_message", "photo", "audio"]```
### Methods
@ -150,6 +160,7 @@ TeleBot supports the following filters:
|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
import telebot
bot = telebot.TeleBot("TOKEN")
@ -176,13 +187,43 @@ def handle_text_doc(message):
#Which could also be defined as:
def test_message(message):
return message.document.mime_type == 'text/plan'
return message.document.mime_type == 'text/plain'
@bot.message_handler(func=test_message, content_types=['document'])
def handle_text_doc(message)
pass
# Handlers can be stacked to create a function which will be called if either message_handler is eligible
# This handler will be called if the message starts with '/hello' OR is some emoji
@bot.message_handler(commands=['hello'])
@bot.message_handler(func=lambda msg: msg.text.encode("utf-8") == SOME_FANCY_EMOJI)
def send_something(message):
pass
```
**Important: all handlers are tested in the order in which they were declared**
#### Edited Message handlers
Same as Message handlers
#### channel_post_handler
Same as Message handlers
#### edited_channel_post_handler
Same as Message handlers
#### Callback Query Handler
In bot2.0 update. You can get `callback_query` in update object. In telebot use `callback_query_handler` to process callback_querys.
```python
@bot.callback_query_handler(func=lambda call: True)
def test_callback(call):
logger.info(call)
```
#### TeleBot
```python
import telebot
@ -194,18 +235,23 @@ tb = telebot.TeleBot(TOKEN) #create a new Telegram Bot object
# - none_stop: True/False (default False) - Don't stop polling when receiving an error from the Telegram servers
# - interval: True/False (default False) - The interval between polling requests
# Note: Editing this parameter harms the bot's response time
# - block: True/False (default True) - Blocks upon calling this function
tb.polling(none_stop=False, interval=0, block=True)
# - timeout: integer (default 20) - Timeout in seconds for long polling.
tb.polling(none_stop=False, interval=0, timeout=20)
# getMe
user = tb.get_me()
# setWebhook
tb.set_webhook(url="http://example.com", certificate=open('mycert.pem'))
# unset webhook
tb.remove_webhook()
# getUpdates
updates = tb.get_updates()
updates = tb.get_updates(1234,100,20) #get_Updates(offset, limit, timeout):
# sendMessage
tb.send_message(chatid, text)
tb.send_message(chat_id, text)
# forwardMessage
tb.forward_message(to_chat_id, from_chat_id, message_id)
@ -244,6 +290,11 @@ video = open('/tmp/video.mp4', 'rb')
tb.send_video(chat_id, video)
tb.send_video(chat_id, "FILEID")
# sendVideoNote
videonote = open('/tmp/videonote.mp4', 'rb')
tb.send_video_note(chat_id, videonote)
tb.send_video_note(chat_id, "FILEID")
# sendLocation
tb.send_location(chat_id, lat, lon)
@ -251,9 +302,19 @@ tb.send_location(chat_id, lat, lon)
# action_string can be one of the following strings: 'typing', 'upload_photo', 'record_video', 'upload_video',
# 'record_audio', 'upload_audio', 'upload_document' or 'find_location'.
tb.send_chat_action(chat_id, action_string)
# getFile
# Downloading a file is straightforward
# Returns a File object
import requests
file_info = tb.get_file(file_id)
file = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(API_TOKEN, file_info.file_path))
```
#### Reply markup
All `send_xyz` functions of TeleBot take an optional `reply_markup` argument. This argument must be an instance of `ReplyKeyboardMarkup`, `ReplyKeyboardHide` or `ForceReply`, which are defined in types.py.
All `send_xyz` functions of TeleBot take an optional `reply_markup` argument. This argument must be an instance of `ReplyKeyboardMarkup`, `ReplyKeyboardRemove` or `ForceReply`, which are defined in types.py.
```python
from telebot import types
@ -267,23 +328,31 @@ from telebot import types
# row_width is used in combination with the add() function.
# It defines how many buttons are fit on each row before continuing on the next row.
markup = types.ReplyKeyboardMarkup(row_width=2)
markup.add('a', 'v', 'd')
itembtn1 = types.KeyboardButton('a')
itembtn2 = types.KeyboardButton('v')
itembtn3 = types.KeyboardButton('d')
markup.add(itembtn1, itembtn2, itembtn3)
tb.send_message(chat_id, "Choose one letter:", reply_markup=markup)
# or add strings one row at a time:
# or add KeyboardButton one row at a time:
markup = types.ReplyKeyboardMarkup()
markup.row('a', 'v')
markup.row('c', 'd', 'e')
itembtna = types.KeyboardButton('a')
itembtnv = types.KeyboardButton('v')
itembtnc = types.KeyboardButton('c')
itembtnd = types.KeyboardButton('d')
itembtne = types.KeyboardButton('e')
markup.row(itembtna, itembtnv)
markup.row(itembtnc, itembtnd, itembtne)
tb.send_message(chat_id, "Choose one letter:", reply_markup=markup)
```
The last example yields this result:
![ReplyKeyboardMarkup](https://pp.vk.me/c624430/v624430512/473e5/_mxxW7FPe4U.jpg "ReplyKeyboardMarkup")
![ReplyKeyboardMarkup](https://farm3.staticflickr.com/2933/32418726704_9ef76093cf_o_d.jpg "ReplyKeyboardMarkup")
```python
# ReplyKeyboardHide: hides a previously sent ReplyKeyboardMarkup
# ReplyKeyboardRemove: hides a previously sent ReplyKeyboardMarkup
# Takes an optional selective argument (True/False, default False)
markup = types.ReplyKeyboardHide(selective=False)
markup = types.ReplyKeyboardRemove(selective=False)
tb.send_message(chat_id, message, reply_markup=markup)
```
@ -295,7 +364,65 @@ tb.send_message(chat_id, "Send me another word:", reply_markup=markup)
```
ForceReply:
![ForceReply](https://pp.vk.me/c624430/v624430512/473ec/602byyWUHcs.jpg "ForceReply")
![ForceReply](https://farm4.staticflickr.com/3809/32418726814_d1baec0fc2_o_d.jpg "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_query 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:
This object represents one special entity in a text message. For example, hashtags, usernames, URLs, etc.
Attributes:
* `type`
* `url`
* `offset`
* `length`
* `user`
**Here's an Example:**`message.entities[num].<attribute>`<br>
Here `num` is the entity number or order of entity in a reply, for if incase there are multiple entities in the reply/message.<br>
`message.entities` returns a list of entities object. <br>
`message.entities[0].type` would give the type of the first entity<br>
Refer [Bot Api](https://core.telegram.org/bots/api#messageentity) for extra details
## Advanced use of the API
@ -335,15 +462,14 @@ for text in splitted_text:
### Controlling the amount of Threads used by TeleBot
The TeleBot constructor takes the following optional arguments:
- create_threads: True/False (default True). A flag to indicate whether
- threaded: True/False (default True). A flag to indicate whether
TeleBot should execute message handlers on it's polling Thread.
- num_threads: integer (default 4). Controls the amount of WorkerThreads created for the internal thread pool that TeleBot uses to execute message handlers. Is not used when create_threads is False.
### The listener mechanism
As an alternative to the message handlers, one can also register a function as a listener to TeleBot. Example:
```python
def handle_messages(messages):
for message in messsages:
for message in messages:
# Do something with the message
bot.reply_to(message, 'Hi')
@ -352,7 +478,9 @@ bot.polling()
```
### Using web hooks
If you prefer using web hooks to the getUpdates method, you can use the `process_new_messages(messages)` function in TeleBot to make it process the messages that you supply. It takes a list of Message objects. This function is still incubating.
When using webhooks telegram sends one Update per call, for processing it you should call process_new_messages([update.message]) when you recieve it.
There are some examples using webhooks in the *examples/webhook_examples* directory.
### Logging
@ -366,34 +494,111 @@ logger = telebot.logger
telebot.logger.setLevel(logging.DEBUG) # Outputs debug messages to console.
```
### Proxy
You can use proxy for request. `apihelper.proxy` object will use by call `requests` proxies argument.
```python
from telebot import apihelper
apihelper.proxy = {'http':'http://10.10.1.10:3128'}
```
If you want to use socket5 proxy you need install dependency `pip install requests[socks]` and make sure, that you have the latest version of `gunicorn`, `PySocks`, `pyTelegramBotAPI`, `requests` and `urllib3`.
```python
apihelper.proxy = {'https':'socks5://userproxy:password@proxy_address:port'}
```
## New in library
06.06.2019 - Добавленна поддержка опросов (Poll). Добавлены функции 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?
There are two ways to do this:
Telegram Bot API support new type Chat for message.chat.
- Checking the instance of message.chat with `isinstance`:
- Check the ```type``` attribute in ```Chat``` object:
-
```python
def is_user(chat):
return isinstance(chat, types.User)
if message.chat.type == "private":
# private chat message
print is_user(message.chat) # True or False
```
- Checking whether the chat id is negative or positive. If the chat id is negative, the chat is a GroupChat, if it is positive, it is a User. Example:
```python
def is_user(chat):
return chat.id > 0
if message.chat.type == "group":
# group chat message
if message.chat.type == "supergroup":
# supergroup chat message
if message.chat.type == "channel":
# channel message
print is_user(message.chat) # True or False
```
## The Telegram Chat Group
Get help. Discuss. Chat.
Join the [pyTelegramBotAPI Telegram Chat Group](https://telegram.me/joinchat/067e22c60035523fda8f6025ee87e30b).
* 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
* [Echo Bot](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/echo_bot.py)
* [Deep Linking](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/deep_linking.py)
* [next_step_handler Example](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/step_example.py)
## 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://bitbucket.org/master_groosha/telegram-proxy-bot) by *Groosha* - A simple BITM (bot-in-the-middle) for Telegram acting as some kind of "proxy".
* [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`.
* [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*
* [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
* [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 audiosamles 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 IDs
* [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.
Want to have your bot listed here? Send a Telegram message to @eternnoir or @pevdh.

View File

@ -1,528 +0,0 @@
#
.. raw:: html
<p align="center">
pyTelegramBotAPI
.. raw:: html
<p align="center">
A simple, but extensible Python implementation for the `Telegram Bot
API <https://core.telegram.org/bots/api>`__.
.. raw:: html
<p align="center">
|Build Status|
- `Getting started. <#getting-started>`__
- `Writing your first bot <#writing-your-first-bot>`__
- `Prerequisites <#prerequisites>`__
- `A simple echo bot <#a-simple-echo-bot>`__
- `General API Documentation <#general-api-documentation>`__
- `Types <#types>`__
- `Methods <#methods>`__
- `General use of the API <#general-use-of-the-api>`__
- `Message handlers <#message-handlers>`__
- `TeleBot <#telebot>`__
- `Reply markup <#reply-markup>`__
- `Advanced use of the API <#advanced-use-of-the-api>`__
- `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>`__
- `The listener mechanism <#the-listener-mechanism>`__
- `Using web hooks <#using-web-hooks>`__
- `Logging <#logging>`__
- `F.A.Q. <#faq>`__
- `How can I distinguish a User and a GroupChat in
message.chat? <#how-can-i-distinguish-a-user-and-a-groupchat-in-messagechat>`__
- `The Telegram Chat Group <#the-telegram-chat-group>`__
- `More examples <#more-examples>`__
Getting started.
================
This API is tested with Python 2.6, Python 2.7, Python 3.4, Pypy and
Pypy 3. There are two ways to install the library:
- Installation using pip (a Python package manager)\*:
::
$ pip install pyTelegramBotAPI
- Installation from source (requires git):
::
$ git clone https://github.com/eternnoir/pyTelegramBotAPI.git
$ cd pyTelegramBotAPI
$ python setup.py install
It is generally recommended to use the first option.
\*\*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
``pip install pytelegrambotapi --upgrade``\ \*
Writing your first bot
======================
Prerequisites
-------------
It is presumed that you [have obtained an API token with
@BotFather](https://core.telegram.org/bots#botfather). We will call this
token ``TOKEN``. Furthermore, you have basic knowledge of the Python
programming language and more importantly `the Telegram Bot
API <https://core.telegram.org/bots/api>`__.
A simple echo bot
-----------------
The TeleBot class (defined in \_\_init\_\_.py) encapsulates all API
calls in a single class. It provides functions such as ``send_xyz``
(``send_message``, ``send_document`` etc.) and several ways to listen
for incoming messages.
Create a file called ``echo_bot.py``. Then, open the file and create an
instance of the TeleBot class.
.. code:: python
import telebot
bot = telebot.TeleBot("TOKEN")
*Note: Make sure to actually replace TOKEN with your own API token.*
After that declaration, we need to register some so-called message
handlers. Message handlers define filters which a message must pass. If
a message passes the filter, the decorated function is called and the
incoming message is passed as an argument.
Let's define a message handler which handles incoming ``/start`` and
``/help`` commands.
.. code:: python
@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
bot.reply_to(message, "Howdy, how are you doing?")
A function which is decorated by a message handler **can have an
arbitrary name, however, it must have only one parameter (the
message)**.
Let's add another handler:
.. code:: python
@bot.message_handler(func=lambda m: True)
def echo_all(message):
bot.reply_to(message, message.text)
This one echoes all incoming text messages back to the sender. It uses a
lambda function to test a message. If the lambda returns True, the
message is handled by the decorated function. Since we want all messages
to be handled by this function, we simply always return True.
*Note: all handlers are tested in the order in which they were declared*
We now have a basic bot which replies a static message to "/start" and
"/help" commands and which echoes the rest of the sent messages. To
start the bot, add the following to our source file:
.. code:: python
bot.polling()
Alright, that's it! Our source file now looks like this:
.. code:: python
import telebot
bot = telebot.TeleBot("TOKEN")
@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
bot.reply_to(message, "Howdy, how are you doing?")
@bot.message_handler(func=lambda message: True)
def echo_all(message):
bot.reply_to(message, message.text)
bot.polling()
To start the bot, simply open up a terminal and enter
``python echo_bot.py`` to run the bot! Test it by sending commands
('/start' and '/help') and arbitrary text messages.
General API Documentation
=========================
Types
-----
All types are defined in types.py. They are all completely in line with
the `Telegram API's definition of the
types <https://core.telegram.org/bots/api#available-types>`__, except
for the Message's ``from`` field, which is renamed to ``from_user``
(because ``from`` is a Python reserved token). Thus, attributes such as
``message_id`` can be accessed directly with ``message.message_id``.
Note that ``message.chat`` can be either an instance of ``User`` or
``GroupChat`` (see `How can I distinguish a User and a GroupChat in
message.chat? <#how-can-i-distinguish-a-user-and-a-groupchat-in-messagechat>`__).
The Message object also has a ``content_type``\ attribute, which defines
the type of the Message. ``content_type`` can be one of the following
strings: 'text', 'audio', 'document', 'photo', 'sticker', 'video',
'location', 'contact', 'new\_chat\_participant',
'left\_chat\_participant', 'new\_chat\_title', 'new\_chat\_photo',
'delete\_chat\_photo', 'group\_chat\_created'.
Methods
-------
All `API
methods <https://core.telegram.org/bots/api#available-methods>`__ are
located in the TeleBot class. They are renamed to follow common Python
naming conventions. E.g. ``getMe`` is renamed to ``get_me`` and
``sendMessage`` to ``send_message``.
General use of the API
----------------------
Outlined below are some general use cases of the API.
Message handlers
~~~~~~~~~~~~~~~~
A message handler is a function which is decorated with the
``message_handler`` decorator of a TeleBot instance. The following
examples illustrate the possibilities of message handlers:
.. code:: python
import telebot
bot = telebot.TeleBot("TOKEN")
# Handles all text messages that contains the commands '/start' or '/help'.
@bot.message_handler(commands=['start', 'help'])
def handle_start_help(message):
pass
# Handles all sent documents and audio files
@bot.message_handler(content_types=['document', 'audio'])
def handle_docs_audio(message):
pass
# Handles all text messages that match the regular expression
@bot.message_handler(regexp="SOME_REGEXP")
def handle_message(message):
pass
#Handles all messages for which the lambda returns True
@bot.message_handler(func=lambda message: message.document.mime_type == 'text/plain', content_types=['document'])
def handle_text_doc(message):
pass
#Which could also be defined as:
def test_message(message):
return message.document.mime_type == 'text/plan'
@bot.message_handler(func=test_message, content_types=['document'])
def handle_text_doc(message)
pass
*Note: all handlers are tested in the order in which they were declared*
#### TeleBot
.. code:: python
import telebot
TOKEN = '<token_string>'
tb = telebot.TeleBot(TOKEN) #create a new Telegram Bot object
# Upon calling this function, TeleBot starts polling the Telegram servers for new messages.
# - none_stop: True/False (default False) - Don't stop polling when receiving an error from the Telegram servers
# - interval: True/False (default False) - The interval between polling requests
# Note: Editing this parameter harms the bot's response time
# - block: True/False (default True) - Blocks upon calling this function
tb.polling(none_stop=False, interval=0, block=True)
# getMe
user = tb.get_me()
# getUpdates
updates = tb.get_updates()
updates = tb.get_updates(1234,100,20) #get_Updates(offset, limit, timeout):
# sendMessage
tb.send_message(chatid, text)
# forwardMessage
tb.forward_message(to_chat_id, from_chat_id, message_id)
# All send_xyz functions which can take a file as an argument, can also take a file_id instead of a file.
# sendPhoto
photo = open('/tmp/photo.png', 'rb')
tb.send_photo(chat_id, photo)
tb.send_photo(chat_id, "FILEID")
# sendAudio
audio = open('/tmp/audio.mp3', 'rb')
tb.send_audio(chat_id, audio)
tb.send_audio(chat_id, "FILEID")
## sendAudio with duration, performer and title.
tb.send_audio(CHAT_ID, file_data, 1, 'eternnoir', 'pyTelegram')
# sendVoice
voice = open('/tmp/voice.ogg', 'rb')
tb.send_voice(chat_id, voice)
tb.send_voice(chat_id, "FILEID")
# sendDocument
doc = open('/tmp/file.txt', 'rb')
tb.send_document(chat_id, doc)
tb.send_document(chat_id, "FILEID")
# sendSticker
sti = open('/tmp/sti.webp', 'rb')
tb.send_sticker(chat_id, sti)
tb.send_sticker(chat_id, "FILEID")
# sendVideo
video = open('/tmp/video.mp4', 'rb')
tb.send_video(chat_id, video)
tb.send_video(chat_id, "FILEID")
# sendLocation
tb.send_location(chat_id, lat, lon)
# sendChatAction
# action_string can be one of the following strings: 'typing', 'upload_photo', 'record_video', 'upload_video',
# 'record_audio', 'upload_audio', 'upload_document' or 'find_location'.
tb.send_chat_action(chat_id, action_string)
Reply markup
~~~~~~~~~~~~
All ``send_xyz`` functions of TeleBot take an optional ``reply_markup``
argument. This argument must be an instance of ``ReplyKeyboardMarkup``,
``ReplyKeyboardHide`` or ``ForceReply``, which are defined in types.py.
.. code:: python
from telebot import types
# Using the ReplyKeyboardMarkup class
# It's constructor can take the following optional arguments:
# - resize_keyboard: True/False (default False)
# - one_time_keyboard: True/False (default False)
# - selective: True/False (default False)
# - row_width: integer (default 3)
# row_width is used in combination with the add() function.
# It defines how many buttons are fit on each row before continuing on the next row.
markup = types.ReplyKeyboardMarkup(row_width=2)
markup.add('a', 'v', 'd')
tb.send_message(chat_id, "Choose one letter:", reply_markup=markup)
# or add strings one row at a time:
markup = types.ReplyKeyboardMarkup()
markup.row('a', 'v')
markup.row('c', 'd', 'e')
tb.send_message(chat_id, "Choose one letter:", reply_markup=markup)
The last example yields this result:
.. figure:: https://pp.vk.me/c624430/v624430512/473e5/_mxxW7FPe4U.jpg
:alt: ReplyKeyboardMarkup
ReplyKeyboardMarkup
.. code:: python
# ReplyKeyboardHide: hides a previously sent ReplyKeyboardMarkup
# Takes an optional selective argument (True/False, default False)
markup = types.ReplyKeyboardHide(selective=False)
tb.send_message(chat_id, message, reply_markup=markup)
.. code:: python
# ForceReply: forces a user to reply to a message
# Takes an optional selective argument (True/False, default False)
markup = types.ForceReply(selective=False)
tb.send_message(chat_id, "Send me another word:", reply_markup=markup)
ForceReply:
.. figure:: https://pp.vk.me/c624430/v624430512/473ec/602byyWUHcs.jpg
:alt: ForceReply
ForceReply
Advanced use of the API
=======================
Asynchronous delivery of messages
---------------------------------
There exists an implementation of TeleBot which executes all
``send_xyz`` and the ``get_me`` functions asynchronously. This can speed
up you bot **significantly**, but it has unwanted side effects if used
without caution. To enable this behaviour, create an instance of
AsyncTeleBot instead of TeleBot.
.. code:: python
tb = telebot.AsyncTeleBot("TOKEN")
Now, every function that calls the Telegram API is executed in a
separate Thread. The functions are modified to return an AsyncTask
instance (defined in util.py). Using AsyncTeleBot allows you to do the
following:
.. code:: python
import telebot
tb = telebot.AsyncTeleBot("TOKEN")
task = tb.get_me() # Execute an API call
# Do some other operations...
a = 0
for a in range(100):
a += 10
result = task.wait() # Get the result of the execution
*Note: if you execute send\_xyz functions after eachother without
calling wait(), the order in which messages are delivered might be
wrong.*
Sending large text messages
---------------------------
Sometimes you must send messages that exceed 5000 characters. The
Telegram API can not handle that many characters in one request, so we
need to split the message in multiples. Here is how to do that using the
API:
.. code:: python
from telebot import util
large_text = open("large_text.txt", "rb").read()
# Split the text each 3000 characters.
# split_string returns a list with the splitted text.
splitted_text = util.split_string(large_text, 3000)
for text in splitted_text:
tb.send_message(chat_id, text)
Controlling the amount of Threads used by TeleBot
-------------------------------------------------
The TeleBot constructor takes the following optional arguments:
- create\_threads: True/False (default True). A flag to indicate
whether TeleBot should execute message handlers on it's polling
Thread.
- num\_threads: integer (default 4). Controls the amount of
WorkerThreads created for the internal thread pool that TeleBot uses
to execute message handlers. Is not used when create\_threads is
False.
The listener mechanism
----------------------
As an alternative to the message handlers, one can also register a
function as a listener to TeleBot. Example:
.. code:: python
def handle_messages(messages):
for message in messsages:
# Do something with the message
bot.reply_to(message, 'Hi')
bot.set_update_listener(handle_messages)
bot.polling()
Using web hooks
---------------
If you prefer using web hooks to the getUpdates method, you can use the
``process_new_messages(messages)`` function in TeleBot to make it
process the messages that you supply. It takes a list of Message
objects. This function is still incubating.
Logging
-------
You can use the Telebot module logger to log debug info about Telebot.
Use ``telebot.logger`` to get the logger of the TeleBot module.
.. code:: python
logger = telebot.logger
formatter = logging.Formatter('[%(asctime)s] %(thread)d {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
'%m-%d %H:%M:%S')
ch = logging.StreamHandler(sys.stdout)
logger.addHandler(ch)
logger.setLevel(logging.DEBUG) # or use logging.INFO
ch.setFormatter(formatter)
F.A.Q.
======
How can I distinguish a User and a GroupChat in message.chat?
-------------------------------------------------------------
There are two ways to do this:
- Checking the instance of message.chat with ``isinstance``:
\`\`\`python def is\_user(chat): return isinstance(chat, types.User)
print is\_user(message.chat) # True or False
``- Checking whether the chat id is negative or positive. If the chat id is negative, the chat is a GroupChat, if it is positive, it is a User. Example:``\ python
def is\_user(chat): return chat.id > 0
print is\_user(message.chat) # True or False \`\`\`
The Telegram Chat Group
=======================
Get help. Discuss. Chat.
Join the `pyTelegramBotAPI Telegram Chat
Group <https://telegram.me/joinchat/067e22c60035523fda8f6025ee87e30b>`__.
More examples
=============
- `Echo
Bot <https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/echo_bot.py>`__
- `Deep
Linking <https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/deep_linking.py>`__
- `next\_step\_handler
Example <https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/step_example.py>`__
.. |Build Status| image:: https://travis-ci.org/eternnoir/pyTelegramBotAPI.svg?branch=master
:target: https://travis-ci.org/eternnoir/pyTelegramBotAPI

View File

@ -1,3 +1,5 @@
#!/usr/bin/python
# This example shows how to implement deep linking (https://core.telegram.org/bots#deep-linking)
# with the pyTelegramBotAPI.
# Note: This is not a working, production-ready sample.
@ -31,34 +33,38 @@
# steps are not shown here. Only steps 5 to 7 are illustrated, some in pseudo-code, with this example.
import telebot
import time
bot = telebot.TeleBot('TOKEN')
def extract_unique_code(text):
# Extracts the unique_code from the sent /start command.
return text.split()[1] if len(text.split()) > 1 else None
def in_storage(unique_code):
# (pseudo-code) Should check if a unique code exists in storage
return True
def get_username_from_storage(unique_code):
# (pseudo-code) Does a query to the storage, retrieving the associated username
# Should be replaced by a real database-lookup.
return "ABC" if in_storage(unique_code) else None
def save_chat_id(chat_id, username):
# (pseudo-code) Save the chat_id->username to storage
# Should be replaced by a real database query.
pass
@bot.message_handler(commands=['start'])
def send_welcome(message):
unique_code = extract_unique_code(message.text)
if unique_code: # if the '/start' command contains a unique_code
if unique_code: # if the '/start' command contains a unique_code
username = get_username_from_storage(unique_code)
if username: # if the username exists in our database
if username: # if the username exists in our database
save_chat_id(message.chat.id, username)
reply = "Hello {0}, how are you?".format(username)
else:
@ -67,4 +73,5 @@ def send_welcome(message):
reply = "Please visit me via a provided URL from the website."
bot.reply_to(message, reply)
bot.polling()

View File

@ -2,9 +2,10 @@
This is a detailed example using almost every command of the API
"""
import time
import telebot
from telebot import types
import time
TOKEN = '<token_string>'
@ -12,16 +13,16 @@ knownUsers = [] # todo: save these in a file,
userStep = {} # so they won't reset every time the bot restarts
commands = { # command description used in the "help" command
'start': 'Get used to the bot',
'help': 'Gives you information about the available commands',
'sendLongText': 'A test using the \'send_chat_action\' command',
'getImage': 'A test using multi-stage messages, custom keyboard, and media sending'
'start' : 'Get used to the bot',
'help' : 'Gives you information about the available commands',
'sendLongText': 'A test using the \'send_chat_action\' command',
'getImage' : 'A test using multi-stage messages, custom keyboard, and media sending'
}
imageSelect = types.ReplyKeyboardMarkup(one_time_keyboard=True) # create the image selection keyboard
imageSelect.add('cock', 'pussy')
imageSelect.add('Mickey', 'Minnie')
hideBoard = types.ReplyKeyboardHide() # if sent as reply_markup, will hide the keyboard
hideBoard = types.ReplyKeyboardRemove() # if sent as reply_markup, will hide the keyboard
# error handling if user isn't known yet
@ -33,7 +34,7 @@ def get_user_step(uid):
else:
knownUsers.append(uid)
userStep[uid] = 0
print "New user detected, who hasn't used \"/start\" yet"
print("New user detected, who hasn't used \"/start\" yet")
return 0
@ -45,7 +46,7 @@ def listener(messages):
for m in messages:
if m.content_type == 'text':
# print the sent message to the console
print str(m.chat.first_name) + " [" + str(m.chat.id) + "]: " + m.text
print(str(m.chat.first_name) + " [" + str(m.chat.id) + "]: " + m.text)
bot = telebot.TeleBot(TOKEN)
@ -104,15 +105,15 @@ def msg_image_select(m):
# for some reason the 'upload_photo' status isn't quite working (doesn't show at all)
bot.send_chat_action(cid, 'typing')
if text == "cock": # send the appropriate image based on the reply to the "/getImage" command
if text == 'Mickey': # send the appropriate image based on the reply to the "/getImage" command
bot.send_photo(cid, open('rooster.jpg', 'rb'),
reply_markup=hideBoard) # send file and hide keyboard, after image is sent
userStep[cid] = 0 # reset the users step back to 0
elif text == "pussy":
elif text == 'Minnie':
bot.send_photo(cid, open('kitten.jpg', 'rb'), reply_markup=hideBoard)
userStep[cid] = 0
else:
bot.send_message(cid, "Don't type bullsh*t, if I give you a predefined keyboard!")
bot.send_message(cid, "Please, use the predefined keyboard!")
bot.send_message(cid, "Please try again")
@ -128,4 +129,5 @@ def command_default(m):
# this is the standard reply to a normal message
bot.send_message(m.chat.id, "I don't understand \"" + m.text + "\"\nMaybe try the help page at /help")
bot.polling()

View File

@ -0,0 +1,15 @@
import telebot
TOKEN = 'YOUR BOT TOKEN'
CHAT_ID = 'YOUR CHAT ID'
bot = telebot.TeleBot(TOKEN)
ret_msg = bot.send_voice(CHAT_ID, open('tests/test_data/record.ogg', 'rb'))
file_info = bot.get_file(ret_msg.voice.file_id)
downloaded_file = bot.download_file(file_info.file_path)
with open('new_file.ogg', 'wb') as new_file:
new_file.write(downloaded_file)

View File

@ -1,3 +1,5 @@
#!/usr/bin/python
# This is a simple echo bot using the decorator mechanism.
# It echoes any incoming text messages.
@ -7,6 +9,7 @@ API_TOKEN = '<api_token>'
bot = telebot.TeleBot(API_TOKEN)
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
@ -21,4 +24,5 @@ I am here to echo your kind words back to you. Just say anything nice and I'll s
def echo_message(message):
bot.reply_to(message, message.text)
bot.polling()

View File

@ -0,0 +1,74 @@
# This example show how to write an inline mode telegram bot use pyTelegramBotAPI.
import logging
import sys
import time
import telebot
from telebot import types
API_TOKEN = '<TOKEN>'
bot = telebot.TeleBot(API_TOKEN)
telebot.logger.setLevel(logging.DEBUG)
@bot.inline_handler(lambda query: query.query == 'text')
def query_text(inline_query):
try:
r = types.InlineQueryResultArticle('1', 'Result1', types.InputTextMessageContent('hi'))
r2 = types.InlineQueryResultArticle('2', 'Result2', types.InputTextMessageContent('hi'))
bot.answer_inline_query(inline_query.id, [r, r2])
except Exception as e:
print(e)
@bot.inline_handler(lambda query: query.query == 'photo1')
def query_photo(inline_query):
try:
r = types.InlineQueryResultPhoto('1',
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/kitten.jpg',
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/kitten.jpg',
input_message_content=types.InputTextMessageContent('hi'))
r2 = types.InlineQueryResultPhoto('2',
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/rooster.jpg',
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/rooster.jpg')
bot.answer_inline_query(inline_query.id, [r, r2], cache_time=1)
except Exception as e:
print(e)
@bot.inline_handler(lambda query: query.query == 'video')
def query_video(inline_query):
try:
r = types.InlineQueryResultVideo('1',
'https://github.com/eternnoir/pyTelegramBotAPI/blob/master/tests/test_data/test_video.mp4?raw=true',
'video/mp4', 'Video',
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/rooster.jpg',
'Title'
)
bot.answer_inline_query(inline_query.id, [r])
except Exception as e:
print(e)
@bot.inline_handler(lambda query: len(query.query) == 0)
def default_query(inline_query):
try:
r = types.InlineQueryResultArticle('1', 'default', types.InputTextMessageContent('default'))
bot.answer_inline_query(inline_query.id, [r])
except Exception as e:
print(e)
def main_loop():
bot.polling(True)
while 1:
time.sleep(3)
if __name__ == '__main__':
try:
main_loop()
except KeyboardInterrupt:
print('\nExiting by user request.\n')
sys.exit(0)

View File

@ -0,0 +1,27 @@
# This example show how to use inline keyboards and process button presses
import telebot
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
TELEGRAM_TOKEN = '<TOKEN>'
bot = telebot.TeleBot(TELEGRAM_TOKEN)
def gen_markup():
markup = InlineKeyboardMarkup()
markup.row_width = 2
markup.add(InlineKeyboardButton("Yes", callback_data="cb_yes"),
InlineKeyboardButton("No", callback_data="cb_no"))
return markup
@bot.callback_query_handler(func=lambda call: True)
def callback_query(call):
if call.data == "cb_yes":
bot.answer_callback_query(call.id, "Answer is Yes")
elif call.data == "cb_no":
bot.answer_callback_query(call.id, "Answer is No")
@bot.message_handler(func=lambda message: True)
def message_handler(message):
bot.send_message(message.chat.id, "Yes/no?", reply_markup=gen_markup())
bot.polling(none_stop=True)

View File

@ -0,0 +1,82 @@
import telebot
from telebot.types import LabeledPrice, ShippingOption
token = '1234567890:AAAABBBBCCCCDDDDeeeeFFFFgggGHHHH'
provider_token = '1234567890:TEST:AAAABBBBCCCCDDDD' # @BotFather -> Bot Settings -> Payments
bot = telebot.TeleBot(token)
# More about Payments: https://core.telegram.org/bots/payments
prices = [LabeledPrice(label='Working Time Machine', amount=5750), LabeledPrice('Gift wrapping', 500)]
shipping_options = [
ShippingOption(id='instant', title='WorldWide Teleporter').add_price(LabeledPrice('Teleporter', 1000)),
ShippingOption(id='pickup', title='Local pickup').add_price(LabeledPrice('Pickup', 300))]
@bot.message_handler(commands=['start'])
def command_start(message):
bot.send_message(message.chat.id,
"Hello, I'm the demo merchant bot."
" I can sell you a Time Machine."
" Use /buy to order one, /terms for Terms and Conditions")
@bot.message_handler(commands=['terms'])
def command_terms(message):
bot.send_message(message.chat.id,
'Thank you for shopping with our demo bot. We hope you like your new time machine!\n'
'1. If your time machine was not delivered on time, please rethink your concept of time and try again.\n'
'2. If you find that your time machine is not working, kindly contact our future service workshops on Trappist-1e.'
' They will be accessible anywhere between May 2075 and November 4000 C.E.\n'
'3. If you would like a refund, kindly apply for one yesterday and we will have sent it to you immediately.')
@bot.message_handler(commands=['buy'])
def command_pay(message):
bot.send_message(message.chat.id,
"Real cards won't work with me, no money will be debited from your account."
" Use this test card number to pay for your Time Machine: `4242 4242 4242 4242`"
"\n\nThis is your demo invoice:", parse_mode='Markdown')
bot.send_invoice(message.chat.id, title='Working Time Machine',
description='Want to visit your great-great-great-grandparents?'
' Make a fortune at the races?'
' Shake hands with Hammurabi and take a stroll in the Hanging Gardens?'
' Order our Working Time Machine today!',
provider_token=provider_token,
currency='usd',
photo_url='http://erkelzaar.tsudao.com/models/perrotta/TIME_MACHINE.jpg',
photo_height=512, # !=0/None or picture won't be shown
photo_width=512,
photo_size=512,
is_flexible=False, # True If you need to set up Shipping Fee
prices=prices,
start_parameter='time-machine-example',
invoice_payload='HAPPY FRIDAYS COUPON')
@bot.shipping_query_handler(func=lambda query: True)
def shipping(shipping_query):
print(shipping_query)
bot.answer_shipping_query(shipping_query.id, ok=True, shipping_options=shipping_options,
error_message='Oh, seems like our Dog couriers are having a lunch right now. Try again later!')
@bot.pre_checkout_query_handler(func=lambda query: True)
def checkout(pre_checkout_query):
bot.answer_pre_checkout_query(pre_checkout_query.id, ok=True,
error_message="Aliens tried to steal your card's CVV, but we successfully protected your credentials,"
" try to pay again in a few minutes, we need a small rest.")
@bot.message_handler(content_types=['successful_payment'])
def got_payment(message):
bot.send_message(message.chat.id,
'Hoooooray! Thanks for payment! We will proceed your order for `{} {}` as fast as possible! '
'Stay in touch.\n\nUse /buy again to get a Time Machine for your friend!'.format(
message.successful_payment.total_amount / 100, message.successful_payment.currency),
parse_mode='Markdown')
bot.skip_pending = True
bot.polling(none_stop=True, interval=0)

View File

@ -0,0 +1,69 @@
# Using Azure Functions for serverless bots.
# (Thanks to twitter.com/masyan for the idea)
# By default the Azure Functions url is https://.../api/HttpTrigger for HttpTrigger type.
# In this example we will use clear webhook url without /api/ -> https://.../HttpTrigger.
# Also we set "authLevel": "anonymous".
# For HttpTrigger type set "route" and "authLevel" in functions.json
# {
# "bindings": [
# ...
# "authLevel": "anonymous"
# "route": "HttpTrigger"
# ]
# }
# To avoid using /api/ in url set "routePrefix":"" in host.json
# {
# ...
# "extensions": {
# "http": {
# "routePrefix": ""
# }
# }
# }
import logging
import azure.functions as func
import telebot
from telebot import apihelper, types
logger = telebot.logger
telebot.logger.setLevel(logging.DEBUG)
# Set bot token
TOKEN = ''
# Uncomment this for using proxy for request
# PROXY = ''
# apihelper.proxy = {'https': PROXY}
# Set WEBHOOK as your Azure Functions url (https://...azurewebsites.net/HttpTrigger)
WEBHOOK = ''
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=['start'])
def start(message):
bot.reply_to(message, 'Hello, ' + message.from_user.first_name)
@bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)
# To avoid "error 429 too many request" set webhook only once. Or use time.sleep(1).
def main(req: func.HttpRequest) -> func.HttpResponse:
bot.set_webhook(url=WEBHOOK)
request_body_dict = req.get_json()
update = telebot.types.Update.de_json(request_body_dict)
bot.process_new_messages([update.message])
return func.HttpResponse(body='', status_code=200)
# Sometimes "requests" version is important.
# azure-functions==1.0.4
# PySocks==1.7.1
# pyTelegramBotAPI==3.6.6
# requests==2.10.0

View File

@ -2,7 +2,6 @@
"""
This Example will show you how to use register_next_step handler.
"""
import time
import telebot
from telebot import types
@ -75,4 +74,13 @@ def process_sex_step(message):
bot.reply_to(message, 'oooops')
# Enable saving next step handlers to file "./.handlers-saves/step.save".
# Delay=2 means that after any change in next step handlers (e.g. calling register_next_step_handler())
# saving will hapen after delay 2 seconds.
bot.enable_save_next_step_handlers(delay=2)
# Load next_step_handlers from save file (default "./.handlers-saves/step.save")
# WARNING It will work only if enable_save_next_step_handlers was called!
bot.load_next_step_handlers()
bot.polling()

View File

@ -3,9 +3,10 @@
# and goes by the name 'TeleBot (@pyTeleBot)'. Join our group to talk to him!
# WARNING: Tested with Python 2.7
import telebot
import os
import telebot
text_messages = {
'welcome':
u'Please welcome {name}!\n\n'
@ -33,8 +34,10 @@ if "TELEBOT_BOT_TOKEN" not in os.environ or "GROUP_CHAT_ID" not in os.environ:
bot = telebot.AsyncTeleBot(os.environ["TELEBOT_BOT_TOKEN"])
GROUP_CHAT_ID = int(os.environ["GROUP_CHAT_ID"])
def is_api_group(chat_id):
return chat_id== GROUP_CHAT_ID
return chat_id == GROUP_CHAT_ID
@bot.message_handler(func=lambda m: True, content_types=['new_chat_participant'])
def on_user_joins(message):
@ -50,6 +53,7 @@ def on_user_joins(message):
bot.reply_to(message, text_messages['welcome'].format(name=name))
@bot.message_handler(commands=['info', 'help'])
def on_info(message):
if not is_api_group(message.chat.id):
@ -58,21 +62,23 @@ def on_info(message):
bot.reply_to(message, text_messages['info'])
@bot.message_handler(commands=["ping"])
def on_ping(message):
bot.reply_to(message, "Still alive and kicking!")
@bot.message_handler(commands=['start'])
def on_start(message):
if not is_api_group(message.chat.id):
bot.reply_to(message, text_messages['wrong_chat'])
return
def listener(messages):
for m in messages:
print str(m)
print(str(m))
bot.set_update_listener(listener)
bot.polling()

View File

@ -0,0 +1,45 @@
# Webhook examples using pyTelegramBotAPI
There are 4 examples in this directory using different libraries:
* **Python (CPython):** *webhook_cpython_echo_bot.py*
* **Pros:**
* Official python libraries, it works out of the box (doesn't require to
install anything).
* Works with Python 2 and Python 3 (need to be converted with 2to3).
* **Cons:**
* Ugly code.
* Many things to handle yourself, this can lead to errors.
* Not powerful, do the trick but the performance is low.
* **CherryPy (3.8.0):** *webhook_cherrypy_echo_bot.py*
* **Pros:**
* It's a web application framework, cleaner code, uses objects for defining
the web application.
* Very good performance.
* The project seems to be active, latest version is recent.
* Works with Python 2 and Python 3.
* **Cons:**
* Some things are not very intuitive, reading the doc is a must.
* **Flask (0.10.1):** *webhook_flask_echo_bot.py*
* **Pros:**
* It's a web application framework, cleaner code, uses decorator which can
be nice.
* Good performance.
* It's intuitive if you know how web application works.
* **Cons:**
* The project seems not to be very active, latest version dates 2013.
* They don't recommend to use it with Python 3, but may work.
* May be a oversized for just handling webhook petitions.
* **aiohttp (1.2.0):** *webhook_aiohttp_echo_bot.py*
* **Pros:**
* It's a web application framework
* Python 3 compatible
* Asynchronous, excellent perfomance
* Utilizes new async/await syntax
* **Cons:**
* Requires Python 3.4.2+, don't work with Python 2
*Latest update of this document: 2017-01-30*

View File

@ -0,0 +1,87 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This is a simple echo bot using decorators and webhook with aiohttp
# It echoes any incoming text messages and does not use the polling method.
import logging
import ssl
from aiohttp import web
import telebot
API_TOKEN = '<api_token>'
WEBHOOK_HOST = '<ip/host where the bot is running>'
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
WEBHOOK_SSL_CERT = './webhook_cert.pem' # Path to the ssl certificate
WEBHOOK_SSL_PRIV = './webhook_pkey.pem' # Path to the ssl private key
# Quick'n'dirty SSL certificate generation:
#
# openssl genrsa -out webhook_pkey.pem 2048
# openssl req -new -x509 -days 3650 -key webhook_pkey.pem -out webhook_cert.pem
#
# When asked for "Common Name (e.g. server FQDN or YOUR name)" you should reply
# with the same value in you put in WEBHOOK_HOST
WEBHOOK_URL_BASE = "https://{}:{}".format(WEBHOOK_HOST, WEBHOOK_PORT)
WEBHOOK_URL_PATH = "/{}/".format(API_TOKEN)
logger = telebot.logger
telebot.logger.setLevel(logging.INFO)
bot = telebot.TeleBot(API_TOKEN)
app = web.Application()
# Process webhook calls
async def handle(request):
if request.match_info.get('token') == bot.token:
request_body_dict = await request.json()
update = telebot.types.Update.de_json(request_body_dict)
bot.process_new_updates([update])
return web.Response()
else:
return web.Response(status=403)
app.router.add_post('/{token}/', handle)
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message,
("Hi there, I am EchoBot.\n"
"I am here to echo your kind words back to you."))
# Handle all other messages
@bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)
# Remove webhook, it fails sometimes the set if there is a previous webhook
bot.remove_webhook()
# Set webhook
bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
certificate=open(WEBHOOK_SSL_CERT, 'r'))
# Build ssl context
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain(WEBHOOK_SSL_CERT, WEBHOOK_SSL_PRIV)
# Start aiohttp server
web.run_app(
app,
host=WEBHOOK_LISTEN,
port=WEBHOOK_PORT,
ssl_context=context,
)

View File

@ -0,0 +1,90 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This is a simple echo bot using decorators and webhook with CherryPy
# It echoes any incoming text messages and does not use the polling method.
import logging
import cherrypy
import telebot
API_TOKEN = '<api_token>'
WEBHOOK_HOST = '<ip/host where the bot is running>'
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
WEBHOOK_SSL_CERT = './webhook_cert.pem' # Path to the ssl certificate
WEBHOOK_SSL_PRIV = './webhook_pkey.pem' # Path to the ssl private key
# Quick'n'dirty SSL certificate generation:
#
# openssl genrsa -out webhook_pkey.pem 2048
# openssl req -new -x509 -days 3650 -key webhook_pkey.pem -out webhook_cert.pem
#
# When asked for "Common Name (e.g. server FQDN or YOUR name)" you should reply
# with the same value in you put in WEBHOOK_HOST
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
WEBHOOK_URL_PATH = "/%s/" % (API_TOKEN)
logger = telebot.logger
telebot.logger.setLevel(logging.INFO)
bot = telebot.TeleBot(API_TOKEN)
# WebhookServer, process webhook calls
class WebhookServer(object):
@cherrypy.expose
def index(self):
if 'content-length' in cherrypy.request.headers and \
'content-type' in cherrypy.request.headers and \
cherrypy.request.headers['content-type'] == 'application/json':
length = int(cherrypy.request.headers['content-length'])
json_string = cherrypy.request.body.read(length).decode("utf-8")
update = telebot.types.Update.de_json(json_string)
bot.process_new_updates([update])
return ''
else:
raise cherrypy.HTTPError(403)
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message,
("Hi there, I am EchoBot.\n"
"I am here to echo your kind words back to you."))
# Handle all other messages
@bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)
# Remove webhook, it fails sometimes the set if there is a previous webhook
bot.remove_webhook()
# Set webhook
bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
certificate=open(WEBHOOK_SSL_CERT, 'r'))
# Disable CherryPy requests log
access_log = cherrypy.log.access_log
for handler in tuple(access_log.handlers):
access_log.removeHandler(handler)
# Start cherrypy server
cherrypy.config.update({
'server.socket_host' : WEBHOOK_LISTEN,
'server.socket_port' : WEBHOOK_PORT,
'server.ssl_module' : 'builtin',
'server.ssl_certificate': WEBHOOK_SSL_CERT,
'server.ssl_private_key': WEBHOOK_SSL_PRIV
})
cherrypy.quickstart(WebhookServer(), WEBHOOK_URL_PATH, {'/': {}})

View File

@ -0,0 +1,106 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This is a simple echo bot using decorators and webhook with BaseHTTPServer
# It echoes any incoming text messages and does not use the polling method.
try:
# Python 2
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
except ImportError:
# Python 3
from http.server import BaseHTTPRequestHandler, HTTPServer
import logging
import ssl
import telebot
API_TOKEN = '<api_token>'
WEBHOOK_HOST = '<ip/host where the bot is running>'
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
WEBHOOK_SSL_CERT = './webhook_cert.pem' # Path to the ssl certificate
WEBHOOK_SSL_PRIV = './webhook_pkey.pem' # Path to the ssl private key
# Quick'n'dirty SSL certificate generation:
#
# openssl genrsa -out webhook_pkey.pem 2048
# openssl req -new -x509 -days 3650 -key webhook_pkey.pem -out webhook_cert.pem
#
# When asked for "Common Name (e.g. server FQDN or YOUR name)" you should reply
# with the same value in you put in WEBHOOK_HOST
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
WEBHOOK_URL_PATH = "/%s/" % (API_TOKEN)
logger = telebot.logger
telebot.logger.setLevel(logging.INFO)
bot = telebot.TeleBot(API_TOKEN)
# WebhookHandler, process webhook calls
class WebhookHandler(BaseHTTPRequestHandler):
server_version = "WebhookHandler/1.0"
def do_HEAD(self):
self.send_response(200)
self.end_headers()
def do_GET(self):
self.send_response(200)
self.end_headers()
def do_POST(self):
if self.path == WEBHOOK_URL_PATH and \
'content-type' in self.headers and \
'content-length' in self.headers and \
self.headers['content-type'] == 'application/json':
json_string = self.rfile.read(int(self.headers['content-length']))
self.send_response(200)
self.end_headers()
update = telebot.types.Update.de_json(json_string)
bot.process_new_messages([update.message])
else:
self.send_error(403)
self.end_headers()
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message,
("Hi there, I am EchoBot.\n"
"I am here to echo your kind words back to you."))
# Handle all other messages
@bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)
# Remove webhook, it fails sometimes the set if there is a previous webhook
#bot.remove_webhook()
# Set webhook
# Beacuse telegram bot api server will check webhook server is alive.
# Here we need set webhook after server started manually.
#bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
# certificate=open(WEBHOOK_SSL_CERT, 'r'))
# Start server
httpd = HTTPServer((WEBHOOK_LISTEN, WEBHOOK_PORT),
WebhookHandler)
httpd.socket = ssl.wrap_socket(httpd.socket,
certfile=WEBHOOK_SSL_CERT,
keyfile=WEBHOOK_SSL_PRIV,
server_side=True)
httpd.serve_forever()

View File

@ -0,0 +1,87 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This is a simple echo bot using decorators and webhook with flask
# It echoes any incoming text messages and does not use the polling method.
import logging
import time
import flask
import telebot
API_TOKEN = '<api_token>'
WEBHOOK_HOST = '<ip/host where the bot is running>'
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
WEBHOOK_SSL_CERT = './webhook_cert.pem' # Path to the ssl certificate
WEBHOOK_SSL_PRIV = './webhook_pkey.pem' # Path to the ssl private key
# Quick'n'dirty SSL certificate generation:
#
# openssl genrsa -out webhook_pkey.pem 2048
# openssl req -new -x509 -days 3650 -key webhook_pkey.pem -out webhook_cert.pem
#
# When asked for "Common Name (e.g. server FQDN or YOUR name)" you should reply
# with the same value in you put in WEBHOOK_HOST
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
WEBHOOK_URL_PATH = "/%s/" % (API_TOKEN)
logger = telebot.logger
telebot.logger.setLevel(logging.INFO)
bot = telebot.TeleBot(API_TOKEN)
app = flask.Flask(__name__)
# Empty webserver index, return nothing, just http 200
@app.route('/', methods=['GET', 'HEAD'])
def index():
return ''
# Process webhook calls
@app.route(WEBHOOK_URL_PATH, methods=['POST'])
def webhook():
if flask.request.headers.get('content-type') == 'application/json':
json_string = flask.request.get_data().decode('utf-8')
update = telebot.types.Update.de_json(json_string)
bot.process_new_updates([update])
return ''
else:
flask.abort(403)
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message,
("Hi there, I am EchoBot.\n"
"I am here to echo your kind words back to you."))
# Handle all other messages
@bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)
# Remove webhook, it fails sometimes the set if there is a previous webhook
bot.remove_webhook()
time.sleep(0.1)
# Set webhook
bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
certificate=open(WEBHOOK_SSL_CERT, 'r'))
# Start flask server
app.run(host=WEBHOOK_LISTEN,
port=WEBHOOK_PORT,
ssl_context=(WEBHOOK_SSL_CERT, WEBHOOK_SSL_PRIV),
debug=True)

View File

@ -0,0 +1,36 @@
import os
from flask import Flask, request
import telebot
TOKEN = '<api_token>'
bot = telebot.TeleBot(TOKEN)
server = Flask(__name__)
@bot.message_handler(commands=['start'])
def start(message):
bot.reply_to(message, 'Hello, ' + message.from_user.first_name)
@bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)
@server.route('/' + TOKEN, methods=['POST'])
def getMessage():
bot.process_new_updates([telebot.types.Update.de_json(request.stream.read().decode("utf-8"))])
return "!", 200
@server.route("/")
def webhook():
bot.remove_webhook()
bot.set_webhook(url='https://your_heroku_project.com/' + TOKEN)
return "!", 200
if __name__ == "__main__":
server.run(host="0.0.0.0", port=int(os.environ.get('PORT', 5000)))

View File

@ -0,0 +1,105 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This example shows webhook echo bot with Tornado web framework
# Documenation to Tornado: http://tornadoweb.org
import signal
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import telebot
API_TOKEN = '<api_token>'
WEBHOOK_CERT = "./cert.pem"
WEBHOOK_PKEY = "./pkey.pem"
WEBHOOK_HOST = "<domain_or_ip>"
WEBHOOK_SECRET = "<secret_uri_for_updates"
WEBHOOK_PORT = 88
WEBHOOK_URL_BASE = "https://{0}:{1}/{2}".format(WEBHOOK_HOST, str(WEBHOOK_PORT), WEBHOOK_SECRET)
# Quick'n'dirty SSL certificate generation:
#
# openssl genrsa -out pkey.pem 2048
# openssl req -new -x509 -days 3650 -key pkey.pem -out cert.pem
#
# When asked for "Common Name (e.g. server FQDN or YOUR name)" you should reply
# with the same value in you put in WEBHOOK_HOST
bot = telebot.TeleBot(API_TOKEN)
class Root(tornado.web.RequestHandler):
def get(self):
self.write("Hi! This is webhook example!")
self.finish()
class webhook_serv(tornado.web.RequestHandler):
def get(self):
self.write("What are you doing here?")
self.finish()
def post(self):
if "Content-Length" in self.request.headers and \
"Content-Type" in self.request.headers and \
self.request.headers['Content-Type'] == "application/json":
# length = int(self.request.headers['Content-Length'])
json_data = self.request.body.decode("utf-8")
update = telebot.types.Update.de_json(json_data)
bot.process_new_updates([update])
self.write("")
self.finish()
else:
self.write("What are you doing here?")
self.finish()
tornado.options.define("port", default=WEBHOOK_PORT, help="run on the given port", type=int)
is_closing = False
def signal_handler(signum, frame):
global is_closing
print("Exiting...")
is_closing = True
def try_exit():
global is_closing
if is_closing:
# clean up here
tornado.ioloop.IOLoop.instance().stop()
print("Exit success!")
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message,
("Hi there, I am EchoBot.\n"
"I am here to echo your kind words back to you."))
bot.remove_webhook()
bot.set_webhook(url=WEBHOOK_URL_BASE,
certificate=open(WEBHOOK_CERT, 'r'))
tornado.options.options.logging = None
tornado.options.parse_command_line()
signal.signal(signal.SIGINT, signal_handler)
application = tornado.web.Application([
(r"/", Root),
(r"/" + WEBHOOK_SECRET, webhook_serv)
])
http_server = tornado.httpserver.HTTPServer(application, ssl_options={
"certfile": WEBHOOK_CERT,
"keyfile" : WEBHOOK_PKEY,
})
http_server.listen(tornado.options.options.port)
tornado.ioloop.PeriodicCallback(try_exit, 100).start()
tornado.ioloop.IOLoop.instance().start()

View File

@ -1,5 +1,5 @@
py==1.4.29
pytest==2.7.2
requests==2.7.0
pytest==3.0.2
requests==2.20.0
six==1.9.0
wheel==0.24.0

View File

@ -1,25 +1,29 @@
#!/usr/bin/env python
from setuptools import setup
from io import open
def readme():
with open('README.rst') as f:
return f.read()
def read(filename):
with open(filename, encoding='utf-8') as file:
return file.read()
setup(name='pyTelegramBotAPI',
version='0.3.4',
version='3.6.6',
description='Python Telegram bot api. ',
long_description=readme(),
long_description=read('README.md'),
long_description_content_type="text/markdown",
author='eternnoir',
author_email='eternnoir@gmail.com',
url='https://github.com/eternnoir/pyTelegramBotAPI',
packages=['telebot'],
license='GPL2',
keywords='telegram bot api tools',
install_requires=['pytest', 'requests', 'six'],
install_requires=['requests', 'six'],
extras_require={
'json': 'ujson',
},
classifiers=[
'Development Status :: 5 - Production/Stable',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Environment :: Console',

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,123 @@
# -*- coding: utf-8 -*-
import random
import re
import string
import sys
import threading
import traceback
import six
from six import string_types
# Python3 queue support.
try:
import Queue
except ImportError:
import queue as Queue
import logging
logger = logging.getLogger('TeleBot')
thread_local = threading.local()
class ThreadPool:
class WorkerThread(threading.Thread):
class WorkerThread(threading.Thread):
count = 0
def __init__(self, queue):
threading.Thread.__init__(self, name="WorkerThread{0}".format(self.__class__.count + 1))
self.__class__.count += 1
def __init__(self, exception_callback=None, queue=None, name=None):
if not name:
name = "WorkerThread{0}".format(self.__class__.count + 1)
self.__class__.count += 1
if not queue:
queue = Queue.Queue()
threading.Thread.__init__(self, name=name)
self.queue = queue
self.daemon = True
self.received_task_event = threading.Event()
self.done_event = threading.Event()
self.exception_event = threading.Event()
self.continue_event = threading.Event()
self.exception_callback = exception_callback
self.exc_info = None
self._running = True
self.start()
def run(self):
while self._running:
try:
task, args, kwargs = self.queue.get(block=True, timeout=.01)
task, args, kwargs = self.queue.get(block=True, timeout=.5)
self.continue_event.clear()
self.received_task_event.clear()
self.done_event.clear()
self.exception_event.clear()
logger.debug("Received task")
self.received_task_event.set()
task(*args, **kwargs)
logger.debug("Task complete")
self.done_event.set()
except Queue.Empty:
pass
except Exception as e:
logger.error(type(e).__name__ + " occurred, args=" + str(e.args) + "\n" + traceback.format_exc())
self.exc_info = sys.exc_info()
self.exception_event.set()
if self.exception_callback:
self.exception_callback(self, self.exc_info)
self.continue_event.wait()
def put(self, task, *args, **kwargs):
self.queue.put((task, args, kwargs))
def raise_exceptions(self):
if self.exception_event.is_set():
six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2])
def clear_exceptions(self):
self.exception_event.clear()
self.continue_event.set()
def stop(self):
self._running = False
def __init__(self, num_threads=4):
self.tasks = Queue.Queue()
self.workers = [self.WorkerThread(self.tasks) for _ in range(num_threads)]
class ThreadPool:
def __init__(self, num_threads=2):
self.tasks = Queue.Queue()
self.workers = [WorkerThread(self.on_exception, self.tasks) for _ in range(num_threads)]
self.num_threads = num_threads
self.exception_event = threading.Event()
self.exc_info = None
def put(self, func, *args, **kwargs):
self.tasks.put((func, args, kwargs))
def on_exception(self, worker_thread, exc_info):
self.exc_info = exc_info
self.exception_event.set()
worker_thread.continue_event.set()
def raise_exceptions(self):
if self.exception_event.is_set():
six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2])
def clear_exceptions(self):
self.exception_event.clear()
def close(self):
for worker in self.workers:
worker.stop()
for worker in self.workers:
worker.join()
class AsyncTask:
def __init__(self, target, *args, **kwargs):
self.target = target
@ -62,20 +131,20 @@ class AsyncTask:
def _run(self):
try:
self.result = self.target(*self.args, **self.kwargs)
except Exception as e:
self.result = e
except:
self.result = sys.exc_info()
self.done = True
def wait(self):
if not self.done:
self.thread.join()
if isinstance(self.result, Exception):
raise self.result
if isinstance(self.result, BaseException):
six.reraise(self.result[0], self.result[1], self.result[2])
else:
return self.result
def async():
def async_dec():
def decorator(fn):
def wrapper(*args, **kwargs):
return AsyncTask(fn, *args, **kwargs)
@ -124,3 +193,69 @@ def split_string(text, chars_per_string):
:return: The splitted text as a list of strings.
"""
return [text[i:i + chars_per_string] for i in range(0, len(text), chars_per_string)]
# CREDITS TO http://stackoverflow.com/questions/12317940#answer-12320352
def or_set(self):
self._set()
self.changed()
def or_clear(self):
self._clear()
self.changed()
def orify(e, changed_callback):
e._set = e.set
e._clear = e.clear
e.changed = changed_callback
e.set = lambda: or_set(e)
e.clear = lambda: or_clear(e)
def OrEvent(*events):
or_event = threading.Event()
def changed():
bools = [e.is_set() for e in events]
if any(bools):
or_event.set()
else:
or_event.clear()
def busy_wait():
while not or_event.is_set():
or_event._wait(3)
for e in events:
orify(e, changed)
or_event._wait = or_event.wait
or_event.wait = busy_wait
changed()
return or_event
def extract_arguments(text):
"""
Returns the argument after the command.
Examples:
extract_arguments("/get name"): 'name'
extract_arguments("/get"): ''
extract_arguments("/get@botName name"): 'name'
:param text: String to extract the arguments from a command
:return: the arguments if `text` is a command (according to is_command), else None.
"""
regexp = re.compile("/\w*(@\w*)*\s*([\s\S]*)",re.IGNORECASE)
result = regexp.match(text)
return result.group(2) if is_command(text) else None
def per_thread(key, construct_value, reset=False):
if reset or not hasattr(thread_local, key):
value = construct_value()
setattr(thread_local, key, value)
return getattr(thread_local, key)
def generate_random_token():
return ''.join(random.sample(string.ascii_letters, 16))

View File

@ -9,7 +9,6 @@ import os
import telebot
from telebot import types
from telebot import apihelper
from telebot import util
should_skip = 'TOKEN' and 'CHAT_ID' not in os.environ
@ -17,6 +16,7 @@ should_skip = 'TOKEN' and 'CHAT_ID' not in os.environ
if not should_skip:
TOKEN = os.environ['TOKEN']
CHAT_ID = os.environ['CHAT_ID']
GROUP_ID = os.environ['GROUP_ID']
@pytest.mark.skipif(should_skip, reason="No environment variables configured")
@ -56,6 +56,30 @@ class TestTeleBot:
time.sleep(1)
assert msg.text == 'got'
def test_message_handler_lambda(self):
bot = telebot.TeleBot('')
msg = self.create_text_message(r'lambda_text')
@bot.message_handler(func=lambda message: r'lambda' in message.text)
def command_url(message):
msg.text = 'got'
bot.process_new_messages([msg])
time.sleep(1)
assert msg.text == 'got'
def test_message_handler_lambda_fail(self):
bot = telebot.TeleBot('')
msg = self.create_text_message(r'text')
@bot.message_handler(func=lambda message: r'lambda' in message.text)
def command_url(message):
msg.text = 'got'
bot.process_new_messages([msg])
time.sleep(1)
assert not msg.text == 'got'
def test_message_handler_reg_fail(self):
bot = telebot.TeleBot('')
msg = self.create_text_message(r'web.telegram.org/')
@ -78,6 +102,15 @@ class TestTeleBot:
ret_msg = tb.send_message(CHAT_ID, markdown, parse_mode="Markdown")
assert ret_msg.message_id
def test_send_message_with_disable_notification(self):
tb = telebot.TeleBot(TOKEN)
markdown = """
*bold text*
_italic text_
[text](URL)
"""
ret_msg = tb.send_message(CHAT_ID, markdown, parse_mode="Markdown", disable_notification=True)
assert ret_msg.message_id
def test_send_file(self):
file_data = open('../examples/detailed_example/kitten.jpg', 'rb')
@ -88,18 +121,48 @@ class TestTeleBot:
ret_msg = tb.send_document(CHAT_ID, ret_msg.document.file_id)
assert ret_msg.message_id
def test_send_file_dis_noti(self):
file_data = open('../examples/detailed_example/kitten.jpg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_document(CHAT_ID, file_data, disable_notification=True)
assert ret_msg.message_id
ret_msg = tb.send_document(CHAT_ID, ret_msg.document.file_id)
assert ret_msg.message_id
def test_send_file_caption(self):
file_data = open('../examples/detailed_example/kitten.jpg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_document(CHAT_ID, file_data, caption="Test")
assert ret_msg.message_id
ret_msg = tb.send_document(CHAT_ID, ret_msg.document.file_id)
assert ret_msg.message_id
def test_send_video(self):
file_data = open('./test_data/test_video.mp4', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_video(CHAT_ID, file_data)
assert ret_msg.message_id
def test_send_video_dis_noti(self):
file_data = open('./test_data/test_video.mp4', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_video(CHAT_ID, file_data, disable_notification=True)
assert ret_msg.message_id
def test_send_video_more_params(self):
file_data = open('./test_data/test_video.mp4', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_video(CHAT_ID, file_data, 1)
assert ret_msg.message_id
def test_send_video_more_params_dis_noti(self):
file_data = open('./test_data/test_video.mp4', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_video(CHAT_ID, file_data, 1, disable_notification=True)
assert ret_msg.message_id
def test_send_file_exception(self):
tb = telebot.TeleBot(TOKEN)
try:
@ -118,10 +181,28 @@ class TestTeleBot:
ret_msg = tb.send_photo(CHAT_ID, ret_msg.photo[0].file_id)
assert ret_msg.message_id
def test_send_photo_dis_noti(self):
file_data = open('../examples/detailed_example/kitten.jpg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_photo(CHAT_ID, file_data)
assert ret_msg.message_id
ret_msg = tb.send_photo(CHAT_ID, ret_msg.photo[0].file_id, disable_notification=True)
assert ret_msg.message_id
def test_send_audio(self):
file_data = open('./test_data/record.mp3', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_audio(CHAT_ID, file_data, 1, 'eternnoir', 'pyTelegram')
ret_msg = tb.send_audio(CHAT_ID, file_data, 1, performer='eternnoir', title='pyTelegram')
assert ret_msg.content_type == 'audio'
assert ret_msg.audio.performer == 'eternnoir'
assert ret_msg.audio.title == 'pyTelegram'
def test_send_audio_dis_noti(self):
file_data = open('./test_data/record.mp3', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_audio(CHAT_ID, file_data, 1, performer='eternnoir', title='pyTelegram',
disable_notification=True)
assert ret_msg.content_type == 'audio'
assert ret_msg.audio.performer == 'eternnoir'
assert ret_msg.audio.title == 'pyTelegram'
@ -132,12 +213,69 @@ class TestTeleBot:
ret_msg = tb.send_voice(CHAT_ID, file_data)
assert ret_msg.voice.mime_type == 'audio/ogg'
def test_send_voice_dis_noti(self):
file_data = open('./test_data/record.ogg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_voice(CHAT_ID, file_data, disable_notification=True)
assert ret_msg.voice.mime_type == 'audio/ogg'
def test_get_file(self):
file_data = open('./test_data/record.ogg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_voice(CHAT_ID, file_data)
file_id = ret_msg.voice.file_id
file_info = tb.get_file(file_id)
assert file_info.file_id == file_id
def test_get_file_dis_noti(self):
file_data = open('./test_data/record.ogg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_voice(CHAT_ID, file_data, disable_notification=True)
file_id = ret_msg.voice.file_id
file_info = tb.get_file(file_id)
assert file_info.file_id == file_id
def test_send_message(self):
text = 'CI Test Message'
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_message(CHAT_ID, text)
assert ret_msg.message_id
def test_send_message_dis_noti(self):
text = 'CI Test Message'
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_message(CHAT_ID, text, disable_notification=True)
assert ret_msg.message_id
def test_send_message_with_markup(self):
text = 'CI Test Message'
tb = telebot.TeleBot(TOKEN)
markup = types.ReplyKeyboardMarkup()
markup.add(types.KeyboardButton("1"))
markup.add(types.KeyboardButton("2"))
ret_msg = tb.send_message(CHAT_ID, text, disable_notification=True, reply_markup=markup)
assert ret_msg.message_id
def test_send_message_with_markup_use_string(self):
text = 'CI Test Message'
tb = telebot.TeleBot(TOKEN)
markup = types.ReplyKeyboardMarkup()
markup.add("1")
markup.add("2")
markup.add("3")
markup.add("4")
ret_msg = tb.send_message(CHAT_ID, text, disable_notification=True, reply_markup=markup)
assert ret_msg.message_id
def test_send_message_with_inlinemarkup(self):
text = 'CI Test Message'
tb = telebot.TeleBot(TOKEN)
markup = types.InlineKeyboardMarkup()
markup.add(types.InlineKeyboardButton("Google", url="http://www.google.com"))
markup.add(types.InlineKeyboardButton("Yahoo", url="http://www.yahoo.com"))
ret_msg = tb.send_message(CHAT_ID, text, disable_notification=True, reply_markup=markup)
assert ret_msg.message_id
def test_forward_message(self):
text = 'CI forward_message Test Message'
tb = telebot.TeleBot(TOKEN)
@ -145,6 +283,13 @@ class TestTeleBot:
ret_msg = tb.forward_message(CHAT_ID, CHAT_ID, msg.message_id)
assert ret_msg.forward_from
def test_forward_message_dis_noti(self):
text = 'CI forward_message Test Message'
tb = telebot.TeleBot(TOKEN)
msg = tb.send_message(CHAT_ID, text)
ret_msg = tb.forward_message(CHAT_ID, CHAT_ID, msg.message_id, disable_notification=True)
assert ret_msg.forward_from
def test_reply_to(self):
text = 'CI reply_to Test Message'
tb = telebot.TeleBot(TOKEN)
@ -173,10 +318,95 @@ class TestTeleBot:
assert int(ret_msg.location.longitude) == int(lon)
assert int(ret_msg.location.latitude) == int(lat)
def create_text_message(self, text):
def test_send_location_dis_noti(self):
tb = telebot.TeleBot(TOKEN)
lat = 26.3875591
lon = -161.2901042
ret_msg = tb.send_location(CHAT_ID, lat, lon, disable_notification=True)
assert int(ret_msg.location.longitude) == int(lon)
assert int(ret_msg.location.latitude) == int(lat)
def test_send_venue(self):
tb = telebot.TeleBot(TOKEN)
lat = 26.3875591
lon = -161.2901042
ret_msg = tb.send_venue(CHAT_ID, lat, lon, "Test Venue", "1123 Test Venue address")
assert ret_msg.venue.title == "Test Venue"
assert int(lat) == int(ret_msg.venue.location.latitude)
def test_send_venue_dis_noti(self):
tb = telebot.TeleBot(TOKEN)
lat = 26.3875591
lon = -161.2901042
ret_msg = tb.send_venue(CHAT_ID, lat, lon, "Test Venue", "1123 Test Venue address", disable_notification=True)
assert ret_msg.venue.title == "Test Venue"
def test_Chat(self):
tb = telebot.TeleBot(TOKEN)
me = tb.get_me()
msg = tb.send_message(CHAT_ID, 'Test')
assert me.id == msg.from_user.id
assert msg.chat.id == int(CHAT_ID)
def test_edit_message_text(self):
tb = telebot.TeleBot(TOKEN)
msg = tb.send_message(CHAT_ID, 'Test')
new_msg = tb.edit_message_text('Edit test', chat_id=CHAT_ID, message_id=msg.message_id)
assert new_msg.text == 'Edit test'
def test_edit_message_caption(self):
file_data = open('../examples/detailed_example/kitten.jpg', 'rb')
tb = telebot.TeleBot(TOKEN)
msg = tb.send_document(CHAT_ID, file_data, caption="Test")
new_msg = tb.edit_message_caption(caption='Edit test', chat_id=CHAT_ID, message_id=msg.message_id)
assert new_msg.caption == 'Edit test'
def test_edit_message_media(self):
file_data = open('../examples/detailed_example/kitten.jpg', 'rb')
file_data_2 = open('../examples/detailed_example/rooster.jpg', 'rb')
tb = telebot.TeleBot(TOKEN)
msg = tb.send_photo(CHAT_ID, file_data)
new_msg = tb.edit_message_media(chat_id=CHAT_ID, message_id=msg.message_id,
media=types.InputMediaPhoto(file_data_2, caption='Test editMessageMedia 0'))
assert type(new_msg) != bool
new_msg = tb.edit_message_media(chat_id=CHAT_ID, message_id=msg.message_id,
media=types.InputMediaPhoto(msg.photo[0].file_id, caption='Test editMessageMedia'))
assert type(new_msg) != bool
assert new_msg.caption == 'Test editMessageMedia'
def test_get_chat(self):
tb = telebot.TeleBot(TOKEN)
ch = tb.get_chat(GROUP_ID)
assert str(ch.id) == GROUP_ID
def test_get_chat_administrators(self):
tb = telebot.TeleBot(TOKEN)
cas = tb.get_chat_administrators(GROUP_ID)
assert len(cas) > 0
def test_get_chat_members_count(self):
tb = telebot.TeleBot(TOKEN)
cn = tb.get_chat_members_count(GROUP_ID)
assert cn > 1
def test_edit_markup(self):
text = 'CI Test Message'
tb = telebot.TeleBot(TOKEN)
markup = types.InlineKeyboardMarkup()
markup.add(types.InlineKeyboardButton("Google", url="http://www.google.com"))
markup.add(types.InlineKeyboardButton("Yahoo", url="http://www.yahoo.com"))
ret_msg = tb.send_message(CHAT_ID, text, disable_notification=True, reply_markup=markup)
markup.add(types.InlineKeyboardButton("Google2", url="http://www.google.com"))
markup.add(types.InlineKeyboardButton("Yahoo2", url="http://www.yahoo.com"))
new_msg = tb.edit_message_reply_markup(chat_id=CHAT_ID, message_id=ret_msg.message_id, reply_markup=markup)
assert new_msg.message_id
@staticmethod
def create_text_message(text):
params = {'text': text}
chat = types.User(11, 'test')
return types.Message(1, None, None, chat, 'text', params)
chat = types.User(11, False, 'test')
return types.Message(1, None, None, chat, 'text', params, "")
def test_is_string_unicode(self):
s1 = u'string'
@ -190,3 +420,72 @@ class TestTeleBot:
i1 = 10
assert not util.is_string(i1)
def test_send_video_note(self):
file_data = open('./test_data/test_video.mp4', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_video_note(CHAT_ID, file_data)
assert ret_msg.message_id
def test_send_media_group(self):
tb = telebot.TeleBot(TOKEN)
img1 = 'https://i.imgur.com/CjXjcnU.png'
img2 = 'https://i.imgur.com/CjXjcnU.png'
medias = [types.InputMediaPhoto(img1, "View"), types.InputMediaPhoto(img2, "Dog")]
result = tb.send_media_group(CHAT_ID, medias)
assert len(result) == 2
assert result[0].media_group_id is not None
assert result[0].media_group_id == result[1].media_group_id
def test_send_media_group_local_files(self):
photo = open('../examples/detailed_example/kitten.jpg', 'rb')
video = open('./test_data/test_video.mp4', 'rb')
tb = telebot.TeleBot(TOKEN)
medias = [types.InputMediaPhoto(photo, "View"),
types.InputMediaVideo(video)]
result = tb.send_media_group(CHAT_ID, medias)
assert len(result) == 2
assert result[0].media_group_id is not None
assert result[1].media_group_id is not None
def test_send_photo_formating_caption(self):
file_data = open('../examples/detailed_example/kitten.jpg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_photo(CHAT_ID, file_data, caption='_italic_', parse_mode='Markdown')
assert ret_msg.caption_entities[0].type == 'italic'
def test_send_video_formatting_caption(self):
file_data = open('./test_data/test_video.mp4', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_video(CHAT_ID, file_data, caption='_italic_', parse_mode='Markdown')
assert ret_msg.caption_entities[0].type == 'italic'
def test_send_audio_formatting_caption(self):
file_data = open('./test_data/record.mp3', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_audio(CHAT_ID, file_data, caption='<b>bold</b>', parse_mode='HTML')
assert ret_msg.caption_entities[0].type == 'bold'
def test_send_voice_formatting_caprion(self):
file_data = open('./test_data/record.ogg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_voice(CHAT_ID, file_data, caption='<b>bold</b>', parse_mode='HTML')
assert ret_msg.caption_entities[0].type == 'bold'
assert ret_msg.voice.mime_type == 'audio/ogg'
def test_send_media_group_formatting_caption(self):
tb = telebot.TeleBot(TOKEN)
img1 = 'https://i.imgur.com/CjXjcnU.png'
img2 = 'https://i.imgur.com/CjXjcnU.png'
medias = [types.InputMediaPhoto(img1, "*View*", parse_mode='Markdown'),
types.InputMediaPhoto(img2, "_Dog_", parse_mode='Markdown')]
result = tb.send_media_group(CHAT_ID, medias)
assert len(result) == 2
assert result[0].media_group_id is not None
assert result[0].caption_entities[0].type == 'bold'
assert result[1].caption_entities[0].type == 'italic'
def test_send_document_formating_caption(self):
file_data = open('../examples/detailed_example/kitten.jpg', 'rb')
tb = telebot.TeleBot(TOKEN)
ret_msg = tb.send_document(CHAT_ID, file_data, caption='_italic_', parse_mode='Markdown')
assert ret_msg.caption_entities[0].type == 'italic'

View File

@ -6,19 +6,19 @@ from telebot import types
def test_json_user():
jsonstring = r'{"id":101176298,"first_name":"RDSSBOT","username":"rdss_bot"}'
jsonstring = r'{"id":101176298,"first_name":"RDSSBOT","username":"rdss_bot","is_bot":true}'
u = types.User.de_json(jsonstring)
assert u.id == 101176298
def test_json_message():
jsonstring = r'{"message_id":1,"from":{"id":108929734,"first_name":"Frank","last_name":"Wang","username":"eternnoir"},"chat":{"id":108929734,"first_name":"Frank","last_name":"Wang","username":"eternnoir"},"date":1435296025,"text":"HIHI"}'
jsonstring = r'{"message_id":1,"from":{"id":108929734,"first_name":"Frank","last_name":"Wang","username":"eternnoir","is_bot":true},"chat":{"id":1734,"first_name":"F","type":"private","last_name":"Wa","username":"oir"},"date":1435296025,"text":"HIHI"}'
msg = types.Message.de_json(jsonstring)
assert msg.text == 'HIHI'
def test_json_message_group():
json_string = r'{"message_id":10,"from":{"id":12345,"first_name":"g","last_name":"G","username":"GG"},"chat":{"id":-866,"title":"\u4ea4"},"date":1435303157,"text":"HIHI"}'
json_string = r'{"message_id":10,"from":{"id":12345,"first_name":"g","last_name":"G","username":"GG","is_bot":true},"chat":{"id":-866,"type":"private","title":"\u4ea4"},"date":1435303157,"text":"HIHI"}'
msg = types.Message.de_json(json_string)
assert msg.text == 'HIHI'
assert len(msg.chat.title) != 0
@ -39,7 +39,7 @@ def test_json_Document():
def test_json_Message_Audio():
json_string = r'{"message_id":131,"from":{"id":12775,"first_name":"dd","username":"dd"},"chat":{"id":10834,"first_name":"dd","last_name":"dd","username":"dd"},"date":1439978364,"audio":{"duration":1,"mime_type":"audio\/mpeg","title":"pyTelegram","performer":"eternnoir","file_id":"BQADBQADDH1JaB8-1KyWUss2-Ag","file_size":20096}}'
json_string = r'{"message_id":131,"from":{"id":12775,"first_name":"dd","username":"dd","is_bot":true },"chat":{"id":10834,"first_name":"dd","type":"private","type":"private","last_name":"dd","username":"dd"},"date":1439978364,"audio":{"duration":1,"mime_type":"audio\/mpeg","title":"pyTelegram","performer":"eternnoir","file_id":"BQADBQADDH1JaB8-1KyWUss2-Ag","file_size":20096}}'
msg = types.Message.de_json(json_string)
assert msg.audio.duration == 1
assert msg.content_type == 'audio'
@ -48,7 +48,7 @@ def test_json_Message_Audio():
def test_json_Message_Sticker():
json_string = r'{"message_id":98,"from":{"id":10734,"first_name":"Fd","last_name":"Wd","username":"dd"},"chat":{"id":10734,"first_name":"Fd","last_name":"Wd","username":"dd"},"date":1435479551,"sticker":{"width":550,"height":368,"thumb":{"file_id":"AAQFABPJLB0sAAQq17w-li3bzoIfAAIC","file_size":1822,"width":90,"height":60},"file_id":"BQADBQADNAIAAsYifgYdGJOa6bGAsQI","file_size":30320}}'
json_string = r'{"message_id":98,"from":{"id":10734,"first_name":"Fd","last_name":"Wd","username":"dd","is_bot":true },"chat":{"id":10734,"first_name":"Fd","type":"private","last_name":"Wd","username":"dd"},"date":1435479551,"sticker":{"width":550,"height":368,"is_animated":true,"thumb":{"file_id":"AAQFABPJLB0sAAQq17w-li3bzoIfAAIC","file_size":1822,"width":90,"height":60},"file_id":"BQADBQADNAIAAsYifgYdGJOa6bGAsQI","file_size":30320}}'
msg = types.Message.de_json(json_string)
assert msg.sticker.height == 368
assert msg.sticker.thumb.height == 60
@ -56,29 +56,29 @@ def test_json_Message_Sticker():
def test_json_Message_Sticker_without_thumb():
json_string = r'{"message_id":98,"from":{"id":10734,"first_name":"Fd","last_name":"Wd","username":"dd"},"chat":{"id":10734,"first_name":"Fd","last_name":"Wd","username":"dd"},"date":1435479551,"sticker":{"width":550,"height":368,"file_id":"BQADBQADNAIAAsYifgYdGJOa6bGAsQI","file_size":30320}}'
json_string = r'{"message_id":98,"from":{"id":10734,"first_name":"Fd","last_name":"Wd","username":"dd","is_bot":true },"chat":{"id":10734,"first_name":"Fd","type":"private","last_name":"Wd","username":"dd"},"date":1435479551,"sticker":{"width":550,"height":368,"is_animated":true,"file_id":"BQADBQADNAIAAsYifgYdGJOa6bGAsQI","file_size":30320}}'
msg = types.Message.de_json(json_string)
assert msg.sticker.height == 368
assert msg.sticker.thumb == None
assert msg.sticker.thumb 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"},"chat":{"id":10,"first_name":"Fd","last_name":"Wd","username":"dd"},"date":1435478744,"document":{"file_name":"Text File","thumb":{},"file_id":"BQADBQADMwIAAsYifgZ_CEh0u682xwI","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","thumb":{},"file_id":"BQADBQADMwIAAsYifgZ_CEh0u682xwI","file_size":446}}'
msg = types.Message.de_json(json_string)
assert msg.document.file_name == 'Text File'
assert msg.content_type == 'document'
def test_json_Message_Photo():
json_string = r'{"message_id":96,"from":{"id":109734,"first_name":"Fd","last_name":"Wd","username":"dd"},"chat":{"id":10734,"first_name":"Fd","last_name":"dd","username":"dd"},"date":1435478191,"photo":[{"file_id":"AgADBQADIagxG8YifgYv8yLSj76i-dd","file_size":615,"width":90,"height":67},{"file_id":"AgADBQADIagxG8YifgYv8yLSj76i-dd","file_size":10174,"width":320,"height":240},{"file_id":"dd-A_LsTIABFNx-FUOaEa_3AABAQABAg","file_size":53013,"width":759,"height":570}]}'
json_string = r'{"message_id":96,"from":{"id":109734,"first_name":"Fd","last_name":"Wd","username":"dd","is_bot":true },"chat":{"id":10734,"first_name":"Fd","type":"private","last_name":"dd","username":"dd"},"date":1435478191,"photo":[{"file_id":"AgADBQADIagxG8YifgYv8yLSj76i-dd","file_size":615,"width":90,"height":67},{"file_id":"AgADBQADIagxG8YifgYv8yLSj76i-dd","file_size":10174,"width":320,"height":240},{"file_id":"dd-A_LsTIABFNx-FUOaEa_3AABAQABAg","file_size":53013,"width":759,"height":570}]}'
msg = types.Message.de_json(json_string)
assert len(msg.photo) == 3
assert msg.content_type == 'photo'
def test_json_Message_Video():
json_string = r'{"message_id":101,"from":{"id":109734,"first_name":"dd","last_name":"dd","username":"dd"},"chat":{"id":109734,"first_name":"dd","last_name":"dd","username":"dd"},"date":1435481960,"video":{"duration":3,"caption":"","width":360,"height":640,"thumb":{"file_id":"AAQFABPiYnBjkDwMAAIC","file_size":1597,"width":50,"height":90},"file_id":"BAADBQADNifgb_TOPEKErGoQI","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,"thumb":{"file_id":"AAQFABPiYnBjkDwMAAIC","file_size":1597,"width":50,"height":90},"file_id":"BAADBQADNifgb_TOPEKErGoQI","file_size":260699}}'
msg = types.Message.de_json(json_string)
assert msg.video
assert msg.video.duration == 3
@ -87,7 +87,7 @@ def test_json_Message_Video():
def test_json_Message_Location():
json_string = r'{"message_id":102,"from":{"id":108734,"first_name":"dd","last_name":"dd","username":"dd"},"chat":{"id":1089734,"first_name":"dd","last_name":"dd","username":"dd"},"date":1535482469,"location":{"longitude":127.479471,"latitude":26.090577}}'
json_string = r'{"message_id":102,"from":{"id":108734,"first_name":"dd","last_name":"dd","username":"dd","is_bot":true },"chat":{"id":1089734,"first_name":"dd","type":"private","last_name":"dd","username":"dd"},"date":1535482469,"location":{"longitude":127.479471,"latitude":26.090577}}'
msg = types.Message.de_json(json_string)
assert msg.location.latitude == 26.090577
assert msg.content_type == 'location'
@ -113,10 +113,48 @@ def test_json_voice():
assert voice.duration == 0
assert voice.file_size == 10481
def test_json_update():
json_string = r'{"update_id":938203,"message":{"message_id":241,"from":{"id":9734,"first_name":"Fk","last_name":"Wg","username":"nir"},"chat":{"id":1111,"first_name":"Fk","last_name":"Wg","username":"oir"},"date":1441447009,"text":"HIHI"}}'
json_string = r'{"update_id":938203,"message":{"message_id":241,"from":{"is_bot":true,"id":9734,"first_name":"Fk","last_name":"Wg","username":"nir"},"chat":{"id":1111,"first_name":"Fk","type":"private","last_name":"Wg","username":"oir"},"date":1441447009,"text":"HIHI"}}'
update = types.Update.de_json(json_string)
assert update.update_id == 938203
assert update.message.message_id == 241
assert update.message.from_user.id == 9734
def test_json_chat():
json_string = r'{"id": -111111,"title": "Test Title","type": "group"}'
chat = types.Chat.de_json(json_string)
assert chat.id == -111111
assert chat.type == 'group'
assert chat.title == 'Test Title'
def test_InlineQueryResultCachedPhoto():
iq = types.InlineQueryResultCachedPhoto('aaa', 'Fileid')
json_str = iq.to_json()
assert 'aa' in json_str
assert 'Fileid' in json_str
assert 'caption' not in json_str
def test_InlineQueryResultCachedPhoto_with_title():
iq = types.InlineQueryResultCachedPhoto('aaa', 'Fileid', title='Title')
json_str = iq.to_json()
assert 'aa' in json_str
assert 'Fileid' in json_str
assert 'Title' in json_str
assert 'caption' not in json_str
def test_InlineQueryResultCachedPhoto_with_markup():
markup = types.InlineKeyboardMarkup()
markup.add(types.InlineKeyboardButton("Google", url="http://www.google.com"))
markup.add(types.InlineKeyboardButton("Yahoo", url="http://www.yahoo.com"))
iq = types.InlineQueryResultCachedPhoto('aaa', 'Fileid', title='Title', reply_markup=markup)
json_str = iq.to_json()
assert 'aa' in json_str
assert 'Fileid' in json_str
assert 'Title' in json_str
assert 'caption' not in json_str
assert 'reply_markup' in json_str