Spaces:
Paused
Paused
| import os | |
| import sys | |
| import threading | |
| from http.server import HTTPServer, BaseHTTPRequestHandler | |
| import asyncio | |
| import urllib.parse | |
| # ========================================== | |
| # πͺ THE HUGGING FACE TRICK | |
| # ========================================== | |
| class DummyHandler(BaseHTTPRequestHandler): | |
| def do_GET(self): | |
| self.send_response(200) | |
| self.end_headers() | |
| self.wfile.write(b"Bot is online and running on Hugging Face!") | |
| def keep_alive(): | |
| server = HTTPServer(('0.0.0.0', 7860), DummyHandler) | |
| server.serve_forever() | |
| threading.Thread(target=keep_alive, daemon=True).start() | |
| # ========================================== | |
| # π€ BOT LIBRARIES (MODERN PY-TGCALLS) | |
| # ========================================== | |
| from pyrogram import Client, filters | |
| from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery | |
| # π MONKEY PATCH | |
| import pyrogram.errors | |
| if not hasattr(pyrogram.errors, 'GroupcallForbidden'): | |
| class GroupcallForbidden(Exception): | |
| pass | |
| pyrogram.errors.GroupcallForbidden = GroupcallForbidden | |
| from pytgcalls import PyTgCalls | |
| from pytgcalls.types import MediaStream, AudioQuality, VideoQuality | |
| import requests | |
| import sqlite3 | |
| import random | |
| # ========================================== | |
| # π YOUR CREDENTIALS | |
| # ========================================== | |
| API_ID = 2040 | |
| API_HASH = "b18441a1ff607e10a989891a5462e627" | |
| BOT_TOKEN = "8402411770:AAFvqCzvHwKRX0ScCzbGO3jGsDoD6LJphg4" | |
| app = Client("MusicQuizBot", api_id=API_ID, api_hash=API_HASH, bot_token=BOT_TOKEN) | |
| call_py = PyTgCalls(app) | |
| # ========================================== | |
| # πΎ DATABASE SETUP | |
| # ========================================== | |
| db = sqlite3.connect("bot_database.db", check_same_thread=False) | |
| cursor = db.cursor() | |
| cursor.execute("CREATE TABLE IF NOT EXISTS local_quizzes (id INTEGER PRIMARY KEY, question TEXT, correct TEXT, wrong1 TEXT, wrong2 TEXT, wrong3 TEXT)") | |
| db.commit() | |
| # ========================================== | |
| # π΅ DAVID CYRIL API DOWNLOADERS | |
| # ========================================== | |
| def download_audio_api(query): | |
| # Hit your API to get the audio download URL | |
| api_url = f"https://apis.davidcyril.name.ng/play?query={urllib.parse.quote(query)}" | |
| res = requests.get(api_url).json() | |
| if not res.get("status") or not res.get("result"): | |
| raise Exception("API could not find the song.") | |
| data = res["result"] | |
| title = data.get("title", "Unknown_Audio").replace("/", "_") | |
| download_url = data.get("download_url") | |
| # Download the MP3 to the server so PyTgCalls can stream it smoothly | |
| file_path = f"{title}.mp3" | |
| audio_data = requests.get(download_url).content | |
| with open(file_path, "wb") as f: | |
| f.write(audio_data) | |
| return file_path, title | |
| def download_video_api(query): | |
| # Hit your API to get the video link | |
| search_res = requests.get(f"https://apis.davidcyril.name.ng/play?query={urllib.parse.quote(query)}").json() | |
| if not search_res.get("status"): | |
| raise Exception("API could not find the video.") | |
| yt_url = search_res["result"]["video_url"] | |
| title = search_res["result"]["title"].replace("/", "_") | |
| video_res = requests.get(f"https://apis.davidcyril.name.ng/download/ytmp4?url={urllib.parse.quote(yt_url)}").json() | |
| if not video_res.get("success"): | |
| raise Exception("API failed to generate video link.") | |
| download_url = video_res["result"]["download_url"] | |
| # Download the MP4 to the server | |
| file_path = f"{title}.mp4" | |
| video_data = requests.get(download_url).content | |
| with open(file_path, "wb") as f: | |
| f.write(video_data) | |
| return file_path, title | |
| # ========================================== | |
| # ποΈ VOICE CHAT STREAMING | |
| # ========================================== | |
| async def play_audio(client, message): | |
| if len(message.command) < 2: return await message.reply_text("π©Έ `/play <song>`") | |
| query = message.text.split(" ", 1)[1] | |
| status = await message.reply_text("π Fetching Audio from API...") | |
| try: | |
| # Download in background so bot doesn't freeze | |
| file_path, title = await asyncio.to_thread(download_audio_api, query) | |
| await status.edit_text(f"π Joining VC & Playing: **{title}**") | |
| # Stream the file directly into the VC! | |
| await call_py.play(message.chat.id, MediaStream(file_path, audio_parameters=AudioQuality.HIGH)) | |
| except Exception as e: | |
| await status.edit_text(f"π©Έ **VC Error:** {str(e)}") | |
| async def play_video(client, message): | |
| if len(message.command) < 2: return await message.reply_text("π©Έ `/vplay <video>`") | |
| query = message.text.split(" ", 1)[1] | |
| status = await message.reply_text("π Fetching Video from API (This might take a minute)...") | |
| try: | |
| file_path, title = await asyncio.to_thread(download_video_api, query) | |
| await status.edit_text(f"π¬ Joining VC & Streaming Video: **{title}**") | |
| await call_py.play(message.chat.id, MediaStream(file_path, audio_parameters=AudioQuality.HIGH, video_parameters=VideoQuality.HD_720p)) | |
| except Exception as e: | |
| await status.edit_text(f"π©Έ **VC Error:** {str(e)}") | |
| async def stop_stream(client, message): | |
| try: | |
| await call_py.leave_call(message.chat.id) | |
| await message.reply_text("π Left the Voice Chat.") | |
| except: | |
| await message.reply_text("I am not in a Voice Chat right now.") | |
| # ========================================== | |
| # π§ INTERACTIVE QUIZ SYSTEM | |
| # ========================================== | |
| async def send_quiz(client, chat_id): | |
| status = await client.send_message(chat_id, "π Generating trivia...") | |
| try: | |
| res = await asyncio.to_thread(requests.get, "https://opentdb.com/api.php?amount=1&type=multiple") | |
| data = res.json()["results"][0] | |
| q = data["question"].replace(""", '"').replace("'", "'").replace("&", "&") | |
| correct = data["correct_answer"].replace(""", '"').replace("'", "'").replace("&", "&") | |
| wrongs = [w.replace(""", '"').replace("'", "'").replace("&", "&") for w in data["incorrect_answers"]] | |
| options = wrongs + [correct] | |
| random.shuffle(options) | |
| buttons = [[InlineKeyboardButton(opt, callback_data="ans_T" if opt == correct else f"ans_F_{correct[:20]}")] for opt in options] | |
| await status.delete() | |
| await client.send_message(chat_id, f"π§ **Trivia Time!**\n\n{q}", reply_markup=InlineKeyboardMarkup(buttons)) | |
| except: | |
| await status.edit_text("π©Έ API Error.") | |
| async def trigger_quiz(client, message): | |
| await send_quiz(client, message.chat.id) | |
| async def callback_handler(client, query: CallbackQuery): | |
| data = query.data | |
| if data == "cmd_music": | |
| await query.answer("Type /play <song> or /vplay <video> in the group!", show_alert=True) | |
| elif data == "cmd_quiz": | |
| await query.answer() | |
| await send_quiz(client, query.message.chat.id) | |
| elif data.startswith("ans_"): | |
| if data == "ans_T": | |
| await query.message.edit_text(f"{query.message.text}\n\nβ **{query.from_user.first_name} got it right!**") | |
| else: | |
| await query.answer(f"β Wrong! Correct answer: {data.replace('ans_F_', '')}", show_alert=True) | |
| # ========================================== | |
| # π’ START COMMAND | |
| # ========================================== | |
| async def start_command(client, message): | |
| buttons = [ | |
| [InlineKeyboardButton("π΅ Music Guide", callback_data="cmd_music"), | |
| InlineKeyboardButton("π§ Play Quiz", callback_data="cmd_quiz")] | |
| ] | |
| await message.reply_text( | |
| "π Welcome to the **Live VC Music & Quiz Bot**!\n\n" | |
| "**ποΈ VC Streaming:**\n" | |
| "`/play <song>` - Stream Audio in VC\n" | |
| "`/vplay <video>` - Stream Video in VC\n" | |
| "`/stop` - Leave VC\n\n" | |
| "**π§ Quizzes:**\n" | |
| "`/quiz` - Online Trivia", | |
| reply_markup=InlineKeyboardMarkup(buttons) | |
| ) | |
| if __name__ == "__main__": | |
| print("π Booting Engine...") | |
| app.start() | |
| print("π Booting Voice Chat Module...") | |
| call_py.start() | |
| print("β ALL SYSTEMS ONLINE! READY FOR VOICE CHATS!") | |
| from pyrogram import idle | |
| idle() |