diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ac8104 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +tdlib \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..9e98a23 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,26 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d4a7326 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..48195dd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/telescope.iml b/.idea/telescope.iml new file mode 100644 index 0000000..2c80e12 --- /dev/null +++ b/.idea/telescope.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..560c3a5 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1715666423051 + + + + + + + + + \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..5e3c677 --- /dev/null +++ b/main.py @@ -0,0 +1,81 @@ +import sys +from tdlib import TDLib + +class TelegramClient: + def __init__(self): + self.tdlib = TDLib() + self.client_id = self.tdlib.create_client_id() + + def send(self, query): + self.tdlib.send(self.client_id, query) + + def receive(self): + return self.tdlib.receive() + + +def main(): + client = TelegramClient() + + # Setting TDLib log verbosity level to 1 (errors) + print(client.tdlib.td_execute({'@type': 'setLogVerbosityLevel', 'new_verbosity_level': 1, '@extra': 1.01234})) + + # Example request + print(client.tdlib.td_execute( + {'@type': 'getTextEntities', 'text': '@telegram /test_command https://telegram.org telegram.me', + '@extra': ['5', 7.0, 'a']})) + + # Start the client by sending a request to it + client.send({'@type': 'getOption', 'name': 'version', '@extra': 1.01234}) + + while True: + event = client.receive() + if event: + if event['@type'] == 'updateAuthorizationState': + auth_state = event['authorization_state'] + + if auth_state['@type'] == 'authorizationStateClosed': + break + + if auth_state['@type'] == 'authorizationStateWaitTdlibParameters': + client.send({'@type': 'setTdlibParameters', + 'database_directory': 'tdlib', + 'use_message_database': True, + 'use_secret_chats': True, + 'api_id': 94575, + 'api_hash': 'a3406de8d171bb422bb6ddf3bbd800e2', + 'system_language_code': 'en', + 'device_model': 'Desktop', + 'application_version': '1.0'}) + + if auth_state['@type'] == 'authorizationStateWaitPhoneNumber': + phone_number = input('Please enter your phone number: ') + client.send({'@type': 'setAuthenticationPhoneNumber', 'phone_number': phone_number}) + + if auth_state['@type'] == 'authorizationStateWaitEmailAddress': + email_address = input('Please enter your email address: ') + client.send({'@type': 'setAuthenticationEmailAddress', 'email_address': email_address}) + + if auth_state['@type'] == 'authorizationStateWaitEmailCode': + code = input('Please enter the email authentication code you received: ') + client.send({'@type': 'checkAuthenticationEmailCode', + 'code': {'@type': 'emailAddressAuthenticationCode', 'code': code}}) + + if auth_state['@type'] == 'authorizationStateWaitCode': + code = input('Please enter the authentication code you received: ') + client.send({'@type': 'checkAuthenticationCode', 'code': code}) + + if auth_state['@type'] == 'authorizationStateWaitRegistration': + first_name = input('Please enter your first name: ') + last_name = input('Please enter your last name: ') + client.send({'@type': 'registerUser', 'first_name': first_name, 'last_name': last_name}) + + if auth_state['@type'] == 'authorizationStateWaitPassword': + password = input('Please enter your password: ') + client.send({'@type': 'checkAuthenticationPassword', 'password': password}) + + print(str(event).encode('utf-8')) + sys.stdout.flush() + + +if __name__ == "__main__": + main() diff --git a/natives/windows/libcrypto-3-x64.dll b/natives/windows/libcrypto-3-x64.dll new file mode 100644 index 0000000..bfc53ac Binary files /dev/null and b/natives/windows/libcrypto-3-x64.dll differ diff --git a/natives/windows/libssl-3-x64.dll b/natives/windows/libssl-3-x64.dll new file mode 100644 index 0000000..9565b3c Binary files /dev/null and b/natives/windows/libssl-3-x64.dll differ diff --git a/natives/windows/tdjson.dll b/natives/windows/tdjson.dll new file mode 100644 index 0000000..986b4e0 Binary files /dev/null and b/natives/windows/tdjson.dll differ diff --git a/natives/windows/zlib1.dll b/natives/windows/zlib1.dll new file mode 100644 index 0000000..5905b70 Binary files /dev/null and b/natives/windows/zlib1.dll differ diff --git a/tdlib.py b/tdlib.py new file mode 100644 index 0000000..7d25859 --- /dev/null +++ b/tdlib.py @@ -0,0 +1,81 @@ +from ctypes.util import find_library +from ctypes import * +import json +import os +import sys +import platform + +_log_message_callback_type = CFUNCTYPE(None, c_int, c_char_p) + +class TDLib: + _instance = None + _tdjson_path = None + _tdjson = None + + def __new__(cls): + if cls._instance is None: + cls._instance = super(TDLib, cls).__new__(cls) + cls._instance._load_tdjson() + cls._instance._initialize_tdjson() + cls._instance._set_log_message_callback() + return cls._instance + + def _load_tdjson(self): + if self._tdjson_path is None: + self._tdjson_path = find_library('tdjson') + if self._tdjson_path is None: + if os.name == 'nt': + self._tdjson_path = os.path.join(os.path.dirname(__file__), "natives", platform.system().lower(), "tdjson.dll") + else: + sys.exit("Can't find 'tdjson' library") + self._tdjson = CDLL(self._tdjson_path) + + def _initialize_tdjson(self): + self._td_create_client_id = self._tdjson.td_create_client_id + self._td_create_client_id.restype = c_int + self._td_create_client_id.argtypes = [] + + self._td_receive = self._tdjson.td_receive + self._td_receive.restype = c_char_p + self._td_receive.argtypes = [c_double] + + self._td_send = self._tdjson.td_send + self._td_send.restype = None + self._td_send.argtypes = [c_int, c_char_p] + + self._td_execute = self._tdjson.td_execute + self._td_execute.restype = c_char_p + self._td_execute.argtypes = [c_char_p] + + self._td_set_log_message_callback = self._tdjson.td_set_log_message_callback + self._td_set_log_message_callback.restype = None + self._td_set_log_message_callback.argtypes = [c_int, _log_message_callback_type] + + @_log_message_callback_type + @staticmethod + def _on_log_message_callback(verbosity_level, message): + if verbosity_level == 0: + sys.exit('TDLib fatal error: %r' % message) + + def _set_log_message_callback(self): + self._td_set_log_message_callback(2, self._on_log_message_callback) + + def td_execute(self, query): + query = json.dumps(query).encode('utf-8') + result = self._td_execute(query) + if result: + result = json.loads(result.decode('utf-8')) + return result + + def create_client_id(self): + return self._td_create_client_id() + + def send(self, client_id, query): + query = json.dumps(query).encode('utf-8') + self._td_send(client_id, query) + + def receive(self): + result = self._td_receive(1.0) + if result: + result = json.loads(result.decode('utf-8')) + return result