mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-10 19:46:36 +03:00
134 lines
4.9 KiB
Python
134 lines
4.9 KiB
Python
|
# This file is based on TLSharp
|
||
|
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/TelegramClient.cs
|
||
|
from network.mtproto_sender import MtProtoSender
|
||
|
from network.tcp_transport import TcpTransport
|
||
|
import network.authenticator as authenticator
|
||
|
from tl.session import Session
|
||
|
import utils.helpers as utils
|
||
|
import platform
|
||
|
import re
|
||
|
|
||
|
from tl.functions.invoke_with_layer import InvokeWithLayer
|
||
|
from tl.functions.init_connection import InitConnection
|
||
|
from tl.functions.help.get_config import GetConfig
|
||
|
from tl.functions.auth.check_phone import CheckPhone
|
||
|
from tl.functions.auth.send_code import SendCode
|
||
|
from tl.functions.auth.sign_in import SignIn
|
||
|
from tl.functions.contacts.get_contacts import GetContacts
|
||
|
from tl.types.input_peer_user import InputPeerUser
|
||
|
from tl.functions.messages.send_message import SendMessage
|
||
|
|
||
|
|
||
|
class TelegramClient:
|
||
|
|
||
|
def __init__(self, session_user_id, layer, api_id=None, api_hash=None):
|
||
|
if api_id is None or api_hash is None:
|
||
|
raise PermissionError('Your API ID or Hash are invalid. Make sure to obtain yours in http://my.telegram.org')
|
||
|
|
||
|
self.api_id = api_id
|
||
|
self.api_hash = api_hash
|
||
|
|
||
|
self.layer = layer
|
||
|
|
||
|
self.session = Session.try_load_or_create_new(session_user_id)
|
||
|
self.transport = TcpTransport(self.session.server_address, self.session.port)
|
||
|
self.dc_options = None
|
||
|
|
||
|
# TODO Should this be async?
|
||
|
def connect(self, reconnect=False):
|
||
|
if self.session.auth_key is None or reconnect:
|
||
|
self.session.auth_key, self.session.time_offset= authenticator.do_authentication(self.transport)
|
||
|
|
||
|
self.sender = MtProtoSender(self.transport, self.session)
|
||
|
|
||
|
if not reconnect:
|
||
|
request = InvokeWithLayer(layer=self.layer,
|
||
|
query=InitConnection(api_id=self.api_id,
|
||
|
device_model=platform.node(),
|
||
|
system_version=platform.system(),
|
||
|
app_version='0.1',
|
||
|
lang_code='en',
|
||
|
query=GetConfig()))
|
||
|
|
||
|
self.sender.send(request)
|
||
|
self.sender.receive(request)
|
||
|
|
||
|
# Result is a Config TLObject
|
||
|
self.dc_options = request.result.dc_options
|
||
|
|
||
|
return True
|
||
|
|
||
|
def reconnect_to_dc(self, dc_id):
|
||
|
if self.dc_options is None or not self.dc_options:
|
||
|
raise ConnectionError("Can't reconnect. Stabilise an initial connection first.")
|
||
|
|
||
|
# dc is a DcOption TLObject
|
||
|
dc = next(dc for dc in self.dc_options if dc.id == dc_id)
|
||
|
|
||
|
self.transport = TcpTransport(dc.ip_address, dc.port)
|
||
|
self.session.server_address = dc.ip_address
|
||
|
self.session.port = dc.port
|
||
|
|
||
|
self.connect(reconnect=True)
|
||
|
|
||
|
def is_user_authorized(self):
|
||
|
return self.session.user is not None
|
||
|
|
||
|
def is_phone_registered(self, phone_number):
|
||
|
assert self.sender is not None, 'Not connected!'
|
||
|
|
||
|
request = CheckPhone(phone_number)
|
||
|
self.sender.send(request)
|
||
|
self.sender.receive(request)
|
||
|
|
||
|
# Result is an Auth.CheckedPhone
|
||
|
return request.result.phone_registered
|
||
|
|
||
|
def send_code_request(self, phone_number, destination='code'):
|
||
|
if destination == 'code':
|
||
|
destination = 5
|
||
|
elif destination == 'sms':
|
||
|
destination = 0
|
||
|
else:
|
||
|
raise ValueError('Destination must be either "code" or "sms"')
|
||
|
|
||
|
request = SendCode(phone_number, self.api_id, self.api_hash)
|
||
|
completed = False
|
||
|
while not completed:
|
||
|
try:
|
||
|
self.sender.send(request)
|
||
|
self.sender.receive(request)
|
||
|
completed = True
|
||
|
except ConnectionError as error:
|
||
|
if str(error).startswith('Your phone number is registered to'):
|
||
|
dc = int(re.search(r'\d+', str(error)).group(0))
|
||
|
self.reconnect_to_dc(dc)
|
||
|
else:
|
||
|
raise error
|
||
|
|
||
|
return request.result.phone_code_hash
|
||
|
|
||
|
def make_auth(self, phone_number, phone_code_hash, code):
|
||
|
request = SignIn(phone_number, phone_code_hash, code)
|
||
|
self.sender.send(request)
|
||
|
self.sender.receive(request)
|
||
|
|
||
|
# Result is an Auth.Authorization TLObject
|
||
|
self.session.user = request.result.user
|
||
|
self.session.save()
|
||
|
|
||
|
return self.session.user
|
||
|
|
||
|
def import_contacts(self, phone_code_hash):
|
||
|
request = GetContacts(phone_code_hash)
|
||
|
self.sender.send(request)
|
||
|
self.sender.receive(request)
|
||
|
return request.result.contacts, request.result.users
|
||
|
|
||
|
def send_message(self, user, message):
|
||
|
peer = InputPeerUser(user.id, user.access_hash)
|
||
|
request = SendMessage(peer, message, utils.generate_random_long())
|
||
|
|
||
|
self.sender.send(request)
|
||
|
self.sender.send(request)
|