Compare commits

127 Commits

Author SHA1 Message Date
53802728a1 Compliance with bot API 7.9
Implemented a system to get administration privileges if running the bot in absence of administrators (the token is provided through the command line).

(cherry picked from commit db240ce199)
2024-08-17 21:12:47 +02:00
2cdb4e743f Get package version from metadata when package has no __version__ attribute 2024-08-04 18:49:16 +02:00
98fbbf0127 Compliance with bot API 7.8 2024-08-04 18:30:21 +02:00
856d53de1c Compliance with bot API 7.7
(cherry picked from commit fd4374f328)
2024-07-07 14:37:21 +02:00
5e8a2b65f5 Compliance with bot API 7.2
- Included python version in `/version` command
- Added the parameter `business_connection_id` to the methods sendMessage, sendPhoto, sendVideo, sendAnimation, sendAudio, sendDocument, sendSticker, sendVideoNote, sendVoice, sendLocation, sendVenue, sendContact, sendPoll, sendDice, sendGame, and sendMediaGroup, sendChatAction.
- Moved the parameter `format` to Sticker instead of StickerSet (and related methods)

(cherry picked from commit 6b489363de)
2024-04-13 11:17:11 +02:00
3b0bfb4880 Compliance with bot API 7.1
- Added the class ReplyParameters and replaced parameters reply_to_message_id and allow_sending_without_reply in the methods copyMessage, sendMessage, sendPhoto, sendVideo, sendAnimation, sendAudio, sendDocument, sendSticker, sendVideoNote, sendVoice, sendLocation, sendVenue, sendContact, sendPoll, sendDice, sendInvoice, sendGame, and sendMediaGroup with the field reply_parameters of type ReplyParameters.
- Added the class LinkPreviewOptions and replaced the parameter disable_web_page_preview with link_preview_options in the methods sendMessage and editMessageText.

(cherry picked from commit a343e095e8)
2024-04-13 11:17:07 +02:00
a49e727e31 Allow to overwrite file when using bot.download_file method
(cherry picked from commit a3b28bc1d6)
2024-04-13 11:17:04 +02:00
c78522d46b download_file behaves differently if a local bot API server is used. Wrong default API url was being used
(cherry picked from commit 3969794075)
2024-04-13 11:17:00 +02:00
c4964105b4 Support Local Bot API Server (with custom api_url).
(cherry picked from commit 748ba624a4)
2024-02-17 14:47:28 +01:00
3396bc6f18 download_file method updated to handle exceptions and return information about downloaded file
(cherry picked from commit 41507067be)
2024-02-14 19:31:20 +01:00
c1f4abc541 Specify encoding in send_part_of_text_file function
(cherry picked from commit ec747bef1d)
2024-02-14 19:31:17 +01:00
c4a822e45d Compliance with bot API 6.8 and 6.9
Added the method `unpinAllGeneralForumTopicMessages` (6.8).

