- * Bot will automatically download links in those chats/channels.
- * Now copy that message's link and you will get something like
- https://t.me/c/123456789/1
- * So your values would be LOG=-100123456789 MESSAGE=1
+ * Copy the links of those messages.
+
+ * The last digits of these links are the message ids.
+
+ * These two are your AUTO_DL_MESSAGE_ID and BLOCKED_USERS_MESSAGE_ID DB.
+ * Add their IDs in config respectively.
+
+
+ Now send another message but this time include your id in the list: [12345678]
+
+ * Copy this message's link and add the message id in USERS_MESSAGE_ID var
{len(Config.CHATS)}
chats\n"
+ supported_sites, photo = await bot.get_messages("Social_DL", [2, 3])
+ await photo.copy(message.chat.id, caption="\n".join([head, chat_count, supported_sites.text.html]))
+
+@bot.add_cmd(cmd="help")
+async def help(bot, message):
+ commands = "\n".join([ f"{Config.TRIGGER}{i}
" for i in Config.CMD_DICT.keys()])
+ await message.reply(f"Available Commands:\n\n{commands}")
+
+@bot.add_cmd(cmd="restart")
+async def restart(bot, message):
+ reply = await message.reply("restarting....")
+ if message.chat.type in [ChatType.GROUP, ChatType.SUPERGROUP]:
+ os.environ["RESTART_MSG"] = str(reply.id)
+ os.environ["RESTART_CHAT"] = str(reply.chat.id)
+ await bot.restart()
+
+
+@bot.add_cmd(cmd="update")
+async def chat_update(bot, message):
+ await bot.set_filter_list()
+ await message.reply("Filters Refreshed")
diff --git a/app/plugins/tgUtils.py b/app/plugins/tgUtils.py
new file mode 100644
index 0000000..dace3b9
--- /dev/null
+++ b/app/plugins/tgUtils.py
@@ -0,0 +1,75 @@
+import os
+
+from pyrogram.enums import ChatType
+from pyrogram.errors import BadRequest
+from pyrogram.types import Message
+
+from app import bot
+
+# Delete replied and command message
+
+
+@bot.add_cmd(cmd="del")
+async def delete_message(bot, message: Message):
+ await message.delete(reply=True)
+
+
+# Delete Multiple messages from replied to command.
+@bot.add_cmd(cmd="purge")
+async def purge_(bot, message: Message):
+ reply = message.replied
+ if not reply:
+ return await message.reply("reply to a message")
+ start_message = reply.id
+ end_message = message.id
+ messages = [end_message] + [i for i in range(int(start_message), int(end_message))]
+ await bot.delete_messages(chat_id=message.chat.id, message_ids=messages, revoke=True)
+
+
+@bot.add_cmd(cmd="ids")
+async def get_ids(bot, message):
+ if reply := message.replied:
+ ids = ""
+ reply_forward = reply.forward_from_chat
+ reply_user = reply.from_user
+ ids += f"Chat : `{reply.chat.id}`\n"
+ if reply_forward:
+ ids += f"Replied {'Channel' if reply_forward.type == ChatType.CHANNEL else 'Chat'} : `{reply_forward.id}`\n"
+ if reply_user:
+ ids += f"User : {reply.from_user.id}"
+ else:
+ ids = f"Chat :`{message.chat.id}`"
+ await message.reply(ids)
+
+
+@bot.add_cmd(cmd="join")
+async def join_chat(bot, message):
+ chat = message.input
+ if chat.isdigit():
+ chat = int(f"-100{chat}")
+ try:
+ await bot.join_chat(chat)
+ except (KeyError, BadRequest):
+ try:
+ await bot.join_chat(os.path.basename(chat).strip())
+ except Exception as e:
+ return await message.reply(str(e))
+ await message.reply("Joined")
+
+
+@bot.add_cmd(cmd="leave")
+async def leave_chat(bot, message):
+ if message.input:
+ chat = message.input
+ else:
+ chat = message.chat.id
+ try:
+ await bot.leave_chat(chat)
+ except Exception as e:
+ await message.reply(str(e))
+
+
+@bot.add_cmd(cmd="reply")
+async def reply(bot, message):
+ text = message.input
+ await bot.send_message(chat_id=message.chat.id, text=text, reply_to_message_id=message.reply_id, disable_web_page_preview=True)
diff --git a/app/plugins/tools.py b/app/plugins/tools.py
new file mode 100644
index 0000000..742ad13
--- /dev/null
+++ b/app/plugins/tools.py
@@ -0,0 +1,76 @@
+import asyncio
+import sys
+import traceback
+from io import StringIO
+
+from pyrogram.enums import ParseMode
+
+from app import Config
+from app.core import shell
+from app.core.aiohttp_tools import SESSION, in_memory_dl
+
+# Run shell commands
+
+async def run_cmd(bot, message):
+ cmd = message.input.strip()
+ status_ = await message.reply("executing...")
+ proc_stdout = await shell.run_shell_cmd(cmd)
+ output = f"`${cmd}`\n\n`{proc_stdout}`"
+ return await status_.edit(output, name="sh.txt", disable_web_page_preview=True)
+
+
+# Shell but Live Output
+
+
+async def live_shell(bot, message):
+ cmd = message.input.strip()
+ sub_process = await shell.AsyncShell.run_cmd(cmd)
+ reply = await message.reply("`getting live output....`")
+ output = ""
+ sleep_for = 1
+ while sub_process.is_not_completed:
+ # Edit message only when there's new output.
+ if output != sub_process.full_std:
+ output = sub_process.full_std
+ if len(output) <= 4096:
+ await reply.edit(f"`{output}`", disable_web_page_preview=True, parse_mode=ParseMode.MARKDOWN)
+ # Reset sleep duration
+ if sleep_for >= 5:
+ sleep_for = 1
+ # Sleep to Unblock running loop and let output reader read new
+ # output.
+ await asyncio.sleep(sleep_for)
+ sleep_for += 1
+ # If the subprocess is finished edit the message with cmd and full
+ # output
+ return await reply.edit(f"`$ {cmd}\n\n``{sub_process.full_std}`", name="shell.txt", disable_web_page_preview=True)
+
+
+# Run Python code
+async def executor_(bot, message):
+ code = message.flt_input.strip()
+ if not code:
+ return await message.reply("exec Jo mama?")
+ reply = await message.reply("executing")
+ sys.stdout = codeOut = StringIO()
+ sys.stderr = codeErr = StringIO()
+ # Indent code as per proper python syntax
+ formatted_code = "\n ".join(code.splitlines())
+ try:
+ # Create and initialise the function
+ exec(f"async def _exec(bot, message):\n {formatted_code}")
+ func_out = await locals().get("_exec")(bot, message)
+ except BaseException:
+ func_out = str(traceback.format_exc())
+ sys.stdout = sys.__stdout__
+ sys.stderr = sys.__stderr__
+ output = f"`{codeOut.getvalue().strip() or codeErr.getvalue().strip() or func_out}`"
+ if "-s" not in message.flags:
+ output = f"> `{code}`\n\n>> {output}"
+ return await reply.edit(output, name="exec.txt", disable_web_page_preview=True,parse_mode=ParseMode.MARKDOWN)
+
+
+if Config.DEV_MODE:
+ Config.CMD_DICT["sh"] = run_cmd
+ Config.CMD_DICT["shell"] = live_shell
+ Config.CMD_DICT["exec"] = executor_
diff --git a/app/social_dl.py b/app/social_dl.py
new file mode 100644
index 0000000..85a322a
--- /dev/null
+++ b/app/social_dl.py
@@ -0,0 +1,39 @@
+import traceback
+from app import Config, bot
+from app.core import filters
+from app.core.MediaHandler import ExtractAndSendMedia
+from app.core.message import Message
+
+
+@bot.add_cmd(cmd="dl")
+async def dl(bot, message):
+ reply = await bot.send_message(chat_id=message.chat.id, text="`trying to download...`")
+ media = await ExtractAndSendMedia.process(message)
+ if media.exceptions:
+ exceptions = "\n".join(media.exceptions)
+ await bot.log(text=exceptions, func="DL", chat=message.chat.id, name="traceback.txt")
+ return await reply.edit(f"Media Download Failed.")
+ if media.media_objects:
+ await message.delete()
+ await reply.delete()
+
+
+@bot.on_message(filters.user_filter)
+@bot.on_edited_message(filters.user_filter)
+async def cmd_dispatcher(bot, message):
+ func = Config.CMD_DICT[message.text.split(maxsplit=1)[0].lstrip(Config.TRIGGER)]
+ parsed_message = Message.parse_message(message)
+ try:
+ await func(bot, parsed_message)
+ except BaseException:
+ await bot.log(text=str(traceback.format_exc()), chat=message.chat.id, func=func.__name__, name="traceback.txt")
+
+
+@bot.on_message(filters.chat_filter)
+async def dl_dispatcher(bot, message):
+ func = Config.CMD_DICT["dl"]
+ parsed_message = Message.parse_message(message)
+ try:
+ await func(bot, parsed_message)
+ except BaseException:
+ await bot.log(text=str(traceback.format_exc()), chat=message.chat.id, func=func.__name__, name="traceback.txt")
diff --git a/assets/social_downloader.png b/assets/social_downloader.png
new file mode 100644
index 0000000000000000000000000000000000000000..d3f013b76a3a7d07d759fdc3194d07b8e1ca0502
GIT binary patch
literal 269018
zcmeEsg;!PI*7iYKNB#{W6lIQrPBYp-P7kTmTF(awq
zT}w`6Qg^wd*>AK--3SB6I0H37A1jm@^(L1~!>;NXqhn@VQ8Ma-{tUG=*K}l^R+{6|
zK-ZZio?<95AoppdnRT|3e~~ZHa06PkZ5vmY-8}>*qCwA)dDlIK!_e3kRewAww+(nT
zHZ#N2B@4wu>ffNRp8fqv%Fu?~iIcOY&gG(XJkZY~1~-0%9A9KfNj-lrqLv@nS=3Jl
z#L4EY_p~KiYU(6MDoLE{qFo=c^(mG%M@4V5+1w*6fqi_N Vx~O4Gxk195!&_9Y`S2!X-<$)$?p|X
zi