Skip to content

Commit ac247bf

Browse files
committed
feat: now using sqlite sessions
1 parent 7806dd0 commit ac247bf

File tree

2 files changed

+87
-30
lines changed

2 files changed

+87
-30
lines changed

scripts/manage_account.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
import getpass
55
import argparse
66
import logging
7+
import os
78
from typing import Dict, Optional
89

910
# Add project root to sys.path
1011
project_root = Path(__file__).resolve().parent.parent
1112
if str(project_root) not in sys.path:
1213
sys.path.insert(0, str(project_root))
1314

14-
from telethon.sessions import StringSession
15+
from telethon.sessions import SQLiteSession
1516
from telethon.errors import SessionPasswordNeededError
1617

1718
from userbot import TelegramClient, _generate_random_device
@@ -33,6 +34,7 @@ async def add_account_logic(args: argparse.Namespace) -> None:
3334
"""
3435
logger.info(f"--- Adding new account: {args.name} ---")
3536

37+
session_file: str = f"temp_cli_{args.name}.session"
3638
temp_client: Optional[TelegramClient] = None
3739
try:
3840
async with get_db() as db:
@@ -48,7 +50,7 @@ async def add_account_logic(args: argparse.Namespace) -> None:
4850
return
4951

5052
logger.info("Initializing temporary session to verify credentials...")
51-
temp_client = TelegramClient(StringSession(), int(api_id), api_hash)
53+
temp_client = TelegramClient(SQLiteSession(session_file), int(api_id), api_hash)
5254
await temp_client.connect()
5355

5456
if not await temp_client.is_user_authorized():
@@ -66,6 +68,8 @@ async def add_account_logic(args: argparse.Namespace) -> None:
6668
access_hash: int = me.access_hash
6769
logger.info(f"Successfully logged in as user ID: {user_id}.")
6870

71+
await temp_client.disconnect() # Disconnect to ensure session file is fully written
72+
6973
existing_by_id = await db_manager.get_account_by_user_id(db, user_id)
7074
if existing_by_id:
7175
logger.error(f"Error: This Telegram account (ID: {user_id}) already exists as '{existing_by_id.account_name}'.")
@@ -128,16 +132,41 @@ async def add_account_logic(args: argparse.Namespace) -> None:
128132
proxy_password=proxy_password
129133
)
130134

131-
if new_account:
132-
logger.info(f"\nSuccess! Account '{args.name}' was added. Restart the bot to activate.")
133-
else:
135+
if not new_account:
134136
logger.error("\nFailed to add the account to the database.")
137+
return
138+
139+
# Now extract session from file and save to DB
140+
logger.info("Extracting session data and saving to the database...")
141+
reader_session = SQLiteSession(session_file)
142+
reader_session.load()
143+
144+
update_state = reader_session.get_update_state(0)
145+
pts, qts, date_ts, seq, _ = (None, None, None, None, None)
146+
if update_state:
147+
pts, qts, date_ts, seq, _ = update_state
148+
149+
await db_manager.add_or_update_session(
150+
db,
151+
account_id=new_account.account_id,
152+
dc_id=reader_session.dc_id,
153+
server_address=reader_session.server_address,
154+
port=reader_session.port,
155+
auth_key_data=reader_session.auth_key.key,
156+
takeout_id=reader_session.takeout_id,
157+
pts=pts, qts=qts, date=date_ts, seq=seq
158+
)
159+
160+
logger.info(f"\nSuccess! Account '{args.name}' was added. Restart the bot to activate.")
135161

136162
except Exception as e:
137-
logger.error(f"\nAn unexpected error occurred: {e}", exc_info=False)
163+
logger.error(f"\nAn unexpected error occurred: {e}", exc_info=True)
138164
finally:
139165
if temp_client and temp_client.is_connected():
140166
await temp_client.disconnect()
167+
if os.path.exists(session_file):
168+
os.remove(session_file)
169+
logger.info(f"Cleaned up temporary session file: {session_file}")
141170

142171

143172
async def edit_account_logic(args: argparse.Namespace) -> None:

userbot/src/core_handlers.py

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import asyncio
22
import io
33
import logging
4+
import os
45
import shlex
56
import subprocess
67
import sys
78
from datetime import datetime
8-
from typing import Dict, Any, List, Set
9+
from typing import Dict, Any, List, Set, Optional
910

1011
from telethon import events
1112
from telethon.errors import SessionPasswordNeededError
12-
from telethon.sessions import StringSession
13+
from telethon.sessions import SQLiteSession
1314

1415
from userbot import TelegramClient, FAKE, GLOBAL_HELP_INFO, _generate_random_device, ACTIVE_CLIENTS
1516
from 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

7576
async 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

149177
async def delete_account_handler(event: events.NewMessage.Event):

0 commit comments

Comments
 (0)