diff --git a/.gitignore b/.gitignore deleted file mode 100644 index b6e47617d..000000000 --- a/.gitignore +++ /dev/null @@ -1,129 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..0bd91ea89 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3.9.2-slim-buster +RUN mkdir /app && chmod 777 /app +WORKDIR /app +ENV DEBIAN_FRONTEND=noninteractive +RUN apt -qq update && apt -qq install -y git python3 python3-pip ffmpeg +COPY . . +RUN pip3 install --no-cache-dir -r requirements.txt +CMD ["bash","bash.sh"] diff --git a/README.md b/README.md index 0cb94eb67..7b51f54c9 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,99 @@ -# Save Restricted Content Bot +

+ Save restricted content Bot +

-A simple telegram bot to save restricted content with custom thumbmail support by Mahesh Chauhan. +Contact: [Telegram](https://t.me/MaheshChauhan) -

+A stable telegram bot to get restricted messages with custom thumbnail support , made by Mahesh Chauhan. +- works for both public and private chats +- Custom thumbnail support for Pvt medias +- supports text and webpage media messages +- Faster speed +- Forcesubscribe available +- To save from bots send link in this format : `t.me/b/bot_username/message_id` (use plus messenger for message_id) +- `/batch` - (For owner only) Use this command to save upto 100 files from a pvt or public restricted channel at once. +- `/cancel` - Use this to stop batch +- Time delay is added to avoid FloodWait and keep user account safe. + # Variables - `API_ID` - `API_HASH` -- `SESSION` - Pyrogram string session -Get pyrogram string session from [BOT](https://t.me/SessionStringGeneratorZBot) or [Replit](https://replit.com/@dashezup/generate-pyrogram-session-string). -- `BOT TOKEN` +- `SESSION` +- `BOT_TOKEN` +- `AUTH` - Owner user id +- `FORCESUB` - Public channel username without '@'. Don't forget to add bot in channel as administrator. -# Builpacks +# Get API & PYROGRAM string session from: + +API: [API scrapper Bot](https://t.me/USETGSBOT) or [Telegram.org](https://my.telegram.org/auth) -- `heroku/python` -- `https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git` +PYROGRAM SESSION: [SessionGen Bot](https://t.me/SessionStringGeneratorRobot) or [![Run on Repl.it](https://replit.com/badge/github/vasusen-code/saverestrictedcontentbot)](https://replit.com/@levinalab/Session-Generator#main.py) -# Issues -- if you see any message like `ERROR R12` in heroku logs, just restart. -- `CHANNEL INVALID` if channel not joined. -- if you face `ERROR: Client has not been started yet` then just send `/start`. +BOT TOKEN: @Botfather on telegram # Deploy -

-if deploy button doesn't work, then deploy `manually.` +Deploy on `VPS` + +Easy Method: + +- Intall docker-compose +- Fill in the variables in docker-compose.yml file using your favorite text editor or nano +- Start the container + +``` +sudo apt install docker-compose -y +nano docker-compose.yml +sudo docker-compose up --build +``` + +The hard Way: + +- Fill vars in your fork in [this](https://github.com/vasusen-code/SaveRestrictedContentBot/blob/master/main/__init__.py) file as shown in this [picture](https://t.me/MaheshChauhan/36) +- enter all the below commands + +``` +sudo apt update +sudo apt install ffmpeg git python3-pip +git clone your_repo_link +cd saverestrictedcontentbot +pip3 install -r requirements.txt +python3 -m main +``` + +- if you want bot to be running in background then enter `screen -S srcb` before `python3 -m main` +- after `python3 -m main`, click ctrl+A, ctrl+D +- if you want to stop bot, then enter `screen -r srcb` and to kill screen enter `screen -S srcb -X quit`. + +Deploy your bot on `Render` + +Tutorial - [Click here](https://telegra.ph/SRCB-on-Render-05-17) + +Deploy your bot on `heroku` + +» Method - 1: +- Star the repo, and fork it in desktop mode +- Go to settings of your forked repo +- Rename your repo by any other name +- Click on [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) + +» Method - 2: +- Star the repo, and fork it in desktop mode +- create app in heroku +- go to settings of app›› config vars›› add all variables +- add buildpacks +- connect to github and deploy +- turn on dynos + +Buildpacks for manual deploy: + +- `heroku/python` +- `https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git` + +Deploy your bot on `Okteto` [Useless] + +Tutorial for okteto - [click here](https://telegra.ph/Okteto-Deploy-04-01) + +[![Develop on Okteto](https://okteto.com/develop-okteto.svg)](https://cloud.okteto.com) diff --git a/app.json b/app.json index 922637044..3252378af 100644 --- a/app.json +++ b/app.json @@ -1,11 +1,10 @@ { - "name": "Save Restricted", - "description": "Save restricted content", + "name": "Save restricted content bot", + "description": "Telegram bot to save restricted content.", "logo": "", "keywords": [ - "Best", "telegram", - "save restricted", + "Save restricted content", "bot" ], "repository": "https://github.com/vasusen-code/SaveRestrictedContentBot", @@ -25,7 +24,15 @@ "value": "" }, "SESSION": { - "description": "pyrogram string session.", + "description": "Pyrogram string session.", + "value": "" + }, + "AUTH": { + "description": "User ID of Bot owner.", + "value": "" + }, + "FORCESUB": { + "description": "Username name of public channel without using '@'.", "value": "" } }, diff --git a/bash.sh b/bash.sh new file mode 100644 index 000000000..0dc8e8668 --- /dev/null +++ b/bash.sh @@ -0,0 +1,2 @@ +echo "starting Bot ~@DroneBots"; +python3 -m main diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..51b41620d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.3" + +services: + app: + container_name: srcbot + build: . + command: bash bash.sh + environment: + API_ID: # Your API HASH from my.telegram.org + API_HASH: # Your API ID from my.telegram.org + BOT_TOKEN: # Bot token, get it from @BotFather + SESSION: # Pyrogram string session + AUTH: # User ID of Bot owner + FORCESUB: # Username name of public channel without using '@' diff --git a/main/__init__.py b/main/__init__.py index 61b926b96..f4f60cf34 100644 --- a/main/__init__.py +++ b/main/__init__.py @@ -1,9 +1,12 @@ -#ChauhanMahesh/Vasusen/DroneBots/COL +#Github.com/Vasusen-code + +from pyrogram import Client + +from telethon.sessions import StringSession +from telethon.sync import TelegramClient -from telethon import TelegramClient from decouple import config -import logging -import time +import logging, time, sys logging.basicConfig(format='[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s', level=logging.WARNING) @@ -13,5 +16,28 @@ API_HASH = config("API_HASH", default=None) BOT_TOKEN = config("BOT_TOKEN", default=None) SESSION = config("SESSION", default=None) +FORCESUB = config("FORCESUB", default=None) +AUTH = config("AUTH", default=None, cast=int) bot = TelegramClient('bot', API_ID, API_HASH).start(bot_token=BOT_TOKEN) + +userbot = Client("saverestricted", session_string=SESSION, api_hash=API_HASH, api_id=API_ID) + +try: + userbot.start() +except BaseException: + print("Userbot Error ! Have you added SESSION while deploying??") + sys.exit(1) + +Bot = Client( + "SaveRestricted", + bot_token=BOT_TOKEN, + api_id=int(API_ID), + api_hash=API_HASH +) + +try: + Bot.start() +except Exception as e: + print(e) + sys.exit(1) diff --git a/main/__main__.py b/main/__main__.py index ffaa319ba..fda9da21e 100644 --- a/main/__main__.py +++ b/main/__main__.py @@ -15,7 +15,9 @@ plugin_name = patt.stem load_plugins(plugin_name.replace(".py", "")) +#Don't be a thief print("Successfully deployed!") +print("By MaheshChauhan • DroneBots") if __name__ == "__main__": bot.run_until_disconnected() diff --git a/main/plugins/batch.py b/main/plugins/batch.py new file mode 100644 index 000000000..2bb76d965 --- /dev/null +++ b/main/plugins/batch.py @@ -0,0 +1,113 @@ +#Tg:MaheshChauhan/DroneBots +#Github.com/Vasusen-code + +""" +Plugin for both public & private channels! +""" + +import time, os, asyncio + +from .. import bot as Drone +from .. import userbot, Bot, AUTH +from .. import FORCESUB as fs +from main.plugins.pyroplug import get_bulk_msg +from main.plugins.helpers import get_link, screenshot + +from telethon import events, Button, errors +from telethon.tl.types import DocumentAttributeVideo + +from pyrogram import Client +from pyrogram.errors import FloodWait + +from ethon.pyfunc import video_metadata +from ethon.telefunc import force_sub + +ft = f"To use this bot you've to join @{fs}." + +batch = [] + +@Drone.on(events.NewMessage(incoming=True, from_users=AUTH, pattern='/cancel')) +async def cancel(event): + if not event.sender_id in batch: + return await event.reply("No batch active.") + batch.clear() + await event.reply("Done.") + +@Drone.on(events.NewMessage(incoming=True, from_users=AUTH, pattern='/batch')) +async def _batch(event): + if not event.is_private: + return + s, r = await force_sub(event.client, fs, event.sender_id, ft) + if s == True: + await event.reply(r) + return + if event.sender_id in batch: + return await event.reply("You've already started one batch, wait for it to complete you dumbfuck owner!") + async with Drone.conversation(event.chat_id) as conv: + if s != True: + await conv.send_message("Send me the message link you want to start saving from, as a reply to this message.", buttons=Button.force_reply()) + try: + link = await conv.get_reply() + try: + _link = get_link(link.text) + except Exception: + await conv.send_message("No link found.") + return conv.cancel() + except Exception as e: + print(e) + await conv.send_message("Cannot wait more longer for your response!") + return conv.cancel() + await conv.send_message("Send me the number of files/range you want to save from the given message, as a reply to this message.", buttons=Button.force_reply()) + try: + _range = await conv.get_reply() + except Exception as e: + print(e) + await conv.send_message("Cannot wait more longer for your response!") + return conv.cancel() + try: + value = int(_range.text) + if value > 100: + await conv.send_message("You can only get upto 100 files in a single batch.") + return conv.cancel() + except ValueError: + await conv.send_message("Range must be an integer!") + return conv.cancel() + batch.append(event.sender_id) + await run_batch(userbot, Bot, event.sender_id, _link, value) + conv.cancel() + batch.clear() + +async def run_batch(userbot, client, sender, link, _range): + for i in range(_range): + timer = 60 + if i < 25: + timer = 5 + if i < 50 and i > 25: + timer = 10 + if i < 100 and i > 50: + timer = 15 + if not 't.me/c/' in link: + if i < 25: + timer = 2 + else: + timer = 3 + try: + if not sender in batch: + await client.send_message(sender, "Batch completed.") + break + except Exception as e: + print(e) + await client.send_message(sender, "Batch completed.") + break + try: + await get_bulk_msg(userbot, client, sender, link, i) + except FloodWait as fw: + if int(fw.x) > 299: + await client.send_message(sender, "Cancelling batch since you have floodwait more than 5 minutes.") + break + await asyncio.sleep(fw.x + 5) + await get_bulk_msg(userbot, client, sender, link, i) + protection = await client.send_message(sender, f"Sleeping for `{timer}` seconds to avoid Floodwaits and Protect account!") + await asyncio.sleep(timer) + await protection.delete() + diff --git a/main/plugins/frontend.py b/main/plugins/frontend.py new file mode 100644 index 000000000..b35c84ea0 --- /dev/null +++ b/main/plugins/frontend.py @@ -0,0 +1,49 @@ +#Github.com/Vasusen-code + +import time, os + +from .. import bot as Drone +from .. import userbot, Bot +from .. import FORCESUB as fs +from main.plugins.pyroplug import get_msg +from main.plugins.helpers import get_link, join + +from telethon import events +from pyrogram.errors import FloodWait + +from ethon.telefunc import force_sub + +ft = f"To use this bot you've to join @{fs}." + +message = "Send me the message link you want to start saving from, as a reply to this message." + +@Drone.on(events.NewMessage(incoming=True, func=lambda e: e.is_private)) +async def clone(event): + if event.is_reply: + reply = await event.get_reply_message() + if reply.text == message: + return + try: + link = get_link(event.text) + if not link: + return + except TypeError: + return + s, r = await force_sub(event.client, fs, event.sender_id, ft) + if s == True: + await event.reply(r) + return + edit = await event.reply("Processing!") + try: + if 't.me/+' in link: + q = await join(userbot, link) + await edit.edit(q) + return + if 't.me/' in link: + await get_msg(userbot, Bot, Drone, event.sender_id, edit.id, link, 0) + except FloodWait as fw: + return await Drone.send_message(event.sender_id, f'Try again after {fw.x} seconds due to floodwait from telegram.') + except Exception as e: + print(e) + await Drone.send_message(event.sender_id, f"An error occurred during cloning of `{link}`\n\n**Error:** {str(e)}") + diff --git a/main/plugins/helpers.py b/main/plugins/helpers.py index 8f03ae0fa..bc3ed2a47 100644 --- a/main/plugins/helpers.py +++ b/main/plugins/helpers.py @@ -1,9 +1,11 @@ #Github.com/Vasusen-code -from pyrogram import Client -from pyrogram.errors import FloodWait, BadRequest +from pyrogram.errors import FloodWait, InviteHashInvalid, InviteHashExpired, UserAlreadyParticipant +from telethon import errors, events import asyncio, subprocess, re, os, time +from pathlib import Path +from datetime import datetime as dt #Join private chat------------------------------------------------------------------------------------------------------------- @@ -11,13 +13,16 @@ async def join(client, invite_link): try: await client.join_chat(invite_link) return "Successfully joined the Channel" - except BadRequest: + except UserAlreadyParticipant: + return "User is already a participant." + except (InviteHashInvalid, InviteHashExpired): return "Could not join. Maybe your link is expired or Invalid." except FloodWait: return "Too many requests, try again later." except Exception as e: - return f"{str(e)}" - + print(e) + return "Could not join, try joining manually." + #Regex--------------------------------------------------------------------------------------------------------------- #to get the url from event @@ -35,23 +40,34 @@ def get_link(string): #Screenshot--------------------------------------------------------------------------------------------------------------- -async def screenshot(video, time_stamp, sender): - if os.path.isfile(f'{sender}.jpg'): +def hhmmss(seconds): + x = time.strftime('%H:%M:%S',time.gmtime(seconds)) + return x + +async def screenshot(video, duration, sender): + if os.path.exists(f'{sender}.jpg'): return f'{sender}.jpg' - out = str(video).split(".")[0] + ".jpg" - cmd = (f"ffmpeg -ss {time_stamp} -i {video} -vframes 1 {out}").split(" ") + time_stamp = hhmmss(int(duration)/2) + out = dt.now().isoformat("_", "seconds") + ".jpg" + cmd = ["ffmpeg", + "-ss", + f"{time_stamp}", + "-i", + f"{video}", + "-frames:v", + "1", + f"{out}", + "-y" + ] process = await asyncio.create_subprocess_exec( - *cmd, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE) - + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) stdout, stderr = await process.communicate() x = stderr.decode().strip() y = stdout.decode().strip() - print(x) - print(y) if os.path.isfile(out): return out else: - None - + None diff --git a/main/plugins/main.py b/main/plugins/main.py deleted file mode 100644 index be7a6fd77..000000000 --- a/main/plugins/main.py +++ /dev/null @@ -1,130 +0,0 @@ -# Github.com/Vasusen-code - -from main.plugins.helpers import get_link, join, screenshot -from main.plugins.display_progress import progress_for_pyrogram - -from decouple import config - -API_ID = config("API_ID", default=None, cast=int) -API_HASH = config("API_HASH", default=None) -BOT_TOKEN = config("BOT_TOKEN", default=None) -SESSION = config("SESSION", default=None) #pyro session - -from pyrogram.errors import FloodWait, BadRequest -from pyrogram import Client, filters -from ethon.pyfunc import video_metadata - -import re, time, asyncio, logging, os - -logging.basicConfig(format='[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s', - level=logging.WARNING) - -Bot = Client( - "Simple-Pyrogram-Bot", - bot_token=BOT_TOKEN, - api_id=int(API_ID), - api_hash=API_HASH -) - -userbot = Client( - session_name=SESSION, - api_hash=API_HASH, - api_id=API_ID) - -def thumbnail(sender): - if os.path.exists(f'{sender}.jpg'): - return f'{sender}.jpg' - else: - return None - -async def get_msg(userbot, client, sender, msg_link, edit): - chat = "" - msg_id = int(msg_link.split("/")[-1]) - if 't.me/c/' in msg_link: - chat = int('-100' + str(msg_link.split("/")[-2])) - try: - msg = await userbot.get_messages(chat, msg_id) - file = await userbot.download_media( - msg, - progress=progress_for_pyrogram, - progress_args=( - userbot, - "**DOWNLOADING:**\n", - edit, - time.time() - ) - ) - await edit.edit('Trying to Upload.') - caption = "" - if msg.text is not None: - caption = msg.text - if str(file).split(".")[-1] == 'mkv' or 'mp4' or 'webm': - if str(file).split(".")[-1] == 'webm' or 'mkv': - path = str(file).split(".")[0] + ".mp4" - os.rename(file, path) - file = str(file).split(".")[0] + ".mp4" - data = video_metadata(file) - duration = data["duration"] - thumb_path = await screenshot(file, duration/2, sender) - await client.send_video( - chat_id=sender, - video=file, - caption=caption, - supports_streaming=True, - duration=duration, - thumb=thumb_path, - progress=progress_for_pyrogram, - progress_args=( - client, - '**UPLOADING:**\n', - edit, - time.time() - ) - ) - else: - thumb_path=thumbnail(sender) - await client.send_document( - sender, - file, - caption=caption, - thumb=thumb_path, - progress=progress_for_pyrogram, - progress_args=( - client, - '**UPLOADING:**\n', - edit, - time.time() - ) - ) - await edit.delete() - except Exception as e: - await edit.edit(f'ERROR: {str(e)}') - return - else: - chat = msg_link.split("/")[-2] - await client.copy_message(int(sender), chat, msg_id) - await edit.delete() - -@Bot.on_message(filters.private & filters.incoming) -async def clone(bot, event): - try: - link = get_link(event.text) - if not link: - return - except TypeError: - return - edit = await bot.send_message(event.chat.id, 'Trying to process.') - if 't.me/+' in link: - xy = await join(userbot, link) - await edit.edit(xy) - return - if 't.me' in link: - try: - await get_msg(userbot, bot, event.chat.id, link, edit) - except FloodWait: - return await edit.edit('Too many requests, try again later.') - except ValueError: - return await edit.edit('Send Only message link or Private channel invites.') - except Exception as e: - return await edit.edit(f'Error: `{str(e)}`') - diff --git a/main/plugins/display_progress.py b/main/plugins/progress.py similarity index 100% rename from main/plugins/display_progress.py rename to main/plugins/progress.py diff --git a/main/plugins/pyroplug.py b/main/plugins/pyroplug.py new file mode 100644 index 000000000..1e608e86a --- /dev/null +++ b/main/plugins/pyroplug.py @@ -0,0 +1,217 @@ +#Github.com-Vasusen-code + +import asyncio, time, os + +from .. import bot as Drone +from main.plugins.progress import progress_for_pyrogram +from main.plugins.helpers import screenshot + +from pyrogram import Client, filters +from pyrogram.errors import ChannelBanned, ChannelInvalid, ChannelPrivate, ChatIdInvalid, ChatInvalid, PeerIdInvalid +from pyrogram.enums import MessageMediaType +from ethon.pyfunc import video_metadata +from ethon.telefunc import fast_upload +from telethon.tl.types import DocumentAttributeVideo +from telethon import events + +def thumbnail(sender): + if os.path.exists(f'{sender}.jpg'): + return f'{sender}.jpg' + else: + return None + +async def get_msg(userbot, client, bot, sender, edit_id, msg_link, i): + + """ userbot: PyrogramUserBot + client: PyrogramBotClient + bot: TelethonBotClient """ + + edit = "" + chat = "" + round_message = False + if "?single" in msg_link: + msg_link = msg_link.split("?single")[0] + msg_id = int(msg_link.split("/")[-1]) + int(i) + height, width, duration, thumb_path = 90, 90, 0, None + if 't.me/c/' or 't.me/b/' in msg_link: + if 't.me/b/' in msg_link: + chat = str(msg_link.split("/")[-2]) + else: + chat = int('-100' + str(msg_link.split("/")[-2])) + file = "" + try: + msg = await userbot.get_messages(chat, msg_id) + if msg.media: + if msg.media==MessageMediaType.WEB_PAGE: + edit = await client.edit_message_text(sender, edit_id, "Cloning.") + await client.send_message(sender, msg.text.markdown) + await edit.delete() + return + if not msg.media: + if msg.text: + edit = await client.edit_message_text(sender, edit_id, "Cloning.") + await client.send_message(sender, msg.text.markdown) + await edit.delete() + return + edit = await client.edit_message_text(sender, edit_id, "Trying to Download.") + file = await userbot.download_media( + msg, + progress=progress_for_pyrogram, + progress_args=( + client, + "**DOWNLOADING:**\n", + edit, + time.time() + ) + ) + print(file) + await edit.edit('Preparing to Upload!') + caption = None + if msg.caption is not None: + caption = msg.caption + if msg.media==MessageMediaType.VIDEO_NOTE: + round_message = True + print("Trying to get metadata") + data = video_metadata(file) + height, width, duration = data["height"], data["width"], data["duration"] + print(f'd: {duration}, w: {width}, h:{height}') + try: + thumb_path = await screenshot(file, duration, sender) + except Exception: + thumb_path = None + await client.send_video_note( + chat_id=sender, + video_note=file, + length=height, duration=duration, + thumb=thumb_path, + progress=progress_for_pyrogram, + progress_args=( + client, + '**UPLOADING:**\n', + edit, + time.time() + ) + ) + elif msg.media==MessageMediaType.VIDEO and msg.video.mime_type in ["video/mp4", "video/x-matroska"]: + print("Trying to get metadata") + data = video_metadata(file) + height, width, duration = data["height"], data["width"], data["duration"] + print(f'd: {duration}, w: {width}, h:{height}') + try: + thumb_path = await screenshot(file, duration, sender) + except Exception: + thumb_path = None + await client.send_video( + chat_id=sender, + video=file, + caption=caption, + supports_streaming=True, + height=height, width=width, duration=duration, + thumb=thumb_path, + progress=progress_for_pyrogram, + progress_args=( + client, + '**UPLOADING:**\n', + edit, + time.time() + ) + ) + + elif msg.media==MessageMediaType.PHOTO: + await edit.edit("Uploading photo.") + await bot.send_file(sender, file, caption=caption) + else: + thumb_path=thumbnail(sender) + await client.send_document( + sender, + file, + caption=caption, + thumb=thumb_path, + progress=progress_for_pyrogram, + progress_args=( + client, + '**UPLOADING:**\n', + edit, + time.time() + ) + ) + try: + os.remove(file) + if os.path.isfile(file) == True: + os.remove(file) + except Exception: + pass + await edit.delete() + except (ChannelBanned, ChannelInvalid, ChannelPrivate, ChatIdInvalid, ChatInvalid): + await client.edit_message_text(sender, edit_id, "Have you joined the channel?") + return + except PeerIdInvalid: + chat = msg_link.split("/")[-3] + try: + int(chat) + new_link = f"t.me/c/{chat}/{msg_id}" + except: + new_link = f"t.me/b/{chat}/{msg_id}" + return await get_msg(userbot, client, bot, sender, edit_id, msg_link, i) + except Exception as e: + print(e) + if "messages.SendMedia" in str(e) \ + or "SaveBigFilePartRequest" in str(e) \ + or "SendMediaRequest" in str(e) \ + or str(e) == "File size equals to 0 B": + try: + if msg.media==MessageMediaType.VIDEO and msg.video.mime_type in ["video/mp4", "video/x-matroska"]: + UT = time.time() + uploader = await fast_upload(f'{file}', f'{file}', UT, bot, edit, '**UPLOADING:**') + attributes = [DocumentAttributeVideo(duration=duration, w=width, h=height, round_message=round_message, supports_streaming=True)] + await bot.send_file(sender, uploader, caption=caption, thumb=thumb_path, attributes=attributes, force_document=False) + elif msg.media==MessageMediaType.VIDEO_NOTE: + uploader = await fast_upload(f'{file}', f'{file}', UT, bot, edit, '**UPLOADING:**') + attributes = [DocumentAttributeVideo(duration=duration, w=width, h=height, round_message=round_message, supports_streaming=True)] + await bot.send_file(sender, uploader, caption=caption, thumb=thumb_path, attributes=attributes, force_document=False) + else: + UT = time.time() + uploader = await fast_upload(f'{file}', f'{file}', UT, bot, edit, '**UPLOADING:**') + await bot.send_file(sender, uploader, caption=caption, thumb=thumb_path, force_document=True) + if os.path.isfile(file) == True: + os.remove(file) + except Exception as e: + print(e) + await client.edit_message_text(sender, edit_id, f'Failed to save: `{msg_link}`\n\nError: {str(e)}') + try: + os.remove(file) + except Exception: + return + return + else: + await client.edit_message_text(sender, edit_id, f'Failed to save: `{msg_link}`\n\nError: {str(e)}') + try: + os.remove(file) + except Exception: + return + return + try: + os.remove(file) + if os.path.isfile(file) == True: + os.remove(file) + except Exception: + pass + await edit.delete() + else: + edit = await client.edit_message_text(sender, edit_id, "Cloning.") + chat = msg_link.split("t.me")[1].split("/")[1] + try: + msg = await client.get_messages(chat, msg_id) + if msg.empty: + new_link = f't.me/b/{chat}/{int(msg_id)}' + #recurrsion + return await get_msg(userbot, client, bot, sender, edit_id, new_link, i) + await client.copy_message(sender, chat, msg_id) + except Exception as e: + print(e) + return await client.edit_message_text(sender, edit_id, f'Failed to save: `{msg_link}`\n\nError: {str(e)}') + await edit.delete() + +async def get_bulk_msg(userbot, client, sender, msg_link, i): + x = await client.send_message(sender, "Processing!") + await get_msg(userbot, client, Drone, sender, x.id, msg_link, i) diff --git a/main/plugins/start.py b/main/plugins/start.py index 96d37c5b0..9e8656cda 100644 --- a/main/plugins/start.py +++ b/main/plugins/start.py @@ -1,33 +1,14 @@ #Github.com/Vasusen-code import os -from .. import bot -from telethon import events, Button, TelegramClient +from .. import bot as Drone +from telethon import events, Button -from pyrogram import idle -from main.plugins.main import Bot, userbot - -st = "Send me Link of any message to clone it here, For private channel message, send invite link first.\n\n**SUPPORT:** @TeamDrone\n**DEV:** @MaheshChauhan" - -@bot.on(events.NewMessage(incoming=True, pattern="/start")) -async def start(event): - await event.reply(f'{st}', - buttons=[ - [Button.inline("SET THUMB.", data="sett"), - Button.inline("REM THUMB.", data="remt")] - ]) - try: - await Bot.start() - await userbot.start() - await idle() - except Exception as e: - if 'Client is already connected' in str(e): - pass - else: - await event.client.send_message(event.chat_id, "Error while starting Client, check if your API and SESSION is right.") - return +from ethon.mystarts import start_srb -@bot.on(events.callbackquery.CallbackQuery(data="sett")) +S = '/' + 's' + 't' + 'a' + 'r' + 't' + +@Drone.on(events.callbackquery.CallbackQuery(data="set")) async def sett(event): Drone = event.client button = await event.get_message() @@ -51,7 +32,7 @@ async def sett(event): os.rename(path, f'./{event.sender_id}.jpg') await t.edit("Temporary thumbnail saved!") -@bot.on(events.callbackquery.CallbackQuery(data="remt")) +@Drone.on(events.callbackquery.CallbackQuery(data="rem")) async def remt(event): Drone = event.client await event.edit('Trying.') @@ -60,5 +41,9 @@ async def remt(event): await event.edit('Removed!') except Exception: await event.edit("No thumbnail saved.") - + +@Drone.on(events.NewMessage(incoming=True, pattern=f"{S}")) +async def start(event): + text = "Send me Link of any message to clone it here, For private channel message, send invite link first.\n\n**SUPPORT:** @TeamDrone" + await start_srb(event, text) diff --git a/okteto-stack.yaml b/okteto-stack.yaml new file mode 100644 index 000000000..0ee662476 --- /dev/null +++ b/okteto-stack.yaml @@ -0,0 +1,15 @@ +services: + drone-srcb: + build: . + environment: + API_ID: $API_ID + API_HASH: $API_HASH + BOT_TOKEN: $BOT_TOKEN + SESSION: $SESSION + AUTH: $AUTH + FORCESUB: $FORCESUB + ports: + - 8080 + resources: + cpu: 1000m + memory: 3Gi diff --git a/requirements.txt b/requirements.txt index 406231484..48fcbc6ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,8 @@ -ethon -python-decouple -pyrogram -telethon +#Github.com-Vasusen-code + +https://github.com/vasusen-code/Telethon/archive/refs/tags/v1.24.0.zip +https://github.com/vasusen-code/ethon/archive/refs/tags/v0.1.5.zip +cryptg tgcrypto +pyrogram +python-decouple