diff --git a/.gitignore b/.gitignore index aef0b91f..dd5de4c3 100755 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ telethon/tl/functions/ telethon/tl/types/ telethon/tl/all_tlobjects.py +telethon/tl/errors/rpc_error_list.py # User session *.session diff --git a/telethon/errors/__init__.py b/telethon/errors/__init__.py index d65d426c..6e62bfb9 100644 --- a/telethon/errors/__init__.py +++ b/telethon/errors/__init__.py @@ -8,15 +8,8 @@ from .common import ( CdnFileTamperedError ) -from .rpc_errors import ( - RPCError, InvalidDCError, BadRequestError, UnauthorizedError, - ForbiddenError, NotFoundError, FloodError, ServerError, BadMessageError -) - -from .rpc_errors_303 import * -from .rpc_errors_400 import * -from .rpc_errors_401 import * -from .rpc_errors_420 import * +# This imports the base errors too, as they're imported there +from .rpc_error_list import * def report_error(code, message, report_method): @@ -43,27 +36,31 @@ def rpc_message_to_error(code, message, report_method=None): args=(code, message, report_method) ).start() - errors = { - 303: rpc_errors_303_all, - 400: rpc_errors_400_all, - 401: rpc_errors_401_all, - 420: rpc_errors_420_all - }.get(code, None) + # Try to get the error by direct look-up, otherwise regex + # TODO Maybe regexes could live in a separate dictionary? + cls = rpc_errors_all.get(message, None) + if cls: + return cls() - if errors is not None: - for msg, cls in errors.items(): - m = re.match(msg, message) - if m: - extra = int(m.group(1)) if m.groups() else None - return cls(extra=extra) + for msg_regex, cls in rpc_errors_all.items(): + m = re.match(msg_regex, message) + if m: + capture = int(m.group(1)) if m.groups() else None + return cls(capture=capture) - elif code == 403: + if code == 400: + return BadRequestError(message) + + if code == 401: + return UnauthorizedError(message) + + if code == 403: return ForbiddenError(message) - elif code == 404: + if code == 404: return NotFoundError(message) - elif code == 500: + if code == 500: return ServerError(message) return RPCError('{} (code {})'.format(message, code)) diff --git a/telethon/errors/rpc_errors.py b/telethon/errors/rpc_base_errors.py similarity index 100% rename from telethon/errors/rpc_errors.py rename to telethon/errors/rpc_base_errors.py diff --git a/telethon/errors/rpc_errors_303.py b/telethon/errors/rpc_errors_303.py deleted file mode 100644 index 21963154..00000000 --- a/telethon/errors/rpc_errors_303.py +++ /dev/null @@ -1,51 +0,0 @@ -from . import InvalidDCError - - -class FileMigrateError(InvalidDCError): - def __init__(self, **kwargs): - self.new_dc = kwargs['extra'] - super(Exception, self).__init__( - self, - 'The file to be accessed is currently stored in DC {}.' - .format(self.new_dc) - ) - - -class PhoneMigrateError(InvalidDCError): - def __init__(self, **kwargs): - self.new_dc = kwargs['extra'] - super(Exception, self).__init__( - self, - 'The phone number a user is trying to use for authorization is ' - 'associated with DC {}.' - .format(self.new_dc) - ) - - -class NetworkMigrateError(InvalidDCError): - def __init__(self, **kwargs): - self.new_dc = kwargs['extra'] - super(Exception, self).__init__( - self, - 'The source IP address is associated with DC {}.' - .format(self.new_dc) - ) - - -class UserMigrateError(InvalidDCError): - def __init__(self, **kwargs): - self.new_dc = kwargs['extra'] - super(Exception, self).__init__( - self, - 'The user whose identity is being used to execute queries is ' - 'associated with DC {}.' - .format(self.new_dc) - ) - - -rpc_errors_303_all = { - 'FILE_MIGRATE_(\d+)': FileMigrateError, - 'PHONE_MIGRATE_(\d+)': PhoneMigrateError, - 'NETWORK_MIGRATE_(\d+)': NetworkMigrateError, - 'USER_MIGRATE_(\d+)': UserMigrateError -} diff --git a/telethon/errors/rpc_errors_400.py b/telethon/errors/rpc_errors_400.py deleted file mode 100644 index 63f8dd0d..00000000 --- a/telethon/errors/rpc_errors_400.py +++ /dev/null @@ -1,453 +0,0 @@ -from . import BadRequestError - - -class ApiIdInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The api_id/api_hash combination is invalid.' - ) - - -class BotMethodInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The API access for bot users is restricted. The method you ' - 'tried to invoke cannot be executed as a bot.' - ) - - -class CdnMethodInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'This method cannot be invoked on a CDN server. Refer to ' - 'https://core.telegram.org/cdn#schema for available methods.' - ) - - -class ChannelInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Invalid channel object. Make sure to pass the right types,' - ' for instance making sure that the request is designed for ' - 'channels or otherwise look for a different one more suited.' - ) - - -class ChannelPrivateError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The channel specified is private and you lack permission to ' - 'access it. Another reason may be that you were banned from it.' - ) - - -class ChatAdminRequiredError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Chat admin privileges are required to do that in the specified ' - 'chat (for example, to send a message in a channel which is not ' - 'yours).' - ) - - -class ChatIdInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Invalid object ID for a chat. Make sure to pass the right types,' - ' for instance making sure that the request is designed for chats' - ' (not channels/megagroups) or otherwise look for a different one' - ' more suited.\nAn example working with a megagroup and' - ' AddChatUserRequest, it will fail because megagroups are channels' - '. Use InviteToChannelRequest instead.' - ) - - -class ConnectionLangPackInvalid(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The specified language pack is not valid. This is meant to be ' - 'used by official applications only so far, leave it empty.' - ) - - -class ConnectionLayerInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The very first request must always be InvokeWithLayerRequest.' - ) - - -class DcIdInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'This occurs when an authorization is tried to be exported for ' - 'the same data center one is currently connected to.' - ) - - -class FieldNameEmptyError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The field with the name FIELD_NAME is missing.' - ) - - -class FieldNameInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The field with the name FIELD_NAME is invalid.' - ) - - -class FilePartsInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The number of file parts is invalid.' - ) - - -class FilePartMissingError(BadRequestError): - def __init__(self, **kwargs): - self.which = kwargs['extra'] - super(Exception, self).__init__( - self, - 'Part {} of the file is missing from storage.'.format(self.which) - ) - - -class FilePartInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The file part number is invalid.' - ) - - -class FirstNameInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The first name is invalid.' - ) - - -class InputMethodInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The invoked method does not exist anymore or has never existed.' - ) - - -class InputRequestTooLongError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The input request was too long. This may be a bug in the library ' - 'as it can occur when serializing more bytes than it should (like' - 'appending the vector constructor code at the end of a message).' - ) - - -class LastNameInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The last name is invalid.' - ) - - -class LimitInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'An invalid limit was provided. See ' - 'https://core.telegram.org/api/files#downloading-files' - ) - - -class LocationInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The location given for a file was invalid. See ' - 'https://core.telegram.org/api/files#downloading-files' - ) - - -class Md5ChecksumInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The MD5 check-sums do not match.' - ) - - -class MessageEmptyError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Empty or invalid UTF-8 message was sent.' - ) - - -class MessageIdInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The specified message ID is invalid.' - ) - - -class MessageTooLongError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Message was too long. Current maximum length is 4096 UTF-8 ' - 'characters.' - ) - - -class MessageNotModifiedError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Content of the message was not modified.' - ) - - -class MsgWaitFailedError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'A waiting call returned an error.' - ) - - -class OffsetInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The given offset was invalid, it must be divisible by 1KB. ' - 'See https://core.telegram.org/api/files#downloading-files' - ) - - - -class PasswordHashInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The password (and thus its hash value) you entered is invalid.' - ) - - -class PeerIdInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'An invalid Peer was used. Make sure to pass the right peer type.' - ) - - -class PhoneCodeEmptyError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The phone code is missing.' - ) - - -class PhoneCodeExpiredError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The confirmation code has expired.' - ) - - -class PhoneCodeHashEmptyError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The phone code hash is missing.' - ) - - -class PhoneCodeInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The phone code entered was invalid.' - ) - - -class PhoneNumberBannedError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The used phone number has been banned from Telegram and cannot ' - 'be used anymore. Maybe check https://www.telegram.org/faq_spam.' - ) - - -class PhoneNumberInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The phone number is invalid.' - ) - - -class PhoneNumberOccupiedError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The phone number is already in use.' - ) - - -class PhoneNumberUnoccupiedError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The phone number is not yet being used.' - ) - - -class PhotoInvalidDimensionsError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The photo dimensions are invalid.' - ) - - -class TypeConstructorInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The type constructor is invalid.' - ) - - -class UsernameInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Unacceptable username. Must match r"[a-zA-Z][\w\d]{4,31}".' - ) - - -class UsernameNotModifiedError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The username is not different from the current username.' - ) - - -class UsernameNotOccupiedError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The username is not in use by anyone else yet.' - ) - - -class UsernameOccupiedError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The username is already taken.' - ) - - -class UsersTooFewError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Not enough users (to create a chat, for example).' - ) - - -class UsersTooMuchError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The maximum number of users has been exceeded (to create a ' - 'chat, for example).' - ) - - -class UserIdInvalidError(BadRequestError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Invalid object ID for an user. Make sure to pass the right types,' - 'for instance making sure that the request is designed for users' - 'or otherwise look for a different one more suited.' - ) - - -rpc_errors_400_all = { - 'API_ID_INVALID': ApiIdInvalidError, - 'BOT_METHOD_INVALID': BotMethodInvalidError, - 'CDN_METHOD_INVALID': CdnMethodInvalidError, - 'CHANNEL_INVALID': ChannelInvalidError, - 'CHANNEL_PRIVATE': ChannelPrivateError, - 'CHAT_ADMIN_REQUIRED': ChatAdminRequiredError, - 'CHAT_ID_INVALID': ChatIdInvalidError, - 'CONNECTION_LAYER_INVALID': ConnectionLayerInvalidError, - 'DC_ID_INVALID': DcIdInvalidError, - 'FIELD_NAME_EMPTY': FieldNameEmptyError, - 'FIELD_NAME_INVALID': FieldNameInvalidError, - 'FILE_PARTS_INVALID': FilePartsInvalidError, - 'FILE_PART_(\d+)_MISSING': FilePartMissingError, - 'FILE_PART_INVALID': FilePartInvalidError, - 'FIRSTNAME_INVALID': FirstNameInvalidError, - 'INPUT_METHOD_INVALID': InputMethodInvalidError, - 'INPUT_REQUEST_TOO_LONG': InputRequestTooLongError, - 'LASTNAME_INVALID': LastNameInvalidError, - 'LIMIT_INVALID': LimitInvalidError, - 'LOCATION_INVALID': LocationInvalidError, - 'MD5_CHECKSUM_INVALID': Md5ChecksumInvalidError, - 'MESSAGE_EMPTY': MessageEmptyError, - 'MESSAGE_ID_INVALID': MessageIdInvalidError, - 'MESSAGE_TOO_LONG': MessageTooLongError, - 'MESSAGE_NOT_MODIFIED': MessageNotModifiedError, - 'MSG_WAIT_FAILED': MsgWaitFailedError, - 'OFFSET_INVALID': OffsetInvalidError, - 'PASSWORD_HASH_INVALID': PasswordHashInvalidError, - 'PEER_ID_INVALID': PeerIdInvalidError, - 'PHONE_CODE_EMPTY': PhoneCodeEmptyError, - 'PHONE_CODE_EXPIRED': PhoneCodeExpiredError, - 'PHONE_CODE_HASH_EMPTY': PhoneCodeHashEmptyError, - 'PHONE_CODE_INVALID': PhoneCodeInvalidError, - 'PHONE_NUMBER_BANNED': PhoneNumberBannedError, - 'PHONE_NUMBER_INVALID': PhoneNumberInvalidError, - 'PHONE_NUMBER_OCCUPIED': PhoneNumberOccupiedError, - 'PHONE_NUMBER_UNOCCUPIED': PhoneNumberUnoccupiedError, - 'PHOTO_INVALID_DIMENSIONS': PhotoInvalidDimensionsError, - 'TYPE_CONSTRUCTOR_INVALID': TypeConstructorInvalidError, - 'USERNAME_INVALID': UsernameInvalidError, - 'USERNAME_NOT_MODIFIED': UsernameNotModifiedError, - 'USERNAME_NOT_OCCUPIED': UsernameNotOccupiedError, - 'USERNAME_OCCUPIED': UsernameOccupiedError, - 'USERS_TOO_FEW': UsersTooFewError, - 'USERS_TOO_MUCH': UsersTooMuchError, - 'USER_ID_INVALID': UserIdInvalidError, -} diff --git a/telethon/errors/rpc_errors_401.py b/telethon/errors/rpc_errors_401.py deleted file mode 100644 index 5b22cb73..00000000 --- a/telethon/errors/rpc_errors_401.py +++ /dev/null @@ -1,98 +0,0 @@ -from . import UnauthorizedError - - -class ActiveUserRequiredError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The method is only available to already activated users.' - ) - - -class AuthKeyInvalidError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The key is invalid.' - ) - - -class AuthKeyPermEmptyError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The method is unavailable for temporary authorization key, not ' - 'bound to permanent.' - ) - - -class AuthKeyUnregisteredError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The key is not registered in the system.' - ) - - -class InviteHashExpiredError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The chat the user tried to join has expired and is not valid ' - 'anymore.' - ) - - -class SessionExpiredError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The authorization has expired.' - ) - - -class SessionPasswordNeededError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'Two-steps verification is enabled and a password is required.' - ) - - -class SessionRevokedError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The authorization has been invalidated, because of the user ' - 'terminating all sessions.' - ) - - -class UserAlreadyParticipantError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The authenticated user is already a participant of the chat.' - ) - - -class UserDeactivatedError(UnauthorizedError): - def __init__(self, **kwargs): - super(Exception, self).__init__( - self, - 'The user has been deleted/deactivated.' - ) - - -rpc_errors_401_all = { - 'ACTIVE_USER_REQUIRED': ActiveUserRequiredError, - 'AUTH_KEY_INVALID': AuthKeyInvalidError, - 'AUTH_KEY_PERM_EMPTY': AuthKeyPermEmptyError, - 'AUTH_KEY_UNREGISTERED': AuthKeyUnregisteredError, - 'INVITE_HASH_EXPIRED': InviteHashExpiredError, - 'SESSION_EXPIRED': SessionExpiredError, - 'SESSION_PASSWORD_NEEDED': SessionPasswordNeededError, - 'SESSION_REVOKED': SessionRevokedError, - 'USER_ALREADY_PARTICIPANT': UserAlreadyParticipantError, - 'USER_DEACTIVATED': UserDeactivatedError, -} diff --git a/telethon/errors/rpc_errors_420.py b/telethon/errors/rpc_errors_420.py deleted file mode 100644 index 8106cc5c..00000000 --- a/telethon/errors/rpc_errors_420.py +++ /dev/null @@ -1,16 +0,0 @@ -from . import FloodError - - -class FloodWaitError(FloodError): - def __init__(self, **kwargs): - self.seconds = kwargs['extra'] - super(Exception, self).__init__( - self, - 'A wait of {} seconds is required.' - .format(self.seconds) - ) - - -rpc_errors_420_all = { - 'FLOOD_WAIT_(\d+)': FloodWaitError -} diff --git a/telethon_generator/error_descriptions b/telethon_generator/error_descriptions new file mode 100644 index 00000000..f0a14e68 --- /dev/null +++ b/telethon_generator/error_descriptions @@ -0,0 +1,65 @@ +# These are comments. Spaces around the = are optional. Empty lines ignored. +#CODE=Human readable description + +FILE_MIGRATE_X=The file to be accessed is currently stored in DC {} +PHONE_MIGRATE_X=The phone number a user is trying to use for authorization is associated with DC {} +NETWORK_MIGRATE_X=The source IP address is associated with DC {} +USER_MIGRATE_X=The user whose identity is being used to execute queries is associated with DC {} +API_ID_INVALID=The api_id/api_hash combination is invalid +BOT_METHOD_INVALID=The API access for bot users is restricted. The method you tried to invoke cannot be executed as a bot +CDN_METHOD_INVALID=This method cannot be invoked on a CDN server. Refer to https://core.telegram.org/cdn#schema for available methods +CHANNEL_INVALID=Invalid channel object. Make sure to pass the right types, for instance making sure that the request is designed for channels or otherwise look for a different one more suited +CHANNEL_PRIVATE=The channel specified is private and you lack permission to access it. Another reason may be that you were banned from it +CHAT_ADMIN_REQUIRED=Chat admin privileges are required to do that in the specified chat (for example, to send a message in a channel which is not yours) +CHAT_ID_INVALID=Invalid object ID for a chat. Make sure to pass the right types, for instance making sure that the request is designed for chats (not channels/megagroups) or otherwise look for a different one more suited\nAn example working with a megagroup and AddChatUserRequest, it will fail because megagroups are channels. Use InviteToChannelRequest instead +CONNECTION_LANG_PACK_INVALID=The specified language pack is not valid. This is meant to be used by official applications only so far, leave it empty +CONNECTION_LAYER_INVALID=The very first request must always be InvokeWithLayerRequest +DC_ID_INVALID=This occurs when an authorization is tried to be exported for the same data center one is currently connected to +FIELD_NAME_EMPTY=The field with the name FIELD_NAME is missing +FIELD_NAME_INVALID=The field with the name FIELD_NAME is invalid +FILE_PARTS_INVALID=The number of file parts is invalid +FILE_PART_X_MISSING=Part {} of the file is missing from storage +FILE_PART_INVALID=The file part number is invalid +FIRSTNAME_INVALID=The first name is invalid +INPUT_METHOD_INVALID=The invoked method does not exist anymore or has never existed +INPUT_REQUEST_TOO_LONG=The input request was too long. This may be a bug in the library as it can occur when serializing more bytes than it should (likeappending the vector constructor code at the end of a message) +LASTNAME_INVALID=The last name is invalid +LIMIT_INVALID=An invalid limit was provided. See https://core.telegram.org/api/files#downloading-files +LOCATION_INVALID=The location given for a file was invalid. See https://core.telegram.org/api/files#downloading-files +MD5_CHECKSUM_INVALID=The MD5 check-sums do not match +MESSAGE_EMPTY=Empty or invalid UTF-8 message was sent +MESSAGE_ID_INVALID=The specified message ID is invalid +MESSAGE_TOO_LONG=Message was too long. Current maximum length is 4096 UTF-8 characters +MESSAGE_NOT_MODIFIED=Content of the message was not modified +MSG_WAIT_FAILED=A waiting call returned an error +OFFSET_INVALID=The given offset was invalid, it must be divisible by 1KB. See https://core.telegram.org/api/files#downloading-files +PASSWORD_HASH_INVALID=The password (and thus its hash value) you entered is invalid +PEER_ID_INVALID=An invalid Peer was used. Make sure to pass the right peer type +PHONE_CODE_EMPTY=The phone code is missing +PHONE_CODE_EXPIRED=The confirmation code has expired +PHONE_CODE_HASH_EMPTY=The phone code hash is missing +PHONE_CODE_INVALID=The phone code entered was invalid +PHONE_NUMBER_BANNED=The used phone number has been banned from Telegram and cannot be used anymore. Maybe check https://www.telegram.org/faq_spam +PHONE_NUMBER_INVALID=The phone number is invalid +PHONE_NUMBER_OCCUPIED=The phone number is already in use +PHONE_NUMBER_UNOCCUPIED=The phone number is not yet being used +PHOTO_INVALID_DIMENSIONS=The photo dimensions are invalid +TYPE_CONSTRUCTOR_INVALID=The type constructor is invalid +USERNAME_INVALID=Unacceptable username. Must match r"[a-zA-Z][\w\d]{4,31}" +USERNAME_NOT_MODIFIED=The username is not different from the current username +USERNAME_NOT_OCCUPIED=The username is not in use by anyone else yet +USERNAME_OCCUPIED=The username is already taken +USERS_TOO_FEW=Not enough users (to create a chat, for example) +USERS_TOO_MUCH=The maximum number of users has been exceeded (to create a chat, for example) +USER_ID_INVALID=Invalid object ID for an user. Make sure to pass the right types, for instance making sure that the request is designed for users or otherwise look for a different one more suited +ACTIVE_USER_REQUIRED=The method is only available to already activated users +AUTH_KEY_INVALID=The key is invalid +AUTH_KEY_PERM_EMPTY=The method is unavailable for temporary authorization key, not bound to permanent +AUTH_KEY_UNREGISTERED=The key is not registered in the system +INVITE_HASH_EXPIRED=The chat the user tried to join has expired and is not valid anymore +SESSION_EXPIRED=The authorization has expired +SESSION_PASSWORD_NEEDED=Two-steps verification is enabled and a password is required +SESSION_REVOKED=The authorization has been invalidated, because of the user terminating all sessions +USER_ALREADY_PARTICIPANT=The authenticated user is already a participant of the chat +USER_DEACTIVATED=The user has been deleted/deactivated +FLOOD_WAIT_X=A wait of {} seconds is required diff --git a/telethon_generator/error_generator.py b/telethon_generator/error_generator.py new file mode 100644 index 00000000..fb5d0ef7 --- /dev/null +++ b/telethon_generator/error_generator.py @@ -0,0 +1,172 @@ +import json +import re +import urllib.request +from collections import defaultdict + +URL = 'https://rpc.pwrtelegram.xyz/?all' +OUTPUT = '../telethon/errors/rpc_error_list.py' +JSON_OUTPUT = 'errors.json' + +known_base_classes = { + 303: 'InvalidDCError', + 400: 'BadRequestError', + 401: 'UnauthorizedError', + 403: 'ForbiddenError', + 404: 'NotFoundError', + 420: 'FloodError', + 500: 'ServerError', +} + +# The API doesn't return the code for some (vital) errors. They are +# all assumed to be 400, except these well-known ones that aren't. +known_codes = { + 'ACTIVE_USER_REQUIRED': 401, + 'AUTH_KEY_UNREGISTERED': 401, + 'USER_DEACTIVATED': 401 +} + + +def fetch_errors(url=URL, output=JSON_OUTPUT): + print('Opening a connection to', url, '...') + r = urllib.request.urlopen(url) + print('Checking response...') + data = json.loads( + r.read().decode(r.info().get_param('charset') or 'utf-8') + ) + if data.get('ok'): + print('Response was okay, saving data') + with open(output, 'w', encoding='utf-8') as f: + json.dump(data, f) + return True + else: + print('The data received was not okay:') + print(json.dumps(data, indent=4)) + return False + + +def get_class_name(error_code): + if isinstance(error_code, int): + return known_base_classes.get( + error_code, 'RPCError' + str(error_code).replace('-', 'Neg') + ) + + if 'FIRSTNAME' in error_code: + error_code = error_code.replace('FIRSTNAME', 'FIRST_NAME') + + result = re.sub( + r'_([a-z])', lambda m: m.group(1).upper(), error_code.lower() + ) + return result[:1].upper() + result[1:].replace('_', '') + 'Error' + + +def write_error(f, code, name, desc, capture_name): + f.write( + f'\n' + f'\n' + f'class {name}({get_class_name(code)}):\n' + f' def __init__(self, **kwargs):\n' + f' ' + ) + if capture_name: + f.write( + f"self.{capture_name} = int(kwargs.get('capture', 0))\n" + f" " + ) + f.write(f'super(Exception, self).__init__(self, {repr(desc)}') + if capture_name: + f.write(f'.format(self.{capture_name})') + f.write(')\n') + + +def generate_code(json_file=JSON_OUTPUT, output=OUTPUT): + with open(json_file, encoding='utf-8') as f: + data = json.load(f) + + errors = defaultdict(set) + # PWRTelegram's API doesn't return all errors, which we do need here. + # Add some special known-cases manually first. + errors[420].add('FLOOD_WAIT_X') + errors[401].update(( + 'AUTH_KEY_INVALID', 'SESSION_EXPIRED', 'SESSION_REVOKED' + )) + errors[303].update(( + 'FILE_MIGRATE_X', 'PHONE_MIGRATE_X', + 'NETWORK_MIGRATE_X', 'USER_MIGRATE_X' + )) + for error_code, method_errors in data['result'].items(): + for error_list in method_errors.values(): + for error in error_list: + errors[int(error_code)].add(re.sub('_\d+', '_X', error).upper()) + + # Some errors are in the human result, but not with a code. Assume code 400 + for error in data['human_result']: + if error[0] != '-' and not error.isdigit(): + error = re.sub('_\d+', '_X', error).upper() + if not any(error in es for es in errors.values()): + errors[known_codes.get(error, 400)].add(error) + + # Some error codes are not known, so create custom base classes if needed + needed_base_classes = [ + (e, get_class_name(e)) for e in errors if e not in known_base_classes + ] + + # Prefer the descriptions that are related with Telethon way of coding to + # those that PWRTelegram's API provides. + telethon_descriptions = {} + with open('error_descriptions', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line and not line.startswith('#'): + equal = line.index('=') + message, description = line[:equal], line[equal + 1:] + telethon_descriptions[message.rstrip()] = description.lstrip() + + # Names for the captures, or 'x' if unknown + capture_names = { + 'FloodWaitError': 'seconds', + 'FileMigrateError': 'new_dc', + 'NetworkMigrateError': 'new_dc', + 'PhoneMigrateError': 'new_dc', + 'UserMigrateError': 'new_dc', + 'FilePartMissingError': 'which' + } + + # Everything ready, generate the code + with open(output, 'w', encoding='utf-8') as f: + f.write( + f'from .rpc_base_errors import RPCError, BadMessageError, ' + f'{", ".join(known_base_classes.values())}\n' + ) + for code, cls in needed_base_classes: + f.write( + f'\n' + f'\n' + f'class {cls}(RPCError):\n' + f' code = {code}\n' + ) + + patterns = [] # Save this dictionary later in the generated code + for error_code, error_set in errors.items(): + for error in sorted(error_set): + description = telethon_descriptions.get( + error, '\n'.join(data['human_result'].get( + error, ['No description known.'] + )) + ) + has_captures = '_X' in error + if has_captures: + name = get_class_name(error.replace('_X', '')) + pattern = error.replace('_X', r'_(\d+)') + else: + name, pattern = get_class_name(error), error + + patterns.append((pattern, name)) + capture = capture_names.get(name, 'x') if has_captures else None + # TODO Some errors have the same name but different code, + # split this accross different files? + write_error(f, error_code, name, description, capture) + + f.write('\n\nrpc_errors_all = {\n') + for pattern, name in patterns: + f.write(f' {repr(pattern)}: {name},\n') + f.write('}\n') diff --git a/telethon_generator/errors.json b/telethon_generator/errors.json new file mode 100644 index 00000000..e807ff2d --- /dev/null +++ b/telethon_generator/errors.json @@ -0,0 +1 @@ +{"ok": true, "result": {"400": {"account.updateProfile": ["ABOUT_TOO_LONG", "FIRSTNAME_INVALID"], "auth.importBotAuthorization": ["ACCESS_TOKEN_EXPIRED", "ACCESS_TOKEN_INVALID", "API_ID_INVALID"], "auth.sendCode": ["API_ID_INVALID", "INPUT_REQUEST_TOO_LONG", "PHONE_NUMBER_APP_SIGNUP_FORBIDDEN", "PHONE_NUMBER_BANNED", "PHONE_NUMBER_FLOOD", "PHONE_NUMBER_INVALID", "PHONE_PASSWORD_PROTECTED"], "messages.setInlineBotResults": ["ARTICLE_TITLE_EMPTY", "BUTTON_DATA_INVALID", "BUTTON_TYPE_INVALID", "BUTTON_URL_INVALID", "MESSAGE_EMPTY", "QUERY_ID_INVALID", "REPLY_MARKUP_INVALID", "RESULT_TYPE_INVALID", "SEND_MESSAGE_TYPE_INVALID", "START_PARAM_INVALID"], "auth.importAuthorization": ["AUTH_BYTES_INVALID", "USER_ID_INVALID"], "invokeWithLayer": ["AUTH_BYTES_INVALID", "CDN_METHOD_INVALID", "CONNECTION_API_ID_INVALID", "CONNECTION_LANG_PACK_INVALID", "INPUT_LAYER_INVALID"], "channels.inviteToChannel": ["BOT_GROUPS_BLOCKED", "BOTS_TOO_MUCH", "CHANNEL_INVALID", "CHANNEL_PRIVATE", "CHAT_ADMIN_REQUIRED", "INPUT_USER_DEACTIVATED", "USER_BANNED_IN_CHANNEL", "USER_BLOCKED", "USER_BOT", "USER_ID_INVALID", "USER_KICKED", "USER_NOT_MUTUAL_CONTACT", "USERS_TOO_MUCH"], "messages.getInlineBotResults": ["BOT_INLINE_DISABLED", "BOT_INVALID"], "messages.startBot": ["BOT_INVALID", "PEER_ID_INVALID", "START_PARAM_EMPTY", "START_PARAM_INVALID"], "messages.uploadMedia": ["BOT_MISSING", "PEER_ID_INVALID"], "stickers.addStickerToSet": ["BOT_MISSING", "STICKERSET_INVALID"], "stickers.changeStickerPosition": ["BOT_MISSING", "STICKER_INVALID"], "stickers.createStickerSet": ["BOT_MISSING", "PACK_SHORT_NAME_INVALID", "PEER_ID_INVALID", "STICKERS_EMPTY", "USER_ID_INVALID"], "stickers.removeStickerFromSet": ["BOT_MISSING", "STICKER_INVALID"], "messages.sendMessage": ["BUTTON_DATA_INVALID", "BUTTON_TYPE_INVALID", "BUTTON_URL_INVALID", "CHANNEL_INVALID", "CHANNEL_PRIVATE", "CHAT_ADMIN_REQUIRED", "CHAT_ID_INVALID", "ENTITY_MENTION_USER_INVALID", "INPUT_USER_DEACTIVATED", "MESSAGE_EMPTY", "MESSAGE_TOO_LONG", "PEER_ID_INVALID", "REPLY_MARKUP_INVALID", "USER_BANNED_IN_CHANNEL", "USER_IS_BLOCKED", "USER_IS_BOT", "YOU_BLOCKED_USER"], "phone.acceptCall": ["CALL_ALREADY_ACCEPTED", "CALL_ALREADY_DECLINED", "CALL_PEER_INVALID", "CALL_PROTOCOL_FLAGS_INVALID"], "phone.discardCall": ["CALL_ALREADY_ACCEPTED", "CALL_PEER_INVALID"], "phone.confirmCall": ["CALL_ALREADY_DECLINED", "CALL_PEER_INVALID"], "phone.receivedCall": ["CALL_ALREADY_DECLINED", "CALL_PEER_INVALID"], "phone.saveCallDebug": ["CALL_PEER_INVALID", "DATA_JSON_INVALID"], "phone.setCallRating": ["CALL_PEER_INVALID"], "phone.requestCall": ["CALL_PROTOCOL_FLAGS_INVALID", "PARTICIPANT_VERSION_OUTDATED", "USER_ID_INVALID"], "updates.getDifference": ["CDN_METHOD_INVALID", "DATE_EMPTY", "PERSISTENT_TIMESTAMP_EMPTY", "PERSISTENT_TIMESTAMP_INVALID"], "upload.getCdnFileHashes": ["CDN_METHOD_INVALID", "RSA_DECRYPT_FAILED"], "channels.checkUsername": ["CHANNEL_INVALID", "CHAT_ID_INVALID", "USERNAME_INVALID"], "channels.deleteChannel": ["CHANNEL_INVALID", "CHANNEL_PRIVATE"], "channels.deleteMessages": ["CHANNEL_INVALID", "CHANNEL_PRIVATE"], "channels.deleteUserHistory": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED"], "channels.editAbout": ["CHANNEL_INVALID", "CHAT_ABOUT_NOT_MODIFIED", "CHAT_ABOUT_TOO_LONG", "CHAT_ADMIN_REQUIRED"], "channels.editAdmin": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED", "USER_CREATOR", "USER_ID_INVALID", "USER_NOT_MUTUAL_CONTACT"], "channels.editBanned": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "CHAT_ADMIN_REQUIRED", "USER_ADMIN_INVALID", "USER_ID_INVALID"], "channels.editPhoto": ["CHANNEL_INVALID"], "channels.editTitle": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED", "CHAT_NOT_MODIFIED"], "channels.exportInvite": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED", "INVITE_HASH_EXPIRED"], "channels.exportMessageLink": ["CHANNEL_INVALID"], "channels.getAdminLog": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED"], "channels.getChannels": ["CHANNEL_INVALID", "CHANNEL_PRIVATE"], "channels.getFullChannel": ["CHANNEL_INVALID", "CHANNEL_PRIVATE"], "channels.getMessages": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "MESSAGE_IDS_EMPTY"], "channels.getParticipant": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED", "USER_ID_INVALID", "USER_NOT_PARTICIPANT"], "channels.getParticipants": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "CHAT_ADMIN_REQUIRED", "INPUT_CONSTRUCTOR_INVALID"], "channels.joinChannel": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "CHANNELS_TOO_MUCH"], "channels.leaveChannel": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "USER_CREATOR", "USER_NOT_PARTICIPANT"], "channels.readHistory": ["CHANNEL_INVALID", "CHANNEL_PRIVATE"], "channels.readMessageContents": ["CHANNEL_INVALID", "CHANNEL_PRIVATE"], "channels.reportSpam": ["CHANNEL_INVALID"], "channels.setStickers": ["CHANNEL_INVALID", "PARTICIPANTS_TOO_FEW"], "channels.toggleInvites": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED"], "channels.toggleSignatures": ["CHANNEL_INVALID"], "channels.updatePinnedMessage": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED", "CHAT_NOT_MODIFIED"], "channels.updateUsername": ["CHANNEL_INVALID", "CHAT_ADMIN_REQUIRED", "USERNAME_INVALID", "USERNAME_OCCUPIED"], "messages.editMessage": ["CHANNEL_INVALID", "MESSAGE_EDIT_TIME_EXPIRED", "MESSAGE_EMPTY", "MESSAGE_ID_INVALID", "MESSAGE_NOT_MODIFIED", "PEER_ID_INVALID"], "messages.forwardMessages": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "CHAT_ADMIN_REQUIRED", "CHAT_ID_INVALID", "MEDIA_EMPTY", "MESSAGE_ID_INVALID", "MESSAGE_IDS_EMPTY", "PEER_ID_INVALID", "RANDOM_ID_INVALID", "USER_BANNED_IN_CHANNEL", "USER_IS_BLOCKED", "USER_IS_BOT", "YOU_BLOCKED_USER"], "messages.getHistory": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "CHAT_ID_INVALID", "PEER_ID_INVALID"], "messages.getPeerSettings": ["CHANNEL_INVALID", "PEER_ID_INVALID"], "messages.sendMedia": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "FILE_PART_0_MISSING", "FILE_PART_LENGTH_INVALID", "FILE_PARTS_INVALID", "INPUT_USER_DEACTIVATED", "MEDIA_CAPTION_TOO_LONG", "MEDIA_EMPTY", "PEER_ID_INVALID", "PHOTO_EXT_INVALID", "USER_IS_BLOCKED", "USER_IS_BOT", "WEBPAGE_CURL_FAILED", "WEBPAGE_MEDIA_EMPTY"], "messages.setTyping": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "CHAT_ID_INVALID", "PEER_ID_INVALID"], "updates.getChannelDifference": ["CHANNEL_INVALID", "CHANNEL_PRIVATE", "PERSISTENT_TIMESTAMP_EMPTY", "PERSISTENT_TIMESTAMP_INVALID", "RANGES_INVALID"], "messages.getMessagesViews": ["CHANNEL_PRIVATE", "CHAT_ID_INVALID", "PEER_ID_INVALID"], "messages.getPeerDialogs": ["CHANNEL_PRIVATE", "PEER_ID_INVALID"], "messages.addChatUser": ["CHAT_ADMIN_REQUIRED", "CHAT_ID_INVALID", "PEER_ID_INVALID", "USER_ALREADY_PARTICIPANT", "USER_ID_INVALID", "USERS_TOO_MUCH"], "messages.discardEncryption": ["CHAT_ID_EMPTY", "ENCRYPTION_ALREADY_DECLINED", "ENCRYPTION_ID_INVALID"], "messages.acceptEncryption": ["CHAT_ID_INVALID", "ENCRYPTION_ALREADY_ACCEPTED", "ENCRYPTION_ALREADY_DECLINED"], "messages.deleteChatUser": ["CHAT_ID_INVALID", "PEER_ID_INVALID", "USER_NOT_PARTICIPANT"], "messages.editChatAdmin": ["CHAT_ID_INVALID"], "messages.editChatPhoto": ["CHAT_ID_INVALID", "PEER_ID_INVALID"], "messages.editChatTitle": ["CHAT_ID_INVALID"], "messages.exportChatInvite": ["CHAT_ID_INVALID"], "messages.forwardMessage": ["CHAT_ID_INVALID", "MESSAGE_ID_INVALID", "PEER_ID_INVALID", "YOU_BLOCKED_USER"], "messages.getChats": ["CHAT_ID_INVALID", "PEER_ID_INVALID"], "messages.getFullChat": ["CHAT_ID_INVALID", "PEER_ID_INVALID"], "messages.migrateChat": ["CHAT_ID_INVALID", "PEER_ID_INVALID"], "messages.reportEncryptedSpam": ["CHAT_ID_INVALID"], "messages.sendEncrypted": ["CHAT_ID_INVALID", "DATA_INVALID", "MSG_WAIT_FAILED"], "messages.setEncryptedTyping": ["CHAT_ID_INVALID"], "messages.toggleChatAdmins": ["CHAT_ID_INVALID", "CHAT_NOT_MODIFIED"], "channels.createChannel": ["CHAT_TITLE_EMPTY"], "auth.recoverPassword": ["CODE_EMPTY"], "account.confirmPhone": ["CODE_HASH_INVALID", "PHONE_CODE_EMPTY"], "initConnection": ["CONNECTION_LAYER_INVALID", "INPUT_FETCH_FAIL"], "contacts.block": ["CONTACT_ID_INVALID"], "contacts.deleteContact": ["CONTACT_ID_INVALID"], "contacts.unblock": ["CONTACT_ID_INVALID"], "messages.getBotCallbackAnswer": ["DATA_INVALID", "MESSAGE_ID_INVALID", "PEER_ID_INVALID"], "messages.sendEncryptedService": ["DATA_INVALID", "MSG_WAIT_FAILED"], "auth.exportAuthorization": ["DC_ID_INVALID"], "messages.requestEncryption": ["DH_G_A_INVALID", "USER_ID_INVALID"], "auth.bindTempAuthKey": ["ENCRYPTED_MESSAGE_INVALID", "INPUT_REQUEST_TOO_LONG", "TEMP_AUTH_KEY_EMPTY"], "messages.setBotPrecheckoutResults": ["ERROR_TEXT_EMPTY"], "contacts.importCard": ["EXPORT_CARD_INVALID"], "upload.getFile": ["FILE_ID_INVALID", "LIMIT_INVALID", "LOCATION_INVALID", "OFFSET_INVALID"], "photos.uploadProfilePhoto": ["FILE_PART_0_MISSING", "FILE_PARTS_INVALID", "IMAGE_PROCESS_FAILED", "PHOTO_CROP_SIZE_SMALL", "PHOTO_EXT_INVALID"], "upload.saveBigFilePart": ["FILE_PART_EMPTY", "FILE_PART_INVALID", "FILE_PART_SIZE_INVALID", "FILE_PARTS_INVALID"], "upload.saveFilePart": ["FILE_PART_EMPTY", "FILE_PART_INVALID"], "auth.signUp": ["FIRSTNAME_INVALID", "PHONE_CODE_EMPTY", "PHONE_CODE_EXPIRED", "PHONE_CODE_INVALID", "PHONE_NUMBER_FLOOD", "PHONE_NUMBER_INVALID", "PHONE_NUMBER_OCCUPIED"], "messages.saveGif": ["GIF_ID_INVALID"], "account.resetAuthorization": ["HASH_INVALID"], "account.sendConfirmPhoneCode": ["HASH_INVALID"], "messages.sendInlineBotResult": ["INLINE_RESULT_EXPIRED", "PEER_ID_INVALID", "QUERY_ID_EMPTY"], "messages.getDialogs": ["INPUT_CONSTRUCTOR_INVALID", "OFFSET_PEER_ID_INVALID"], "messages.search": ["INPUT_CONSTRUCTOR_INVALID", "INPUT_USER_DEACTIVATED", "PEER_ID_INVALID", "PEER_ID_NOT_SUPPORTED", "SEARCH_QUERY_EMPTY", "USER_ID_INVALID"], "messages.checkChatInvite": ["INVITE_HASH_EMPTY", "INVITE_HASH_EXPIRED", "INVITE_HASH_INVALID"], "messages.importChatInvite": ["INVITE_HASH_EMPTY", "INVITE_HASH_EXPIRED", "INVITE_HASH_INVALID", "USER_ALREADY_PARTICIPANT", "USERS_TOO_MUCH"], "{}": ["INVITE_HASH_EXPIRED"], "langpack.getDifference": ["LANG_PACK_INVALID"], "langpack.getLangPack": ["LANG_PACK_INVALID"], "langpack.getLanguages": ["LANG_PACK_INVALID"], "langpack.getStrings": ["LANG_PACK_INVALID"], "upload.getWebFile": ["LOCATION_INVALID"], "photos.getUserPhotos": ["MAX_ID_INVALID", "USER_ID_INVALID"], "auth.sendInvites": ["MESSAGE_EMPTY"], "messages.editInlineBotMessage": ["MESSAGE_ID_INVALID", "MESSAGE_NOT_MODIFIED"], "messages.getInlineGameHighScores": ["MESSAGE_ID_INVALID", "USER_BOT_REQUIRED"], "messages.setInlineGameScore": ["MESSAGE_ID_INVALID", "USER_BOT_REQUIRED"], "payments.getPaymentForm": ["MESSAGE_ID_INVALID"], "payments.getPaymentReceipt": ["MESSAGE_ID_INVALID"], "payments.sendPaymentForm": ["MESSAGE_ID_INVALID"], "payments.validateRequestedInfo": ["MESSAGE_ID_INVALID"], "messages.readEncryptedHistory": ["MSG_WAIT_FAILED"], "messages.receivedQueue": ["MSG_WAIT_FAILED"], "messages.sendEncryptedFile": ["MSG_WAIT_FAILED"], "account.updatePasswordSettings": ["NEW_SALT_INVALID", "NEW_SETTINGS_INVALID", "PASSWORD_HASH_INVALID"], "auth.requestPasswordRecovery": ["PASSWORD_EMPTY"], "account.getPasswordSettings": ["PASSWORD_HASH_INVALID"], "account.getTmpPassword": ["PASSWORD_HASH_INVALID", "TMP_PASSWORD_DISABLED"], "auth.checkPassword": ["PASSWORD_HASH_INVALID"], "account.getNotifySettings": ["PEER_ID_INVALID"], "account.reportPeer": ["PEER_ID_INVALID"], "account.updateNotifySettings": ["PEER_ID_INVALID"], "contacts.resetTopPeerRating": ["PEER_ID_INVALID"], "messages.deleteHistory": ["PEER_ID_INVALID"], "messages.getGameHighScores": ["PEER_ID_INVALID", "USER_BOT_REQUIRED"], "messages.getMessageEditData": ["PEER_ID_INVALID"], "messages.getUnreadMentions": ["PEER_ID_INVALID"], "messages.hideReportSpam": ["PEER_ID_INVALID"], "messages.readHistory": ["PEER_ID_INVALID"], "messages.reorderPinnedDialogs": ["PEER_ID_INVALID"], "messages.reportSpam": ["PEER_ID_INVALID"], "messages.saveDraft": ["PEER_ID_INVALID"], "messages.sendScreenshotNotification": ["PEER_ID_INVALID"], "messages.setGameScore": ["PEER_ID_INVALID", "USER_BOT_REQUIRED"], "messages.toggleDialogPin": ["PEER_ID_INVALID"], "auth.signIn": ["PHONE_CODE_EMPTY", "PHONE_CODE_EXPIRED", "PHONE_CODE_INVALID", "PHONE_NUMBER_INVALID", "PHONE_NUMBER_UNOCCUPIED"], "auth.checkPhone": ["PHONE_NUMBER_BANNED", "PHONE_NUMBER_INVALID"], "account.changePhone": ["PHONE_NUMBER_INVALID"], "account.sendChangePhoneCode": ["PHONE_NUMBER_INVALID"], "auth.cancelCode": ["PHONE_NUMBER_INVALID"], "auth.resendCode": ["PHONE_NUMBER_INVALID"], "account.getPrivacy": ["PRIVACY_KEY_INVALID"], "account.setPrivacy": ["PRIVACY_KEY_INVALID"], "bots.answerWebhookJSONQuery": ["QUERY_ID_INVALID", "USER_BOT_INVALID"], "messages.setBotCallbackAnswer": ["QUERY_ID_INVALID"], "messages.setBotShippingResults": ["QUERY_ID_INVALID"], "contacts.search": ["QUERY_TOO_SHORT", "SEARCH_QUERY_EMPTY"], "messages.getDhConfig": ["RANDOM_LENGTH_INVALID"], "upload.reuploadCdnFile": ["RSA_DECRYPT_FAILED"], "messages.searchGifs": ["SEARCH_QUERY_EMPTY"], "messages.searchGlobal": ["SEARCH_QUERY_EMPTY"], "messages.getDocumentByHash": ["SHA256_HASH_INVALID"], "messages.faveSticker": ["STICKER_ID_INVALID"], "messages.saveRecentSticker": ["STICKER_ID_INVALID"], "messages.getStickerSet": ["STICKERSET_INVALID"], "messages.installStickerSet": ["STICKERSET_INVALID"], "messages.uninstallStickerSet": ["STICKERSET_INVALID"], "account.registerDevice": ["TOKEN_INVALID"], "account.unregisterDevice": ["TOKEN_INVALID"], "account.setAccountTTL": ["TTL_DAYS_INVALID"], "contacts.getTopPeers": ["TYPES_EMPTY"], "bots.sendCustomRequest": ["USER_BOT_INVALID"], "messages.getCommonChats": ["USER_ID_INVALID"], "users.getFullUser": ["USER_ID_INVALID"], "account.checkUsername": ["USERNAME_INVALID"], "account.updateUsername": ["USERNAME_INVALID", "USERNAME_NOT_MODIFIED", "USERNAME_OCCUPIED"], "contacts.resolveUsername": ["USERNAME_INVALID", "USERNAME_NOT_OCCUPIED"], "messages.createChat": ["USERS_TOO_FEW"]}, "401": {"contacts.resolveUsername": ["AUTH_KEY_PERM_EMPTY", "SESSION_PASSWORD_NEEDED"], "messages.getHistory": ["AUTH_KEY_PERM_EMPTY"], "auth.signIn": ["SESSION_PASSWORD_NEEDED"], "messages.getDialogs": ["SESSION_PASSWORD_NEEDED"], "updates.getDifference": ["SESSION_PASSWORD_NEEDED"], "updates.getState": ["SESSION_PASSWORD_NEEDED"], "upload.saveFilePart": ["SESSION_PASSWORD_NEEDED"], "users.getUsers": ["SESSION_PASSWORD_NEEDED"]}, "500": {"auth.sendCode": ["AUTH_RESTART"], "phone.acceptCall": ["CALL_OCCUPY_FAILED"], "messages.acceptEncryption": ["ENCRYPTION_OCCUPY_FAILED"], "updates.getChannelDifference": ["HISTORY_GET_FAILED", "PERSISTENT_TIMESTAMP_OUTDATED"], "users.getUsers": ["MEMBER_NO_LOCATION", "NEED_MEMBER_INVALID"], "auth.signUp": ["MEMBER_OCCUPY_PRIMARY_LOC_FAILED", "REG_ID_GENERATE_FAILED"], "channels.getChannels": ["NEED_CHAT_INVALID"], "messages.editChatTitle": ["NEED_CHAT_INVALID"], "contacts.deleteContacts": ["NEED_MEMBER_INVALID"], "contacts.importCard": ["NEED_MEMBER_INVALID"], "updates.getDifference": ["NEED_MEMBER_INVALID"], "phone.requestCall": ["PARTICIPANT_CALL_FAILED"], "messages.forwardMessages": ["PTS_CHANGE_EMPTY", "RANDOM_ID_DUPLICATE"], "messages.sendMessage": ["RANDOM_ID_DUPLICATE"], "messages.sendMedia": ["STORAGE_CHECK_FAILED"], "upload.getCdnFile": ["UNKNOWN_METHOD"]}, "403": {"channels.getFullChannel": ["CHANNEL_PUBLIC_GROUP_NA"], "updates.getChannelDifference": ["CHANNEL_PUBLIC_GROUP_NA"], "channels.editAdmin": ["CHAT_ADMIN_INVITE_REQUIRED", "RIGHT_FORBIDDEN", "USER_PRIVACY_RESTRICTED"], "messages.migrateChat": ["CHAT_ADMIN_REQUIRED"], "messages.forwardMessages": ["CHAT_SEND_GIFS_FORBIDDEN", "CHAT_SEND_MEDIA_FORBIDDEN", "CHAT_SEND_STICKERS_FORBIDDEN", "CHAT_WRITE_FORBIDDEN"], "channels.inviteToChannel": ["CHAT_WRITE_FORBIDDEN", "USER_CHANNELS_TOO_MUCH", "USER_PRIVACY_RESTRICTED"], "messages.editMessage": ["CHAT_WRITE_FORBIDDEN", "MESSAGE_AUTHOR_REQUIRED"], "messages.sendMedia": ["CHAT_WRITE_FORBIDDEN"], "messages.sendMessage": ["CHAT_WRITE_FORBIDDEN"], "messages.setTyping": ["CHAT_WRITE_FORBIDDEN"], "messages.getMessageEditData": ["MESSAGE_AUTHOR_REQUIRED"], "channels.deleteMessages": ["MESSAGE_DELETE_FORBIDDEN"], "messages.deleteMessages": ["MESSAGE_DELETE_FORBIDDEN"], "messages.setInlineBotResults": ["USER_BOT_INVALID"], "phone.requestCall": ["USER_IS_BLOCKED", "USER_PRIVACY_RESTRICTED"], "messages.addChatUser": ["USER_NOT_MUTUAL_CONTACT", "USER_PRIVACY_RESTRICTED"], "channels.createChannel": ["USER_RESTRICTED"], "messages.createChat": ["USER_RESTRICTED"]}, "406": {"auth.checkPhone": ["PHONE_NUMBER_INVALID"], "auth.sendCode": ["PHONE_PASSWORD_FLOOD"]}, "-503": {"auth.resetAuthorizations": ["Timeout"], "contacts.deleteContacts": ["Timeout"], "messages.forwardMessages": ["Timeout"], "messages.getBotCallbackAnswer": ["Timeout"], "messages.getHistory": ["Timeout"], "messages.getInlineBotResults": ["Timeout"], "updates.getState": ["Timeout"]}}, "human_result": {"-429": ["Too many requests"], "ABOUT_TOO_LONG": ["The provided bio is too long"], "ACCESS_TOKEN_EXPIRED": ["Bot token expired"], "ACCESS_TOKEN_INVALID": ["The provided token is not valid"], "ACTIVE_USER_REQUIRED": ["The method is only available to already activated users"], "API_ID_INVALID": ["The api_id/api_hash combination is invalid"], "ARTICLE_TITLE_EMPTY": ["The title of the article is empty"], "AUTH_BYTES_INVALID": ["The provided authorization is invalid"], "AUTH_KEY_PERM_EMPTY": ["The temporary auth key must be binded to the permanent auth key to use these methods."], "AUTH_KEY_UNREGISTERED": ["The authorization key has expired"], "AUTH_RESTART": ["Restart the authorization process"], "BOT_GROUPS_BLOCKED": ["This bot can't be added to groups"], "BOT_INLINE_DISABLED": ["This bot can't be used in inline mode"], "BOT_INVALID": ["This is not a valid bot"], "BOT_METHOD_INVALID": ["This method cannot be run by a bot"], "BOT_MISSING": ["This method can only be run by a bot"], "BOTS_TOO_MUCH": ["There are too many bots in this chat/channel"], "BUTTON_DATA_INVALID": ["The provided button data is invalid"], "BUTTON_TYPE_INVALID": ["The type of one of the buttons you provided is invalid"], "BUTTON_URL_INVALID": ["Button URL invalid"], "CALL_ALREADY_ACCEPTED": ["The call was already accepted"], "CALL_ALREADY_DECLINED": ["The call was already declined"], "CALL_OCCUPY_FAILED": ["The call failed because the user is already making another call"], "CALL_PEER_INVALID": ["The provided call peer object is invalid"], "CALL_PROTOCOL_FLAGS_INVALID": ["Call protocol flags invalid"], "CDN_METHOD_INVALID": ["You can't call this method in a CDN DC"], "CHANNEL_INVALID": ["The provided channel is invalid"], "CHANNEL_PRIVATE": ["You haven't joined this channel/supergroup"], "CHANNEL_PUBLIC_GROUP_NA": ["channel/supergroup not available"], "CHANNELS_TOO_MUCH": ["You have joined too many channels/supergroups"], "CHAT_ABOUT_NOT_MODIFIED": ["About text has not changed"], "CHAT_ADMIN_INVITE_REQUIRED": ["You do not have the rights to do this"], "CHAT_ADMIN_REQUIRED": ["You must be an admin in this chat to do this"], "CHAT_FORBIDDEN": ["You cannot write in this chat"], "CHAT_ID_EMPTY": ["The provided chat ID is empty"], "CHAT_ID_INVALID": ["The provided chat id is invalid"], "CHAT_NOT_MODIFIED": ["The pinned message wasn't modified"], "CHAT_SEND_GIFS_FORBIDDEN": ["You can't send gifs in this chat"], "CHAT_SEND_MEDIA_FORBIDDEN": ["You can't send media in this chat"], "CHAT_SEND_STICKERS_FORBIDDEN": ["You can't send stickers in this chat."], "CHAT_TITLE_EMPTY": ["No chat title provided"], "CHAT_WRITE_FORBIDDEN": ["You can't write in this chat"], "CODE_EMPTY": ["The provided code is empty"], "CODE_HASH_INVALID": ["Code hash invalid"], "CONNECTION_API_ID_INVALID": ["The provided API id is invalid"], "CONNECTION_LANG_PACK_INVALID": ["Language pack invalid"], "CONNECTION_LAYER_INVALID": ["Layer invalid"], "CONTACT_ID_INVALID": ["The provided contact ID is invalid"], "DATA_INVALID": ["Encrypted data invalid"], "DATA_JSON_INVALID": ["The provided JSON data is invalid"], "DATE_EMPTY": ["Date empty"], "DC_ID_INVALID": ["The provided DC ID is invalid"], "DH_G_A_INVALID": ["g_a invalid"], "ENCRYPTED_MESSAGE_INVALID": ["Encrypted message invalid"], "ENCRYPTION_ALREADY_ACCEPTED": ["Secret chat already accepted"], "ENCRYPTION_ALREADY_DECLINED": ["The secret chat was already declined"], "ENCRYPTION_ID_INVALID": ["The provided secret chat ID is invalid"], "ENCRYPTION_OCCUPY_FAILED": ["Internal server error while accepting secret chat"], "ENTITY_MENTION_USER_INVALID": ["You can't use this entity"], "ERROR_TEXT_EMPTY": ["The provided error message is empty"], "EXPORT_CARD_INVALID": ["Provided card is invalid"], "FIELD_NAME_EMPTY": ["The field with the name FIELD_NAME is missing"], "FIELD_NAME_INVALID": ["The field with the name FIELD_NAME is invalid"], "FILE_ID_INVALID": ["The provided file id is invalid"], "FILE_PART_0_MISSING": ["File part 0 missing"], "FILE_PART_EMPTY": ["The provided file part is empty"], "FILE_PART_INVALID": ["The file part number is invalid"], "FILE_PART_LENGTH_INVALID": ["The length of a file part is invalid"], "FILE_PART_SIZE_INVALID": ["The provided file part size is invalid"], "FILE_PARTS_INVALID": ["The number of file parts is invalid"], "FIRSTNAME_INVALID": ["The first name is invalid"], "FLOOD_WAIT_666": ["Spooky af m8"], "GIF_ID_INVALID": ["The provided GIF ID is invalid"], "HASH_INVALID": ["The provided hash is invalid"], "HISTORY_GET_FAILED": ["Fetching of history failed"], "IMAGE_PROCESS_FAILED": ["Failure while processing image"], "INLINE_RESULT_EXPIRED": ["The inline query expired"], "INPUT_CONSTRUCTOR_INVALID": ["The provided constructor is invalid"], "INPUT_FETCH_ERROR": ["An error occurred while deserializing TL parameters"], "INPUT_FETCH_FAIL": ["Failed deserializing TL payload"], "INPUT_LAYER_INVALID": ["The provided layer is invalid"], "INPUT_METHOD_INVALID": ["The provided method is invalid"], "INPUT_REQUEST_TOO_LONG": ["The request is too big"], "INPUT_USER_DEACTIVATED": ["The specified user was deleted"], "INTERDC_1_CALL_ERROR": ["An error occurred while communicating with DC 1"], "INTERDC_1_CALL_RICH_ERROR": ["A rich error occurred while communicating with DC 1"], "INTERDC_2_CALL_ERROR": ["An error occurred while communicating with DC 2"], "INTERDC_2_CALL_RICH_ERROR": ["A rich error occurred while communicating with DC 2"], "INTERDC_3_CALL_ERROR": ["An error occurred while communicating with DC 3"], "INTERDC_3_CALL_RICH_ERROR": ["A rich error occurred while communicating with DC 3"], "INTERDC_4_CALL_ERROR": ["An error occurred while communicating with DC 4"], "INTERDC_4_CALL_RICH_ERROR": ["A rich error occurred while communicating with DC 4"], "INTERDC_5_CALL_ERROR": ["An error occurred while communicating with DC 5"], "INTERDC_5_CALL_RICH_ERROR": ["A rich error occurred while communicating with DC 5"], "INVITE_HASH_EMPTY": ["The invite hash is empty"], "INVITE_HASH_EXPIRED": ["The invite link has expired"], "INVITE_HASH_INVALID": ["The invite hash is invalid"], "LANG_PACK_INVALID": ["The provided language pack is invalid"], "LASTNAME_INVALID": ["The last name is invalid"], "LIMIT_INVALID": ["The provided limit is invalid"], "LOCATION_INVALID": ["The provided location is invalid"], "MAX_ID_INVALID": ["The provided max ID is invalid"], "MD5_CHECKSUM_INVALID": ["The MD5 checksums do not match"], "MEDIA_CAPTION_TOO_LONG": ["The caption is too long"], "MEDIA_EMPTY": ["The provided media object is invalid"], "MEMBER_OCCUPY_PRIMARY_LOC_FAILED": ["Occupation of primary member location failed"], "MESSAGE_AUTHOR_REQUIRED": ["Message author required"], "MESSAGE_DELETE_FORBIDDEN": ["You can't delete one of the messages you tried to delete, most likely because it is a service message."], "MESSAGE_EDIT_TIME_EXPIRED": ["You can't edit this message anymore, too much time has passed since its creation."], "MESSAGE_EMPTY": ["The provided message is empty"], "MESSAGE_ID_INVALID": ["The provided message id is invalid"], "MESSAGE_IDS_EMPTY": ["No message ids were provided"], "MESSAGE_NOT_MODIFIED": ["The message text has not changed"], "MESSAGE_TOO_LONG": ["The provided message is too long"], "MSG_WAIT_FAILED": ["A waiting call returned an error"], "NEED_CHAT_INVALID": ["The provided chat is invalid"], "NEED_MEMBER_INVALID": ["The provided member is invalid"], "NEW_SALT_INVALID": ["The new salt is invalid"], "NEW_SETTINGS_INVALID": ["The new settings are invalid"], "OFFSET_INVALID": ["The provided offset is invalid"], "OFFSET_PEER_ID_INVALID": ["The provided offset peer is invalid"], "PACK_SHORT_NAME_INVALID": ["Short pack name invalid"], "PARTICIPANT_CALL_FAILED": ["Failure while making call"], "PARTICIPANT_VERSION_OUTDATED": ["The other participant does not use an up to date telegram client with support for calls"], "PARTICIPANTS_TOO_FEW": ["Not enough participants"], "PASSWORD_EMPTY": ["The provided password is empty"], "PASSWORD_HASH_INVALID": ["The provided password hash is invalid"], "PEER_FLOOD": ["Too many requests"], "PEER_ID_INVALID": ["The provided peer id is invalid"], "PEER_ID_NOT_SUPPORTED": ["The provided peer ID is not supported"], "PERSISTENT_TIMESTAMP_EMPTY": ["Persistent timestamp empty"], "PERSISTENT_TIMESTAMP_INVALID": ["Persistent timestamp invalid"], "PERSISTENT_TIMESTAMP_OUTDATED": ["Persistent timestamp outdated"], "PHONE_CODE_EMPTY": ["phone_code is missing"], "PHONE_CODE_EXPIRED": ["The phone code you provided has expired, this may happen if it was sent to any chat on telegram (if the code is sent through a telegram chat (not the official account) to avoid it append or prepend to the code some chars)"], "PHONE_CODE_HASH_EMPTY": ["phone_code_hash is missing"], "PHONE_CODE_INVALID": ["The provided phone code is invalid"], "PHONE_NUMBER_APP_SIGNUP_FORBIDDEN": [""], "PHONE_NUMBER_BANNED": ["The provided phone number is banned from telegram"], "PHONE_NUMBER_FLOOD": ["You asked for the code too many times."], "PHONE_NUMBER_INVALID": ["The phone number is invalid"], "PHONE_NUMBER_OCCUPIED": ["The phone number is already in use"], "PHONE_NUMBER_UNOCCUPIED": ["The phone number is not yet being used"], "PHONE_PASSWORD_FLOOD": ["You have tried logging in too many times"], "PHONE_PASSWORD_PROTECTED": ["This phone is password protected"], "PHOTO_CROP_SIZE_SMALL": ["Photo is too small"], "PHOTO_EXT_INVALID": ["The extension of the photo is invalid"], "PHOTO_INVALID_DIMENSIONS": ["The photo dimensions are invalid"], "PRIVACY_KEY_INVALID": ["The privacy key is invalid"], "PTS_CHANGE_EMPTY": ["No PTS change"], "QUERY_ID_EMPTY": ["The query ID is empty"], "QUERY_ID_INVALID": ["The query ID is invalid"], "QUERY_TOO_SHORT": ["The query string is too short"], "RANDOM_ID_DUPLICATE": ["You provided a random ID that was already used"], "RANDOM_ID_INVALID": ["A provided random ID is invalid"], "RANDOM_LENGTH_INVALID": ["Random length invalid"], "RANGES_INVALID": ["Invalid range provided"], "REG_ID_GENERATE_FAILED": ["Failure while generating registration ID"], "REPLY_MARKUP_INVALID": ["The provided reply markup is invalid"], "RESULT_TYPE_INVALID": ["Result type invalid"], "RIGHT_FORBIDDEN": ["Your admin rights do not allow you to do this"], "RPC_CALL_FAIL": ["Telegram is having internal issues, please try again later."], "RPC_MCGET_FAIL": ["Telegram is having internal issues, please try again later."], "RSA_DECRYPT_FAILED": ["Internal RSA decryption failed"], "SEARCH_QUERY_EMPTY": ["The search query is empty"], "SEND_MESSAGE_TYPE_INVALID": ["The message type is invalid"], "SESSION_PASSWORD_NEEDED": ["2FA is enabled, use a password to login"], "SHA256_HASH_INVALID": ["The provided SHA256 hash is invalid"], "START_PARAM_EMPTY": ["The start parameter is empty"], "START_PARAM_INVALID": ["Start parameter invalid"], "STICKER_ID_INVALID": ["The provided sticker ID is invalid"], "STICKER_INVALID": ["The provided sticker is invalid"], "STICKERS_EMPTY": ["No sticker provided"], "STICKERSET_INVALID": ["The provided sticker set is invalid"], "STORAGE_CHECK_FAILED": ["Server storage check failed"], "TEMP_AUTH_KEY_EMPTY": ["No temporary auth key provided"], "Timeout": ["A timeout occurred while fetching data from the bot"], "TMP_PASSWORD_DISABLED": ["The temporary password is disabled"], "TOKEN_INVALID": ["The provided token is invalid"], "TTL_DAYS_INVALID": ["The provided TTL is invalid"], "TYPE_CONSTRUCTOR_INVALID": ["The type constructor is invalid"], "TYPES_EMPTY": ["The types field is empty"], "UNKNOWN_METHOD": ["The method you tried to call cannot be called on non-CDN DCs"], "USER_ADMIN_INVALID": ["You're not an admin"], "USER_ALREADY_PARTICIPANT": ["The user is already in the group"], "USER_BANNED_IN_CHANNEL": ["You're banned from sending messages in supergroups/channels"], "USER_BLOCKED": ["User blocked"], "USER_BOT": ["Bots can only be admins in channels."], "USER_BOT_INVALID": ["This method can only be called by a bot"], "USER_BOT_REQUIRED": ["This method can only be called by a bot"], "USER_CHANNELS_TOO_MUCH": ["One of the users you tried to add is already in too many channels/supergroups"], "USER_CREATOR": ["You can't leave this channel, because you're its creator"], "USER_DEACTIVATED": ["The user was deactivated"], "USER_ID_INVALID": ["The provided user ID is invalid"], "USER_IS_BLOCKED": ["User is blocked"], "USER_IS_BOT": ["Bots can't send messages to other bots"], "USER_KICKED": ["This user was kicked from this supergroup/channel"], "USER_NOT_MUTUAL_CONTACT": ["The provided user is not a mutual contact"], "USER_NOT_PARTICIPANT": ["You're not a member of this supergroup/channel"], "USER_PRIVACY_RESTRICTED": ["The user's privacy settings do not allow you to do this"], "USER_RESTRICTED": ["You're spamreported, you can't create channels or chats."], "USERNAME_INVALID": ["The provided username is not valid"], "USERNAME_NOT_MODIFIED": ["The username was not modified"], "USERNAME_NOT_OCCUPIED": ["The provided username is not occupied"], "USERNAME_OCCUPIED": ["The provided username is already occupied"], "USERS_TOO_FEW": ["Not enough users (to create a chat, for example)"], "USERS_TOO_MUCH": ["The maximum number of users has been exceeded (to create a chat, for example)"], "WEBPAGE_CURL_FAILED": ["Failure while fetching the webpage with cURL"], "YOU_BLOCKED_USER": ["You blocked this user"]}} \ No newline at end of file