Added the new administrator privileges `can_post_stories`, `can_edit_stories` and `can_delete_stories` to the class `ChatAdministratorRights` and to the method `promoteChatMember` (6.9).
2023-11-12 11:55:03 +01:00
6b4a95be36 Method to add table columns if missing 2023-08-23 18:23:32 +02:00
beaf3f8516 Allow non-null standard output and/or error pipe to be passed to aio_subprocess_shell function 2023-08-23 17:17:55 +02:00
fc1f087d4a When answering inline queries, prevent invalid InlineQueryResultsButton instantiation
(cherry picked from commit eab81b065d)
2023-08-07 20:19:50 +02:00
aeac4aea52 Better variable regex: accept only one decimal separator in float numbers
(cherry picked from commit 51a77c695b)
2023-07-25 18:58:45 +02:00
5ab22909cf Whitespace 2023-07-25 16:42:26 +02:00
9094955812 Config command implemented, allowing administrators to add variables to configuration files 2023-07-25 16:25:56 +02:00
173783e154 Moved join_path function to utilities module 2023-07-25 16:24:18 +02:00
92a986d090 Catch up with branch main (v 2.9.1) 2023-07-25 16:23:21 +02:00
3e6e364336 Compliance with Telegram Bot API 6.5 2023-02-03 21:40:09 +01:00
f0a4c914e4 Compliance with Telegram Bot API 6.4 2023-01-06 10:30:25 +01:00
80a1440e75 Make the regex dot match any character at all, including a newline, when cleaning HTML strings (so multiline tag bodies are allowed, as they are in Telegram HTML markdown). 2022-12-26 14:12:23 +01:00
b978022658 HTML parse_mode check upgraded.
All supported tags permitted, malformed tags replaced with escaped characters
2022-12-12 22:45:08 +01:00
50f561e7f9 Method to add a table and its columns to and ObjectWithDatabase 2022-12-10 18:46:29 +01:00
a9b785f49d Compliance with Telegram Bot API 6.3 2022-12-08 16:19:45 +01:00
b7d08ab2ba When admin A requests profile picture of user B, send B's picture and not A's. 2022-12-06 22:18:35 +01:00
d362ec496b Browse users via /auth command 2022-12-05 22:04:59 +01:00
0bfc1e157b Working on users browsing via /auth command 2022-12-04 22:13:48 +01:00
bc40957b27 Syntax-breaking typo 2022-10-12 14:19:46 +02:00
45117610f9 Bug fix: use a unique loop 2022-10-12 14:01:10 +02:00
f91661927e Bug fix: use a unique loop 2022-10-12 13:34:01 +02:00
12f3a2cc73 Bug fix: asyncio.run cannot take asyncio.gather as coroutine 2022-10-12 13:31:23 +02:00
25abb80343 Bug fix: no running loop, need to create a new one. 2022-10-12 13:26:03 +02:00
76ea65a660 asyncio get_event_loop method is being deprecated; use new_event_loop / get_running_loop and asyncio.run instead
Major version change because it may not be backward-compatible
2022-10-12 13:24:40 +02:00
e254dbf42a send_document method should not require a chat_id since it can be passed an update object 2020-12-20 20:30:49 +01:00
b7b91a65ea send_photo method should not require a chat_id since it can be passed an update object 2020-12-11 08:21:57 +01:00
abebff43d9 Avoid relative import statements 2020-11-19 15:18:50 +01:00
a460f71b69 Items in __all__ must be str, not module 2020-11-19 14:37:33 +01:00
6ad5ec2865 Document can be None if document_path is provided 2020-11-19 12:32:50 +01:00
cfae729270 Do not log chardet INFO and DEBUG levels 2020-11-16 23:05:24 +01:00
dc9c2a7b14 Compliance with Telegram Bot API 5.0 and improved type hinting for API methods. 2020-11-16 22:54:25 +01:00
a3cc676432 Identify edited methods (new or deprecated parameters) in addition to new methods. 2020-11-16 20:51:27 +01:00
15a7a58537 Version number 2020-11-15 21:35:45 +01:00
ea30fd39cf Import statements refactored 2020-11-15 21:34:26 +01:00
a5cabdd102 web should not be imported from aiohttp; use aiohttp.web instead 2020-11-15 20:55:22 +01:00
89fa73d1a5 Store user profile pictures in bot database and show them in authorization panel 2020-10-07 16:22:51 +02:00
4b22658bf5 MySQL compatibility: specify VARCHAR length
`db.types.string` becomes now `db.types.string(n)`
`db.types.text` is the wrong type to use (text blobs)
2020-10-07 16:19:03 +02:00
bce8cff3cf Pass all information to command handler when using /start 2020-09-26 19:28:03 +02:00
ea07aa47cf Make general_handler handle photo updates 2020-09-05 10:35:52 +02:00
d49bab54ca Updated examples 2020-08-23 14:21:37 +02:00
83d01e4da9 Remove argument parameter from parser decorator 2020-08-23 14:07:51 +02:00
59dde0d25e In text message handler, make available both lowered and original text and inspect condition parameters 2020-08-23 14:03:42 +02:00
713f4ffd0e Accept language directly 2020-08-20 15:50:53 +02:00
51bc95332f General handler implemented and applied to contact updates 2020-08-17 23:52:16 +02:00
92758d923c Document handlers implemented 2020-08-16 15:17:09 +02:00
946e2a881f Declare packenv variable 2020-07-19 16:17:39 +02:00
Davte
0f4d31892f Prevent globbing and word splitting 2020-07-19 16:11:00 +02:00
Davte
c4eaa0b9db Update default help messages with given ones, instead of replacing them 2020-07-17 09:48:52 +02:00
Davte
21214feb0a In default keyboard, show only buttons for commands the user is authorized to call 2020-07-16 10:05:28 +02:00
Davte
f7ee5b71a1 Prevent decoding None objects 2020-07-15 13:16:21 +02:00
Davte
fb58c0239d Async function to run shell commands 2020-07-15 13:11:04 +02:00
Davte
c848bfc228 Script to merge split files 2020-06-22 22:53:25 +02:00
Davte
f823057cbe Split outgoing documents bigger than 50 MB and send chunks 2020-06-22 20:30:03 +02:00
Davte
d7a1acd23b Typos 2020-06-20 15:44:26 +02:00
Davte
70053c9279 Send error message if database could not be sent - new version 2020-06-20 15:34:39 +02:00
Davte
1c76c7d797 Send error message if database could not be sent 2020-06-20 15:31:42 +02:00
Davte
dfffbff7c6 Merge 2020-06-20 15:20:22 +02:00
Davte
a4b1ed09a2 longest_cooldown_timedelta property defined 2020-06-20 15:18:13 +02:00
Davte
a1bd681cbf Merge 2020-06-20 15:16:46 +02:00
Davte
9c57677320 Accept both updates and raw_updates in maintenance exception criteria 2020-05-21 15:32:04 +02:00
Davte
956e982157 Pass to handlers the parameters they take and preserve update_id 2020-05-21 14:55:32 +02:00
Davte
4bd10894a8 Merge branch 'master' into develop 2020-05-19 15:21:02 +02:00
Davte
89a9863510 Send long text messages as files 2020-05-19 15:12:38 +02:00
Davte
ed36e53a28 Consider _ as a digit when prettifying expressions 2020-05-19 15:11:58 +02:00
Davte
8977e0fbc3 Shorten buffer time for calculation sessions 2020-05-19 14:04:02 +02:00
Davte
cf7e0c740b Redundant escape 2020-05-19 13:59:15 +02:00
Davte
12b18cff58 Prettify expressions removing whitespace around newlines and adjusting whitespace around parentheses 2020-05-19 12:53:20 +02:00
Davte
3160723aa7 TypeError bug fixed 2020-05-18 22:25:30 +02:00
Davte
8e2feb5ac2 Prevent message is not modified exceptions 2020-05-18 22:08:10 +02:00
Davte
cbc7424a97 Prettify expressions 2020-05-18 19:31:26 +02:00
Davte
1e7c384b6d Multilanguage message in version command
(cherry picked from commit a7fd054106)
2020-05-18 18:58:23 +02:00
Davte
7cc2e02f47 Remove whitespace at the end of the expression after del button is pressed 2020-05-18 18:50:21 +02:00
Davte
6315c0dcc2 Track input via message of algebraic expressions as well as input via buttons. 2020-05-18 18:33:40 +02:00
Davte
f06c525f5b Merged branch master 2020-05-18 15:09:05 +02:00
Davte
ea5c63c1f8 Finished working on calc command 2020-05-18 15:04:18 +02:00
Davte
ea549b63c8 Working on calc command 2020-05-18 13:04:19 +02:00
Davte
e63b0f9265 Working on calc command 2020-05-18 12:42:04 +02:00
Davte
cb9310437f Working on calc button 2020-05-17 19:45:39 +02:00
Davte
5bc58dd7d5 Working on calc button 2020-05-16 15:51:49 +02:00
Davte
5d35579e10 Working on /calc command 2020-05-15 19:48:04 +02:00
Davte
b0132e0b30 /when command implemented 2020-05-14 22:18:21 +02:00
Davte
49ecee63d0 /info command implemented 2020-05-14 21:58:38 +02:00
Davte
273eda2b67 /ping command implemented
/length command returns characters in text message even, not only in reply
2020-05-14 20:25:29 +02:00
Davte
b12f653096 Useful tools module added 2020-05-14 18:50:05 +02:00
Davte
05878f3fbd Language-labelled commands are accepted only for selected language. /father uses selected language for commands 2020-05-14 18:49:40 +02:00
Davte
c583c3c3b0 Allow language-labelled commands 2020-05-14 15:32:06 +02:00
Davte
2d40903069 Finished working on /version command 2020-05-13 19:44:04 +02:00
Davte
217a445a65 Working on /version command 2020-05-13 15:54:38 +02:00
Davte
b68dbe7a07 /ban command implemented 2020-05-13 15:31:59 +02:00
Davte
258ca9f6ef /ban command implemented 2020-05-13 15:31:20 +02:00
Davte
3648a36636 Version 2020-05-13 15:22:37 +02:00
Davte
ef99493c7f Finished working on /ban 2020-05-13 15:22:14 +02:00
Davte
841f7f0c8d Working on /ban 2020-05-13 12:47:37 +02:00
Davte
23882e5b3b Implemented button to delete all commands stored by BotFather 2020-05-07 22:52:42 +02:00
Davte
6ba21f0115 Version 2020-05-07 15:29:10 +02:00
Davte
ca6dca3cb7 Finished working on /father command 2020-05-07 15:07:45 +02:00
Davte
9072c3abe5 Working on /father command 2020-05-06 23:18:27 +02:00
Davte
e74e38c6ae Comment 2020-05-06 15:39:45 +02:00
Davte
7a23045479 New parameters of sendPoll method 2020-05-06 15:33:23 +02:00
Davte
5ef449a542 Temp 2020-05-06 00:44:21 +02:00
Davte
a2c83f8d9c Pass language to update handlers 2020-05-06 00:39:23 +02:00
Davte
dddaf20ea2 Temp 2020-05-05 23:44:58 +02:00
Davte
a828bb5d3c Move functions outside init 2020-05-05 12:29:55 +02:00
Davte
25f5514dff Type hinting
(cherry picked from commit 3896776f0e)
2020-04-28 12:08:01 +02:00
Davte
34f802732b Do not notify package updates too often
(cherry picked from commit ab6a0bc0ad)
2020-04-28 09:48:53 +02:00
Davte
f6466b0540 Merge branch 'develop' of ssh://gogs.davte.it:8445/Davte/davtelepot into develop
# Conflicts:
#	davtelepot/__init__.py
2020-04-28 09:48:42 +02:00
Davte
7565df17ba New version
(cherry picked from commit e61d757c1a)
2020-04-28 00:36:28 +02:00
Davte
4be33370b9 Text made more clear
(cherry picked from commit e7274dce07)
2020-04-28 00:27:36 +02:00
Davte
cf3f7a88fb Deprecated admin_tools submodule 2020-04-28 00:26:38 +02:00
Davte
a4d464da58 Text made more clear 2020-04-27 19:07:10 +02:00
Davte
83c0a91919 Missing whitespace
(cherry picked from commit b107cc105d)
2020-04-27 18:03:24 +02:00
Davte
85a5ce3882 Merge branch 'develop' of ssh://gogs.davte.it:8445/Davte/davtelepot into develop 2020-04-27 17:30:05 +02:00
Davte
77405d2dd3 Merge branch 'master' into develop
# Conflicts:
#	davtelepot/__init__.py
#	davtelepot/administration_tools.py
2020-04-27 14:03:58 +02:00
Davte
1e2316e748 Package update notifier completed 2020-04-27 13:45:25 +02:00
Davte
16014c5a42 Working on package update notifier 2020-04-26 23:30:44 +02:00
Davte
f0be5b5ff2 Working on package update notifier 2020-04-26 23:14:10 +02:00
7 changed files with 38 additions and 889 deletions

