mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-22 09:26:37 +03:00
81e8ae5bea
The interactive example allows you to list the top dialogs and send messages to them until "!q" is entered More documetation has been added Fixes when representing TLObjects (lists did not represent well) The `send_code_request` now allows to use multiple phone numbers at once
206 lines
8.6 KiB
Python
206 lines
8.6 KiB
Python
import re
|
|
|
|
|
|
class InvalidParameterError(Exception):
|
|
"""Occurs when an invalid parameter is given, for example,
|
|
when either A or B are required but none is given"""
|
|
|
|
|
|
class TypeNotFoundError(Exception):
|
|
"""Occurs when a type is not found, for example,
|
|
when trying to read a TLObject with an invalid constructor code"""
|
|
def __init__(self, invalid_constructor_id):
|
|
super().__init__(self, 'Could not find a matching Constructor ID for the TLObject '
|
|
'that was supposed to be read with ID {}. Most likely, a TLObject '
|
|
'was trying to be read when it should not be read.'
|
|
.format(hex(invalid_constructor_id)))
|
|
|
|
self.invalid_constructor_id = invalid_constructor_id
|
|
|
|
|
|
class InvalidDCError(Exception):
|
|
def __init__(self, new_dc):
|
|
super().__init__(self, 'Your phone number is registered to #{} DC. '
|
|
'This should have been handled automatically; '
|
|
'if it has not, please restart the app.'.format(new_dc))
|
|
|
|
self.new_dc = new_dc
|
|
|
|
|
|
class InvalidChecksumError(Exception):
|
|
def __init__(self, checksum, valid_checksum):
|
|
super().__init__(self, 'Invalid checksum ({} when {} was expected). This packet should be skipped.'
|
|
.format(checksum, valid_checksum))
|
|
|
|
self.checksum = checksum
|
|
self.valid_checksum = valid_checksum
|
|
|
|
|
|
class RPCError(Exception):
|
|
|
|
CodeMessages = {
|
|
303: ('ERROR_SEE_OTHER', 'The request must be repeated, but directed to a different data center.'),
|
|
|
|
400: ('BAD_REQUEST', 'The query contains errors. In the event that a request was created using a '
|
|
'form and contains user generated data, the user should be notified that the '
|
|
'data must be corrected before the query is repeated.'),
|
|
|
|
401: ('UNAUTHORIZED', 'There was an unauthorized attempt to use functionality available only to '
|
|
'authorized users.'),
|
|
|
|
403: ('FORBIDDEN', 'Privacy violation. For example, an attempt to write a message to someone who '
|
|
'has blacklisted the current user.'),
|
|
|
|
404: ('NOT_FOUND', 'An attempt to invoke a non-existent object, such as a method.'),
|
|
|
|
420: ('FLOOD', 'The maximum allowed number of attempts to invoke the given method with '
|
|
'the given input parameters has been exceeded. For example, in an attempt '
|
|
'to request a large number of text messages (SMS) for the same phone number.'),
|
|
|
|
500: ('INTERNAL', 'An internal server error occurred while a request was being processed; '
|
|
'for example, there was a disruption while accessing a database or file storage.')
|
|
}
|
|
|
|
ErrorMessages = {
|
|
# 303 ERROR_SEE_OTHER
|
|
'FILE_MIGRATE_(\d+)': 'The file to be accessed is currently stored in a different data center (#{}).',
|
|
|
|
'PHONE_MIGRATE_(\d+)': 'The phone number a user is trying to use for authorization is associated '
|
|
'with a different data center (#{}).',
|
|
|
|
'NETWORK_MIGRATE_(\d+)': 'The source IP address is associated with a different data center (#{}, '
|
|
'for registration).',
|
|
|
|
'USER_MIGRATE_(\d+)': 'The user whose identity is being used to execute queries is associated with '
|
|
'a different data center (#{} for registration).',
|
|
|
|
# 400 BAD_REQUEST
|
|
'FIRSTNAME_INVALID': 'The first name is invalid.',
|
|
|
|
'LASTNAME_INVALID': 'The last name is invalid.',
|
|
|
|
'PHONE_NUMBER_INVALID': 'The phone number is invalid.',
|
|
|
|
'PHONE_CODE_HASH_EMPTY': 'phone_code_hash is missing.',
|
|
|
|
'PHONE_CODE_EMPTY': 'phone_code is missing.',
|
|
|
|
'PHONE_CODE_EXPIRED': 'The confirmation code has expired.',
|
|
|
|
'API_ID_INVALID': 'The api_id/api_hash combination is invalid.',
|
|
|
|
'PHONE_NUMBER_OCCUPIED': 'The phone number is already in use.',
|
|
|
|
'PHONE_NUMBER_UNOCCUPIED': 'The phone number is not yet being used.',
|
|
|
|
'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).',
|
|
|
|
'TYPE_CONSTRUCTOR_INVALID': 'The type constructor is invalid.',
|
|
|
|
'FILE_PART_INVALID': 'The file part number is invalid.',
|
|
|
|
'FILE_PARTS_INVALID': 'The number of file parts is invalid.',
|
|
|
|
'FILE_PART_(\d+)_MISSING': 'Part {} of the file is missing from storage.',
|
|
|
|
'MD5_CHECKSUM_INVALID': 'The MD5 checksums do not match.',
|
|
|
|
'PHOTO_INVALID_DIMENSIONS': 'The photo dimensions are invalid.',
|
|
|
|
'FIELD_NAME_INVALID': 'The field with the name FIELD_NAME is invalid.',
|
|
|
|
'FIELD_NAME_EMPTY': 'The field with the name FIELD_NAME is missing.',
|
|
|
|
'MSG_WAIT_FAILED': 'A waiting call returned an error.',
|
|
|
|
'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).',
|
|
|
|
# 401 UNAUTHORIZED
|
|
'AUTH_KEY_UNREGISTERED': 'The key is not registered in the system.',
|
|
|
|
'AUTH_KEY_INVALID': 'The key is invalid.',
|
|
|
|
'USER_DEACTIVATED': 'The user has been deleted/deactivated.',
|
|
|
|
'SESSION_REVOKED': 'The authorization has been invalidated, because of the user terminating all sessions.',
|
|
|
|
'SESSION_EXPIRED': 'The authorization has expired.',
|
|
|
|
'ACTIVE_USER_REQUIRED': 'The method is only available to already activated users.',
|
|
|
|
'AUTH_KEY_PERM_EMPTY': 'The method is unavailable for temporary authorization key, not bound to permanent.',
|
|
|
|
# 420 FLOOD
|
|
'FLOOD_WAIT_(\d+)': 'A wait of {} seconds is required.'
|
|
}
|
|
|
|
def __init__(self, code, message):
|
|
self.code = code
|
|
self.code_meaning = RPCError.CodeMessages[code]
|
|
|
|
self.message = message
|
|
self.must_resend = code == 303 # ERROR_SEE_OTHER, "The request must be repeated"
|
|
|
|
called_super = False
|
|
for key, error_msg in RPCError.ErrorMessages.items():
|
|
match = re.match(key, message)
|
|
if match:
|
|
# Get additional_data, if any
|
|
if match.groups():
|
|
self.additional_data = int(match.group(1))
|
|
else:
|
|
self.additional_data = None
|
|
|
|
super().__init__(self, error_msg)
|
|
called_super = True
|
|
break
|
|
|
|
if not called_super:
|
|
super().__init__(self, 'Unknown error message with code {}: {}'.format(code, message))
|
|
|
|
|
|
class BadMessageError(Exception):
|
|
"""Occurs when handling a bad_message_notification"""
|
|
ErrorMessages = {
|
|
16: 'msg_id too low (most likely, client time is wrong it would be worthwhile to '
|
|
'synchronize it using msg_id notifications and re-send the original message '
|
|
'with the “correct” msg_id or wrap it in a container with a new msg_id if the '
|
|
'original message had waited too long on the client to be transmitted).',
|
|
|
|
17: 'msg_id too high (similar to the previous case, the client time has to be '
|
|
'synchronized, and the message re-sent with the correct msg_id).',
|
|
|
|
18: 'Incorrect two lower order msg_id bits (the server expects client message msg_id '
|
|
'to be divisible by 4).',
|
|
|
|
19: 'Container msg_id is the same as msg_id of a previously received message '
|
|
'(this must never happen).',
|
|
|
|
20: 'Message too old, and it cannot be verified whether the server has received a '
|
|
'message with this msg_id or not.',
|
|
|
|
32: 'msg_seqno too low (the server has already received a message with a lower '
|
|
'msg_id but with either a higher or an equal and odd seqno).',
|
|
|
|
33: 'msg_seqno too high (similarly, there is a message with a higher msg_id but with '
|
|
'either a lower or an equal and odd seqno).',
|
|
|
|
34: 'An even msg_seqno expected (irrelevant message), but odd received.',
|
|
|
|
35: 'Odd msg_seqno expected (relevant message), but even received.',
|
|
|
|
48: 'Incorrect server salt (in this case, the bad_server_salt response is received with '
|
|
'the correct salt, and the message is to be re-sent with it).',
|
|
|
|
64: 'Invalid container.'
|
|
}
|
|
|
|
def __init__(self, code):
|
|
super().__init__(self, BadMessageError
|
|
.ErrorMessages.get(code,'Unknown error code (this should not happen): {}.'.format(code)))
|
|
|
|
self.code = code
|