mirror of
https://github.com/eternnoir/pyTelegramBotAPI.git
synced 2023-08-10 21:12:57 +03:00
Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
ae2dbd00fa | |||
6550a5d745 | |||
593b27358b | |||
a51ff0f100 | |||
a96bc802bc | |||
df8f34e726 | |||
00998ac9c8 | |||
3f243c64ca | |||
034241ba31 | |||
ed6fb57cb5 | |||
b71507387f | |||
e7d0ec1f6c | |||
b3b318fd28 | |||
d334f5cb8d | |||
7f06424980 | |||
7490aa0d26 | |||
e59e2ee2ee | |||
f25dcad10c | |||
24a9491ec0 | |||
744549defe | |||
c86fc4c3fa | |||
943396767c | |||
13fffe58a1 | |||
7fe60e19ef | |||
ba9bf17f46 | |||
373ee4b45b | |||
e5f0ba67fc | |||
096d58ae71 | |||
ed5b47cb96 | |||
e92946301f | |||
7588c9fb9f | |||
6d10bfefbd | |||
cebfbb83fa | |||
5a06d8021b | |||
a75841aa8e | |||
e76649bb49 | |||
7567c6cd71 | |||
751deeafd7 | |||
3ebefa15bf | |||
bb19687854 | |||
311eec6888 | |||
08fc32b70a | |||
555257a3fe | |||
5a03ab62d0 | |||
038be81db3 |
@ -1,6 +1,5 @@
|
||||
language: python
|
||||
python:
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
|
28
README.md
28
README.md
@ -9,7 +9,7 @@
|
||||
<p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.</p>
|
||||
<p align="center">Supports both sync and async ways.</p>
|
||||
|
||||
## <p align="center">Supporting Bot API version: <a href="https://core.telegram.org/bots/api#november-5-2021">5.4</a>!
|
||||
## <p align="center">Supporting Bot API version: <a href="https://core.telegram.org/bots/api#december-30-2021">5.6</a>!
|
||||
|
||||
## Contents
|
||||
|
||||
@ -58,6 +58,7 @@
|
||||
* [How can I distinguish a User and a GroupChat in message.chat?](#how-can-i-distinguish-a-user-and-a-groupchat-in-messagechat)
|
||||
* [How can I handle reocurring ConnectionResetErrors?](#how-can-i-handle-reocurring-connectionreseterrors)
|
||||
* [The Telegram Chat Group](#the-telegram-chat-group)
|
||||
* [Telegram Channel](#telegram-channel)
|
||||
* [More examples](#more-examples)
|
||||
* [Bots using this API](#bots-using-this-api)
|
||||
|
||||
@ -685,8 +686,10 @@ Result will be:
|
||||
|
||||
## API conformance
|
||||
|
||||
* ✔ [Bot API 5.6](https://core.telegram.org/bots/api#december-30-2021)
|
||||
* ✔ [Bot API 5.5](https://core.telegram.org/bots/api#december-7-2021)
|
||||
* ✔ [Bot API 5.4](https://core.telegram.org/bots/api#november-5-2021)
|
||||
* ➕ [Bot API 5.3](https://core.telegram.org/bots/api#june-25-2021) - ChatMemberXXX classes are full copies of ChatMember
|
||||
* ➕ [Bot API 5.3](https://core.telegram.org/bots/api#june-25-2021) - ChatMember* classes are full copies of ChatMember
|
||||
* ✔ [Bot API 5.2](https://core.telegram.org/bots/api#april-26-2021)
|
||||
* ✔ [Bot API 5.1](https://core.telegram.org/bots/api#march-9-2021)
|
||||
* ✔ [Bot API 5.0](https://core.telegram.org/bots/api-changelog#november-4-2020)
|
||||
@ -700,18 +703,6 @@ Result will be:
|
||||
* ✔ [Bot API 4.2](https://core.telegram.org/bots/api-changelog#april-14-2019)
|
||||
* ➕ [Bot API 4.1](https://core.telegram.org/bots/api-changelog#august-27-2018) - No Passport support
|
||||
* ➕ [Bot API 4.0](https://core.telegram.org/bots/api-changelog#july-26-2018) - No Passport support
|
||||
* ✔ [Bot API 3.6](https://core.telegram.org/bots/api-changelog#february-13-2018)
|
||||
* ✔ [Bot API 3.5](https://core.telegram.org/bots/api-changelog#november-17-2017)
|
||||
* ✔ [Bot API 3.4](https://core.telegram.org/bots/api-changelog#october-11-2017)
|
||||
* ✔ [Bot API 3.3](https://core.telegram.org/bots/api-changelog#august-23-2017)
|
||||
* ✔ [Bot API 3.2](https://core.telegram.org/bots/api-changelog#july-21-2017)
|
||||
* ✔ [Bot API 3.1](https://core.telegram.org/bots/api-changelog#june-30-2017)
|
||||
* ✔ [Bot API 3.0](https://core.telegram.org/bots/api-changelog#may-18-2017)
|
||||
* ✔ [Bot API 2.3.1](https://core.telegram.org/bots/api-changelog#december-4-2016)
|
||||
* ✔ [Bot API 2.3](https://core.telegram.org/bots/api-changelog#november-21-2016)
|
||||
* ✔ [Bot API 2.2](https://core.telegram.org/bots/api-changelog#october-3-2016)
|
||||
* ✔ [Bot API 2.1](https://core.telegram.org/bots/api-changelog#may-22-2016)
|
||||
* ✔ [Bot API 2.0](https://core.telegram.org/bots/api-changelog#april-9-2016)
|
||||
|
||||
|
||||
## AsyncTeleBot
|
||||
@ -727,6 +718,7 @@ Echo Bot example on AsyncTeleBot:
|
||||
# It echoes any incoming text messages.
|
||||
|
||||
from telebot.async_telebot import AsyncTeleBot
|
||||
import asyncio
|
||||
bot = AsyncTeleBot('TOKEN')
|
||||
|
||||
|
||||
@ -746,7 +738,7 @@ async def echo_message(message):
|
||||
await bot.reply_to(message, message.text)
|
||||
|
||||
|
||||
bot.polling()
|
||||
asyncio.run(bot.polling())
|
||||
```
|
||||
As you can see here, keywords are await and async.
|
||||
|
||||
@ -791,7 +783,11 @@ Bot instances that were idle for a long time might be rejected by the server whe
|
||||
Get help. Discuss. Chat.
|
||||
|
||||
* Join the [pyTelegramBotAPI Telegram Chat Group](https://telegram.me/joinchat/Bn4ixj84FIZVkwhk2jag6A)
|
||||
|
||||
## Telegram Channel
|
||||
|
||||
Join the [News channel](https://t.me/pyTelegramBotAPI). Here we will post releases and updates.
|
||||
|
||||
## More examples
|
||||
|
||||
* [Echo Bot](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/echo_bot.py)
|
||||
@ -845,5 +841,7 @@ Get help. Discuss. Chat.
|
||||
* [ETHGasFeeTrackerBot](https://t.me/ETHGasFeeTrackerBot) ([Source](https://github.com/DevAdvik/ETHGasFeeTrackerBot]) by *DevAdvik* - Get Live Ethereum Gas Fees in GWEI
|
||||
* [Google Sheet Bot](https://github.com/JoachimStanislaus/Tele_Sheet_bot) by [JoachimStanislaus](https://github.com/JoachimStanislaus). This bot can help you to track your expenses by uploading your bot entries to your google sheet.
|
||||
* [GrandQuiz Bot](https://github.com/Carlosma7/TFM-GrandQuiz) by [Carlosma7](https://github.com/Carlosma7). This bot is a trivia game that allows you to play with people from different ages. This project addresses the use of a system through chatbots to carry out a social and intergenerational game as an alternative to traditional game development.
|
||||
* [Diccionario de la RAE](https://t.me/dleraebot) ([source](https://github.com/studentenherz/dleraebot)) This bot lets you find difinitions of words in Spanish using [RAE's dictionary](https://dle.rae.es/). It features direct message and inline search.
|
||||
* [remoteTelegramShell](https://github.com/EnriqueMoran/remoteTelegramShell) by [EnriqueMoran](https://github.com/EnriqueMoran). Control your LinuxOS computer through Telegram.
|
||||
|
||||
**Want to have your bot listed here? Just make a pull request. Only bots with public source code are accepted.**
|
||||
|
@ -84,4 +84,5 @@ async def back_callback(call: types.CallbackQuery):
|
||||
|
||||
|
||||
bot.add_custom_filter(ProductsCallbackFilter())
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -8,4 +8,5 @@ async def make_some(message: telebot.types.ChatJoinRequest):
|
||||
await bot.send_message(message.chat.id, 'I accepted a new user!')
|
||||
await bot.approve_chat_join_request(message.chat.id, message.from_user.id)
|
||||
|
||||
bot.polling(skip_pending=True)
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
@ -30,4 +30,5 @@ async def my_chat_m(message: types.ChatMemberUpdated):
|
||||
@bot.message_handler(content_types=util.content_type_service)
|
||||
async def delall(message: types.Message):
|
||||
await bot.delete_message(message.chat.id,message.message_id)
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -9,4 +9,6 @@ async def answer_for_admin(message):
|
||||
|
||||
# Register filter
|
||||
bot.add_custom_filter(asyncio_filters.IsAdminFilter(bot))
|
||||
bot.polling()
|
||||
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -40,4 +40,5 @@ async def bye_user(message):
|
||||
bot.add_custom_filter(MainFilter())
|
||||
bot.add_custom_filter(IsAdmin())
|
||||
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -14,4 +14,5 @@ async def not_admin(message):
|
||||
|
||||
# Do not forget to register
|
||||
bot.add_custom_filter(telebot.asyncio_filters.ChatFilter())
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -19,4 +19,5 @@ async def text_filter(message):
|
||||
bot.add_custom_filter(telebot.asyncio_filters.IsReplyFilter())
|
||||
bot.add_custom_filter(telebot.asyncio_filters.ForwardFilter())
|
||||
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -17,4 +17,5 @@ async def text_filter(message):
|
||||
bot.add_custom_filter(telebot.asyncio_filters.TextMatchFilter())
|
||||
bot.add_custom_filter(telebot.asyncio_filters.TextStartsFilter())
|
||||
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -71,4 +71,5 @@ bot.add_custom_filter(asyncio_filters.IsDigitFilter())
|
||||
# set saving states into file.
|
||||
bot.enable_saving_states() # you can delete this if you do not need to save states
|
||||
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
@ -17,4 +17,5 @@ async def new_message(message: telebot.types.Message):
|
||||
await bot.edit_message_text(chat_id=message.chat.id, message_id=result_message.id, text='<i>Done!</i>', parse_mode='HTML')
|
||||
|
||||
|
||||
bot.polling(skip_pending=True)
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -23,4 +23,5 @@ async def echo_message(message):
|
||||
await bot.reply_to(message, message.text)
|
||||
|
||||
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -24,4 +24,5 @@ async def photo_send(message: telebot.types.Message):
|
||||
|
||||
|
||||
|
||||
bot.polling(skip_pending=True)
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -36,4 +36,5 @@ bot.setup_middleware(SimpleMiddleware(2))
|
||||
async def start(message):
|
||||
await bot.send_message(message.chat.id, 'Hello!')
|
||||
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
@ -45,4 +45,5 @@ async def start(message, data: dict):
|
||||
await bot.send_message(message.chat.id, data['response'])
|
||||
|
||||
|
||||
bot.polling()
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -15,4 +15,6 @@ bot.register_message_handler(start_executor, commands=['start']) # Start command
|
||||
# bot.register_edited_message_handler(*args, **kwargs)
|
||||
# And other functions..
|
||||
|
||||
bot.polling(skip_pending=True)
|
||||
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -24,4 +24,6 @@ async def photos_send(message: telebot.types.Message):
|
||||
|
||||
|
||||
|
||||
bot.polling(skip_pending=True)
|
||||
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
||||
|
@ -10,4 +10,6 @@ async def send_welcome(message):
|
||||
async def echo_all(message):
|
||||
await bot.reply_to(message, message.text)
|
||||
|
||||
bot.polling(skip_pending=True)# Skip pending skips old updates
|
||||
|
||||
import asyncio
|
||||
asyncio.run(bot.polling(skip_pending=True)) # to skip updates
|
||||
|
@ -11,4 +11,6 @@ async def update_listener(messages):
|
||||
|
||||
bot.set_update_listener(update_listener)
|
||||
|
||||
bot.polling()
|
||||
|
||||
import asyncio
|
||||
asyncio.run(bot.polling())
|
63
examples/reply_keyboard_markup_example.py
Normal file
63
examples/reply_keyboard_markup_example.py
Normal file
@ -0,0 +1,63 @@
|
||||
# This example shows you how to create a custom QWERTY keyboard using reply keyboard markup
|
||||
import telebot
|
||||
from telebot.types import ReplyKeyboardMarkup, KeyboardButton
|
||||
|
||||
TOKEN = "<your_token>"
|
||||
bot = telebot.TeleBot(TOKEN)
|
||||
|
||||
keys = ["1","2","3","4","5","6","7","8","9","0","q","w","e","r","t","y","u","i","o","p","a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m"]
|
||||
symbols = ["1","2","3","4","5","6","7","8","9","0","!","@","#","$","%","^","&","*","(",")","\'","\"","/","\\",",",".",";",":"]
|
||||
|
||||
def keyboard(key_type="Normal"):
|
||||
markup = ReplyKeyboardMarkup(row_width=10)
|
||||
if key_type == "Normal":
|
||||
row = [KeyboardButton(x) for x in keys[:10]]
|
||||
markup.add(*row)
|
||||
row = [KeyboardButton(x) for x in keys[10:20]]
|
||||
markup.add(*row)
|
||||
row = [KeyboardButton(x) for x in keys[20:29]]
|
||||
markup.add(*row)
|
||||
row = [KeyboardButton(x) for x in keys[29:]]
|
||||
markup.add(*row)
|
||||
markup.add(KeyboardButton("Caps Lock"),KeyboardButton("Symbols"),KeyboardButton("🔙Delete"),KeyboardButton("✅Done"))
|
||||
elif key_type == "Symbols":
|
||||
row = [KeyboardButton(x) for x in symbols[:10]]
|
||||
markup.add(*row)
|
||||
row = [KeyboardButton(x) for x in symbols[10:20]]
|
||||
markup.add(*row)
|
||||
row = [KeyboardButton(x) for x in symbols[20:]]
|
||||
markup.add(*row)
|
||||
markup.add(KeyboardButton("Caps Lock"),KeyboardButton("Normal"),KeyboardButton("🔙Delete"),KeyboardButton("✅Done"))
|
||||
else:
|
||||
row = [KeyboardButton(x.upper()) for x in keys[:10]]
|
||||
markup.add(*row)
|
||||
row = [KeyboardButton(x.upper()) for x in keys[10:20]]
|
||||
markup.add(*row)
|
||||
row = [KeyboardButton(x.upper()) for x in keys[20:29]]
|
||||
markup.add(*row)
|
||||
row = [KeyboardButton(x.upper()) for x in keys[29:]]
|
||||
markup.add(*row)
|
||||
markup.add(KeyboardButton("Normal"),KeyboardButton("Symbols"),KeyboardButton("🔙Delete"),KeyboardButton("✅Done"))
|
||||
return markup
|
||||
|
||||
@bot.message_handler(commands=["start"])
|
||||
def start_message(message):
|
||||
bot.send_message(message.chat.id,"You can use the keyboard",reply_markup=keyboard())
|
||||
|
||||
@bot.message_handler(func=lambda message:True)
|
||||
def all_messages(message):
|
||||
if message.text == "✅Done":
|
||||
markup = telebot.types.ReplyKeyboardRemove()
|
||||
bot.send_message(message.from_user.id,"Done with Keyboard",reply_markup=markup)
|
||||
elif message.text == "Symbols":
|
||||
bot.send_message(message.from_user.id,"Special characters",reply_markup=keyboard("Symbols"))
|
||||
elif message.text == "Normal":
|
||||
bot.send_message(message.from_user.id,"Normal Keyboard",reply_markup=keyboard("Normal"))
|
||||
elif message.text == "Caps Lock":
|
||||
bot.send_message(message.from_user.id,"Caps Lock",reply_markup=keyboard("Caps"))
|
||||
elif message.text == "🔙Delete":
|
||||
bot.delete_message(message.from_user.id,message.message_id)
|
||||
else:
|
||||
bot.send_message(message.chat.id,message.text)
|
||||
|
||||
bot.infinity_polling()
|
@ -50,5 +50,12 @@ There are 5 examples in this directory using different libraries:
|
||||
* **Cons:**
|
||||
* Twisted is low-level, which may be good or bad depending on use case
|
||||
* Considerable learning curve - reading docs is a must.
|
||||
* **FastAPI(0.70.1):** *webhook_fastapi_echo_bot.py*
|
||||
* **Pros:**
|
||||
* Can be written for both sync and async
|
||||
* Good documentation
|
||||
* **Cons:**
|
||||
* Requires python 3.6+
|
||||
|
||||
|
||||
*Latest update of this document: 2020-12-17*
|
||||
*Latest update of this document: 01-03-2022
|
||||
|
79
examples/webhook_examples/webhook_fastapi_echo_bot.py
Normal file
79
examples/webhook_examples/webhook_fastapi_echo_bot.py
Normal file
@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This is a simple echo bot using decorators and webhook with fastapi
|
||||
# It echoes any incoming text messages and does not use the polling method.
|
||||
|
||||
import logging
|
||||
import fastapi
|
||||
import telebot
|
||||
|
||||
API_TOKEN = 'TOKEN'
|
||||
|
||||
WEBHOOK_HOST = '<ip/domain>'
|
||||
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
|
||||
WEBHOOK_LISTEN = '0.0.0.0' # 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 = fastapi.FastAPI()
|
||||
|
||||
|
||||
# Process webhook calls
|
||||
@app.post(f'/{API_TOKEN}/')
|
||||
def process_webhook(update: dict):
|
||||
if update:
|
||||
update = telebot.types.Update.de_json(update)
|
||||
bot.process_new_updates([update])
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
|
||||
# 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'))
|
||||
|
||||
|
||||
import uvicorn
|
||||
uvicorn.run(
|
||||
app,
|
||||
host=WEBHOOK_LISTEN,
|
||||
port=WEBHOOK_PORT,
|
||||
ssl_certfile=WEBHOOK_SSL_CERT,
|
||||
ssl_keyfile=WEBHOOK_SSL_PRIV
|
||||
)
|
@ -936,32 +936,35 @@ class TeleBot:
|
||||
|
||||
def send_message(
|
||||
self, chat_id: Union[int, str], text: str,
|
||||
disable_web_page_preview: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
disable_web_page_preview: Optional[bool]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send text messages.
|
||||
|
||||
|
||||
Warning: Do not send more than about 4000 characters each message, otherwise you'll risk an HTTP 414 error.
|
||||
If you must send more than 4000 characters,
|
||||
use the `split_string` or `smart_split` function in util.py.
|
||||
|
||||
:param chat_id:
|
||||
:param text:
|
||||
:param disable_web_page_preview:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:param parse_mode:
|
||||
:param disable_notification: Boolean, Optional. Sends the message silently.
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param text: Text of the message to be sent
|
||||
:param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message.
|
||||
:param entities: List of special entities that appear in message text, which can be specified instead of parse_mode
|
||||
:param disable_web_page_preview: Disables link previews for links in this message
|
||||
:param disable_notification: Sends the message silently. Users will receive a notification with no sound.
|
||||
:param protect_content: If True, the message content will be hidden for all users except for the target user
|
||||
:param reply_to_message_id: If the message is a reply, ID of the original message
|
||||
:param allow_sending_without_reply: Pass True, if the message should be sent even if the specified replied-to message is not found
|
||||
:param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user.
|
||||
:param timeout:
|
||||
:param entities:
|
||||
:param allow_sending_without_reply:
|
||||
:return: API reply.
|
||||
:return:
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
|
||||
@ -969,11 +972,12 @@ class TeleBot:
|
||||
apihelper.send_message(
|
||||
self.token, chat_id, text, disable_web_page_preview, reply_to_message_id,
|
||||
reply_markup, parse_mode, disable_notification, timeout,
|
||||
entities, allow_sending_without_reply))
|
||||
entities, allow_sending_without_reply, protect_content=protect_content))
|
||||
|
||||
def forward_message(
|
||||
self, chat_id: Union[int, str], from_chat_id: Union[int, str],
|
||||
message_id: int, disable_notification: Optional[bool]=None,
|
||||
message_id: int, disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
timeout: Optional[int]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to forward messages of any kind.
|
||||
@ -981,11 +985,12 @@ class TeleBot:
|
||||
:param chat_id: which chat to forward
|
||||
:param from_chat_id: which chat message from
|
||||
:param message_id: message id
|
||||
:param protect_content: Protects the contents of the forwarded message from forwarding and saving
|
||||
:param timeout:
|
||||
:return: API reply.
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
apihelper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout))
|
||||
apihelper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout, protect_content))
|
||||
|
||||
def copy_message(
|
||||
self, chat_id: Union[int, str],
|
||||
@ -995,6 +1000,7 @@ class TeleBot:
|
||||
parse_mode: Optional[str]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
@ -1008,6 +1014,7 @@ class TeleBot:
|
||||
:param parse_mode:
|
||||
:param caption_entities:
|
||||
:param disable_notification:
|
||||
:param protect_content:
|
||||
:param reply_to_message_id:
|
||||
:param allow_sending_without_reply:
|
||||
:param reply_markup:
|
||||
@ -1017,7 +1024,7 @@ class TeleBot:
|
||||
return types.MessageID.de_json(
|
||||
apihelper.copy_message(self.token, chat_id, from_chat_id, message_id, caption, parse_mode, caption_entities,
|
||||
disable_notification, reply_to_message_id, allow_sending_without_reply, reply_markup,
|
||||
timeout))
|
||||
timeout, protect_content))
|
||||
|
||||
def delete_message(self, chat_id: Union[int, str], message_id: int,
|
||||
timeout: Optional[int]=None) -> bool:
|
||||
@ -1036,7 +1043,8 @@ class TeleBot:
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send dices.
|
||||
:param chat_id:
|
||||
@ -1046,35 +1054,39 @@ class TeleBot:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: Message
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
apihelper.send_dice(
|
||||
self.token, chat_id, emoji, disable_notification, reply_to_message_id,
|
||||
reply_markup, timeout, allow_sending_without_reply)
|
||||
reply_markup, timeout, allow_sending_without_reply, protect_content)
|
||||
)
|
||||
|
||||
def send_photo(
|
||||
self, chat_id: Union[int, str], photo: Union[Any, str],
|
||||
caption: Optional[str]=None, reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
parse_mode: Optional[str]=None, disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
caption: Optional[str]=None, parse_mode: Optional[str]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,) -> types.Message:
|
||||
"""
|
||||
Use this method to send photos.
|
||||
Use this method to send photos. On success, the sent Message is returned.
|
||||
:param chat_id:
|
||||
:param photo:
|
||||
:param caption:
|
||||
:param parse_mode:
|
||||
:param caption_entities:
|
||||
:param disable_notification:
|
||||
:param protect_content:
|
||||
:param reply_to_message_id:
|
||||
:param allow_sending_without_reply:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param caption_entities:
|
||||
:param allow_sending_without_reply:
|
||||
:return: API reply.
|
||||
:return: Message
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
|
||||
@ -1082,8 +1094,9 @@ class TeleBot:
|
||||
apihelper.send_photo(
|
||||
self.token, chat_id, photo, caption, reply_to_message_id, reply_markup,
|
||||
parse_mode, disable_notification, timeout, caption_entities,
|
||||
allow_sending_without_reply))
|
||||
allow_sending_without_reply, protect_content))
|
||||
|
||||
# TODO: Rewrite this method like in API.
|
||||
def send_audio(
|
||||
self, chat_id: Union[int, str], audio: Union[Any, str],
|
||||
caption: Optional[str]=None, duration: Optional[int]=None,
|
||||
@ -1095,7 +1108,8 @@ class TeleBot:
|
||||
timeout: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send audio files, if you want Telegram clients to display them in the music player.
|
||||
Your audio must be in the .mp3 format.
|
||||
@ -1113,6 +1127,7 @@ class TeleBot:
|
||||
:param thumb:
|
||||
:param caption_entities:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: Message
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
@ -1121,8 +1136,9 @@ class TeleBot:
|
||||
apihelper.send_audio(
|
||||
self.token, chat_id, audio, caption, duration, performer, title, reply_to_message_id,
|
||||
reply_markup, parse_mode, disable_notification, timeout, thumb,
|
||||
caption_entities, allow_sending_without_reply))
|
||||
caption_entities, allow_sending_without_reply, protect_content))
|
||||
|
||||
# TODO: Rewrite this method like in API.
|
||||
def send_voice(
|
||||
self, chat_id: Union[int, str], voice: Union[Any, str],
|
||||
caption: Optional[str]=None, duration: Optional[int]=None,
|
||||
@ -1132,7 +1148,8 @@ class TeleBot:
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send audio files, if you want Telegram clients to display the file
|
||||
as a playable voice message.
|
||||
@ -1147,6 +1164,7 @@ class TeleBot:
|
||||
:param timeout:
|
||||
:param caption_entities:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: Message
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
@ -1155,10 +1173,11 @@ class TeleBot:
|
||||
apihelper.send_voice(
|
||||
self.token, chat_id, voice, caption, duration, reply_to_message_id, reply_markup,
|
||||
parse_mode, disable_notification, timeout, caption_entities,
|
||||
allow_sending_without_reply))
|
||||
allow_sending_without_reply, protect_content))
|
||||
|
||||
# TODO: Rewrite this method like in API.
|
||||
def send_document(
|
||||
self, chat_id: Union[int, str], data: Union[Any, str],
|
||||
self, chat_id: Union[int, str], document: Union[Any, str],
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
caption: Optional[str]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
@ -1169,11 +1188,13 @@ class TeleBot:
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
visible_file_name: Optional[str]=None,
|
||||
disable_content_type_detection: Optional[bool]=None) -> types.Message:
|
||||
disable_content_type_detection: Optional[bool]=None,
|
||||
data: Optional[Union[Any, str]]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send general files.
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param data: (document) File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data
|
||||
:param document: (document) File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data
|
||||
:param reply_to_message_id: If the message is a reply, ID of the original message
|
||||
:param caption: Document caption (may also be used when resending documents by file_id), 0-1024 characters after entities parsing
|
||||
:param reply_markup:
|
||||
@ -1185,25 +1206,33 @@ class TeleBot:
|
||||
:param allow_sending_without_reply:
|
||||
:param visible_file_name: allows to define file name that will be visible in the Telegram instead of original file name
|
||||
:param disable_content_type_detection: Disables automatic server-side content type detection for files uploaded using multipart/form-data
|
||||
:param data: function typo miss compatibility: do not use it
|
||||
:param protect_content:
|
||||
:return: API reply.
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
if data and not(document):
|
||||
# function typo miss compatibility
|
||||
document = data
|
||||
|
||||
return types.Message.de_json(
|
||||
apihelper.send_data(
|
||||
self.token, chat_id, data, 'document',
|
||||
self.token, chat_id, document, 'document',
|
||||
reply_to_message_id = reply_to_message_id, reply_markup = reply_markup, parse_mode = parse_mode,
|
||||
disable_notification = disable_notification, timeout = timeout, caption = caption, thumb = thumb,
|
||||
caption_entities = caption_entities, allow_sending_without_reply = allow_sending_without_reply,
|
||||
disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name))
|
||||
disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name, protect_content = protect_content))
|
||||
|
||||
# TODO: Rewrite this method like in API.
|
||||
def send_sticker(
|
||||
self, chat_id: Union[int, str], data: Union[Any, str],
|
||||
self, chat_id: Union[int, str], sticker: Union[Any, str],
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content:Optional[bool]=None,
|
||||
data: Union[Any, str]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send .webp stickers.
|
||||
:param chat_id:
|
||||
@ -1213,83 +1242,98 @@ class TeleBot:
|
||||
:param disable_notification: to disable the notification
|
||||
:param timeout: timeout
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:param data: function typo miss compatibility: do not use it
|
||||
:return: API reply.
|
||||
"""
|
||||
if data and not(sticker):
|
||||
# function typo miss compatibility
|
||||
sticker = data
|
||||
return types.Message.de_json(
|
||||
apihelper.send_data(
|
||||
self.token, chat_id, data, 'sticker',
|
||||
self.token, chat_id, sticker, 'sticker',
|
||||
reply_to_message_id=reply_to_message_id, reply_markup=reply_markup,
|
||||
disable_notification=disable_notification, timeout=timeout,
|
||||
allow_sending_without_reply=allow_sending_without_reply))
|
||||
allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content))
|
||||
|
||||
def send_video(
|
||||
self, chat_id: Union[int, str], data: Union[Any, str],
|
||||
duration: Optional[int]=None,
|
||||
caption: Optional[str]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
supports_streaming: Optional[bool]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
width: Optional[int]=None,
|
||||
self, chat_id: Union[int, str], video: Union[Any, str],
|
||||
duration: Optional[int]=None,
|
||||
width: Optional[int]=None,
|
||||
height: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
caption: Optional[str]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
supports_streaming: Optional[bool]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,
|
||||
data: Optional[Union[Any, str]]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send video files, Telegram clients support mp4 videos.
|
||||
:param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
|
||||
:param data: InputFile or String : Video to send. You can either pass a file_id as String to resend
|
||||
a video that is already on the Telegram server
|
||||
:param duration: Integer : Duration of sent video in seconds
|
||||
:param caption: String : Video caption (may also be used when resending videos by file_id).
|
||||
:param parse_mode:
|
||||
:param supports_streaming:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:param disable_notification:
|
||||
:param timeout:
|
||||
:param thumb: InputFile or String : Thumbnail of the file sent
|
||||
:param width:
|
||||
:param height:
|
||||
Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document).
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param video: Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video file using multipart/form-data.
|
||||
:param duration: Duration of sent video in seconds
|
||||
:param width: Video width
|
||||
:param height: Video height
|
||||
:param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>.
|
||||
:param caption: Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing
|
||||
:param parse_mode: Mode for parsing entities in the video caption
|
||||
:param caption_entities:
|
||||
:param supports_streaming: Pass True, if the uploaded video is suitable for streaming
|
||||
:param disable_notification: Sends the message silently. Users will receive a notification with no sound.
|
||||
:param protect_content:
|
||||
:param reply_to_message_id: If the message is a reply, ID of the original message
|
||||
:param allow_sending_without_reply:
|
||||
:return:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param data: function typo miss compatibility: do not use it
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
if data and not(video):
|
||||
# function typo miss compatibility
|
||||
video = data
|
||||
|
||||
return types.Message.de_json(
|
||||
apihelper.send_video(
|
||||
self.token, chat_id, data, duration, caption, reply_to_message_id, reply_markup,
|
||||
self.token, chat_id, video, duration, caption, reply_to_message_id, reply_markup,
|
||||
parse_mode, supports_streaming, disable_notification, timeout, thumb, width, height,
|
||||
caption_entities, allow_sending_without_reply))
|
||||
caption_entities, allow_sending_without_reply, protect_content))
|
||||
|
||||
def send_animation(
|
||||
self, chat_id: Union[int, str], animation: Union[Any, str],
|
||||
duration: Optional[int]=None,
|
||||
caption: Optional[str]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
width: Optional[int]=None,
|
||||
height: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
caption: Optional[str]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None, ) -> types.Message:
|
||||
"""
|
||||
Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
|
||||
:param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
|
||||
:param animation: InputFile or String : Animation to send. You can either pass a file_id as String to resend an
|
||||
animation that is already on the Telegram server
|
||||
:param duration: Integer : Duration of sent video in seconds
|
||||
:param width: Integer : Video width
|
||||
:param height: Integer : Video height
|
||||
:param thumb: InputFile or String : Thumbnail of the file sent
|
||||
:param caption: String : Animation caption (may also be used when resending animation by file_id).
|
||||
:param parse_mode:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:param disable_notification:
|
||||
:param timeout:
|
||||
:param thumb: InputFile or String : Thumbnail of the file sent
|
||||
:param caption_entities:
|
||||
:param allow_sending_without_reply:
|
||||
:return:
|
||||
@ -1300,8 +1344,9 @@ class TeleBot:
|
||||
apihelper.send_animation(
|
||||
self.token, chat_id, animation, duration, caption, reply_to_message_id,
|
||||
reply_markup, parse_mode, disable_notification, timeout, thumb,
|
||||
caption_entities, allow_sending_without_reply))
|
||||
caption_entities, allow_sending_without_reply, protect_content, width, height))
|
||||
|
||||
# TODO: Rewrite this method like in API.
|
||||
def send_video_note(
|
||||
self, chat_id: Union[int, str], data: Union[Any, str],
|
||||
duration: Optional[int]=None,
|
||||
@ -1311,7 +1356,8 @@ class TeleBot:
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send
|
||||
video messages.
|
||||
@ -1326,12 +1372,13 @@ class TeleBot:
|
||||
:param timeout:
|
||||
:param thumb: InputFile or String : Thumbnail of the file sent
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
apihelper.send_video_note(
|
||||
self.token, chat_id, data, duration, length, reply_to_message_id, reply_markup,
|
||||
disable_notification, timeout, thumb, allow_sending_without_reply))
|
||||
disable_notification, timeout, thumb, allow_sending_without_reply, protect_content))
|
||||
|
||||
def send_media_group(
|
||||
self, chat_id: Union[int, str],
|
||||
@ -1339,6 +1386,7 @@ class TeleBot:
|
||||
types.InputMediaAudio, types.InputMediaDocument,
|
||||
types.InputMediaPhoto, types.InputMediaVideo]],
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> List[types.Message]:
|
||||
@ -1347,6 +1395,7 @@ class TeleBot:
|
||||
:param chat_id:
|
||||
:param media:
|
||||
:param disable_notification:
|
||||
:param protect_content:
|
||||
:param reply_to_message_id:
|
||||
:param timeout:
|
||||
:param allow_sending_without_reply:
|
||||
@ -1354,9 +1403,11 @@ class TeleBot:
|
||||
"""
|
||||
result = apihelper.send_media_group(
|
||||
self.token, chat_id, media, disable_notification, reply_to_message_id, timeout,
|
||||
allow_sending_without_reply)
|
||||
allow_sending_without_reply, protect_content)
|
||||
return [types.Message.de_json(msg) for msg in result]
|
||||
|
||||
|
||||
# TODO: Rewrite this method like in API.
|
||||
def send_location(
|
||||
self, chat_id: Union[int, str],
|
||||
latitude: float, longitude: float,
|
||||
@ -1368,7 +1419,8 @@ class TeleBot:
|
||||
horizontal_accuracy: Optional[float]=None,
|
||||
heading: Optional[int]=None,
|
||||
proximity_alert_radius: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
|
||||
|
||||
"""
|
||||
@ -1385,6 +1437,7 @@ class TeleBot:
|
||||
:param heading:
|
||||
:param proximity_alert_radius:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: API reply.
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
@ -1392,7 +1445,7 @@ class TeleBot:
|
||||
self.token, chat_id, latitude, longitude, live_period,
|
||||
reply_to_message_id, reply_markup, disable_notification, timeout,
|
||||
horizontal_accuracy, heading, proximity_alert_radius,
|
||||
allow_sending_without_reply))
|
||||
allow_sending_without_reply, protect_content))
|
||||
|
||||
def edit_message_live_location(
|
||||
self, latitude: float, longitude: float,
|
||||
@ -1444,6 +1497,7 @@ class TeleBot:
|
||||
apihelper.stop_message_live_location(
|
||||
self.token, chat_id, message_id, inline_message_id, reply_markup, timeout))
|
||||
|
||||
# TODO: Rewrite this method like in API.
|
||||
def send_venue(
|
||||
self, chat_id: Union[int, str],
|
||||
latitude: float, longitude: float,
|
||||
@ -1456,7 +1510,8 @@ class TeleBot:
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
google_place_id: Optional[str]=None,
|
||||
google_place_type: Optional[str]=None) -> types.Message:
|
||||
google_place_type: Optional[str]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send information about a venue.
|
||||
:param chat_id: Integer or String : Unique identifier for the target chat or username of the target channel
|
||||
@ -1474,15 +1529,16 @@ class TeleBot:
|
||||
:param allow_sending_without_reply:
|
||||
:param google_place_id:
|
||||
:param google_place_type:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
apihelper.send_venue(
|
||||
self.token, chat_id, latitude, longitude, title, address, foursquare_id, foursquare_type,
|
||||
disable_notification, reply_to_message_id, reply_markup, timeout,
|
||||
allow_sending_without_reply, google_place_id, google_place_type)
|
||||
)
|
||||
allow_sending_without_reply, google_place_id, google_place_type, protect_content))
|
||||
|
||||
# TODO: Rewrite this method like in API.
|
||||
def send_contact(
|
||||
self, chat_id: Union[int, str], phone_number: str,
|
||||
first_name: str, last_name: Optional[str]=None,
|
||||
@ -1491,13 +1547,13 @@ class TeleBot:
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
return types.Message.de_json(
|
||||
apihelper.send_contact(
|
||||
self.token, chat_id, phone_number, first_name, last_name, vcard,
|
||||
disable_notification, reply_to_message_id, reply_markup, timeout,
|
||||
allow_sending_without_reply)
|
||||
)
|
||||
allow_sending_without_reply, protect_content))
|
||||
|
||||
def send_chat_action(
|
||||
self, chat_id: Union[int, str], action: str, timeout: Optional[int]=None) -> bool:
|
||||
@ -1667,6 +1723,38 @@ class TeleBot:
|
||||
"""
|
||||
return apihelper.set_chat_administrator_custom_title(self.token, chat_id, user_id, custom_title)
|
||||
|
||||
|
||||
def ban_chat_sender_chat(self, chat_id: Union[int, str], sender_chat_id: Union[int, str]) -> bool:
|
||||
"""
|
||||
Use this method to ban a channel chat in a supergroup or a channel.
|
||||
The owner of the chat will not be able to send messages and join live
|
||||
streams on behalf of the chat, unless it is unbanned first.
|
||||
The bot must be an administrator in the supergroup or channel
|
||||
for this to work and must have the appropriate administrator rights.
|
||||
Returns True on success.
|
||||
|
||||
:params:
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param sender_chat_id: Unique identifier of the target sender chat
|
||||
:return: True on success.
|
||||
"""
|
||||
return apihelper.ban_chat_sender_chat(self.token, chat_id, sender_chat_id)
|
||||
|
||||
def unban_chat_sender_chat(self, chat_id: Union[int, str], sender_chat_id: Union[int, str]) -> bool:
|
||||
"""
|
||||
Use this method to unban a previously banned channel chat in a supergroup or channel.
|
||||
The bot must be an administrator for this to work and must have the appropriate
|
||||
administrator rights.
|
||||
Returns True on success.
|
||||
|
||||
:params:
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param sender_chat_id: Unique identifier of the target sender chat
|
||||
:return: True on success.
|
||||
"""
|
||||
return apihelper.unban_chat_sender_chat(self.token, chat_id, sender_chat_id)
|
||||
|
||||
|
||||
def set_chat_permissions(
|
||||
self, chat_id: Union[int, str], permissions: types.ChatPermissions) -> bool:
|
||||
"""
|
||||
@ -1989,7 +2077,8 @@ class TeleBot:
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Used to send the game
|
||||
:param chat_id:
|
||||
@ -1999,12 +2088,13 @@ class TeleBot:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
result = apihelper.send_game(
|
||||
self.token, chat_id, game_short_name, disable_notification,
|
||||
reply_to_message_id, reply_markup, timeout,
|
||||
allow_sending_without_reply)
|
||||
allow_sending_without_reply, protect_content)
|
||||
return types.Message.de_json(result)
|
||||
|
||||
def set_game_score(
|
||||
@ -2046,6 +2136,7 @@ class TeleBot:
|
||||
result = apihelper.get_game_high_scores(self.token, user_id, chat_id, message_id, inline_message_id)
|
||||
return [types.GameHighScore.de_json(r) for r in result]
|
||||
|
||||
# TODO: rewrite this method like in API
|
||||
def send_invoice(
|
||||
self, chat_id: Union[int, str], title: str, description: str,
|
||||
invoice_payload: str, provider_token: str, currency: str,
|
||||
@ -2064,7 +2155,8 @@ class TeleBot:
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
max_tip_amount: Optional[int] = None,
|
||||
suggested_tip_amounts: Optional[List[int]]=None) -> types.Message:
|
||||
suggested_tip_amounts: Optional[List[int]]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Sends invoice
|
||||
:param chat_id: Unique identifier for the target private chat
|
||||
@ -2103,6 +2195,7 @@ class TeleBot:
|
||||
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest
|
||||
units of the currency. At most 4 suggested tip amounts can be specified. The suggested tip
|
||||
amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
result = apihelper.send_invoice(
|
||||
@ -2111,10 +2204,11 @@ class TeleBot:
|
||||
photo_height, need_name, need_phone_number, need_email, need_shipping_address,
|
||||
send_phone_number_to_provider, send_email_to_provider, is_flexible, disable_notification,
|
||||
reply_to_message_id, reply_markup, provider_data, timeout, allow_sending_without_reply,
|
||||
max_tip_amount, suggested_tip_amounts)
|
||||
max_tip_amount, suggested_tip_amounts, protect_content)
|
||||
return types.Message.de_json(result)
|
||||
|
||||
# noinspection PyShadowingBuiltins
|
||||
# TODO: rewrite this method like in API
|
||||
def send_poll(
|
||||
self, chat_id: Union[int, str], question: str, options: List[str],
|
||||
is_anonymous: Optional[bool]=None, type: Optional[str]=None,
|
||||
@ -2130,7 +2224,8 @@ class TeleBot:
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
explanation_entities: Optional[List[types.MessageEntity]]=None) -> types.Message:
|
||||
explanation_entities: Optional[List[types.MessageEntity]]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Send polls
|
||||
:param chat_id:
|
||||
@ -2151,6 +2246,7 @@ class TeleBot:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param explanation_entities:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
|
||||
@ -2164,7 +2260,7 @@ class TeleBot:
|
||||
is_anonymous, type, allows_multiple_answers, correct_option_id,
|
||||
explanation, explanation_parse_mode, open_period, close_date, is_closed,
|
||||
disable_notification, reply_to_message_id, allow_sending_without_reply,
|
||||
reply_markup, timeout, explanation_entities))
|
||||
reply_markup, timeout, explanation_entities, protect_content))
|
||||
|
||||
def stop_poll(
|
||||
self, chat_id: Union[int, str], message_id: int,
|
||||
|
@ -232,7 +232,7 @@ def send_message(
|
||||
token, chat_id, text,
|
||||
disable_web_page_preview=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, disable_notification=None, timeout=None,
|
||||
entities=None, allow_sending_without_reply=None):
|
||||
entities=None, allow_sending_without_reply=None, protect_content=None):
|
||||
"""
|
||||
Use this method to send text messages. On success, the sent Message is returned.
|
||||
:param token:
|
||||
@ -266,6 +266,8 @@ def send_message(
|
||||
payload['entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload, method='post')
|
||||
|
||||
|
||||
@ -390,19 +392,21 @@ def get_chat_member(token, chat_id, user_id):
|
||||
|
||||
def forward_message(
|
||||
token, chat_id, from_chat_id, message_id,
|
||||
disable_notification=None, timeout=None):
|
||||
disable_notification=None, timeout=None, protect_content=None):
|
||||
method_url = r'forwardMessage'
|
||||
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
|
||||
if disable_notification is not None:
|
||||
payload['disable_notification'] = disable_notification
|
||||
if timeout:
|
||||
payload['timeout'] = timeout
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_mode=None, caption_entities=None,
|
||||
disable_notification=None, reply_to_message_id=None, allow_sending_without_reply=None,
|
||||
reply_markup=None, timeout=None):
|
||||
reply_markup=None, timeout=None, protect_content=None):
|
||||
method_url = r'copyMessage'
|
||||
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
|
||||
if caption is not None:
|
||||
@ -421,13 +425,15 @@ def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_m
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if timeout:
|
||||
payload['timeout'] = timeout
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
def send_dice(
|
||||
token, chat_id,
|
||||
emoji=None, disable_notification=None, reply_to_message_id=None,
|
||||
reply_markup=None, timeout=None, allow_sending_without_reply=None):
|
||||
reply_markup=None, timeout=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendDice'
|
||||
payload = {'chat_id': chat_id}
|
||||
if emoji:
|
||||
@ -442,6 +448,8 @@ def send_dice(
|
||||
payload['timeout'] = timeout
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -449,7 +457,7 @@ def send_photo(
|
||||
token, chat_id, photo,
|
||||
caption=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, disable_notification=None, timeout=None,
|
||||
caption_entities=None, allow_sending_without_reply=None):
|
||||
caption_entities=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendPhoto'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -475,13 +483,15 @@ def send_photo(
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
def send_media_group(
|
||||
token, chat_id, media,
|
||||
disable_notification=None, reply_to_message_id=None,
|
||||
timeout=None, allow_sending_without_reply=None):
|
||||
timeout=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendMediaGroup'
|
||||
media_json, files = convert_input_media_array(media)
|
||||
payload = {'chat_id': chat_id, 'media': media_json}
|
||||
@ -493,6 +503,8 @@ def send_media_group(
|
||||
payload['timeout'] = timeout
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(
|
||||
token, method_url, params=payload,
|
||||
method='post' if files else 'get',
|
||||
@ -504,7 +516,7 @@ def send_location(
|
||||
live_period=None, reply_to_message_id=None,
|
||||
reply_markup=None, disable_notification=None,
|
||||
timeout=None, horizontal_accuracy=None, heading=None,
|
||||
proximity_alert_radius=None, allow_sending_without_reply=None):
|
||||
proximity_alert_radius=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendLocation'
|
||||
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude}
|
||||
if live_period:
|
||||
@ -525,6 +537,8 @@ def send_location(
|
||||
payload['disable_notification'] = disable_notification
|
||||
if timeout:
|
||||
payload['timeout'] = timeout
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -576,7 +590,7 @@ def send_venue(
|
||||
foursquare_id=None, foursquare_type=None, disable_notification=None,
|
||||
reply_to_message_id=None, reply_markup=None, timeout=None,
|
||||
allow_sending_without_reply=None, google_place_id=None,
|
||||
google_place_type=None):
|
||||
google_place_type=None, protect_content=None):
|
||||
method_url = r'sendVenue'
|
||||
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude, 'title': title, 'address': address}
|
||||
if foursquare_id:
|
||||
@ -597,13 +611,15 @@ def send_venue(
|
||||
payload['google_place_id'] = google_place_id
|
||||
if google_place_type:
|
||||
payload['google_place_type'] = google_place_type
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
def send_contact(
|
||||
token, chat_id, phone_number, first_name, last_name=None, vcard=None,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
|
||||
allow_sending_without_reply=None):
|
||||
allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendContact'
|
||||
payload = {'chat_id': chat_id, 'phone_number': phone_number, 'first_name': first_name}
|
||||
if last_name:
|
||||
@ -620,6 +636,9 @@ def send_contact(
|
||||
payload['timeout'] = timeout
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -633,7 +652,7 @@ def send_chat_action(token, chat_id, action, timeout=None):
|
||||
|
||||
def send_video(token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, supports_streaming=None, disable_notification=None, timeout=None,
|
||||
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None):
|
||||
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendVideo'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -673,13 +692,15 @@ def send_video(token, chat_id, data, duration=None, caption=None, reply_to_messa
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
def send_animation(
|
||||
token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, disable_notification=None, timeout=None, thumb=None, caption_entities=None,
|
||||
allow_sending_without_reply=None):
|
||||
allow_sending_without_reply=None, protect_content=None, width=None, height=None):
|
||||
method_url = r'sendAnimation'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -713,12 +734,18 @@ def send_animation(
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
if width:
|
||||
payload['width'] = width
|
||||
if height:
|
||||
payload['height'] = height
|
||||
return _make_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
def send_voice(token, chat_id, voice, caption=None, duration=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, disable_notification=None, timeout=None, caption_entities=None,
|
||||
allow_sending_without_reply=None):
|
||||
allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendVoice'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -744,11 +771,13 @@ def send_voice(token, chat_id, voice, caption=None, duration=None, reply_to_mess
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_message_id=None, reply_markup=None,
|
||||
disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None):
|
||||
disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendVideoNote'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -780,12 +809,14 @@ def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_m
|
||||
payload['thumb'] = thumb
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
def send_audio(token, chat_id, audio, caption=None, duration=None, performer=None, title=None, reply_to_message_id=None,
|
||||
reply_markup=None, parse_mode=None, disable_notification=None, timeout=None, thumb=None,
|
||||
caption_entities=None, allow_sending_without_reply=None):
|
||||
caption_entities=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendAudio'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -823,6 +854,8 @@ def send_audio(token, chat_id, audio, caption=None, duration=None, performer=Non
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
@ -969,6 +1002,18 @@ def set_chat_administrator_custom_title(token, chat_id, user_id, custom_title):
|
||||
return _make_request(token, method_url, params=payload, method='post')
|
||||
|
||||
|
||||
def ban_chat_sender_chat(token, chat_id, sender_chat_id):
|
||||
method_url = 'banChatSenderChat'
|
||||
payload = {'chat_id': chat_id, 'sender_chat_id': sender_chat_id}
|
||||
return _make_request(token, method_url, params=payload, method='post')
|
||||
|
||||
|
||||
def unban_chat_sender_chat(token, chat_id, sender_chat_id):
|
||||
method_url = 'unbanChatSenderChat'
|
||||
payload = {'chat_id': chat_id, 'sender_chat_id': sender_chat_id}
|
||||
return _make_request(token, method_url, params=payload, method='post')
|
||||
|
||||
|
||||
def set_chat_permissions(token, chat_id, permissions):
|
||||
method_url = 'setChatPermissions'
|
||||
payload = {
|
||||
@ -1224,7 +1269,7 @@ def delete_message(token, chat_id, message_id, timeout=None):
|
||||
def send_game(
|
||||
token, chat_id, game_short_name,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
|
||||
allow_sending_without_reply=None):
|
||||
allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendGame'
|
||||
payload = {'chat_id': chat_id, 'game_short_name': game_short_name}
|
||||
if disable_notification is not None:
|
||||
@ -1237,6 +1282,9 @@ def send_game(
|
||||
payload['timeout'] = timeout
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -1301,7 +1349,8 @@ def send_invoice(
|
||||
need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None,
|
||||
send_phone_number_to_provider = None, send_email_to_provider = None, is_flexible=None,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None, provider_data=None,
|
||||
timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None):
|
||||
timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None,
|
||||
protect_content=None):
|
||||
"""
|
||||
Use this method to send invoices. On success, the sent Message is returned.
|
||||
:param token: Bot's token (you don't need to fill this)
|
||||
@ -1379,6 +1428,8 @@ def send_invoice(
|
||||
payload['max_tip_amount'] = max_tip_amount
|
||||
if suggested_tip_amounts is not None:
|
||||
payload['suggested_tip_amounts'] = json.dumps(suggested_tip_amounts)
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -1527,7 +1578,7 @@ def send_poll(
|
||||
is_anonymous = None, type = None, allows_multiple_answers = None, correct_option_id = None,
|
||||
explanation = None, explanation_parse_mode=None, open_period = None, close_date = None, is_closed = None,
|
||||
disable_notification=False, reply_to_message_id=None, allow_sending_without_reply=None,
|
||||
reply_markup=None, timeout=None, explanation_entities=None):
|
||||
reply_markup=None, timeout=None, explanation_entities=None, protect_content=None):
|
||||
method_url = r'sendPoll'
|
||||
payload = {
|
||||
'chat_id': str(chat_id),
|
||||
@ -1569,6 +1620,8 @@ def send_poll(
|
||||
if explanation_entities:
|
||||
payload['explanation_entities'] = json.dumps(
|
||||
types.MessageEntity.to_list_of_dicts(explanation_entities))
|
||||
if protect_content:
|
||||
payload['protect_content'] = protect_content
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ import re
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
from typing import Any, Callable, List, Optional, Union
|
||||
from typing import Any, List, Optional, Union
|
||||
|
||||
# this imports are used to avoid circular import error
|
||||
import telebot.util
|
||||
@ -94,7 +94,81 @@ class CancelUpdate:
|
||||
pass
|
||||
|
||||
class AsyncTeleBot:
|
||||
|
||||
""" This is AsyncTeleBot Class
|
||||
Methods:
|
||||
getMe
|
||||
logOut
|
||||
close
|
||||
sendMessage
|
||||
forwardMessage
|
||||
copyMessage
|
||||
deleteMessage
|
||||
sendPhoto
|
||||
sendAudio
|
||||
sendDocument
|
||||
sendSticker
|
||||
sendVideo
|
||||
sendVenue
|
||||
sendAnimation
|
||||
sendVideoNote
|
||||
sendLocation
|
||||
sendChatAction
|
||||
sendDice
|
||||
sendContact
|
||||
sendInvoice
|
||||
sendMediaGroup
|
||||
getUserProfilePhotos
|
||||
getUpdates
|
||||
getFile
|
||||
sendPoll
|
||||
stopPoll
|
||||
sendGame
|
||||
setGameScore
|
||||
getGameHighScores
|
||||
editMessageText
|
||||
editMessageCaption
|
||||
editMessageMedia
|
||||
editMessageReplyMarkup
|
||||
editMessageLiveLocation
|
||||
stopMessageLiveLocation
|
||||
banChatMember
|
||||
unbanChatMember
|
||||
restrictChatMember
|
||||
promoteChatMember
|
||||
setChatAdministratorCustomTitle
|
||||
setChatPermissions
|
||||
createChatInviteLink
|
||||
editChatInviteLink
|
||||
revokeChatInviteLink
|
||||
exportChatInviteLink
|
||||
setChatStickerSet
|
||||
deleteChatStickerSet
|
||||
createNewStickerSet
|
||||
addStickerToSet
|
||||
deleteStickerFromSet
|
||||
setStickerPositionInSet
|
||||
uploadStickerFile
|
||||
setStickerSetThumb
|
||||
getStickerSet
|
||||
setChatPhoto
|
||||
deleteChatPhoto
|
||||
setChatTitle
|
||||
setChatDescription
|
||||
pinChatMessage
|
||||
unpinChatMessage
|
||||
leaveChat
|
||||
getChat
|
||||
getChatAdministrators
|
||||
getChatMemberCount
|
||||
getChatMember
|
||||
answerCallbackQuery
|
||||
getMyCommands
|
||||
setMyCommands
|
||||
deleteMyCommands
|
||||
answerInlineQuery
|
||||
answerShippingQuery
|
||||
answerPreCheckoutQuery
|
||||
"""
|
||||
|
||||
def __init__(self, token: str, parse_mode: Optional[str]=None, offset=None,
|
||||
exception_handler=None) -> None: # TODO: ADD TYPEHINTS
|
||||
@ -133,11 +207,11 @@ class AsyncTeleBot:
|
||||
|
||||
|
||||
async def get_updates(self, offset: Optional[int]=None, limit: Optional[int]=None,
|
||||
timeout: Optional[int]=None, allowed_updates: Optional[List]=None, request_timeout: Optional[int]=None) -> types.Update:
|
||||
timeout: Optional[int]=None, allowed_updates: Optional[List]=None, request_timeout: Optional[int]=None) -> List[types.Update]:
|
||||
json_updates = await asyncio_helper.get_updates(self.token, offset, limit, timeout, allowed_updates, request_timeout)
|
||||
return [types.Update.de_json(ju) for ju in json_updates]
|
||||
|
||||
def polling(self, non_stop: bool=False, skip_pending=False, interval: int=0, timeout: int=20,
|
||||
async def polling(self, non_stop: bool=False, skip_pending=False, interval: int=0, timeout: int=20,
|
||||
request_timeout: int=20, allowed_updates: Optional[List[str]]=None,
|
||||
none_stop: Optional[bool]=None):
|
||||
"""
|
||||
@ -166,16 +240,16 @@ class AsyncTeleBot:
|
||||
non_stop = none_stop
|
||||
|
||||
if skip_pending:
|
||||
asyncio.run(self.skip_updates())
|
||||
asyncio.run(self._process_polling(non_stop, interval, timeout, request_timeout, allowed_updates))
|
||||
await self.skip_updates()
|
||||
await self._process_polling(non_stop, interval, timeout, request_timeout, allowed_updates)
|
||||
|
||||
def infinity_polling(self, timeout: int=20, skip_pending: bool=False, request_timeout: int=20, logger_level=logging.ERROR,
|
||||
async def infinity_polling(self, timeout: int=20, skip_pending: bool=False, request_timeout: int=20, logger_level=logging.ERROR,
|
||||
allowed_updates: Optional[List[str]]=None, *args, **kwargs):
|
||||
"""
|
||||
Wrap polling with infinite loop and exception handling to avoid bot stops polling.
|
||||
|
||||
:param timeout: Request connection timeout
|
||||
:param long_polling_timeout: Timeout in seconds for long polling (see API docs)
|
||||
:param request_timeout: Timeout in seconds for long polling (see API docs)
|
||||
:param skip_pending: skip old updates
|
||||
:param logger_level: Custom logging level for infinity_polling logging.
|
||||
Use logger levels from logging as a value. None/NOTSET = no error logging
|
||||
@ -189,12 +263,12 @@ class AsyncTeleBot:
|
||||
so unwanted updates may be received for a short period of time.
|
||||
"""
|
||||
if skip_pending:
|
||||
asyncio.run(self.skip_updates())
|
||||
await self.skip_updates()
|
||||
self._polling = True
|
||||
while self._polling:
|
||||
try:
|
||||
asyncio.run( self._process_polling(non_stop=True, timeout=timeout, request_timeout=request_timeout,
|
||||
allowed_updates=allowed_updates, *args, **kwargs) )
|
||||
await self._process_polling(non_stop=True, timeout=timeout, request_timeout=request_timeout,
|
||||
allowed_updates=allowed_updates, *args, **kwargs)
|
||||
except Exception as e:
|
||||
if logger_level and logger_level >= logging.ERROR:
|
||||
logger.error("Infinity polling exception: %s", str(e))
|
||||
@ -243,6 +317,14 @@ class AsyncTeleBot:
|
||||
except asyncio.CancelledError:
|
||||
return
|
||||
|
||||
except asyncio_helper.RequestTimeout as e:
|
||||
logger.error(str(e))
|
||||
if non_stop:
|
||||
await asyncio.sleep(2)
|
||||
continue
|
||||
else:
|
||||
return
|
||||
|
||||
except asyncio_helper.ApiTelegramException as e:
|
||||
logger.error(str(e))
|
||||
|
||||
@ -1402,16 +1484,19 @@ class AsyncTeleBot:
|
||||
result = await asyncio_helper.get_chat_member(self.token, chat_id, user_id)
|
||||
return types.ChatMember.de_json(result)
|
||||
|
||||
|
||||
|
||||
async def send_message(
|
||||
self, chat_id: Union[int, str], text: str,
|
||||
disable_web_page_preview: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
disable_web_page_preview: Optional[bool]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send text messages.
|
||||
|
||||
@ -1429,6 +1514,7 @@ class AsyncTeleBot:
|
||||
:param timeout:
|
||||
:param entities:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: API reply.
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
@ -1437,11 +1523,12 @@ class AsyncTeleBot:
|
||||
await asyncio_helper.send_message(
|
||||
self.token, chat_id, text, disable_web_page_preview, reply_to_message_id,
|
||||
reply_markup, parse_mode, disable_notification, timeout,
|
||||
entities, allow_sending_without_reply))
|
||||
entities, allow_sending_without_reply, protect_content))
|
||||
|
||||
async def forward_message(
|
||||
self, chat_id: Union[int, str], from_chat_id: Union[int, str],
|
||||
message_id: int, disable_notification: Optional[bool]=None,
|
||||
message_id: int, disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
timeout: Optional[int]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to forward messages of any kind.
|
||||
@ -1449,11 +1536,12 @@ class AsyncTeleBot:
|
||||
:param chat_id: which chat to forward
|
||||
:param from_chat_id: which chat message from
|
||||
:param message_id: message id
|
||||
:param protect_content:
|
||||
:param timeout:
|
||||
:return: API reply.
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
await asyncio_helper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout))
|
||||
await asyncio_helper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout, protect_content))
|
||||
|
||||
async def copy_message(
|
||||
self, chat_id: Union[int, str],
|
||||
@ -1463,6 +1551,7 @@ class AsyncTeleBot:
|
||||
parse_mode: Optional[str]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
@ -1480,12 +1569,13 @@ class AsyncTeleBot:
|
||||
:param allow_sending_without_reply:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param protect_content:
|
||||
:return: API reply.
|
||||
"""
|
||||
return types.MessageID.de_json(
|
||||
await asyncio_helper.copy_message(self.token, chat_id, from_chat_id, message_id, caption, parse_mode, caption_entities,
|
||||
disable_notification, reply_to_message_id, allow_sending_without_reply, reply_markup,
|
||||
timeout))
|
||||
timeout, protect_content))
|
||||
|
||||
async def delete_message(self, chat_id: Union[int, str], message_id: int,
|
||||
timeout: Optional[int]=None) -> bool:
|
||||
@ -1504,7 +1594,8 @@ class AsyncTeleBot:
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send dices.
|
||||
:param chat_id:
|
||||
@ -1514,22 +1605,25 @@ class AsyncTeleBot:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: Message
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
await asyncio_helper.send_dice(
|
||||
self.token, chat_id, emoji, disable_notification, reply_to_message_id,
|
||||
reply_markup, timeout, allow_sending_without_reply)
|
||||
reply_markup, timeout, allow_sending_without_reply, protect_content)
|
||||
)
|
||||
|
||||
async def send_photo(
|
||||
self, chat_id: Union[int, str], photo: Union[Any, str],
|
||||
caption: Optional[str]=None, reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
parse_mode: Optional[str]=None, disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
caption: Optional[str]=None, parse_mode: Optional[str]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,) -> types.Message:
|
||||
"""
|
||||
Use this method to send photos.
|
||||
:param chat_id:
|
||||
@ -1542,6 +1636,7 @@ class AsyncTeleBot:
|
||||
:param timeout:
|
||||
:param caption_entities:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: API reply.
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
@ -1550,7 +1645,7 @@ class AsyncTeleBot:
|
||||
await asyncio_helper.send_photo(
|
||||
self.token, chat_id, photo, caption, reply_to_message_id, reply_markup,
|
||||
parse_mode, disable_notification, timeout, caption_entities,
|
||||
allow_sending_without_reply))
|
||||
allow_sending_without_reply, protect_content))
|
||||
|
||||
async def send_audio(
|
||||
self, chat_id: Union[int, str], audio: Union[Any, str],
|
||||
@ -1563,7 +1658,8 @@ class AsyncTeleBot:
|
||||
timeout: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send audio files, if you want Telegram clients to display them in the music player.
|
||||
Your audio must be in the .mp3 format.
|
||||
@ -1581,6 +1677,7 @@ class AsyncTeleBot:
|
||||
:param thumb:
|
||||
:param caption_entities:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: Message
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
@ -1589,7 +1686,7 @@ class AsyncTeleBot:
|
||||
await asyncio_helper.send_audio(
|
||||
self.token, chat_id, audio, caption, duration, performer, title, reply_to_message_id,
|
||||
reply_markup, parse_mode, disable_notification, timeout, thumb,
|
||||
caption_entities, allow_sending_without_reply))
|
||||
caption_entities, allow_sending_without_reply, protect_content))
|
||||
|
||||
async def send_voice(
|
||||
self, chat_id: Union[int, str], voice: Union[Any, str],
|
||||
@ -1600,7 +1697,8 @@ class AsyncTeleBot:
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send audio files, if you want Telegram clients to display the file
|
||||
as a playable voice message.
|
||||
@ -1615,6 +1713,7 @@ class AsyncTeleBot:
|
||||
:param timeout:
|
||||
:param caption_entities:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: Message
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
@ -1623,10 +1722,10 @@ class AsyncTeleBot:
|
||||
await asyncio_helper.send_voice(
|
||||
self.token, chat_id, voice, caption, duration, reply_to_message_id, reply_markup,
|
||||
parse_mode, disable_notification, timeout, caption_entities,
|
||||
allow_sending_without_reply))
|
||||
allow_sending_without_reply, protect_content))
|
||||
|
||||
async def send_document(
|
||||
self, chat_id: Union[int, str], data: Union[Any, str],
|
||||
self, chat_id: Union[int, str], document: Union[Any, str],
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
caption: Optional[str]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
@ -1637,11 +1736,13 @@ class AsyncTeleBot:
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
visible_file_name: Optional[str]=None,
|
||||
disable_content_type_detection: Optional[bool]=None) -> types.Message:
|
||||
disable_content_type_detection: Optional[bool]=None,
|
||||
data: Optional[Union[Any, str]]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send general files.
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param data: (document) File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data
|
||||
:param document: (document) File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data
|
||||
:param reply_to_message_id: If the message is a reply, ID of the original message
|
||||
:param caption: Document caption (may also be used when resending documents by file_id), 0-1024 characters after entities parsing
|
||||
:param reply_markup:
|
||||
@ -1653,77 +1754,90 @@ class AsyncTeleBot:
|
||||
:param allow_sending_without_reply:
|
||||
:param visible_file_name: allows to async define file name that will be visible in the Telegram instead of original file name
|
||||
:param disable_content_type_detection: Disables automatic server-side content type detection for files uploaded using multipart/form-data
|
||||
:param data: function typo compatibility: do not use it
|
||||
:param protect_content:
|
||||
:return: API reply.
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
if data and not(document):
|
||||
# function typo miss compatibility
|
||||
document = data
|
||||
|
||||
return types.Message.de_json(
|
||||
await asyncio_helper.send_data(
|
||||
self.token, chat_id, data, 'document',
|
||||
self.token, chat_id, document, 'document',
|
||||
reply_to_message_id = reply_to_message_id, reply_markup = reply_markup, parse_mode = parse_mode,
|
||||
disable_notification = disable_notification, timeout = timeout, caption = caption, thumb = thumb,
|
||||
caption_entities = caption_entities, allow_sending_without_reply = allow_sending_without_reply,
|
||||
disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name))
|
||||
disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name, protect_content = protect_content))
|
||||
|
||||
async def send_sticker(
|
||||
self, chat_id: Union[int, str], data: Union[Any, str],
|
||||
self, chat_id: Union[int, str], sticker: Union[Any, str],
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
data: Union[Any, str]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send .webp stickers.
|
||||
:param chat_id:
|
||||
:param data:
|
||||
:param sticker:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:param disable_notification: to disable the notification
|
||||
:param timeout: timeout
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: API reply.
|
||||
"""
|
||||
if data and not(sticker):
|
||||
# function typo miss compatibility
|
||||
sticker = data
|
||||
return types.Message.de_json(
|
||||
await asyncio_helper.send_data(
|
||||
self.token, chat_id, data, 'sticker',
|
||||
self.token, chat_id, sticker, 'sticker',
|
||||
reply_to_message_id=reply_to_message_id, reply_markup=reply_markup,
|
||||
disable_notification=disable_notification, timeout=timeout,
|
||||
allow_sending_without_reply=allow_sending_without_reply))
|
||||
allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content))
|
||||
|
||||
async def send_video(
|
||||
self, chat_id: Union[int, str], data: Union[Any, str],
|
||||
duration: Optional[int]=None,
|
||||
caption: Optional[str]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
supports_streaming: Optional[bool]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
width: Optional[int]=None,
|
||||
self, chat_id: Union[int, str], video: Union[Any, str],
|
||||
duration: Optional[int]=None,
|
||||
width: Optional[int]=None,
|
||||
height: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
caption: Optional[str]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
supports_streaming: Optional[bool]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,
|
||||
data: Optional[Union[Any, str]]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send video files, Telegram clients support mp4 videos.
|
||||
:param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
|
||||
:param data: InputFile or String : Video to send. You can either pass a file_id as String to resend
|
||||
a video that is already on the Telegram server
|
||||
:param duration: Integer : Duration of sent video in seconds
|
||||
:param caption: String : Video caption (may also be used when resending videos by file_id).
|
||||
:param parse_mode:
|
||||
:param supports_streaming:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:param disable_notification:
|
||||
:param timeout:
|
||||
:param thumb: InputFile or String : Thumbnail of the file sent
|
||||
:param width:
|
||||
:param height:
|
||||
Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document).
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param video: Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video file using multipart/form-data.
|
||||
:param duration: Duration of sent video in seconds
|
||||
:param width: Video width
|
||||
:param height: Video height
|
||||
:param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>.
|
||||
:param caption: Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing
|
||||
:param parse_mode: Mode for parsing entities in the video caption
|
||||
:param caption_entities:
|
||||
:param supports_streaming: Pass True, if the uploaded video is suitable for streaming
|
||||
:param disable_notification: Sends the message silently. Users will receive a notification with no sound.
|
||||
:param protect_content:
|
||||
:param reply_to_message_id: If the message is a reply, ID of the original message
|
||||
:param allow_sending_without_reply:
|
||||
:return:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param data: function typo miss compatibility: do not use it
|
||||
"""
|
||||
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
|
||||
|
||||
@ -1731,33 +1845,38 @@ class AsyncTeleBot:
|
||||
await asyncio_helper.send_video(
|
||||
self.token, chat_id, data, duration, caption, reply_to_message_id, reply_markup,
|
||||
parse_mode, supports_streaming, disable_notification, timeout, thumb, width, height,
|
||||
caption_entities, allow_sending_without_reply))
|
||||
caption_entities, allow_sending_without_reply, protect_content))
|
||||
|
||||
async def send_animation(
|
||||
self, chat_id: Union[int, str], animation: Union[Any, str],
|
||||
duration: Optional[int]=None,
|
||||
caption: Optional[str]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
width: Optional[int]=None,
|
||||
height: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
caption: Optional[str]=None,
|
||||
parse_mode: Optional[str]=None,
|
||||
caption_entities: Optional[List[types.MessageEntity]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None, ) -> types.Message:
|
||||
"""
|
||||
Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
|
||||
:param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
|
||||
:param animation: InputFile or String : Animation to send. You can either pass a file_id as String to resend an
|
||||
animation that is already on the Telegram server
|
||||
:param duration: Integer : Duration of sent video in seconds
|
||||
:param width: Integer : Video width
|
||||
:param height: Integer : Video height
|
||||
:param thumb: InputFile or String : Thumbnail of the file sent
|
||||
:param caption: String : Animation caption (may also be used when resending animation by file_id).
|
||||
:param parse_mode:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:param disable_notification:
|
||||
:param timeout:
|
||||
:param thumb: InputFile or String : Thumbnail of the file sent
|
||||
:param caption_entities:
|
||||
:param allow_sending_without_reply:
|
||||
:return:
|
||||
@ -1768,7 +1887,7 @@ class AsyncTeleBot:
|
||||
await asyncio_helper.send_animation(
|
||||
self.token, chat_id, animation, duration, caption, reply_to_message_id,
|
||||
reply_markup, parse_mode, disable_notification, timeout, thumb,
|
||||
caption_entities, allow_sending_without_reply))
|
||||
caption_entities, allow_sending_without_reply, width, height, protect_content))
|
||||
|
||||
async def send_video_note(
|
||||
self, chat_id: Union[int, str], data: Union[Any, str],
|
||||
@ -1779,7 +1898,8 @@ class AsyncTeleBot:
|
||||
disable_notification: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
thumb: Optional[Union[Any, str]]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send
|
||||
video messages.
|
||||
@ -1794,12 +1914,13 @@ class AsyncTeleBot:
|
||||
:param timeout:
|
||||
:param thumb: InputFile or String : Thumbnail of the file sent
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
await asyncio_helper.send_video_note(
|
||||
self.token, chat_id, data, duration, length, reply_to_message_id, reply_markup,
|
||||
disable_notification, timeout, thumb, allow_sending_without_reply))
|
||||
disable_notification, timeout, thumb, allow_sending_without_reply, protect_content))
|
||||
|
||||
async def send_media_group(
|
||||
self, chat_id: Union[int, str],
|
||||
@ -1807,6 +1928,7 @@ class AsyncTeleBot:
|
||||
types.InputMediaAudio, types.InputMediaDocument,
|
||||
types.InputMediaPhoto, types.InputMediaVideo]],
|
||||
disable_notification: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None,
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> List[types.Message]:
|
||||
@ -1818,11 +1940,12 @@ class AsyncTeleBot:
|
||||
:param reply_to_message_id:
|
||||
:param timeout:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
result = await asyncio_helper.send_media_group(
|
||||
self.token, chat_id, media, disable_notification, reply_to_message_id, timeout,
|
||||
allow_sending_without_reply)
|
||||
allow_sending_without_reply, protect_content)
|
||||
return [types.Message.de_json(msg) for msg in result]
|
||||
|
||||
async def send_location(
|
||||
@ -1836,7 +1959,8 @@ class AsyncTeleBot:
|
||||
horizontal_accuracy: Optional[float]=None,
|
||||
heading: Optional[int]=None,
|
||||
proximity_alert_radius: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
|
||||
|
||||
"""
|
||||
@ -1853,6 +1977,7 @@ class AsyncTeleBot:
|
||||
:param heading:
|
||||
:param proximity_alert_radius:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return: API reply.
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
@ -1860,7 +1985,7 @@ class AsyncTeleBot:
|
||||
self.token, chat_id, latitude, longitude, live_period,
|
||||
reply_to_message_id, reply_markup, disable_notification, timeout,
|
||||
horizontal_accuracy, heading, proximity_alert_radius,
|
||||
allow_sending_without_reply))
|
||||
allow_sending_without_reply, protect_content))
|
||||
|
||||
async def edit_message_live_location(
|
||||
self, latitude: float, longitude: float,
|
||||
@ -1924,7 +2049,8 @@ class AsyncTeleBot:
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
google_place_id: Optional[str]=None,
|
||||
google_place_type: Optional[str]=None) -> types.Message:
|
||||
google_place_type: Optional[str]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send information about a venue.
|
||||
:param chat_id: Integer or String : Unique identifier for the target chat or username of the target channel
|
||||
@ -1942,13 +2068,14 @@ class AsyncTeleBot:
|
||||
:param allow_sending_without_reply:
|
||||
:param google_place_id:
|
||||
:param google_place_type:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
await asyncio_helper.send_venue(
|
||||
self.token, chat_id, latitude, longitude, title, address, foursquare_id, foursquare_type,
|
||||
disable_notification, reply_to_message_id, reply_markup, timeout,
|
||||
allow_sending_without_reply, google_place_id, google_place_type)
|
||||
allow_sending_without_reply, google_place_id, google_place_type, protect_content)
|
||||
)
|
||||
|
||||
async def send_contact(
|
||||
@ -1959,12 +2086,27 @@ class AsyncTeleBot:
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Use this method to send phone contacts.
|
||||
:param chat_id: Integer or String : Unique identifier for the target chat or username of the target channel
|
||||
:param phone_number: String : Contact's phone number
|
||||
:param first_name: String : Contact's first name
|
||||
:param last_name: String : Contact's last name
|
||||
:param vcard: String : Additional data about the contact in the form of a vCard, 0-2048 bytes
|
||||
:param disable_notification:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
"""
|
||||
return types.Message.de_json(
|
||||
await asyncio_helper.send_contact(
|
||||
self.token, chat_id, phone_number, first_name, last_name, vcard,
|
||||
disable_notification, reply_to_message_id, reply_markup, timeout,
|
||||
allow_sending_without_reply)
|
||||
allow_sending_without_reply, protect_content)
|
||||
)
|
||||
|
||||
async def send_chat_action(
|
||||
@ -2135,6 +2277,37 @@ class AsyncTeleBot:
|
||||
"""
|
||||
return await asyncio_helper.set_chat_administrator_custom_title(self.token, chat_id, user_id, custom_title)
|
||||
|
||||
|
||||
async def ban_chat_sender_chat(self, chat_id: Union[int, str], sender_chat_id: Union[int, str]) -> bool:
|
||||
"""
|
||||
Use this method to ban a channel chat in a supergroup or a channel.
|
||||
The owner of the chat will not be able to send messages and join live
|
||||
streams on behalf of the chat, unless it is unbanned first.
|
||||
The bot must be an administrator in the supergroup or channel
|
||||
for this to work and must have the appropriate administrator rights.
|
||||
Returns True on success.
|
||||
|
||||
:params:
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param sender_chat_id: Unique identifier of the target sender chat
|
||||
:return: True on success.
|
||||
"""
|
||||
return await asyncio_helper.ban_chat_sender_chat(self.token, chat_id, sender_chat_id)
|
||||
|
||||
async def unban_chat_sender_chat(self, chat_id: Union[int, str], sender_chat_id: Union[int, str]) -> bool:
|
||||
"""
|
||||
Use this method to unban a previously banned channel chat in a supergroup or channel.
|
||||
The bot must be an administrator for this to work and must have the appropriate
|
||||
administrator rights.
|
||||
Returns True on success.
|
||||
|
||||
:params:
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
:param sender_chat_id: Unique identifier of the target sender chat
|
||||
:return: True on success.
|
||||
"""
|
||||
return await asyncio_helper.unban_chat_sender_chat(self.token, chat_id, sender_chat_id)
|
||||
|
||||
async def set_chat_permissions(
|
||||
self, chat_id: Union[int, str], permissions: types.ChatPermissions) -> bool:
|
||||
"""
|
||||
@ -2458,7 +2631,8 @@ class AsyncTeleBot:
|
||||
reply_to_message_id: Optional[int]=None,
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None) -> types.Message:
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Used to send the game
|
||||
:param chat_id:
|
||||
@ -2468,12 +2642,13 @@ class AsyncTeleBot:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
result = await asyncio_helper.send_game(
|
||||
self.token, chat_id, game_short_name, disable_notification,
|
||||
reply_to_message_id, reply_markup, timeout,
|
||||
allow_sending_without_reply)
|
||||
allow_sending_without_reply, protect_content)
|
||||
return types.Message.de_json(result)
|
||||
|
||||
async def set_game_score(
|
||||
@ -2533,7 +2708,8 @@ class AsyncTeleBot:
|
||||
timeout: Optional[int]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
max_tip_amount: Optional[int] = None,
|
||||
suggested_tip_amounts: Optional[List[int]]=None) -> types.Message:
|
||||
suggested_tip_amounts: Optional[List[int]]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Sends invoice
|
||||
:param chat_id: Unique identifier for the target private chat
|
||||
@ -2572,6 +2748,7 @@ class AsyncTeleBot:
|
||||
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest
|
||||
units of the currency. At most 4 suggested tip amounts can be specified. The suggested tip
|
||||
amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
result = await asyncio_helper.send_invoice(
|
||||
@ -2580,7 +2757,7 @@ class AsyncTeleBot:
|
||||
photo_height, need_name, need_phone_number, need_email, need_shipping_address,
|
||||
send_phone_number_to_provider, send_email_to_provider, is_flexible, disable_notification,
|
||||
reply_to_message_id, reply_markup, provider_data, timeout, allow_sending_without_reply,
|
||||
max_tip_amount, suggested_tip_amounts)
|
||||
max_tip_amount, suggested_tip_amounts, protect_content)
|
||||
return types.Message.de_json(result)
|
||||
|
||||
# noinspection PyShadowingBuiltins
|
||||
@ -2599,7 +2776,8 @@ class AsyncTeleBot:
|
||||
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
|
||||
allow_sending_without_reply: Optional[bool]=None,
|
||||
timeout: Optional[int]=None,
|
||||
explanation_entities: Optional[List[types.MessageEntity]]=None) -> types.Message:
|
||||
explanation_entities: Optional[List[types.MessageEntity]]=None,
|
||||
protect_content: Optional[bool]=None) -> types.Message:
|
||||
"""
|
||||
Send polls
|
||||
:param chat_id:
|
||||
@ -2620,6 +2798,7 @@ class AsyncTeleBot:
|
||||
:param reply_markup:
|
||||
:param timeout:
|
||||
:param explanation_entities:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
|
||||
@ -2633,7 +2812,7 @@ class AsyncTeleBot:
|
||||
is_anonymous, type, allows_multiple_answers, correct_option_id,
|
||||
explanation, explanation_parse_mode, open_period, close_date, is_closed,
|
||||
disable_notification, reply_to_message_id, allow_sending_without_reply,
|
||||
reply_markup, timeout, explanation_entities))
|
||||
reply_markup, timeout, explanation_entities, protect_content))
|
||||
|
||||
async def stop_poll(
|
||||
self, chat_id: Union[int, str], message_id: int,
|
||||
|
@ -34,26 +34,39 @@ CONNECT_TIMEOUT = 15
|
||||
READ_TIMEOUT = 30
|
||||
|
||||
LONG_POLLING_TIMEOUT = 10 # Should be positive, short polling should be used for testing purposes only (https://core.telegram.org/bots/api#getupdates)
|
||||
|
||||
REQUEST_TIMEOUT = 10
|
||||
MAX_RETRIES = 3
|
||||
logger = telebot.logger
|
||||
|
||||
RETRY_ON_ERROR = False
|
||||
RETRY_TIMEOUT = 2
|
||||
MAX_RETRIES = 15
|
||||
|
||||
async def _process_request(token, url, method='get', params=None, files=None, request_timeout=None):
|
||||
params = compose_data(params, files)
|
||||
params = prepare_data(params, files)
|
||||
if request_timeout is None:
|
||||
request_timeout = REQUEST_TIMEOUT
|
||||
timeout = aiohttp.ClientTimeout(total=request_timeout)
|
||||
got_result = False
|
||||
current_try=0
|
||||
async with await session_manager._get_new_session() as session:
|
||||
async with session.request(method=method, url=API_URL.format(token, url), data=params, timeout=request_timeout) as response:
|
||||
logger.debug("Request: method={0} url={1} params={2} files={3} request_timeout={4}".format(method, url, params, files, request_timeout).replace(token, token.split(':')[0] + ":{TOKEN}"))
|
||||
json_result = await _check_result(url, response)
|
||||
if json_result:
|
||||
return json_result['result']
|
||||
while not got_result and current_try<MAX_RETRIES-1:
|
||||
current_try +=1
|
||||
try:
|
||||
response = await session.request(method=method, url=API_URL.format(token, url), data=params, timeout=timeout)
|
||||
logger.debug("Request: method={0} url={1} params={2} files={3} request_timeout={4} current_try={5}".format(method, url, params, files, request_timeout, current_try).replace(token, token.split(':')[0] + ":{TOKEN}"))
|
||||
json_result = await _check_result(url, response)
|
||||
if json_result:
|
||||
return json_result['result']
|
||||
except (ApiTelegramException,ApiInvalidJSONException, ApiHTTPException) as e:
|
||||
raise e
|
||||
except:
|
||||
pass
|
||||
if not got_result:
|
||||
raise RequestTimeout("Request timeout. Request: method={0} url={1} params={2} files={3} request_timeout={4}".format(method, url, params, files, request_timeout, current_try))
|
||||
|
||||
|
||||
|
||||
def guess_filename(obj):
|
||||
|
||||
def prepare_file(obj):
|
||||
"""
|
||||
Get file name from object
|
||||
returns os.path.basename for a given file
|
||||
|
||||
:param obj:
|
||||
:return:
|
||||
@ -63,9 +76,9 @@ def guess_filename(obj):
|
||||
return os.path.basename(name)
|
||||
|
||||
|
||||
def compose_data(params=None, files=None):
|
||||
def prepare_data(params=None, files=None):
|
||||
"""
|
||||
Prepare request data
|
||||
prepare data for request.
|
||||
|
||||
:param params:
|
||||
:param files:
|
||||
@ -85,7 +98,7 @@ def compose_data(params=None, files=None):
|
||||
else:
|
||||
raise ValueError('Tuple must have exactly 2 elements: filename, fileobj')
|
||||
else:
|
||||
filename, fileobj = guess_filename(f) or key, f
|
||||
filename, fileobj = prepare_file(f) or key, f
|
||||
|
||||
data.add_field(key, fileobj, filename=filename)
|
||||
|
||||
@ -228,7 +241,7 @@ async def send_message(
|
||||
token, chat_id, text,
|
||||
disable_web_page_preview=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, disable_notification=None, timeout=None,
|
||||
entities=None, allow_sending_without_reply=None):
|
||||
entities=None, allow_sending_without_reply=None, protect_content=None):
|
||||
"""
|
||||
Use this method to send text messages. On success, the sent Message is returned.
|
||||
:param token:
|
||||
@ -242,6 +255,7 @@ async def send_message(
|
||||
:param timeout:
|
||||
:param entities:
|
||||
:param allow_sending_without_reply:
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
method_name = 'sendMessage'
|
||||
@ -262,6 +276,8 @@ async def send_message(
|
||||
params['entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
params['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
params['protect_content'] = protect_content
|
||||
|
||||
return await _process_request(token, method_name, params=params)
|
||||
|
||||
@ -333,19 +349,21 @@ async def get_chat_member(token, chat_id, user_id):
|
||||
|
||||
async def forward_message(
|
||||
token, chat_id, from_chat_id, message_id,
|
||||
disable_notification=None, timeout=None):
|
||||
disable_notification=None, timeout=None, protect_content=None):
|
||||
method_url = r'forwardMessage'
|
||||
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
|
||||
if disable_notification is not None:
|
||||
payload['disable_notification'] = disable_notification
|
||||
if timeout:
|
||||
payload['timeout'] = timeout
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
async def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_mode=None, caption_entities=None,
|
||||
disable_notification=None, reply_to_message_id=None, allow_sending_without_reply=None,
|
||||
reply_markup=None, timeout=None):
|
||||
reply_markup=None, timeout=None, protect_content=None):
|
||||
method_url = r'copyMessage'
|
||||
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
|
||||
if caption is not None:
|
||||
@ -364,13 +382,15 @@ async def copy_message(token, chat_id, from_chat_id, message_id, caption=None, p
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if timeout:
|
||||
payload['timeout'] = timeout
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
async def send_dice(
|
||||
token, chat_id,
|
||||
emoji=None, disable_notification=None, reply_to_message_id=None,
|
||||
reply_markup=None, timeout=None, allow_sending_without_reply=None):
|
||||
reply_markup=None, timeout=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendDice'
|
||||
payload = {'chat_id': chat_id}
|
||||
if emoji:
|
||||
@ -385,6 +405,8 @@ async def send_dice(
|
||||
payload['timeout'] = timeout
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -392,7 +414,7 @@ async def send_photo(
|
||||
token, chat_id, photo,
|
||||
caption=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, disable_notification=None, timeout=None,
|
||||
caption_entities=None, allow_sending_without_reply=None):
|
||||
caption_entities=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendPhoto'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -418,13 +440,15 @@ async def send_photo(
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
async def send_media_group(
|
||||
token, chat_id, media,
|
||||
disable_notification=None, reply_to_message_id=None,
|
||||
timeout=None, allow_sending_without_reply=None):
|
||||
timeout=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendMediaGroup'
|
||||
media_json, files = await convert_input_media_array(media)
|
||||
payload = {'chat_id': chat_id, 'media': media_json}
|
||||
@ -436,6 +460,8 @@ async def send_media_group(
|
||||
payload['timeout'] = timeout
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(
|
||||
token, method_url, params=payload,
|
||||
method='post' if files else 'get',
|
||||
@ -447,7 +473,7 @@ async def send_location(
|
||||
live_period=None, reply_to_message_id=None,
|
||||
reply_markup=None, disable_notification=None,
|
||||
timeout=None, horizontal_accuracy=None, heading=None,
|
||||
proximity_alert_radius=None, allow_sending_without_reply=None):
|
||||
proximity_alert_radius=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendLocation'
|
||||
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude}
|
||||
if live_period:
|
||||
@ -468,6 +494,8 @@ async def send_location(
|
||||
payload['disable_notification'] = disable_notification
|
||||
if timeout:
|
||||
payload['timeout'] = timeout
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -519,7 +547,7 @@ async def send_venue(
|
||||
foursquare_id=None, foursquare_type=None, disable_notification=None,
|
||||
reply_to_message_id=None, reply_markup=None, timeout=None,
|
||||
allow_sending_without_reply=None, google_place_id=None,
|
||||
google_place_type=None):
|
||||
google_place_type=None, protect_content=None):
|
||||
method_url = r'sendVenue'
|
||||
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude, 'title': title, 'address': address}
|
||||
if foursquare_id:
|
||||
@ -540,13 +568,15 @@ async def send_venue(
|
||||
payload['google_place_id'] = google_place_id
|
||||
if google_place_type:
|
||||
payload['google_place_type'] = google_place_type
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
async def send_contact(
|
||||
token, chat_id, phone_number, first_name, last_name=None, vcard=None,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
|
||||
allow_sending_without_reply=None):
|
||||
allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendContact'
|
||||
payload = {'chat_id': chat_id, 'phone_number': phone_number, 'first_name': first_name}
|
||||
if last_name:
|
||||
@ -563,6 +593,8 @@ async def send_contact(
|
||||
payload['timeout'] = timeout
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -576,7 +608,8 @@ async def send_chat_action(token, chat_id, action, timeout=None):
|
||||
|
||||
async def send_video(token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, supports_streaming=None, disable_notification=None, timeout=None,
|
||||
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None):
|
||||
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None,
|
||||
protect_content=None):
|
||||
method_url = r'sendVideo'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -616,13 +649,15 @@ async def send_video(token, chat_id, data, duration=None, caption=None, reply_to
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
async def send_animation(
|
||||
token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, disable_notification=None, timeout=None, thumb=None, caption_entities=None,
|
||||
allow_sending_without_reply=None):
|
||||
allow_sending_without_reply=None, width=None, height=None, protect_content=None):
|
||||
method_url = r'sendAnimation'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -656,12 +691,18 @@ async def send_animation(
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if width:
|
||||
payload['width'] = width
|
||||
if height:
|
||||
payload['height'] = height
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
async def send_voice(token, chat_id, voice, caption=None, duration=None, reply_to_message_id=None, reply_markup=None,
|
||||
parse_mode=None, disable_notification=None, timeout=None, caption_entities=None,
|
||||
allow_sending_without_reply=None):
|
||||
allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendVoice'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -687,11 +728,13 @@ async def send_voice(token, chat_id, voice, caption=None, duration=None, reply_t
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
async def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_message_id=None, reply_markup=None,
|
||||
disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None):
|
||||
disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendVideoNote'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -723,12 +766,14 @@ async def send_video_note(token, chat_id, data, duration=None, length=None, repl
|
||||
payload['thumb'] = thumb
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
async def send_audio(token, chat_id, audio, caption=None, duration=None, performer=None, title=None, reply_to_message_id=None,
|
||||
reply_markup=None, parse_mode=None, disable_notification=None, timeout=None, thumb=None,
|
||||
caption_entities=None, allow_sending_without_reply=None):
|
||||
caption_entities=None, allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendAudio'
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -766,12 +811,14 @@ async def send_audio(token, chat_id, audio, caption=None, duration=None, perform
|
||||
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload, files=files, method='post')
|
||||
|
||||
|
||||
async def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_markup=None, parse_mode=None,
|
||||
disable_notification=None, timeout=None, caption=None, thumb=None, caption_entities=None,
|
||||
allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None):
|
||||
allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None, protect_content=None):
|
||||
method_url = await get_method_by_type(data_type)
|
||||
payload = {'chat_id': chat_id}
|
||||
files = None
|
||||
@ -912,6 +959,17 @@ async def set_chat_administrator_custom_title(token, chat_id, user_id, custom_ti
|
||||
return await _process_request(token, method_url, params=payload, method='post')
|
||||
|
||||
|
||||
async def ban_chat_sender_chat(token, chat_id, sender_chat_id):
|
||||
method_url = 'banChatSenderChat'
|
||||
payload = {'chat_id': chat_id, 'sender_chat_id': sender_chat_id}
|
||||
return await _process_request(token, method_url, params=payload, method='post')
|
||||
|
||||
|
||||
async def unban_chat_sender_chat(token, chat_id, sender_chat_id):
|
||||
method_url = 'unbanChatSenderChat'
|
||||
payload = {'chat_id': chat_id, 'sender_chat_id': sender_chat_id}
|
||||
return await _process_request(token, method_url, params=payload, method='post')
|
||||
|
||||
async def set_chat_permissions(token, chat_id, permissions):
|
||||
method_url = 'setChatPermissions'
|
||||
payload = {
|
||||
@ -1165,7 +1223,7 @@ async def delete_message(token, chat_id, message_id, timeout=None):
|
||||
async def send_game(
|
||||
token, chat_id, game_short_name,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
|
||||
allow_sending_without_reply=None):
|
||||
allow_sending_without_reply=None, protect_content=None):
|
||||
method_url = r'sendGame'
|
||||
payload = {'chat_id': chat_id, 'game_short_name': game_short_name}
|
||||
if disable_notification is not None:
|
||||
@ -1178,6 +1236,8 @@ async def send_game(
|
||||
payload['timeout'] = timeout
|
||||
if allow_sending_without_reply is not None:
|
||||
payload['allow_sending_without_reply'] = allow_sending_without_reply
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -1242,7 +1302,7 @@ async def send_invoice(
|
||||
need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None,
|
||||
send_phone_number_to_provider = None, send_email_to_provider = None, is_flexible=None,
|
||||
disable_notification=None, reply_to_message_id=None, reply_markup=None, provider_data=None,
|
||||
timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None):
|
||||
timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None, protect_content=None):
|
||||
"""
|
||||
Use this method to send invoices. On success, the sent Message is returned.
|
||||
:param token: Bot's token (you don't need to fill this)
|
||||
@ -1274,6 +1334,7 @@ async def send_invoice(
|
||||
:param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency
|
||||
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest units of the currency.
|
||||
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
|
||||
:param protect_content:
|
||||
:return:
|
||||
"""
|
||||
method_url = r'sendInvoice'
|
||||
@ -1320,6 +1381,8 @@ async def send_invoice(
|
||||
payload['max_tip_amount'] = max_tip_amount
|
||||
if suggested_tip_amounts is not None:
|
||||
payload['suggested_tip_amounts'] = json.dumps(suggested_tip_amounts)
|
||||
if protect_content is not None:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
@ -1468,7 +1531,7 @@ async def send_poll(
|
||||
is_anonymous = None, type = None, allows_multiple_answers = None, correct_option_id = None,
|
||||
explanation = None, explanation_parse_mode=None, open_period = None, close_date = None, is_closed = None,
|
||||
disable_notification=False, reply_to_message_id=None, allow_sending_without_reply=None,
|
||||
reply_markup=None, timeout=None, explanation_entities=None):
|
||||
reply_markup=None, timeout=None, explanation_entities=None, protect_content=None):
|
||||
method_url = r'sendPoll'
|
||||
payload = {
|
||||
'chat_id': str(chat_id),
|
||||
@ -1510,6 +1573,8 @@ async def send_poll(
|
||||
if explanation_entities:
|
||||
payload['explanation_entities'] = json.dumps(
|
||||
types.MessageEntity.to_list_of_dicts(explanation_entities))
|
||||
if protect_content:
|
||||
payload['protect_content'] = protect_content
|
||||
return await _process_request(token, method_url, params=payload)
|
||||
|
||||
async def _convert_list_json_serializable(results):
|
||||
@ -1632,4 +1697,10 @@ class ApiTelegramException(ApiException):
|
||||
function_name,
|
||||
result)
|
||||
self.result_json = result_json
|
||||
self.error_code = result_json['error_code']
|
||||
self.error_code = result_json['error_code']
|
||||
|
||||
class RequestTimeout(Exception):
|
||||
"""
|
||||
This class represents a request timeout.
|
||||
"""
|
||||
pass
|
@ -274,10 +274,11 @@ class Chat(JsonDeserializable):
|
||||
return cls(**obj)
|
||||
|
||||
def __init__(self, id, type, title=None, username=None, first_name=None,
|
||||
last_name=None, photo=None, bio=None, description=None, invite_link=None,
|
||||
pinned_message=None, permissions=None, slow_mode_delay=None,
|
||||
message_auto_delete_time=None, sticker_set_name=None, can_set_sticker_set=None,
|
||||
linked_chat_id=None, location=None, **kwargs):
|
||||
last_name=None, photo=None, bio=None, has_private_forwards=None,
|
||||
description=None, invite_link=None, pinned_message=None,
|
||||
permissions=None, slow_mode_delay=None,
|
||||
message_auto_delete_time=None, has_protected_content=None, sticker_set_name=None,
|
||||
can_set_sticker_set=None, linked_chat_id=None, location=None, **kwargs):
|
||||
self.id: int = id
|
||||
self.type: str = type
|
||||
self.title: str = title
|
||||
@ -286,12 +287,14 @@ class Chat(JsonDeserializable):
|
||||
self.last_name: str = last_name
|
||||
self.photo: ChatPhoto = photo
|
||||
self.bio: str = bio
|
||||
self.has_private_forwards: bool = has_private_forwards
|
||||
self.description: str = description
|
||||
self.invite_link: str = invite_link
|
||||
self.pinned_message: Message = pinned_message
|
||||
self.permissions: ChatPermissions = permissions
|
||||
self.slow_mode_delay: int = slow_mode_delay
|
||||
self.message_auto_delete_time: int = message_auto_delete_time
|
||||
self.has_protected_content: bool = has_protected_content
|
||||
self.sticker_set_name: str = sticker_set_name
|
||||
self.can_set_sticker_set: bool = can_set_sticker_set
|
||||
self.linked_chat_id: int = linked_chat_id
|
||||
@ -334,12 +337,16 @@ class Message(JsonDeserializable):
|
||||
opts['forward_sender_name'] = obj.get('forward_sender_name')
|
||||
if 'forward_date' in obj:
|
||||
opts['forward_date'] = obj.get('forward_date')
|
||||
if 'is_automatic_forward' in obj:
|
||||
opts['is_automatic_forward'] = obj.get('is_automatic_forward')
|
||||
if 'reply_to_message' in obj:
|
||||
opts['reply_to_message'] = Message.de_json(obj['reply_to_message'])
|
||||
if 'via_bot' in obj:
|
||||
opts['via_bot'] = User.de_json(obj['via_bot'])
|
||||
if 'edit_date' in obj:
|
||||
opts['edit_date'] = obj.get('edit_date')
|
||||
if 'has_protected_content' in obj:
|
||||
opts['has_protected_content'] = obj.get('has_protected_content')
|
||||
if 'media_group_id' in obj:
|
||||
opts['media_group_id'] = obj.get('media_group_id')
|
||||
if 'author_signature' in obj:
|
||||
@ -503,9 +510,11 @@ class Message(JsonDeserializable):
|
||||
self.forward_signature: Optional[str] = None
|
||||
self.forward_sender_name: Optional[str] = None
|
||||
self.forward_date: Optional[int] = None
|
||||
self.is_automatic_forward: Optional[bool] = None
|
||||
self.reply_to_message: Optional[Message] = None
|
||||
self.via_bot: Optional[User] = None
|
||||
self.edit_date: Optional[int] = None
|
||||
self.has_protected_content: Optional[bool] = None
|
||||
self.media_group_id: Optional[str] = None
|
||||
self.author_signature: Optional[str] = None
|
||||
self.text: Optional[str] = None
|
||||
@ -573,7 +582,8 @@ class Message(JsonDeserializable):
|
||||
# "url": "<a href=\"{url}\">{text}</a>", # @badiboy plain URLs have no text and do not need tags
|
||||
"text_link": "<a href=\"{url}\">{text}</a>",
|
||||
"strikethrough": "<s>{text}</s>",
|
||||
"underline": "<u>{text}</u>"
|
||||
"underline": "<u>{text}</u>",
|
||||
"spoiler": "<span class=\"tg-spoiler\">{text}</span>",
|
||||
}
|
||||
|
||||
if hasattr(self, "custom_subs"):
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Versions should comply with PEP440.
|
||||
# This line is parsed in setup.py:
|
||||
__version__ = '4.2.1'
|
||||
__version__ = '4.3.0'
|
||||
|
@ -50,7 +50,7 @@ def test_json_message_with_dice():
|
||||
|
||||
|
||||
def test_json_message_group():
|
||||
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"}'
|
||||
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","has_protected_content":true}'
|
||||
msg = types.Message.de_json(json_string)
|
||||
assert msg.text == 'HIHI'
|
||||
assert len(msg.chat.title) != 0
|
||||
|
Reference in New Issue
Block a user