1
.gitignore vendored
View File

@@ -41,7 +41,6 @@ __pycache__/
# Distribution / packaging
.Python
env/
.venv/
build/
develop-eggs/
dist/

View File

@@ -11,7 +11,7 @@ __author__ = "Davide Testa"
__email__ = "davide@davte.it"
__credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
__license__ = "GNU General Public License v3.0"
__version__ = "2.10.11"
__version__ = "2.10.6"
__maintainer__ = "Davide Testa"
__contact__ = "t.me/davte"

View File

@@ -836,8 +836,7 @@ def get_maintenance_exception_criterion(bot, allowed_command):
async def get_last_commit():
"""Get last commit hash and message."""
last_commit_message = None
"""Get last commit hash and davtelepot version."""
try:
_subprocess = await asyncio.create_subprocess_exec(
'git', 'rev-parse', 'HEAD',
@@ -845,22 +844,12 @@ async def get_last_commit():
stderr=asyncio.subprocess.STDOUT
)
stdout, _ = await _subprocess.communicate()
last_commit_hash = stdout.decode().strip()
last_commit = stdout.decode().strip()
except Exception as e:
last_commit_hash = f"{e}"
try:
_subprocess = await asyncio.create_subprocess_exec(
'git', 'log', '--pretty=%B', "-n", "1", last_commit_hash,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT
)
stdout, _ = await _subprocess.communicate()
last_commit_message = stdout.decode().strip()
except Exception:
pass
if last_commit_hash.startswith("fatal: not a git repository"):
last_commit_hash = "-"
return last_commit_hash, last_commit_message
last_commit = f"{e}"
if last_commit.startswith("fatal: not a git repository"):
last_commit = "-"
return last_commit
async def get_new_versions(bot: Bot,
@@ -910,15 +899,12 @@ async def get_new_versions(bot: Bot,
async def version_command(bot: Bot, update: dict,
user_record: OrderedDict, language: str):
last_commit_hash, last_commit_message = await get_last_commit()
last_commit = await get_last_commit()
text = bot.get_message(
'admin', 'version_command', 'header',
last_commit=last_commit_hash,
last_commit=last_commit,
update=update, user_record=user_record
)
if last_commit_message:
text += "\n<i>" + last_commit_message + "</i>"
text += "\n\n"
) + '\n\n'
text += f'<b>Python: </b> <code>{platform.python_version()}</code>\n'
text += '\n'.join(
f"<b>{package.__name__}</b>: "
@@ -961,7 +947,7 @@ async def notify_new_version(bot: Bot):
Notify admins when last commit and/or davtelepot version change.
"""
last_commit_hash, last_commit_message = await get_last_commit()
last_commit = await get_last_commit()
old_record = bot.db['version_history'].find_one(
order_by=['-id']
)
@@ -969,7 +955,7 @@ async def notify_new_version(bot: Bot):
f"{package.__name__}_version": get_package_version(package)
for package in bot.packages
}
current_versions['last_commit'] = last_commit_hash
current_versions['last_commit'] = last_commit
if old_record is None:
old_record = dict(
updated_at=datetime.datetime.min,
@@ -992,16 +978,13 @@ async def notify_new_version(bot: Bot):
'admin', 'new_version', 'title',
user_record=admin
) + '\n\n'
if last_commit_hash != old_record['last_commit']:
if last_commit != old_record['last_commit']:
text += bot.get_message(
'admin', 'new_version', 'last_commit',
old_record=old_record,
new_record=current_versions,
user_record=admin
)
if last_commit_message:
text += f"\n<i>{last_commit_message}</i>"
text += "\n\n"
) + '\n\n'
text += '\n'.join(
f"<b>{name[:-len('_version')]}</b>: "
f"<code>{old_record[name]}</code> —> "
@@ -1907,8 +1890,6 @@ async def create_promotion_command(bot: Bot):
of the machine running the bot.
"""
await bot.get_me()
if len(bot.administrators) > 0:
return
bot.administration_token = get_secure_key(length=10)
print(f"To become administrator click "
f"https://t.me/{bot.name}?start="
@@ -2151,4 +2132,6 @@ def init(telegram_bot: Bot,
update=update,
user_record=user_record,
language=language)
if len(telegram_bot.administrators) == 0:
asyncio.ensure_future(create_promotion_command(bot=telegram_bot))

View File

@@ -318,8 +318,7 @@ class InputSticker(dict):
or pass “attach://<file_attach_name>” to upload a new one using
multipart/form-data under <file_attach_name> name.
Animated and video stickers can't be uploaded via HTTP URL.
More information on Sending Files:
https://core.telegram.org/bots/api#sending-files
More information on Sending Files: https://core.telegram.org/bots/api#sending-files
@param format_: Format of the added sticker, must be one of “static”
for a .WEBP or .PNG image, “animated” for a .TGS animation,
“video” for a WEBM video
@@ -404,9 +403,9 @@ class ReactionType(DictToDump):
emoji: str = None,
custom_emoji_id: str = None):
super().__init__(self)
if type_ not in ('emoji', 'custom_emoji', 'paid'):
if type_ not in ('emoji', 'custom_emoji'):
raise TypeError(
f"ReactionType must be `emoji`, `custom_emoji` or `paid`.\n"
f"ReactionType must be `emoji` or `custom_emoji`.\n"
f"Unknown type {type_}"
)
self['type'] = type_
@@ -419,7 +418,7 @@ class ReactionType(DictToDump):
self['emoji'] = emoji
elif custom_emoji_id:
self['custom_emoji_id'] = custom_emoji_id
elif type_ != 'paid':
else:
raise TypeError(
"At least one of the two fields `emoji` or `custom_emoji` "
"must be provided and not None."
@@ -458,310 +457,6 @@ class InputPaidMediaVideo(InputPaidMedia):
self['supports_streaming'] = supports_streaming
class MessageEntity(DictToDump):
def __init__(self,
type_: str,
offset: int,
length: int,
url: str,
user: 'User',
language: str,
custom_emoji_id: str):
super().__init__()
self['type'] = type_
self['offset'] = offset
self['length'] = length
self['url'] = url
self['user'] = user
self['language'] = language
self['custom_emoji_id'] = custom_emoji_id
class PreparedInlineMessage(DictToDump):
"""Describes an inline message to be sent by a user of a Mini App.
Attributes:
id (str): Unique identifier of the prepared message
expiration_date (int): Expiration date of the prepared message,
in Unix time. Expired prepared messages can no longer be used.
"""
def __init__(self,
id: str,
expiration_date: int):
super().__init__()
self['id'] = id
self['expiration_date'] = expiration_date
class StoryAreaPosition(DictToDump):
"""Describes the position of a clickable area within a story.
@param x_percentage: The abscissa of the area's center, as a percentage of
the media width
@param y_percentage: The ordinate of the area's center, as a percentage of
the media height
@param width_percentage: The width of the area's rectangle, as a percentage
of the media width
@param height_percentage: The height of the area's rectangle, as a
percentage of the media height
@param rotation_angle: The clockwise rotation angle of the rectangle, in
degrees; 0-360
@param corner_radius_percentage: The radius of the rectangle corner
rounding, as a percentage of the media width
"""
def __init__(self,x_percentage: float = None,
y_percentage: float = None,
width_percentage: float = None,
height_percentage: float = None,
rotation_angle: float = None,
corner_radius_percentage: float = None):
super().__init__()
for parameter, value in locals().items():
if value:
self[parameter] = value
class StoryAreaType(DictToDump):
"""Describes the type of a clickable area on a story.
Currently, it can be one of:
- StoryAreaTypeLocation
- StoryAreaTypeSuggestedReaction
- StoryAreaTypeLink
- StoryAreaTypeWeather
- StoryAreaTypeUniqueGift
"""
def __init__(self, type_):
assert type_ in ('location',
'suggested_reaction',
'link',
'weather',
'unique_gift'), (
f"Invalid StoryAreaType: {type_}"
)
self['type'] = type_
class LocationAddress(DictToDump):
"""Describes the physical address of a location.
@param country_code: the two-letter ISO 3166-1 alpha-2 country code of the
country where the location is located
@param state (optional): state of the location
@param city (optional): city of the location
@param street(optional): street address of the location
"""
def __init__(self, country_code: str,
state: str = None,
city: str = None, street: str = None):
assert len(f"{country_code}") == 2, (
f"Invalid country code: {country_code}"
)
super().__init__()
for parameter, value in locals().items():
if value:
self[parameter] = value
class StoryAreaTypeLocation(StoryAreaType):
"""Describes a story area pointing to a location.
Currently, a story can have up to 10 location areas.
@param latitude: location latitude in degrees
@param longitude: location longitude in degrees
@param address: Optional. Address of the location
"""
def __init__(self, latitude: float, longitude: float,
address: 'LocationAddress' = None):
super().__init__(type_='location')
for parameter, value in locals().items():
if value:
self[parameter] = value
class StoryAreaTypeSuggestedReaction(StoryAreaType):
"""Describes a story area pointing to a suggested reaction.
Currently, a story can have up to 5 suggested reaction areas.
@param reaction_type: type of the reaction
@param is_dark: pass True if the reaction area has a dark background
@param is_flipped: pass True if reaction area corner is flipped
"""
def __init__(self, reaction_type: 'ReactionType',
is_dark: bool = None,
is_flipped: bool = None):
super().__init__(type_='suggested_reaction')
for parameter, value in locals().items():
if value is not None:
self[parameter] = value
class StoryAreaTypeLink(StoryAreaType):
"""Describes a story area pointing to an HTTP or tg:// link.
Currently, a story can have up to 3 link areas.
@param url: HTTP or tg:// URL to be opened when the area is clicked
"""
def __init__(self, url: str):
super().__init__(type_='link')
self['url'] = url
class StoryAreaTypeWeather(StoryAreaType):
"""Describes a story area containing weather information.
Currently, a story can have up to 3 weather areas.
Parameters:
@param temperature: temperature, in degree Celsius
@param emoji: emoji representing the weather
@param background_color: a color of the area background in the ARGB format
"""
def __init__(self, temperature: float, emoji: str, background_color: int):
super().__init__(type_='weather')
for parameter, value in locals().items():
if value:
self[parameter] = value
class StoryAreaTypeUniqueGift(StoryAreaType):
"""Describes a story area pointing to a unique gift.
Currently, a story can have at most 1 unique gift area.
@param name: unique name of the gift
"""
def __init__(self, name):
super().__init__(type_='unique_gift')
for parameter, value in locals().items():
if value:
self[parameter] = value
class StoryArea(DictToDump):
"""Describes a clickable area on a story media.
@param position: Position of the area
@param type: Type of the area
"""
def __init__(self,
position: 'StoryAreaPosition',
type_: 'StoryAreaType'):
super().__init__()
self['position'] = position
self['type'] = type_
class InputStoryContent(DictToDump):
"""This object describes the content of a story to post.
Currently, it can be one of
- InputStoryContentPhoto
- InputStoryContentVideo
"""
def __init__(self, type_):
assert type_ in ('photo',
'video',), (
f"Invalid InputStoryContent type: {type_}"
)
self['type'] = type_
class InputStoryContentPhoto(InputStoryContent):
"""Describes a photo to post as a story.
@param photo: the photo to post as a story. The photo must be of the size
1080x1920 and must not exceed 10 MB. The photo can't be reused and can
only be uploaded as a new file, so you can pass
attach://<file_attach_name> if the photo was uploaded using
multipart/form-data under <file_attach_name>.
More information: https://core.telegram.org/bots/api#sending-files
"""
def __init__(self, photo: str):
super().__init__(type_='photo')
for parameter, value in locals().items():
if value:
self[parameter] = value
class InputStoryContentVideo(InputStoryContent):
"""Describes a video to post as a story.
@param video: The video to post as a story. The video must be of the size
720x1280, streamable, encoded with H.265 codec, with key frames added
each second in the MPEG4 format, and must not exceed 30 MB. The video
can't be reused and can only be uploaded as a new file, so you can pass
“attach://<file_attach_name>” if the video was uploaded using
multipart/form-data under <file_attach_name>.
More information: https://core.telegram.org/bots/api#sending-files
@param duration: Optional. Precise duration of the video in seconds; 0-60
@param cover_frame_timestamp: Optional. Timestamp in seconds of the frame
that will be used as the static cover for the story. Defaults to 0.0.
@param is_animation: Optional. Pass True if the video has no sound
More information: https://core.telegram.org/bots/api#sending-files
"""
def __init__(self, video: str, duration: float = None,
cover_frame_timestamp: float = None,
is_animation: bool = None):
super().__init__(type_='photo')
for parameter, value in locals().items():
if value is not None:
self[parameter] = value
class InputProfilePhoto(DictToDump):
"""This object describes a profile photo to set.
Currently, it can be one of
- InputProfilePhotoStatic
- InputProfilePhotoAnimated
"""
def __init__(self, type_):
assert type_ in ('InputProfilePhotoStatic',
'InputProfilePhotoAnimated',), (
f"Invalid InputProfilePhoto type: {type_}"
)
self['type'] = type_
class InputProfilePhotoStatic(InputProfilePhoto):
"""A static profile photo in the .JPG format.
@param photo: the static profile photo. Profile photos can't be reused and
can only be uploaded as a new file, so you can pass
"attach://<file_attach_name>" if the photo was uploaded using
multipart/form-data under <file_attach_name>.
More information on Sending Files:
https://core.telegram.org/bots/api#sending-files
"""
def __init__(self, photo: str):
super().__init__(type_='static')
for parameter, value in locals().items():
if value:
self[parameter] = value
class InputProfilePhotoAnimated(InputProfilePhoto):
"""A static profile photo in the MPEG4 format.
@param animation: The animated profile photo. Profile photos can't be reused
and can only be uploaded as a new file, so you can pass
"attach://<file_attach_name>" if the photo was uploaded using
multipart/form-data under <file_attach_name>.
More information on Sending Files:
https://core.telegram.org/bots/api#sending-files
@param main_frame_timestamp: Optional. Timestamp in seconds of the frame
that will be used as the static profile photo. Defaults to 0.0.
"""
def __init__(self, animation: str,
main_frame_timestamp: float = None):
super().__init__(type_='animated')
for parameter, value in locals().items():
if value:
self[parameter] = value
def handle_deprecated_disable_web_page_preview(parameters: dict,
kwargs: dict):
if 'disable_web_page_preview' in kwargs:
@@ -1222,7 +917,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a text message. On success, return it.
@@ -1246,8 +940,7 @@ class TelegramBot:
message_id: int,
message_thread_id: int = None,
protect_content: bool = None,
disable_notification: bool = None,
video_start_timestamp: int = None):
disable_notification: bool = None):
"""Forward a message.
See https://core.telegram.org/bots/api#forwardmessage for details.
@@ -1270,7 +963,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a photo from file_id, HTTP url or file.
@@ -1300,7 +992,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send an audio file from file_id, HTTP url or file.
@@ -1333,7 +1024,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a document from file_id, HTTP url or file.
@@ -1371,9 +1061,6 @@ class TelegramBot:
has_spoiler: bool = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
start_timestamp: int = None,
cover=None,
**kwargs):
"""Send a video from file_id, HTTP url or file.
@@ -1410,7 +1097,6 @@ class TelegramBot:
has_spoiler: bool = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send animation files (GIF or H.264/MPEG-4 AVC video without sound).
@@ -1442,7 +1128,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send an audio file to be displayed as playable voice message.
@@ -1469,7 +1154,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a rounded square mp4 video message of up to 1 minute long.
@@ -1496,7 +1180,6 @@ class TelegramBot:
protect_content: bool = None,
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a group of photos or videos as an album.
@@ -1526,7 +1209,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a point on the map. May be kept updated for a `live_period`.
@@ -1614,7 +1296,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send information about a venue.
@@ -1642,7 +1323,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a phone contact.
@@ -1680,7 +1360,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a native poll in a group, a supergroup or channel.
@@ -2202,7 +1881,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send `.webp` stickers.
@@ -2422,7 +2100,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send an invoice.
@@ -2503,7 +2180,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a game.
@@ -2571,7 +2247,6 @@ class TelegramBot:
message_effect_id: str = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
**kwargs):
"""Send a dice.
@@ -2721,8 +2396,6 @@ class TelegramBot:
disable_notification: bool = None,
reply_parameters: ReplyParameters = None,
reply_markup=None,
allow_paid_broadcast: bool = None,
video_start_timestamp: int = None,
**kwargs):
"""Use this method to copy messages of any kind.
@@ -3085,27 +2758,11 @@ class TelegramBot:
need_shipping_address: bool,
send_phone_number_to_provider: bool,
send_email_to_provider: bool,
is_flexible: bool,
business_connection_id: str = None,
subscription_period: int = None
):
is_flexible: bool):
"""Use this method to create a link for an invoice.
Returns the created invoice link as String on success. See
https://core.telegram.org/bots/api#createinvoicelink for details.
Attributes:
business_connection_id (Optional[str]): Unique identifier of the
business connection on behalf of which the link will be created.
For payments in Telegram Stars only.
subscription_period (Optional[int]): The number of seconds the
subscription will be active for before the next payment. The
currency must be set to “XTR” (Telegram Stars) if the parameter
is used. Currently, it must always be 2592000 (30 days) if
specified. Any number of subscriptions can be active for a given
bot at the same time, including multiple concurrent
subscriptions from the same user.
Subscription price must no exceed 2500 Telegram Stars.
Returns the created invoice link as String on success.
See https://core.telegram.org/bots/api#createinvoicelink for details.
"""
return await self.api_request(
'createInvoiceLink',
@@ -3452,7 +3109,6 @@ class TelegramBot:
async def sendPaidMedia(self, chat_id: Union[int, str], star_count: int,
media: List[InputPaidMedia],
payload: str = None,
business_connection_id: str = None,
caption: str = None, parse_mode: str = None,
caption_entities: List[dict] = None,
@@ -3460,7 +3116,6 @@ class TelegramBot:
disable_notification: bool = None,
protect_content: bool = None,
reply_parameters: ReplyParameters = None,
allow_paid_broadcast: bool = None,
reply_markup = None):
"""Send paid media to channel chats.
@@ -3533,425 +3188,3 @@ class TelegramBot:
'editChatSubscriptionInviteLink',
parameters=locals()
)
async def setUserEmojiStatus(self, user_id: int,
emoji_status_custom_emoji_id: str = None,
emoji_status_expiration_date: int = None):
"""Changes the emoji status for a given user that previously allowed the
bot to manage their emoji status via the Mini App method
requestEmojiStatusAccess.
Returns True on success.
See https://core.telegram.org/bots/api#setuseremojistatus for details.
"""
if emoji_status_custom_emoji_id is None:
emoji_status_custom_emoji_id = ''
return await self.api_request(
'setUserEmojiStatus',
parameters=locals()
)
async def getAvailableGifts(self):
"""Returns the list of gifts that can be sent by the bot to users.
Requires no parameters.
Returns a Gifts object.
See https://core.telegram.org/bots/api#getavailablegifts for details.
"""
return await self.api_request(
'getAvailableGifts',
parameters=locals()
)
async def sendGift(self, user_id: int, chat_id: Union[int, str],
gift_id: str, pay_for_upgrade: bool,
text: str, text_parse_mode: str,
text_entities: List['MessageEntity']):
"""Sends a gift to the given user.
The gift can't be converted to Telegram Stars by the user.
Returns True on success.
See https://core.telegram.org/bots/api#sendgift for details.
"""
return await self.api_request(
'sendGift',
parameters=locals()
)
async def verifyUser(self, user_id: int,
custom_description: str = None):
"""Verifies a user on behalf of the organization which is represented by
the bot.
Returns True on success.
See https://core.telegram.org/bots/api#verifyuser for details.
"""
if len(custom_description) > 70:
raise TypeError("Parameter `custom_description` is too long "
"(0-70 characters).")
return await self.api_request(
'verifyUser',
parameters=locals()
)
async def verifyChat(self, chat_id: Union[int, str],
custom_description: str = None):
"""Verifies a chat on behalf of the organization which is represented by
the bot.
Returns True on success.
See https://core.telegram.org/bots/api#verifychat for details.
"""
if isinstance(chat_id, str) and chat_id.isnumeric():
chat_id = int(chat_id)
if not (isinstance(chat_id, int) or
(isinstance(chat_id, str) and chat_id.startswith('@'))):
raise TypeError(f"Invalid chat_id: `{chat_id}`")
if len(custom_description) > 70:
raise TypeError("Parameter `custom_description` is too long "
"(0-70 characters).")
return await self.api_request(
'verifyChat',
parameters=locals()
)
async def removeUserVerification(self, user_id: int):
"""Removes verification from a user who is currently verified on behalf
of the organization represented by the bot.
Returns True on success.
See https://core.telegram.org/bots/api#removeuserverification for
details.
"""
return await self.api_request(
'removeUserVerification',
parameters=locals()
)
async def removeChatVerification(self, chat_id: Union[int, str]):
"""Removes verification from a chat that is currently verified on behalf
of the organization represented by the bot.
Returns True on success.
See https://core.telegram.org/bots/api#removechatverification for
details.
"""
if not (isinstance(chat_id, int) or
(isinstance(chat_id, str) and chat_id.startswith('@'))):
raise TypeError(f"Invalid chat_id: `{chat_id}`")
return await self.api_request(
'removeChatVerification',
parameters=locals()
)
async def savePreparedInlineMessage(self,
user_id: int,
result: 'InlineQueryResult',
allow_user_chats: bool = None,
allow_bot_chats: bool = None,
allow_group_chats: bool = None,
allow_channel_chats: bool = None
) -> 'PreparedInlineMessage':
"""Stores a message that can be sent by a user of a Mini App.
Returns a PreparedInlineMessage object.
See https://core.telegram.org/bots/api#savepreparedinlinemessage for
details.
"""
return await self.api_request(
'savePreparedInlineMessage',
parameters=locals()
)
async def editUserStarSubscription(self, user_id: int,
telegram_payment_charge_id: str,
is_canceled: bool):
"""Allows the bot to cancel or re-enable extension of a subscription
paid in Telegram Stars.
Returns True on success.
See https://core.telegram.org/bots/api#edituserstarsubscription for
details.
"""
return await self.api_request(
'editUserStarSubscription',
parameters=locals()
)
async def giftPremiumSubscription(
self, user_id: int,
month_count: int, star_count: int,
text: str = None,
text_parse_mode: str = None,
text_entities: List['MessageEntity'] = None
):
"""Gifts a Telegram Premium subscription to the given user.
Returns True on success.
See https://core.telegram.org/bots/api#giftpremiumsubscription for details.
"""
if star_count not in (1000, 1500, 2500):
logging.warning("Star count should be 1000 for three months, 1500 "
"for 6 months or 2000 for 12 months")
return await self.api_request(
'giftPremiumSubscription',
parameters=locals()
)
async def readBusinessMessage(self,
business_connection_id: str,
chat_id: int,
message_id: int):
"""Marks incoming message as read on behalf of a business account.
Requires the can_read_messages business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#readbusinessmessage for details.
"""
return await self.api_request(
'readBusinessMessage',
parameters=locals()
)
async def deleteBusinessMessages(self,
business_connection_id: str,
message_ids: List[int]):
"""Delete messages on behalf of a business account.
Requires the can_delete_outgoing_messages business bot right to delete
messages sent by the bot itself, or the can_delete_all_messages
business bot right to delete any message.
Returns True on success.
See https://core.telegram.org/bots/api#deletebusinessmessages for details.
"""
return await self.api_request(
'deleteBusinessMessages',
parameters=locals()
)
async def setBusinessAccountName(self,
business_connection_id: str,
first_name: str,
last_name: str = None):
"""Changes the first and last name of a managed business account.
Requires the can_change_name business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#setbusinessaccountname for details.
"""
return await self.api_request(
'setBusinessAccountName',
parameters=locals()
)
async def setBusinessAccountUsername(self,
business_connection_id: str,
username: str = None):
"""Changes the username of a managed business account.
Requires the can_change_username business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#setbusinessaccountusername for details.
"""
return await self.api_request(
'setBusinessAccountUsername',
parameters=locals()
)
async def setBusinessAccountBio(self,
business_connection_id: str,
bio: str = None):
"""Changes the bio of a managed business account.
Requires the can_change_bio business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#setbusinessaccountbio for details.
"""
return await self.api_request(
'setBusinessAccountBio',
parameters=locals()
)
async def setBusinessAccountProfilePhoto(self,
business_connection_id: str,
photo: 'InputProfilePhoto',
is_public: bool = None):
"""Changes the profile photo of a managed business account.
Requires the can_edit_profile_photo business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#setbusinessaccountprofilephoto for details.
"""
return await self.api_request(
'setBusinessAccountProfilePhoto',
parameters=locals()
)
async def removeBusinessAccountProfilePhoto(self, business_connection_id: str, is_public: bool):
"""Removes the current profile photo of a managed business account.
Requires the can_edit_profile_photo business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#removebusinessaccountprofilephoto for details.
"""
return await self.api_request(
'removeBusinessAccountProfilePhoto',
parameters=locals()
)
async def setBusinessAccountGiftSettings(self, business_connection_id: str, show_gift_button: bool, accepted_gift_types: 'AcceptedGiftTypes'):
"""Changes the privacy settings pertaining to incoming gifts in a managed
business account.
Requires the can_change_gift_settings business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#setbusinessaccountgiftsettings for details.
"""
return await self.api_request(
'setBusinessAccountGiftSettings',
parameters=locals()
)
async def getBusinessAccountStarBalance(self, business_connection_id: str):
"""Returns the amount of Telegram Stars owned by a managed business
account.
Requires the can_view_gifts_and_stars business bot right.
Returns StarAmount on success.
See https://core.telegram.org/bots/api#getbusinessaccountstarbalance for details.
"""
return await self.api_request(
'getBusinessAccountStarBalance',
parameters=locals()
)
async def transferBusinessAccountStars(self, business_connection_id: str, star_count: int):
"""Transfers Telegram Stars from the business account balance to the bot's
balance.
Requires the can_transfer_stars business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#transferbusinessaccountstars for details.
"""
return await self.api_request(
'transferBusinessAccountStars',
parameters=locals()
)
async def getBusinessAccountGifts(self,
business_connection_id: str,
exclude_unsaved: bool = None,
exclude_saved: bool = None,
exclude_unlimited: bool = None,
exclude_limited: bool = None,
exclude_unique: bool = None,
sort_by_price: bool = None,
offset: str = None,
limit: int = None):
"""Returns the gifts received and owned by a managed business account.
Requires the can_view_gifts_and_stars business bot right.
Returns OwnedGifts on success.
See https://core.telegram.org/bots/api#getbusinessaccountgifts for details.
"""
return await self.api_request(
'getBusinessAccountGifts',
parameters=locals()
)
async def convertGiftToStars(self, business_connection_id: str, owned_gift_id: str):
"""Converts a given regular gift to Telegram Stars.
Requires the can_convert_gifts_to_stars business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#convertgifttostars for details.
"""
return await self.api_request(
'convertGiftToStars',
parameters=locals()
)
async def upgradeGift(self, business_connection_id: str,
owned_gift_id: str,
keep_original_details: bool = None,
star_count: int = None):
"""Upgrades a given regular gift to a unique gift.
Requires the can_transfer_and_upgrade_gifts business bot right.
Additionally requires the can_transfer_stars business bot right if the
upgrade is paid.
Returns True on success.
See https://core.telegram.org/bots/api#upgradegift for details.
"""
return await self.api_request(
'upgradeGift',
parameters=locals()
)
async def transferGift(self, business_connection_id: str,
owned_gift_id: str,
new_owner_chat_id: int,
star_count: int = None):
"""Transfers an owned unique gift to another user.
Requires the can_transfer_and_upgrade_gifts business bot right.
Requires can_transfer_stars business bot right if the transfer is paid.
Returns True on success.
See https://core.telegram.org/bots/api#transfergift for details.
"""
return await self.api_request(
'transferGift',
parameters=locals()
)
async def postStory(self, business_connection_id: str,
content: 'InputStoryContent',
active_period: int,
caption: str = None,
parse_mode: str = None,
caption_entities: List['MessageEntity'] = None,
areas: List['StoryArea'] = None,
post_to_chat_page: bool = None,
protect_content: bool = None):
"""Posts a story on behalf of a managed business account.
Requires the can_manage_stories business bot right.
Returns Story on success.
See https://core.telegram.org/bots/api#poststory for details.
"""
return await self.api_request(
'postStory',
parameters=locals()
)
async def editStory(self, business_connection_id: str,
story_id: int,
content: 'InputStoryContent',
caption: str = None,
parse_mode: str = None,
caption_entities: List[dict] = None,
areas: List['StoryArea'] = None):
"""Edits a story previously posted by the bot on behalf of a managed
business account.
Requires the can_manage_stories business bot right.
Returns Story on success.
See https://core.telegram.org/bots/api#editstory for details.
"""
return await self.api_request(
'editStory',
parameters=locals()
)
async def deleteStory(self, business_connection_id: str, story_id: int):
"""Deletes a story previously posted by the bot on behalf of a managed
business account.
Requires the can_manage_stories business bot right.
Returns True on success.
See https://core.telegram.org/bots/api#deletestory for details.
"""
return await self.api_request(
'deleteStory',
parameters=locals()
)

View File

@@ -25,7 +25,6 @@ class TelegramApiMethod(object):
'Boolean': "bool",
'Integer': "int",
'Integer or String': "Union[int, str]",
'Array of Integer': "List[str]",
'String': "str",
}
"""Telegram bot API method."""
@@ -56,15 +55,14 @@ class TelegramApiMethod(object):
for n, paragraph in enumerate(self.description.replace('.', '.\n').split('\n')):
additional_indentation = 0
if n == 0 and paragraph.startswith(redundant_string):
paragraph = (paragraph[len(redundant_string)].upper()
+ paragraph[len(redundant_string)+1:])
paragraph = paragraph[len(redundant_string)].upper() + paragraph[len(redundant_string)+1:]
for word in paragraph.split(' '):
if len(current_line) + len(word) > 80 - indentation - additional_indentation:
additional_indentation = max(additional_indentation, 4)
result += f"{current_line.strip()}\n{' ' * additional_indentation}"
current_line = ""
current_line += f"{word} "
if len(current_line) > 0:
if len(current_line):
result += f"{current_line.strip()}\n"
current_line = ""
if n == 0:
@@ -205,7 +203,7 @@ async def print_api_methods(filename=None,
)
)
if output_file:
with open(output_file, 'w', encoding="utf-8") as file:
with open(output_file, 'w') as file:
if new_methods:
file.write(
"from typing import List, Union\n"

View File

@@ -122,47 +122,12 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
'edited_message': self.edited_message_handler,
'channel_post': self.channel_post_handler,
'edited_channel_post': self.edited_channel_post_handler,
'business_connection': self.get_update_handler(
update_type='business_connection'
),
'business_message': self.get_update_handler(
update_type='business_message'
),
'edited_business_message': self.get_update_handler(
update_type='edited_business_message'
),
'deleted_business_messages': self.get_update_handler(
update_type='deleted_business_messages'
),
'message_reaction': self.get_update_handler(
update_type='message_reaction'
),
'message_reaction_count': self.get_update_handler(
update_type='message_reaction_count'
),
'inline_query': self.inline_query_handler,
'chosen_inline_result': self.chosen_inline_result_handler,
'callback_query': self.callback_query_handler,
'shipping_query': self.shipping_query_handler,
'pre_checkout_query': self.pre_checkout_query_handler,
'purchased_paid_media': self.get_update_handler(
update_type='purchased_paid_media'
),
'poll': self.poll_handler,
'poll_answer': self.get_update_handler(
update_type='poll_answer'
),
'my_chat_member': self.get_update_handler(
update_type='my_chat_member'
),
'chat_member': self.get_update_handler( update_type='chat_member' ),
'chat_join_request': self.get_update_handler(
update_type='chat_join_request'
),
'chat_boost': self.get_update_handler( update_type='chat_boost' ),
'removed_chat_boost': self.get_update_handler(
update_type='removed_chat_boost'
),
}
# Different message update types need different handlers
self.message_handlers = {
@@ -256,8 +221,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
self.Role = None
self.packages = [sys.modules['davtelepot']]
self._documents_max_dimension = None
self._getting_me = False
self._got_me = False
# Add `users` table with its fields if missing
if 'users' not in self.db.tables:
table = self.db.create_table(
@@ -717,18 +680,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
)
return
def get_update_handler(self, update_type: str):
"""Get update handler for `update_type`."""
bot = self
async def handler(update, user_record, language=None):
"""Handle update message of type `update_type`"""
logging.info(
"The following update was received: %s\n"
"However, this `%s` handler does nothing yet.",
update, update_type
)
return handler
async def edited_channel_post_handler(self, update, user_record, language=None):
"""Handle Telegram `edited_channel_post` update."""
logging.info(
@@ -2853,7 +2804,9 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
"""
if not callable(condition):
raise TypeError(
f'Condition {condition.__name__} is not a callable'
'Condition {c} is not a callable'.format(
c=condition.__name__
)
)
def query_decorator(handler):
@@ -3194,41 +3147,26 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
Restart bots if bot can't be got.
"""
for _ in range(60):
if not self._getting_me:
break
await asyncio.sleep(0.5)
else:
raise TimeoutError("Getting bot information was in progress but "
"did not make it in 30 seconds...")
if self._got_me:
return
self._getting_me = True
try:
me = await self.getMe()
if isinstance(me, Exception):
raise me
if me is None:
raise TypeError('getMe returned None')
elif me is None:
raise Exception('getMe returned None')
self._name = me["username"]
self._telegram_id = me['id']
except Exception as e:
logging.error(
"API getMe method failed, information about this bot could "
"not be retrieved. Restarting in 5 minutes...\n\n"
"Error information:\n%s", e
f"API getMe method failed, information about this bot could "
f"not be retrieved. Restarting in 5 minutes...\n\n"
f"Error information:\n{e}"
)
self._getting_me = False
await asyncio.sleep(5*60)
if self._got_me:
return
self.__class__.stop(
message="Information about this bot could not be retrieved.\n"
"Restarting...",
final_state=65
)
self._getting_me = False
self._got_me = True
def setup(self):
"""Make bot ask for updates and handle responses."""
@@ -3243,11 +3181,9 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
async def close_sessions(self):
"""Close open sessions."""
for session_name in list(self.sessions.keys()):
session = self.sessions[session_name]
for session_name, session in self.sessions.items():
if not session.closed:
await session.close()
del self.sessions[session_name]
async def send_one_message(self, *args, **kwargs):
sent_message = await self.send_message(*args, **kwargs)

View File

@@ -51,7 +51,7 @@ setuptools.setup(
license=find_information("license", "davtelepot", "__init__.py"),
long_description=long_description,
long_description_content_type="text/markdown",
url="https://gitea.davte.it/davte/davtelepot",
url="https://gogs.davte.it/davte/davtelepot",
packages=setuptools.find_packages(),
platforms=['any'],
install_requires=[