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 [](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 [](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)
+
+[](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