11import asyncio
22import io
33import logging
4+ import os
45import shlex
56import subprocess
67import sys
78from datetime import datetime
8- from typing import Dict , Any , List , Set
9+ from typing import Dict , Any , List , Set , Optional
910
1011from telethon import events
1112from telethon .errors import SessionPasswordNeededError
12- from telethon .sessions import StringSession
13+ from telethon .sessions import SQLiteSession
1314
1415from userbot import TelegramClient , FAKE , GLOBAL_HELP_INFO , _generate_random_device , ACTIVE_CLIENTS
1516from userbot .src .db .session import get_db
@@ -73,7 +74,9 @@ async def list_accounts_handler(event: events.NewMessage.Event):
7374 await event .edit ("\n " .join (response_lines ), parse_mode = "html" )
7475
7576async def add_account_handler (event : events .NewMessage .Event ):
76- account_name = event .pattern_match .group (1 )
77+ account_name : str = event .pattern_match .group (1 )
78+ session_file : str = f"temp_add_{ account_name } .session"
79+ temp_client : Optional [TelegramClient ] = None
7780
7881 try :
7982 async with event .client .conversation (event .chat_id , timeout = 600 ) as conv :
@@ -83,29 +86,29 @@ async def add_account_handler(event: events.NewMessage.Event):
8386 api_hash_resp = await conv .get_response (); api_hash = api_hash_resp .text .strip ()
8487
8588 await conv .send_message (await event .client .get_string ("verifying_creds" ))
86- temp_client = TelegramClient (StringSession ( ), int (api_id ), api_hash )
89+ temp_client = TelegramClient (SQLiteSession ( session_file ), int (api_id ), api_hash )
8790
88- try :
89- await temp_client .connect ()
90- if not await temp_client . is_user_authorized ():
91- phone_resp = await conv .send_message ( "Требуется вход. Введите номер телефона:" )
92- phone = ( await conv . get_response ()). text . strip ()
93- await phone_resp . delete ( )
94- await temp_client . send_code_request ( phone )
95- code_resp = await conv .send_message ( "Код отправлен. Введите его:" )
96- code = ( await conv . get_response ()). text . strip ()
97- await code_resp . delete ()
91+ await temp_client . connect ()
92+ if not await temp_client .is_user_authorized ():
93+ phone_resp = await conv . send_message ( "Требуется вход. Введите номер телефона:" )
94+ phone = ( await conv .get_response ()). text . strip ( )
95+ await phone_resp . delete ()
96+ await temp_client . send_code_request ( phone )
97+ code_resp = await conv . send_message ( "Код отправлен. Введите его:" )
98+ code = ( await conv .get_response ()). text . strip ( )
99+ await code_resp . delete ()
100+ try :
98101 await temp_client .sign_in (phone = phone , code = code )
99- except SessionPasswordNeededError :
100- pass_resp = await conv .send_message (await event .client .get_string ("prompt_2fa" ))
101- two_fa_pass = (await conv .get_response ()).text .strip ()
102- await pass_resp .delete ()
103- await temp_client .sign_in (password = two_fa_pass )
102+ except SessionPasswordNeededError :
103+ pass_resp = await conv .send_message (await event .client .get_string ("prompt_2fa" ))
104+ two_fa_pass = (await conv .get_response ()).text .strip ()
105+ await pass_resp .delete ()
106+ await temp_client .sign_in (password = two_fa_pass )
104107
105108 me = await temp_client .get_me (input_peer = True )
106109 user_id = me .user_id
107110 access_hash = me .access_hash
108- await temp_client .disconnect ()
111+ await temp_client .disconnect () # Disconnect to save session file properly
109112
110113 async with get_db () as db :
111114 existing = await db_manager .get_account_by_user_id (db , user_id )
@@ -133,17 +136,42 @@ async def add_account_handler(event: events.NewMessage.Event):
133136 user_telegram_id = user_id ,
134137 access_hash = access_hash
135138 )
139+ if not new_acc :
140+ await conv .send_message (await event .client .get_string ("add_acc_fail" , account_name = account_name ))
141+ return
142+
143+ # Now extract session data and save it
144+ reader_session = SQLiteSession (session_file )
145+ reader_session .load ()
146+
147+ update_state = reader_session .get_update_state (0 )
148+ pts , qts , date_ts , seq , _ = (None , None , None , None , None )
149+ if update_state :
150+ pts , qts , date_ts , seq , _ = update_state
151+
152+ await db_manager .add_or_update_session (
153+ db ,
154+ account_id = new_acc .account_id ,
155+ dc_id = reader_session .dc_id ,
156+ server_address = reader_session .server_address ,
157+ port = reader_session .port ,
158+ auth_key_data = reader_session .auth_key .key ,
159+ takeout_id = reader_session .takeout_id ,
160+ pts = pts , qts = qts , date = date_ts , seq = seq
161+ )
136162
137- if new_acc :
138- await conv .send_message (await event .client .get_string ("add_acc_success" , account_name = account_name ))
139- else :
140- await conv .send_message (await event .client .get_string ("add_acc_fail" , account_name = account_name ))
163+ await conv .send_message (await event .client .get_string ("add_acc_success" , account_name = account_name ))
141164
142165 except asyncio .TimeoutError :
143166 await event .respond (await event .client .get_string ("add_acc_timeout" ))
144167 except Exception as e :
145168 logger .error (f"Error in .addacc handler: { e } " , exc_info = True )
146169 await event .respond (await event .client .get_string ("generic_error" , error = str (e )))
170+ finally :
171+ if temp_client and temp_client .is_connected ():
172+ await temp_client .disconnect ()
173+ if os .path .exists (session_file ):
174+ os .remove (session_file )
147175
148176
149177async def delete_account_handler (event : events .NewMessage .Event ):
0 commit comments