#  Moon-Userbot - telegram userbot #  Copyright (C) 2020-present Moon Userbot Organization # #  This program is free software: you can redistribute it and/or modify #  it under the terms of the GNU General Public License as published by #  the Free Software Foundation, either version 3 of the License, or #  (at your option) any later version. #  This program is distributed in the hope that it will be useful, #  but WITHOUT ANY WARRANTY; without even the implied warranty of #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the #  GNU General Public License for more details. #  You should have received a copy of the GNU General Public License #  along with this program.  If not, see . import os import requests import asyncio from pyrogram import Client, enums, filters from pyrogram.types import Message from utils.misc import modules_help, prefix from modules.url import generate_screenshot from pyrogram import filters from utils.scripts import with_reply, no_prefix np = no_prefix(prefix) # API URLs BASE_URL = "https://deliriussapi-oficial.vercel.app" URL = f"{BASE_URL}/ia" GOOGLE_SEARCH_URL = f"{BASE_URL}/search/googlesearch?query=" YOUTUBE_SEARCH_URL = f"{BASE_URL}/search/ytsearch?q=" MOVIE_SEARCH_URL = f"{BASE_URL}/search/movie?query=" APK_SEARCH_URL = f"https://bk9.fun/search/apkfab?q=" APK_DOWNLOAD_URL = "https://bk9.fun/download/apkfab?url=" def clean_data(data): parts = data.split("$@$") if len(parts) > 1: return parts[-1] else: return data # Store search results temporarily search_results = {} # Helper Functions def format_google_results(results): results = results[:15] return results, "\n\n".join( [ f"{i+1}. **[{item['title']}]({item['url']})**\n{item['description']}" for i, item in enumerate(results) ] ) def format_youtube_results(results): results = results[:15] return results, "\n\n".join( [ f"{i+1}. **[{item['title']}]({item['url']})**\nPublished by: [{item['author']['name']}]({item['author']['url']}) - {item['views']} views - {item['duration']}" for i, item in enumerate(results) ] ) def format_movie_results(results): results = results[:15] return results, "\n\n".join( [ f"{i+1}. **{item['title']}** ({item['release_date']})\nRating: {item['vote_average']}/10\nVotes: {item['vote_count']}" for i, item in enumerate(results) ] ) def format_apk_results(results): results = results[:15] return results, "\n\n".join( [f"{i+1}. [{item['title']}]({item['link']})" for i, item in enumerate(results)] ) async def send_screenshot(client, message, url): screenshot_data = generate_screenshot(url) if screenshot_data: await client.send_photo( message.chat.id, screenshot_data, caption=f"Screenshot of {url}", reply_to_message_id=message.id, ) else: await message.reply("Failed to take screenshot.") async def delete_search_data(client, chat_id, message_id): await asyncio.sleep(60) for key in ["google", "youtube", "movie", "apk"]: search_key = f"{chat_id}_{key}" if ( search_key in search_results and search_results[search_key]["message_id"] == message_id ): del search_results[search_key] try: await client.delete_messages(chat_id, message_id) except: pass break def format_spotify_result(data): result = "" for item in data[:15]: # Limit to 15 results result += f"🎵 **{item['title']}** by {item['artist']}\n" result += f"Album: {item['album']}\n" result += f"Duration: {item['duration']}\n" result += f"Popularity: {item['popularity']}\n" result += f"Publish Date: {item['publish']}\n" result += f"[Listen on Spotify]({item['url']})\n\n" return result def format_lyrics_result(data): return f"🎵 **{data['fullTitle']}** by {data['artist']}\n\n{data['lyrics']}" def format_soundcloud_result(data): result = "" for item in data[:15]: # Limit to 15 results result += f"🎵 **{item['title']}**\n" result += f"Genre: {item['genre']}\n" result += f"Duration: {item['duration'] // 1000 // 60}:{item['duration'] // 1000 % 60}\n" result += f"Likes: {item['likes']}\n" result += f"Plays: {item['play']}\n" result += f"[Listen on SoundCloud]({item['link']})\n\n" return result def format_deezer_result(data): result = "" for item in data[:15]: # Limit to 15 results result += f"🎵 **{item['title']}** by {item['artist']}\n" result += f"Duration: {item['duration']}\n" result += f"Rank: {item['rank']}\n" result += f"[Listen on Deezer]({item['url']})\n\n" return result def format_apple_music_result(data): result = "" for item in data[:15]: # Limit to 15 results title = item.get("title", "Unknown Title") artists = item.get("artists", "Unknown Artist") music_type = item.get("type", "Unknown Type") url = item.get("url", "#") result += f"🎵 **{title}** by {artists}\n" result += f"Type: {music_type}\n" result += f"[Listen on Apple Music]({url})\n\n" return result async def search_music(api_url, format_function, message, query): await message.edit("Searching...") url = f"{api_url}{query}&limit=10" response = requests.get(url) if response.status_code == 200: try: data = response.json() # Directly get the JSON data if isinstance(data, list): result = format_function(data) elif isinstance(data, dict) and "data" in data: result = format_function(data["data"]) else: result = "No data found or unexpected format." await message.edit(result, parse_mode=enums.ParseMode.MARKDOWN) except (ValueError, KeyError, TypeError) as e: await message.edit(f"An error occurred while processing the data: {str(e)}") elif response.json()["msg"]: await message.edit(response.json()["msg"]) else: await message.edit("An error occurred, please try again later.") @Client.on_message(filters.command(["gsearch"], prefix) & filters.me) async def google_search(client: Client, message: Message): if message.reply_to_message: query = message.reply_to_message.text.strip() elif len(message.command) > 1: query = message.text.split(maxsplit=1)[1] else: return await message.edit_text(f"{prefix}gsearch ") await message.edit("Searching...") url = f"{GOOGLE_SEARCH_URL}{query}" response = requests.get(url) if response.status_code == 200: data = response.json() results, formatted_results = format_google_results(data["data"]) search_message = await message.edit( f"**Google Search Results for:** `{query}`\n\n{formatted_results}", parse_mode=enums.ParseMode.MARKDOWN, disable_web_page_preview=True, ) search_key = f"{message.chat.id}_google" global search_results search_results[search_key] = { "results": results, "message_id": search_message.id, } google_url = f"https://www.google.com/search?q={query}" await send_screenshot(client, message, google_url) asyncio.create_task( delete_search_data(client, message.chat.id, search_message.id) ) else: await message.edit("An error occurred, please try again later.") @Client.on_message(filters.command(["ytsearch"], prefix) & filters.me) async def youtube_search(client: Client, message: Message): if message.reply_to_message: query = message.reply_to_message.text.strip() elif len(message.command) > 1: query = message.text.split(maxsplit=1)[1] else: return await message.edit_text(f"{prefix}ytsearch ") await message.edit("Searching...") url = f"{YOUTUBE_SEARCH_URL}{query}" response = requests.get(url) if response.status_code == 200: data = response.json() results, formatted_results = format_youtube_results(data["data"]) search_message = await message.edit( f"**YouTube Search Results for:** `{query}`\n\n{formatted_results}", parse_mode=enums.ParseMode.MARKDOWN, disable_web_page_preview=True, ) search_key = f"{message.chat.id}_youtube" global search_results search_results[search_key] = { "results": results, "message_id": search_message.id, } youtube_url = f"https://www.youtube.com/results?search_query={query}" await send_screenshot(client, message, youtube_url) asyncio.create_task( delete_search_data(client, message.chat.id, search_message.id) ) else: await message.edit("An error occurred, please try again later.") @Client.on_message(filters.command(["moviesearch"], prefix) & filters.me) async def movie_search(client, message: Message): if message.reply_to_message: query = message.reply_to_message.text.strip() elif len(message.command) > 1: query = message.text.split(maxsplit=1)[1] else: return await message.edit_text(f"{prefix}moviesearch ") await message.edit("Searching...") url = f"{MOVIE_SEARCH_URL}{query}" response = requests.get(url) if response.status_code == 200: data = response.json() results, formatted_results = format_movie_results(data["data"]) # Split the message into multiple parts if it's too long parts = [] part_length = 4096 # Telegram's message length limit for i in range(0, len(formatted_results), part_length): parts.append(formatted_results[i : i + part_length]) for part in parts: search_message = await message.reply( f"**Movie Search Results for:** `{query}`\n\n{part}", parse_mode=enums.ParseMode.MARKDOWN, disable_web_page_preview=True, ) search_key = f"{message.chat.id}_movie" global search_results search_results[search_key] = { "results": results, "message_id": search_message.id, } asyncio.create_task( delete_search_data(client, message.chat.id, search_message.id) ) else: await message.edit("An error occurred, please try again later.") @Client.on_message(filters.command(["apksearch"], prefix) & filters.me) async def apk_search(client, message: Message): if message.reply_to_message: query = message.reply_to_message.text.strip() elif len(message.command) > 1: query = message.text.split(maxsplit=1)[1] else: return await message.edit_text(f"{prefix}apksearch ") await message.edit("Searching...") url = f"{APK_SEARCH_URL}{query}" response = requests.get(url) if response.status_code == 200: data = response.json() results, formatted_results = format_apk_results(data["BK9"]) search_message = await message.edit( f"**APK Search Results for:** `{query}`\n\n{formatted_results}", parse_mode=enums.ParseMode.MARKDOWN, disable_web_page_preview=True, ) search_key = f"{message.chat.id}_apk" global search_results search_results[search_key] = { "results": results, "message_id": search_message.id, } asyncio.create_task( delete_search_data(client, message.chat.id, search_message.id) ) else: await message.edit("An error occurred, please try again later.") @Client.on_message(filters.command(["wgpt", "gptweb"], prefix) & filters.me) async def gptweb(_, message: Message): if len(message.command) < 2: await message.edit("Usage: `wgpt `") return await message.edit("Thinking...") query = " ".join(message.command[1:]) url = f"{URL}/gptweb?text={query}" response = requests.get(url) if response.status_code == 200: data = response.json() await message.edit( f"**Question:**\n{query}\n**Answer:**\n{data['data']}", parse_mode=enums.ParseMode.MARKDOWN, ) else: await message.edit("An error occurred, please try again later.") @Client.on_message(filters.command(["wgemini"], prefix) & filters.me) async def gemini(_, message: Message): if len(message.command) < 2: await message.edit("Usage: `wgemini `") return await message.edit("Thinking...") query = " ".join(message.command[1:]) url = f"{URL}/gemini?query={query}" response = requests.get(url) if response.status_code == 200: data = response.json() await message.edit( f"**Question:**\n{query}\n**Answer:**\n{data['message']}", parse_mode=enums.ParseMode.MARKDOWN, ) else: await message.edit("An error occurred, please try again later.") @Client.on_message(filters.command(["sputify"], prefix) & filters.me) async def spotify_search(_, message: Message): query = ( message.text.split(maxsplit=1)[1] if len(message.command) > 1 else message.reply_to_message.text ) if not query: await message.edit("Usage: spotify ") return await search_music( f"{BASE_URL}/search/spotify?q=", format_spotify_result, message, query ) @Client.on_message(filters.command(["lyrics"], prefix) & filters.me) async def lyrics_search(_, message: Message): query = ( message.text.split(maxsplit=1)[1] if len(message.command) > 1 else message.reply_to_message.text ) if not query: await message.edit("Usage: lyrics ") return await search_music( f"{BASE_URL}/search/letra?query=", format_lyrics_result, message, query ) @Client.on_message(filters.command(["soundcloud"], prefix) & filters.me) async def soundcloud_search(_, message: Message): query = ( message.text.split(maxsplit=1)[1] if len(message.command) > 1 else message.reply_to_message.text ) if not query: await message.edit("Usage: soundcloud ") return await search_music( f"{BASE_URL}/search/soundcloud?q=", format_soundcloud_result, message, query ) @Client.on_message(filters.command(["deezer"], prefix) & filters.me) async def deezer_search(_, message: Message): query = ( message.text.split(maxsplit=1)[1] if len(message.command) > 1 else message.reply_to_message.text ) if not query: await message.edit("Usage: deezer ") return await search_music( f"{BASE_URL}/search/deezer?q=", format_deezer_result, message, query ) @Client.on_message(filters.command(["applemusic"], prefix) & filters.me) async def applemusic_search(_, message: Message): query = ( message.text.split(maxsplit=1)[1] if len(message.command) > 1 else message.reply_to_message.text ) if not query: await message.edit("Usage: applemusic ") return await search_music( f"{BASE_URL}/search/applemusic?text=", format_apple_music_result, message, query ) @Client.on_message(filters.reply & filters.text & filters.me & np) async def handle_reply(client: Client, message: Message): chat_id = message.chat.id search_keys = [ f"{chat_id}_google", f"{chat_id}_youtube", f"{chat_id}_movie", f"{chat_id}_apk", ] for search_key in search_keys: if search_key in search_results: try: # Check if the replied-to message is one of the bot's search result messages if message.reply_to_message.from_user.id != (await client.get_me()).id: return index = int(message.text.strip()) - 1 results = search_results[search_key]["results"] search_message_id = search_results[search_key]["message_id"] if ( message.reply_to_message.id == search_message_id and 0 <= index < len(results) ): await message.edit("Please wait...") if search_key.endswith("_movie"): # Send movie details with image movie = results[index] caption = ( f"**{movie['title']}** ({movie['release_date']})\n" f"Original Title: {movie['original_title']}\n" f"Language: {movie['original_language']}\n" f"Overview: {movie['overview']}\n" f"Popularity: {movie['popularity']}\n" f"Rating: {movie['vote_average']}/10\n" f"Votes: {movie['vote_count']}" ) if "image" in movie: response = requests.get(movie["image"]) if response.status_code == 200: with open("movie_image.jpg", "wb") as f: f.write(response.content) await message.reply_photo( photo="movie_image.jpg", caption=caption, parse_mode=enums.ParseMode.MARKDOWN, ) os.remove("movie_image.jpg") else: await message.reply( caption, parse_mode=enums.ParseMode.MARKDOWN ) else: await message.reply( caption, parse_mode=enums.ParseMode.MARKDOWN ) elif search_key.endswith("_apk"): apk_url = f"{APK_DOWNLOAD_URL}{results[index]['link']}" fetch_apk_url = requests.get(apk_url) if fetch_apk_url.status_code != 200: await message.edit("Failed to fetch APK data.") else: data_apk = fetch_apk_url.json() download_url = data_apk["BK9"]["link"] size_apk = data_apk["BK9"]["size"] apk_size = float(size_apk.split(" ")[0]) if "GB" in size_apk or apk_size > 100: await message.edit( "File size is too large to download." ) else: apk_file_name = f"{data_apk['BK9']['title']}.apk" response = requests.get(download_url) if response.status_code != 200: await message.edit( "Failed to download the APK file." ) else: with open(apk_file_name, "wb") as f: f.write(response.content) await message.reply_document(apk_file_name) os.remove(apk_file_name) else: url = results[index]["url"] await send_screenshot(client, message, url) await message.delete() return except ValueError: pass modules_help["sarethai"] = { "wgpt [query]*": "Ask anything to GPT-Web", "gptweb [query]*": "Ask anything to GPT-Web", "wgemini [query]*": "Ask anything to Gemini", "sputify [query]*": "Search for songs on Spotify", "lyrics [song name]*": "Get the lyrics of a song", "soundcloud [query]*": "Search for songs on SoundCloud", "deezer [query]*": "Search for songs on Deezer", "applemusic [query]*": "Search for songs on Apple Music", "gsearch [query]*": "Searches Google for the query.", "ytsearch [query]*": "Searches YouTube for the query.", "moviesearch [query]*": "Searches movies for the query and returns results.", "apksearch [query]*": "Searches APKs for the query and returns results.", }