├── Dockerfile ├── LICENSE ├── Procfile ├── README.md ├── app.json ├── bot.py ├── config.py ├── helper ├── database.py └── utils.py ├── plugins ├── admin_panel.py ├── auto_rename.py ├── file_rename.py ├── force_subs.py ├── start_&_cb.py └── thumb_&_cap.py ├── render.yaml ├── requirements.txt ├── route.py └── runtime.txt /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10 2 | WORKDIR /app 3 | COPY . /app/ 4 | RUN pip install -r requirements.txt 5 | CMD ["python", "bot.py"] 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: python bot.py 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | logo 2 | 3 |

4 | Auto Rename Bot 5 |

6 | 7 |

🩵 Thanks for Being Here 🩵

8 | 9 | 10 | ### CONFIGS VARIABLES 11 | 12 | * `BOT_TOKEN` - Get bot token from @BotFather 13 | * `API_ID` - From my.telegram.org 14 | * `API_HASH` - From my.telegram.org 15 | * `ADMIN` - Admin user id 16 | * `LOG_CHANNEL` - Bot Log Channel Id startswith -100 must. 17 | * `DB_URL` - Mongo Database URL from https://cloud.mongodb.com 18 | * `DB_NAME` - Your database name from mongoDB. (Optional) 19 | * `FORCE_SUB` - Your force sub channel username without @ (Optional) 20 | * `START_PIC` - Start message photo. (Optional) 21 | 22 | 23 | 24 | ### DEPLOYEMENT SUPPORT 25 | 26 | Deploy To Koyeb 27 |

28 |
29 | 30 | Deploy 31 | 32 |

33 | 34 | Deploy To Heroku 35 |

36 |
37 | 38 | Deploy 39 | 40 |

41 | 42 | 43 | 44 | 45 | 46 | ### FEATURES 47 | - Renames very fast . 48 | - Permanent Thumbnail support. 49 | - Supports Broadcasts. 50 | - Set custom caption. 51 | - Has a custom Start-up pic. 52 | - Force subscribe available. 53 | - Supports ulimited renaming at a time. 54 | - Deploy to Koyeb + Heroku + Railway. 55 | - Automatically rename your files 56 | - Set mediatype to upload filetype 57 | - Developer Service 24x7. 🔥 58 | 59 | 60 | 61 | ### ALL COMMANDS 62 | 63 | ``` 64 | start - Check if the bot is running. 65 | autorename - To auto rename your files. 66 | setmedia - To set your media type preference. 67 | tutorial - To know how to use me. 68 | viewthumb - To view current thumbnail. 69 | delthumb - To delete current thumbnail. 70 | set_caption - set a custom caption. 71 | see_caption - see your custom caption. 72 | del_caption - delete custom caption. 73 | restart - To restart the bot [FOR ADMINS USE ONLY] 74 | broadcast - Message Broadcast command [FOR ADMINS USE ONLY]. 75 | status - Check bot status [FOR ADMINS USE ONLY]. 76 | ``` 77 | 78 | 79 | 80 | ### ❤️ RESPECTING ❤️ 81 | - [JishuDeveloper](https://github.com/JishuDeveloper) 82 | - [Trippy](https://github.com/Trippy07) 83 | - [lntechnical](https://github.com/lntechnical2) 84 | 85 | ### 😍 BOTS CHANNEL 😍 86 | - [Madflix Botz](https://t.me/Madflix_Bots) 87 | - [Jishu Botz](https://t.me/JishuBotz) 88 | 89 | ### 💕 CONTACT DEVELOPER 💕 90 | - [Jishu Developer](https://t.me/JishuDeveloper) 91 | - [Trippy](https://t.me/Trippy_xt) 92 | 93 | ### ☕ BUY ME A COFFEE ☕ 94 | - [PayPal](https://paypal.me/jishudeveloper/2.50USD) 95 | - [PhonePe](https://graph.org/file/6822df5af3a2e80637172.jpg) 96 | - [UPI](https://graph.org/file/b831109be4acff5c966d2.jpg) 97 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Auto Renamer Bot", 3 | "description": "Telegram Auto File Renamer Bot ", 4 | "logo": "https://graph.org/file/2f461540c83b362772714.jpg", 5 | "keywords": ["Auto Renamer Bot", "Mongo DB"], 6 | "repository": "https://github.com/JishuDeveloper/Auto-Rename-Bot", 7 | "env": { 8 | "API_ID": { 9 | "description": "Your APP ID From my.telegram.org ", 10 | "value": "" 11 | }, 12 | "API_HASH": { 13 | "description": "Your API Hash From my.telegram.org ", 14 | "value": "" 15 | }, 16 | "WEBHOOK": { 17 | "description": "if your server is need web service! value = True else value = False", 18 | "value": "False" 19 | }, 20 | "FORCE_SUB": { 21 | "description": "Your force sub channel user name without [@] ", 22 | "value": "", 23 | "required": false 24 | }, 25 | "BOT_TOKEN": { 26 | "description": "Your Bot Token From @BotFather", 27 | "value": "" 28 | }, 29 | "ADMIN": { 30 | "description":"Add Your User ID multiple is use space to split" 31 | }, 32 | "LOG_CHANNEL": { 33 | "description":"Bot Log Sending Channel (just create a private channel and add bot to admin and take channel id to add this variable) ⚠️ id startswith -100 must", 34 | "required": false 35 | }, 36 | "DB_URL": { 37 | "description": "Your Mongo DB URL Obtained From mongodb.com", 38 | "value": "" 39 | }, 40 | "DB_NAME":{ 41 | "description":"Your Mongo DB Database Name ", 42 | "value": "", 43 | "required": false 44 | }, 45 | "START_PIC": { 46 | "description": "Your Bot start cmd Pic from @MT_TelegraPH_Bot", 47 | "value": "", 48 | "required": false 49 | } 50 | }, 51 | "buildpacks": [ 52 | { 53 | "url": "heroku/python" 54 | } 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from pytz import timezone 3 | from pyrogram import Client, __version__ 4 | from pyrogram.raw.all import layer 5 | from config import Config 6 | from aiohttp import web 7 | from route import web_server 8 | import pyrogram.utils 9 | 10 | pyrogram.utils.MIN_CHAT_ID = -999999999999 11 | pyrogram.utils.MIN_CHANNEL_ID = -1009999999999 12 | 13 | 14 | class Bot(Client): 15 | 16 | def __init__(self): 17 | super().__init__( 18 | name="renamer", 19 | api_id=Config.API_ID, 20 | api_hash=Config.API_HASH, 21 | bot_token=Config.BOT_TOKEN, 22 | workers=200, 23 | plugins={"root": "plugins"}, 24 | sleep_threshold=15, 25 | ) 26 | 27 | async def start(self): 28 | await super().start() 29 | me = await self.get_me() 30 | self.mention = me.mention 31 | self.username = me.username 32 | self.uptime = Config.BOT_UPTIME 33 | if Config.WEBHOOK: 34 | app = web.AppRunner(await web_server()) 35 | await app.setup() 36 | await web.TCPSite(app, "0.0.0.0", 8080).start() 37 | print(f"{me.first_name} Is Started.....✨️") 38 | for id in Config.ADMIN: 39 | try: await self.send_message(Config.LOG_CHANNEL, f"**{me.first_name} Is Started.....✨️**") 40 | except: pass 41 | if Config.LOG_CHANNEL: 42 | try: 43 | curr = datetime.now(timezone("Asia/Kolkata")) 44 | date = curr.strftime('%d %B, %Y') 45 | time = curr.strftime('%I:%M:%S %p') 46 | await self.send_message(Config.LOG_CHANNEL, f"**{me.mention} Is Restarted !!**\n\n📅 Date : `{date}`\n⏰ Time : `{time}`\n🌐 Timezone : `Asia/Kolkata`\n\n🉐 Version : `v{__version__} (Layer {layer})`
") 47 | except: 48 | print("Please Make This Is Admin In Your Log Channel") 49 | 50 | Bot().run() 51 | 52 | 53 | 54 | # Jishu Developer 55 | # Don't Remove Credit 🥺 56 | # Telegram Channel @Madflix_Bots 57 | # Developer @JishuDeveloper 58 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import re, os, time 2 | id_pattern = re.compile(r'^.\d+$') 3 | 4 | class Config(object): 5 | # pyro client config 6 | API_ID = os.environ.get("API_ID", "") 7 | API_HASH = os.environ.get("API_HASH", "") 8 | BOT_TOKEN = os.environ.get("BOT_TOKEN", "") 9 | 10 | # database config 11 | DB_NAME = os.environ.get("DB_NAME","madflixbotz") 12 | DB_URL = os.environ.get("DB_URL","") 13 | 14 | # other configs 15 | BOT_UPTIME = time.time() 16 | START_PIC = os.environ.get("START_PIC", "https://graph.org/file/4b306f4b15c23a8f22e58.jpg") 17 | ADMIN = [int(admin) if id_pattern.search(admin) else admin for admin in os.environ.get('ADMIN', '').split()] 18 | FORCE_SUB = os.environ.get("FORCE_SUB", "") 19 | LOG_CHANNEL = int(os.environ.get("LOG_CHANNEL", "")) 20 | 21 | # wes response configuration 22 | WEBHOOK = bool(os.environ.get("WEBHOOK", "True")) 23 | 24 | 25 | class Txt(object): 26 | # part of text configuration 27 | 28 | START_TXT = """Hello {} 29 | 30 | ➻ This Is An Advanced And Yet Powerful Rename Bot. 31 | 32 | ➻ Using This Bot You Can Auto Rename Of Your Files. 33 | 34 | ➻ This Bot Also Supports Custom Thumbnail And Custom Caption. 35 | 36 | ➻ Use /tutorial Command To Know How To Use Me. 37 | 38 | Bot Is Made By @Madflix_Bots""" 39 | 40 | FILE_NAME_TXT = """SETUP AUTO RENAME FORMAT 41 | 42 | Use These Keywords To Setup Custom File Name 43 | 44 | ✓ episode :- To Replace Episode Number 45 | ✓ quality :- To Replace Video Resolution 46 | 47 | ➻ Example : /autorename Naruto Shippuden S02 - EPepisode - quality [Dual Audio] - @Madflix_Bots 48 | 49 | ➻ Your Current Auto Rename Format : {format_template} """ 50 | 51 | ABOUT_TXT = f"""🤖 My Name : Auto Rename Bot ⚡ 52 | 📝 Language : Python 3 53 | 📚 Library : Pyrogram 2.0 54 | 🚀 Server : Heroku 55 | 📢 Channel : Madflix Botz 56 | 🧑‍💻 Developer : Jishu Developer 57 | 58 | ♻️ Bot Made By : @Madflix_Bots""" 59 | 60 | 61 | THUMBNAIL_TXT = """🖼️ HOW TO SET THUMBNAIL 62 | 63 | ⦿ You Can Add Custom Thumbnail Simply By Sending A Photo To Me.... 64 | 65 | ⦿ /viewthumb - Use This Command To See Your Thumbnail 66 | ⦿ /delthumb - Use This Command To Delete Your Thumbnail""" 67 | 68 | CAPTION_TXT = """📝  HOW TO SET CAPTION 69 | 70 | ⦿ /set_caption - Use This Command To Set Your Caption 71 | ⦿ /see_caption - Use This Command To See Your Caption 72 | ⦿ /del_caption - Use This Command To Delete Your Caption""" 73 | 74 | PROGRESS_BAR = """\n 75 | 📁 Size : {1} | {2} 76 | ⏳️ Done : {0}% 77 | 🚀 Speed : {3}/s 78 | ⏰️ ETA : {4} """ 79 | 80 | 81 | DONATE_TXT = """🥲 Thanks For Showing Interest In Donation! ❤️ 82 | 83 | If You Like My Bots & Projects, You Can 🎁 Donate Me Any Amount From 10 Rs Upto Your Choice. 84 | 85 | 🛍 UPI ID: madflixofficial@axl """ 86 | 87 | HELP_TXT = """Hey {} 88 | 89 | Here Is The Help For My Commands.""" 90 | 91 | 92 | 93 | 94 | 95 | # Jishu Developer 96 | # Don't Remove Credit 🥺 97 | # Telegram Channel @Madflix_Bots 98 | # Developer @JishuDeveloper 99 | 100 | -------------------------------------------------------------------------------- /helper/database.py: -------------------------------------------------------------------------------- 1 | import motor.motor_asyncio 2 | from config import Config 3 | from .utils import send_log 4 | 5 | class Database: 6 | 7 | def __init__(self, uri, database_name): 8 | self._client = motor.motor_asyncio.AsyncIOMotorClient(uri) 9 | self.madflixbotz = self._client[database_name] 10 | self.col = self.madflixbotz.user 11 | 12 | def new_user(self, id): 13 | return dict( 14 | _id=int(id), 15 | file_id=None, 16 | caption=None, 17 | format_template=None # Add this line for the format template 18 | ) 19 | 20 | async def add_user(self, b, m): 21 | u = m.from_user 22 | if not await self.is_user_exist(u.id): 23 | user = self.new_user(u.id) 24 | await self.col.insert_one(user) 25 | await send_log(b, u) 26 | 27 | async def is_user_exist(self, id): 28 | user = await self.col.find_one({'_id': int(id)}) 29 | return bool(user) 30 | 31 | async def total_users_count(self): 32 | count = await self.col.count_documents({}) 33 | return count 34 | 35 | async def get_all_users(self): 36 | all_users = self.col.find({}) 37 | return all_users 38 | 39 | async def delete_user(self, user_id): 40 | await self.col.delete_many({'_id': int(user_id)}) 41 | 42 | async def set_thumbnail(self, id, file_id): 43 | await self.col.update_one({'_id': int(id)}, {'$set': {'file_id': file_id}}) 44 | 45 | async def get_thumbnail(self, id): 46 | user = await self.col.find_one({'_id': int(id)}) 47 | return user.get('file_id', None) 48 | 49 | async def set_caption(self, id, caption): 50 | await self.col.update_one({'_id': int(id)}, {'$set': {'caption': caption}}) 51 | 52 | async def get_caption(self, id): 53 | user = await self.col.find_one({'_id': int(id)}) 54 | return user.get('caption', None) 55 | 56 | async def set_format_template(self, id, format_template): 57 | await self.col.update_one({'_id': int(id)}, {'$set': {'format_template': format_template}}) 58 | 59 | async def get_format_template(self, id): 60 | user = await self.col.find_one({'_id': int(id)}) 61 | return user.get('format_template', None) 62 | 63 | async def set_media_preference(self, id, media_type): 64 | await self.col.update_one({'_id': int(id)}, {'$set': {'media_type': media_type}}) 65 | 66 | async def get_media_preference(self, id): 67 | user = await self.col.find_one({'_id': int(id)}) 68 | return user.get('media_type', None) 69 | 70 | 71 | 72 | madflixbotz = Database(Config.DB_URL, Config.DB_NAME) 73 | 74 | 75 | 76 | # Jishu Developer 77 | # Don't Remove Credit 🥺 78 | # Telegram Channel @Madflix_Bots 79 | # Developer @JishuDeveloper -------------------------------------------------------------------------------- /helper/utils.py: -------------------------------------------------------------------------------- 1 | import math, time 2 | from datetime import datetime 3 | from pytz import timezone 4 | from config import Config, Txt 5 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 6 | 7 | async def progress_for_pyrogram(current, total, ud_type, message, start): 8 | now = time.time() 9 | diff = now - start 10 | if round(diff % 5.00) == 0 or current == total: 11 | percentage = current * 100 / total 12 | speed = current / diff 13 | elapsed_time = round(diff) * 1000 14 | time_to_completion = round((total - current) / speed) * 1000 15 | estimated_total_time = elapsed_time + time_to_completion 16 | 17 | elapsed_time = TimeFormatter(milliseconds=elapsed_time) 18 | estimated_total_time = TimeFormatter(milliseconds=estimated_total_time) 19 | 20 | progress = "{0}{1}".format( 21 | ''.join(["⬢" for i in range(math.floor(percentage / 5))]), 22 | ''.join(["⬡" for i in range(20 - math.floor(percentage / 5))]) 23 | ) 24 | tmp = progress + Txt.PROGRESS_BAR.format( 25 | round(percentage, 2), 26 | humanbytes(current), 27 | humanbytes(total), 28 | humanbytes(speed), 29 | estimated_total_time if estimated_total_time != '' else "0 s" 30 | ) 31 | try: 32 | await message.edit( 33 | text=f"{ud_type}\n\n{tmp}", 34 | reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("✖️ Cancel ✖️", callback_data="close")]]) 35 | ) 36 | except: 37 | pass 38 | 39 | 40 | 41 | def humanbytes(size): 42 | if not size: 43 | return "" 44 | power = 2**10 45 | n = 0 46 | Dic_powerN = {0: ' ', 1: 'K', 2: 'M', 3: 'G', 4: 'T'} 47 | while size > power: 48 | size /= power 49 | n += 1 50 | return str(round(size, 2)) + " " + Dic_powerN[n] + 'b' 51 | 52 | 53 | def TimeFormatter(milliseconds: int) -> str: 54 | seconds, milliseconds = divmod(int(milliseconds), 1000) 55 | minutes, seconds = divmod(seconds, 60) 56 | hours, minutes = divmod(minutes, 60) 57 | days, hours = divmod(hours, 24) 58 | tmp = ((str(days) + "d, ") if days else "") + \ 59 | ((str(hours) + "h, ") if hours else "") + \ 60 | ((str(minutes) + "m, ") if minutes else "") + \ 61 | ((str(seconds) + "s, ") if seconds else "") + \ 62 | ((str(milliseconds) + "ms, ") if milliseconds else "") 63 | return tmp[:-2] 64 | 65 | def convert(seconds): 66 | seconds = seconds % (24 * 3600) 67 | hour = seconds // 3600 68 | seconds %= 3600 69 | minutes = seconds // 60 70 | seconds %= 60 71 | return "%d:%02d:%02d" % (hour, minutes, seconds) 72 | 73 | async def send_log(b, u): 74 | if Config.LOG_CHANNEL is not None: 75 | curr = datetime.now(timezone("Asia/Kolkata")) 76 | date = curr.strftime('%d %B, %Y') 77 | time = curr.strftime('%I:%M:%S %p') 78 | await b.send_message( 79 | Config.LOG_CHANNEL, 80 | f"New User Started The Bot \n\nUser ID : `{u.id}` \nFirst Name : {u.first_name} \nLast Name : {u.last_name} \nUser Name : @{u.username} \nUser Mention : {u.mention} \nUser Link : Click Here\n\nDate: {date}\nTime: {time}\n\nBy: {b.mention}" 81 | ) 82 | 83 | 84 | 85 | 86 | # Jishu Developer 87 | # Don't Remove Credit 🥺 88 | # Telegram Channel @Madflix_Bots 89 | # Developer @JishuDeveloper -------------------------------------------------------------------------------- /plugins/admin_panel.py: -------------------------------------------------------------------------------- 1 | from config import Config, Txt 2 | from helper.database import madflixbotz 3 | from pyrogram.types import Message 4 | from pyrogram import Client, filters 5 | from pyrogram.errors import FloodWait, InputUserDeactivated, UserIsBlocked, PeerIdInvalid 6 | import os, sys, time, asyncio, logging, datetime 7 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 8 | 9 | logger = logging.getLogger(__name__) 10 | logger.setLevel(logging.INFO) 11 | ADMIN_USER_ID = Config.ADMIN 12 | 13 | # Flag to indicate if the bot is restarting 14 | is_restarting = False 15 | 16 | @Client.on_message(filters.private & filters.command("restart") & filters.user(ADMIN_USER_ID)) 17 | async def restart_bot(b, m): 18 | global is_restarting 19 | if not is_restarting: 20 | is_restarting = True 21 | await m.reply_text("**🔄 Restarting.....**") 22 | 23 | # Gracefully stop the bot's event loop 24 | b.stop() 25 | time.sleep(2) # Adjust the delay duration based on your bot's shutdown time 26 | 27 | # Restart the bot process 28 | os.execl(sys.executable, sys.executable, *sys.argv) 29 | 30 | 31 | @Client.on_message(filters.private & filters.command(["tutorial"])) 32 | async def tutorial(bot,message): 33 | user_id = message.from_user.id 34 | format_template = await madflixbotz.get_format_template(user_id) 35 | await message.reply_text( 36 | text =Txt.FILE_NAME_TXT.format(format_template=format_template), 37 | disable_web_page_preview=True, 38 | reply_markup=InlineKeyboardMarkup([ 39 | [InlineKeyboardButton("🦋 Admin",url = "https://t.me/CallAdminRobot"), 40 | InlineKeyboardButton("⚡ Tutorial",url = "https://t.me/MadflixBots_Support") ]]) 41 | ) 42 | 43 | 44 | @Client.on_message(filters.command(["stats", "status"]) & filters.user(Config.ADMIN)) 45 | async def get_stats(bot, message): 46 | total_users = await madflixbotz.total_users_count() 47 | uptime = time.strftime("%Hh%Mm%Ss", time.gmtime(time.time() - bot.uptime)) 48 | start_t = time.time() 49 | st = await message.reply('**Accessing The Details.....**') 50 | end_t = time.time() 51 | time_taken_s = (end_t - start_t) * 1000 52 | await st.edit(text=f"**--Bot Status--** \n\n**⌚️ Bot Uptime :** {uptime} \n**🐌 Current Ping :** `{time_taken_s:.3f} ms` \n**👭 Total Users :** `{total_users}`") 53 | 54 | @Client.on_message(filters.command("broadcast") & filters.user(Config.ADMIN) & filters.reply) 55 | async def broadcast_handler(bot: Client, m: Message): 56 | await bot.send_message(Config.LOG_CHANNEL, f"{m.from_user.mention} or {m.from_user.id} Is Started The Broadcast......") 57 | all_users = await madflixbotz.get_all_users() 58 | broadcast_msg = m.reply_to_message 59 | sts_msg = await m.reply_text("Broadcast Started..!") 60 | done = 0 61 | failed = 0 62 | success = 0 63 | start_time = time.time() 64 | total_users = await madflixbotz.total_users_count() 65 | async for user in all_users: 66 | sts = await send_msg(user['_id'], broadcast_msg) 67 | if sts == 200: 68 | success += 1 69 | else: 70 | failed += 1 71 | if sts == 400: 72 | await madflixbotz.delete_user(user['_id']) 73 | done += 1 74 | if not done % 20: 75 | await sts_msg.edit(f"Broadcast In Progress: \n\nTotal Users {total_users} \nCompleted : {done} / {total_users}\nSuccess : {success}\nFailed : {failed}") 76 | completed_in = datetime.timedelta(seconds=int(time.time() - start_time)) 77 | await sts_msg.edit(f"Bʀᴏᴀᴅᴄᴀꜱᴛ Cᴏᴍᴩʟᴇᴛᴇᴅ: \nCᴏᴍᴩʟᴇᴛᴇᴅ Iɴ `{completed_in}`.\n\nTotal Users {total_users}\nCompleted: {done} / {total_users}\nSuccess: {success}\nFailed: {failed}") 78 | 79 | async def send_msg(user_id, message): 80 | try: 81 | await message.copy(chat_id=int(user_id)) 82 | return 200 83 | except FloodWait as e: 84 | await asyncio.sleep(e.value) 85 | return send_msg(user_id, message) 86 | except InputUserDeactivated: 87 | logger.info(f"{user_id} : Deactivated") 88 | return 400 89 | except UserIsBlocked: 90 | logger.info(f"{user_id} : Blocked The Bot") 91 | return 400 92 | except PeerIdInvalid: 93 | logger.info(f"{user_id} : User ID Invalid") 94 | return 400 95 | except Exception as e: 96 | logger.error(f"{user_id} : {e}") 97 | return 500 98 | 99 | 100 | 101 | 102 | # Jishu Developer 103 | # Don't Remove Credit 🥺 104 | # Telegram Channel @Madflix_Bots 105 | # Developer @JishuDeveloper 106 | -------------------------------------------------------------------------------- /plugins/auto_rename.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client, filters 2 | from pyrogram.errors import FloodWait 3 | from helper.database import madflixbotz 4 | 5 | @Client.on_message(filters.private & filters.command("autorename")) 6 | async def auto_rename_command(client, message): 7 | user_id = message.from_user.id 8 | 9 | # Extract the format from the command 10 | format_template = message.text.split("/autorename", 1)[1].strip() 11 | 12 | # Save the format template to the database 13 | await madflixbotz.set_format_template(user_id, format_template) 14 | 15 | await message.reply_text("**Auto Rename Format Updated Successfully! ✅**") 16 | 17 | @Client.on_message(filters.private & filters.command("setmedia")) 18 | async def set_media_command(client, message): 19 | user_id = message.from_user.id 20 | media_type = message.text.split("/setmedia", 1)[1].strip().lower() 21 | 22 | # Save the preferred media type to the database 23 | await madflixbotz.set_media_preference(user_id, media_type) 24 | 25 | await message.reply_text(f"**Media Preference Set To :** {media_type} ✅") 26 | 27 | 28 | 29 | 30 | 31 | 32 | # Jishu Developer 33 | # Don't Remove Credit 🥺 34 | # Telegram Channel @Madflix_Bots 35 | # Developer @JishuDeveloper 36 | -------------------------------------------------------------------------------- /plugins/file_rename.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client, filters 2 | from pyrogram.errors import FloodWait 3 | from pyrogram.types import InputMediaDocument, Message 4 | from PIL import Image 5 | from datetime import datetime 6 | from hachoir.metadata import extractMetadata 7 | from hachoir.parser import createParser 8 | from helper.utils import progress_for_pyrogram, humanbytes, convert 9 | from helper.database import madflixbotz 10 | from config import Config 11 | import os 12 | import time 13 | import re 14 | 15 | renaming_operations = {} 16 | 17 | # Pattern 1: S01E02 or S01EP02 18 | pattern1 = re.compile(r'S(\d+)(?:E|EP)(\d+)') 19 | # Pattern 2: S01 E02 or S01 EP02 or S01 - E01 or S01 - EP02 20 | pattern2 = re.compile(r'S(\d+)\s*(?:E|EP|-\s*EP)(\d+)') 21 | # Pattern 3: Episode Number After "E" or "EP" 22 | pattern3 = re.compile(r'(?:[([<{]?\s*(?:E|EP)\s*(\d+)\s*[)\]>}]?)') 23 | # Pattern 3_2: episode number after - [hyphen] 24 | pattern3_2 = re.compile(r'(?:\s*-\s*(\d+)\s*)') 25 | # Pattern 4: S2 09 ex. 26 | pattern4 = re.compile(r'S(\d+)[^\d]*(\d+)', re.IGNORECASE) 27 | # Pattern X: Standalone Episode Number 28 | patternX = re.compile(r'(\d+)') 29 | #QUALITY PATTERNS 30 | # Pattern 5: 3-4 digits before 'p' as quality 31 | pattern5 = re.compile(r'\b(?:.*?(\d{3,4}[^\dp]*p).*?|.*?(\d{3,4}p))\b', re.IGNORECASE) 32 | # Pattern 6: Find 4k in brackets or parentheses 33 | pattern6 = re.compile(r'[([<{]?\s*4k\s*[)\]>}]?', re.IGNORECASE) 34 | # Pattern 7: Find 2k in brackets or parentheses 35 | pattern7 = re.compile(r'[([<{]?\s*2k\s*[)\]>}]?', re.IGNORECASE) 36 | # Pattern 8: Find HdRip without spaces 37 | pattern8 = re.compile(r'[([<{]?\s*HdRip\s*[)\]>}]?|\bHdRip\b', re.IGNORECASE) 38 | # Pattern 9: Find 4kX264 in brackets or parentheses 39 | pattern9 = re.compile(r'[([<{]?\s*4kX264\s*[)\]>}]?', re.IGNORECASE) 40 | # Pattern 10: Find 4kx265 in brackets or parentheses 41 | pattern10 = re.compile(r'[([<{]?\s*4kx265\s*[)\]>}]?', re.IGNORECASE) 42 | 43 | def extract_quality(filename): 44 | # Try Quality Patterns 45 | match5 = re.search(pattern5, filename) 46 | if match5: 47 | print("Matched Pattern 5") 48 | quality5 = match5.group(1) or match5.group(2) # Extracted quality from both patterns 49 | print(f"Quality: {quality5}") 50 | return quality5 51 | 52 | match6 = re.search(pattern6, filename) 53 | if match6: 54 | print("Matched Pattern 6") 55 | quality6 = "4k" 56 | print(f"Quality: {quality6}") 57 | return quality6 58 | 59 | match7 = re.search(pattern7, filename) 60 | if match7: 61 | print("Matched Pattern 7") 62 | quality7 = "2k" 63 | print(f"Quality: {quality7}") 64 | return quality7 65 | 66 | match8 = re.search(pattern8, filename) 67 | if match8: 68 | print("Matched Pattern 8") 69 | quality8 = "HdRip" 70 | print(f"Quality: {quality8}") 71 | return quality8 72 | 73 | match9 = re.search(pattern9, filename) 74 | if match9: 75 | print("Matched Pattern 9") 76 | quality9 = "4kX264" 77 | print(f"Quality: {quality9}") 78 | return quality9 79 | 80 | match10 = re.search(pattern10, filename) 81 | if match10: 82 | print("Matched Pattern 10") 83 | quality10 = "4kx265" 84 | print(f"Quality: {quality10}") 85 | return quality10 86 | 87 | # Return "Unknown" if no pattern matches 88 | unknown_quality = "Unknown" 89 | print(f"Quality: {unknown_quality}") 90 | return unknown_quality 91 | 92 | 93 | def extract_episode_number(filename): 94 | # Try Pattern 1 95 | match = re.search(pattern1, filename) 96 | if match: 97 | print("Matched Pattern 1") 98 | return match.group(2) # Extracted episode number 99 | 100 | # Try Pattern 2 101 | match = re.search(pattern2, filename) 102 | if match: 103 | print("Matched Pattern 2") 104 | return match.group(2) # Extracted episode number 105 | 106 | # Try Pattern 3 107 | match = re.search(pattern3, filename) 108 | if match: 109 | print("Matched Pattern 3") 110 | return match.group(1) # Extracted episode number 111 | 112 | # Try Pattern 3_2 113 | match = re.search(pattern3_2, filename) 114 | if match: 115 | print("Matched Pattern 3_2") 116 | return match.group(1) # Extracted episode number 117 | 118 | # Try Pattern 4 119 | match = re.search(pattern4, filename) 120 | if match: 121 | print("Matched Pattern 4") 122 | return match.group(2) # Extracted episode number 123 | 124 | # Try Pattern X 125 | match = re.search(patternX, filename) 126 | if match: 127 | print("Matched Pattern X") 128 | return match.group(1) # Extracted episode number 129 | 130 | # Return None if no pattern matches 131 | return None 132 | 133 | # Example Usage: 134 | filename = "Naruto Shippuden S01 - EP07 - 1080p [Dual Audio] @Madflix_Bots.mkv" 135 | episode_number = extract_episode_number(filename) 136 | print(f"Extracted Episode Number: {episode_number}") 137 | 138 | # Inside the handler for file uploads 139 | @Client.on_message(filters.private & (filters.document | filters.video | filters.audio)) 140 | async def auto_rename_files(client, message): 141 | user_id = message.from_user.id 142 | firstname = message.from_user.first_name 143 | format_template = await madflixbotz.get_format_template(user_id) 144 | media_preference = await madflixbotz.get_media_preference(user_id) 145 | 146 | if not format_template: 147 | return await message.reply_text("Please Set An Auto Rename Format First Using /autorename") 148 | 149 | # Extract information from the incoming file name 150 | if message.document: 151 | file_id = message.document.file_id 152 | file_name = message.document.file_name 153 | media_type = media_preference or "document" # Use preferred media type or default to document 154 | elif message.video: 155 | file_id = message.video.file_id 156 | file_name = f"{message.video.file_name}.mp4" 157 | media_type = media_preference or "video" # Use preferred media type or default to video 158 | elif message.audio: 159 | file_id = message.audio.file_id 160 | file_name = f"{message.audio.file_name}.mp3" 161 | media_type = media_preference or "audio" # Use preferred media type or default to audio 162 | else: 163 | return await message.reply_text("Unsupported File Type") 164 | 165 | print(f"Original File Name: {file_name}") 166 | 167 | 168 | 169 | # Check whether the file is already being renamed or has been renamed recently 170 | if file_id in renaming_operations: 171 | elapsed_time = (datetime.now() - renaming_operations[file_id]).seconds 172 | if elapsed_time < 10: 173 | print("File is being ignored as it is currently being renamed or was renamed recently.") 174 | return # Exit the handler if the file is being ignored 175 | 176 | # Mark the file as currently being renamed 177 | renaming_operations[file_id] = datetime.now() 178 | 179 | # Extract episode number and qualities 180 | episode_number = extract_episode_number(file_name) 181 | 182 | print(f"Extracted Episode Number: {episode_number}") 183 | 184 | if episode_number: 185 | placeholders = ["episode", "Episode", "EPISODE", "{episode}"] 186 | for placeholder in placeholders: 187 | format_template = format_template.replace(placeholder, str(episode_number), 1) 188 | 189 | # Add extracted qualities to the format template 190 | quality_placeholders = ["quality", "Quality", "QUALITY", "{quality}"] 191 | for quality_placeholder in quality_placeholders: 192 | if quality_placeholder in format_template: 193 | extracted_qualities = extract_quality(file_name) 194 | if extracted_qualities == "Unknown": 195 | await message.reply_text("I Was Not Able To Extract The Quality Properly. Renaming As 'Unknown'...") 196 | # Mark the file as ignored 197 | del renaming_operations[file_id] 198 | return # Exit the handler if quality extraction fails 199 | 200 | format_template = format_template.replace(quality_placeholder, "".join(extracted_qualities)) 201 | 202 | _, file_extension = os.path.splitext(file_name) 203 | new_file_name = f"{format_template}{file_extension}" 204 | file_path = f"downloads/{new_file_name}" 205 | file = message 206 | 207 | download_msg = await message.reply_text(text="Trying To Download.....") 208 | try: 209 | path = await client.download_media(message=file, file_name=file_path, progress=progress_for_pyrogram, progress_args=("Download Started....", download_msg, time.time())) 210 | except Exception as e: 211 | # Mark the file as ignored 212 | del renaming_operations[file_id] 213 | return await download_msg.edit(e) 214 | 215 | duration = 0 216 | try: 217 | metadata = extractMetadata(createParser(file_path)) 218 | if metadata.has("duration"): 219 | duration = metadata.get('duration').seconds 220 | except Exception as e: 221 | print(f"Error getting duration: {e}") 222 | 223 | upload_msg = await download_msg.edit("Trying To Uploading.....") 224 | ph_path = None 225 | c_caption = await madflixbotz.get_caption(message.chat.id) 226 | c_thumb = await madflixbotz.get_thumbnail(message.chat.id) 227 | 228 | caption = c_caption.format(filename=new_file_name, filesize=humanbytes(message.document.file_size), duration=convert(duration)) if c_caption else f"**{new_file_name}**" 229 | 230 | if c_thumb: 231 | ph_path = await client.download_media(c_thumb) 232 | print(f"Thumbnail downloaded successfully. Path: {ph_path}") 233 | elif media_type == "video" and message.video.thumbs: 234 | ph_path = await client.download_media(message.video.thumbs[0].file_id) 235 | 236 | if ph_path: 237 | Image.open(ph_path).convert("RGB").save(ph_path) 238 | img = Image.open(ph_path) 239 | img.resize((320, 320)) 240 | img.save(ph_path, "JPEG") 241 | 242 | 243 | try: 244 | type = media_type # Use 'media_type' variable instead 245 | if type == "document": 246 | await client.send_document( 247 | message.chat.id, 248 | document=file_path, 249 | thumb=ph_path, 250 | caption=caption, 251 | progress=progress_for_pyrogram, 252 | progress_args=("Upload Started.....", upload_msg, time.time()) 253 | ) 254 | elif type == "video": 255 | await client.send_video( 256 | message.chat.id, 257 | video=file_path, 258 | caption=caption, 259 | thumb=ph_path, 260 | duration=duration, 261 | progress=progress_for_pyrogram, 262 | progress_args=("Upload Started.....", upload_msg, time.time()) 263 | ) 264 | elif type == "audio": 265 | await client.send_audio( 266 | message.chat.id, 267 | audio=file_path, 268 | caption=caption, 269 | thumb=ph_path, 270 | duration=duration, 271 | progress=progress_for_pyrogram, 272 | progress_args=("Upload Started.....", upload_msg, time.time()) 273 | ) 274 | except Exception as e: 275 | os.remove(file_path) 276 | if ph_path: 277 | os.remove(ph_path) 278 | # Mark the file as ignored 279 | return await upload_msg.edit(f"Error: {e}") 280 | 281 | await download_msg.delete() 282 | os.remove(file_path) 283 | if ph_path: 284 | os.remove(ph_path) 285 | 286 | # Remove the entry from renaming_operations after successful renaming 287 | del renaming_operations[file_id] 288 | 289 | 290 | 291 | 292 | # Jishu Developer 293 | # Don't Remove Credit 🥺 294 | # Telegram Channel @Madflix_Bots 295 | # Developer @JishuDeveloper 296 | -------------------------------------------------------------------------------- /plugins/force_subs.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client, filters, enums 2 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 3 | from pyrogram.errors import UserNotParticipant 4 | from config import Config 5 | from helper.database import madflixbotz 6 | 7 | async def not_subscribed(_, client, message): 8 | await madflixbotz.add_user(client, message) 9 | if not Config.FORCE_SUB: 10 | return False 11 | try: 12 | user = await client.get_chat_member(Config.FORCE_SUB, message.from_user.id) 13 | if user.status == enums.ChatMemberStatus.BANNED: 14 | return True 15 | else: 16 | return False 17 | except UserNotParticipant: 18 | pass 19 | return True 20 | 21 | 22 | @Client.on_message(filters.private & filters.create(not_subscribed)) 23 | async def forces_sub(client, message): 24 | buttons = [[InlineKeyboardButton(text="🔺 Update Channel 🔺", url=f"https://t.me/{Config.FORCE_SUB}") ]] 25 | text = "Hello Dear \n\nYou Need To Join In My Channel To Use Me\n\nKindly Please Join Channel" 26 | try: 27 | user = await client.get_chat_member(Config.FORCE_SUB, message.from_user.id) 28 | if user.status == enums.ChatMemberStatus.BANNED: 29 | return await client.send_message(message.from_user.id, text="Sorry You Are Banned To Use Me") 30 | except UserNotParticipant: 31 | return await message.reply_text(text=text, reply_markup=InlineKeyboardMarkup(buttons)) 32 | return await message.reply_text(text=text, reply_markup=InlineKeyboardMarkup(buttons)) 33 | 34 | 35 | 36 | 37 | # Jishu Developer 38 | # Don't Remove Credit 🥺 39 | # Telegram Channel @Madflix_Bots 40 | # Developer @JishuDeveloper -------------------------------------------------------------------------------- /plugins/start_&_cb.py: -------------------------------------------------------------------------------- 1 | import random 2 | from pyrogram import Client, filters 3 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, ForceReply, CallbackQuery, Message, InputMediaPhoto 4 | 5 | from helper.database import madflixbotz 6 | from config import Config, Txt 7 | 8 | @Client.on_message(filters.private & filters.command("start")) 9 | async def start(client, message): 10 | user = message.from_user 11 | await madflixbotz.add_user(client, message) 12 | button = InlineKeyboardMarkup([[ 13 | InlineKeyboardButton('📢 Updates', url='https://t.me/Madflix_Bots'), 14 | InlineKeyboardButton('💬 Support', url='https://t.me/MadflixBots_Support') 15 | ],[ 16 | InlineKeyboardButton('⚙️ Help', callback_data='help'), 17 | InlineKeyboardButton('💙 About', callback_data='about') 18 | ],[ 19 | InlineKeyboardButton("🧑‍💻 Developer 🧑‍💻", url='https://t.me/CallAdminRobot') 20 | ]]) 21 | if Config.START_PIC: 22 | await message.reply_photo(Config.START_PIC, caption=Txt.START_TXT.format(user.mention), reply_markup=button) 23 | else: 24 | await message.reply_text(text=Txt.START_TXT.format(user.mention), reply_markup=button, disable_web_page_preview=True) 25 | 26 | @Client.on_callback_query() 27 | async def cb_handler(client, query: CallbackQuery): 28 | data = query.data 29 | user_id = query.from_user.id 30 | 31 | if data == "home": 32 | await query.message.edit_text( 33 | text=Txt.START_TXT.format(query.from_user.mention), 34 | disable_web_page_preview=True, 35 | reply_markup=InlineKeyboardMarkup([[ 36 | InlineKeyboardButton('📢 Updates', url='https://t.me/Madflix_Bots'), 37 | InlineKeyboardButton('💬 Support', url='https://t.me/MadflixBots_Support') 38 | ],[ 39 | InlineKeyboardButton('⚙️ Help', callback_data='help'), 40 | InlineKeyboardButton('💙 About', callback_data='about') 41 | ],[ 42 | InlineKeyboardButton("🧑‍💻 Developer 🧑‍💻", url='https://t.me/CallAdminRobot') 43 | ]]) 44 | ) 45 | elif data == "caption": 46 | await query.message.edit_text( 47 | text=Txt.CAPTION_TXT, 48 | disable_web_page_preview=True, 49 | reply_markup=InlineKeyboardMarkup([[ 50 | InlineKeyboardButton("✖️ Close", callback_data="close"), 51 | InlineKeyboardButton("🔙 Back", callback_data="help") 52 | ]]) 53 | ) 54 | elif data == "help": 55 | await query.message.edit_text( 56 | text=Txt.HELP_TXT.format(client.mention), 57 | disable_web_page_preview=True, 58 | reply_markup=InlineKeyboardMarkup([[ 59 | InlineKeyboardButton("⚙️ Setup AutoRename Format ⚙️", callback_data='file_names') 60 | ],[ 61 | InlineKeyboardButton('🖼️ Thumbnail', callback_data='thumbnail'), 62 | InlineKeyboardButton('✏️ Caption', callback_data='caption') 63 | ],[ 64 | InlineKeyboardButton('🏠 Home', callback_data='home'), 65 | InlineKeyboardButton('💰 Donate', callback_data='donate') 66 | ]]) 67 | ) 68 | elif data == "donate": 69 | await query.message.edit_text( 70 | text=Txt.DONATE_TXT, 71 | disable_web_page_preview=True, 72 | reply_markup=InlineKeyboardMarkup([[ 73 | InlineKeyboardButton("✖️ Close", callback_data="close"), 74 | InlineKeyboardButton("🔙 Back", callback_data="help") 75 | ]]) 76 | ) 77 | 78 | elif data == "file_names": 79 | format_template = await madflixbotz.get_format_template(user_id) 80 | await query.message.edit_text( 81 | text=Txt.FILE_NAME_TXT.format(format_template=format_template), 82 | disable_web_page_preview=True, 83 | reply_markup=InlineKeyboardMarkup([[ 84 | InlineKeyboardButton("✖️ Close", callback_data="close"), 85 | InlineKeyboardButton("🔙 Back", callback_data="help") 86 | ]]) 87 | ) 88 | 89 | elif data == "thumbnail": 90 | await query.message.edit_caption( 91 | caption=Txt.THUMBNAIL_TXT, 92 | reply_markup=InlineKeyboardMarkup([[ 93 | InlineKeyboardButton("✖️ Close", callback_data="close"), 94 | InlineKeyboardButton("🔙 Back", callback_data="help"), 95 | ]]), 96 | ) 97 | 98 | elif data == "about": 99 | await query.message.edit_text( 100 | text=Txt.ABOUT_TXT, 101 | disable_web_page_preview=True, 102 | reply_markup=InlineKeyboardMarkup([[ 103 | InlineKeyboardButton("✖️ Close", callback_data="close"), 104 | InlineKeyboardButton("🔙 Back", callback_data="home") 105 | ]]) 106 | ) 107 | 108 | 109 | elif data == "close": 110 | try: 111 | await query.message.delete() 112 | await query.message.reply_to_message.delete() 113 | await query.message.continue_propagation() 114 | except: 115 | await query.message.delete() 116 | await query.message.continue_propagation() 117 | 118 | 119 | 120 | 121 | 122 | 123 | # Jishu Developer 124 | # Don't Remove Credit 🥺 125 | # Telegram Channel @Madflix_Bots 126 | # Developer @JishuDeveloper 127 | -------------------------------------------------------------------------------- /plugins/thumb_&_cap.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client, filters 2 | from helper.database import madflixbotz 3 | 4 | @Client.on_message(filters.private & filters.command('set_caption')) 5 | async def add_caption(client, message): 6 | if len(message.command) == 1: 7 | return await message.reply_text("**Give The Caption\n\nExample :- `/set_caption 📕Name ➠ : {filename} \n\n🔗 Size ➠ : {filesize} \n\n⏰ Duration ➠ : {duration}`**") 8 | caption = message.text.split(" ", 1)[1] 9 | await madflixbotz.set_caption(message.from_user.id, caption=caption) 10 | await message.reply_text("**Your Caption Successfully Added ✅**") 11 | 12 | @Client.on_message(filters.private & filters.command('del_caption')) 13 | async def delete_caption(client, message): 14 | caption = await madflixbotz.get_caption(message.from_user.id) 15 | if not caption: 16 | return await message.reply_text("**You Don't Have Any Caption ❌**") 17 | await madflixbotz.set_caption(message.from_user.id, caption=None) 18 | await message.reply_text("**Your Caption Successfully Deleted 🗑️**") 19 | 20 | @Client.on_message(filters.private & filters.command(['see_caption', 'view_caption'])) 21 | async def see_caption(client, message): 22 | caption = await madflixbotz.get_caption(message.from_user.id) 23 | if caption: 24 | await message.reply_text(f"**Your Caption :**\n\n`{caption}`") 25 | else: 26 | await message.reply_text("**You Don't Have Any Caption ❌**") 27 | 28 | 29 | @Client.on_message(filters.private & filters.command(['view_thumb', 'viewthumb'])) 30 | async def viewthumb(client, message): 31 | thumb = await madflixbotz.get_thumbnail(message.from_user.id) 32 | if thumb: 33 | await client.send_photo(chat_id=message.chat.id, photo=thumb) 34 | else: 35 | await message.reply_text("**You Don't Have Any Thumbnail ❌**") 36 | 37 | @Client.on_message(filters.private & filters.command(['del_thumb', 'delthumb'])) 38 | async def removethumb(client, message): 39 | await madflixbotz.set_thumbnail(message.from_user.id, file_id=None) 40 | await message.reply_text("**Thumbnail Deleted Successfully 🗑️**") 41 | 42 | @Client.on_message(filters.private & filters.photo) 43 | async def addthumbs(client, message): 44 | mkn = await message.reply_text("Please Wait ...") 45 | await madflixbotz.set_thumbnail(message.from_user.id, file_id=message.photo.file_id) 46 | await mkn.edit("**Thumbnail Saved Successfully ✅️**") 47 | 48 | 49 | 50 | 51 | 52 | # Jishu Developer 53 | # Don't Remove Credit 🥺 54 | # Telegram Channel @Madflix_Bots 55 | # Developer @JishuDeveloper -------------------------------------------------------------------------------- /render.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | - type: web 3 | plan: free 4 | name: auto-rename-bot 5 | env: python 6 | buildCommand: pip install -r requirements.txt 7 | startCommand: python bot.py 8 | repo: https://github.com/jishudeveloper/Auto-Rename-Bot.git 9 | branch: main 10 | autoDeploy: false 11 | envVars: 12 | - key: BOT_TOKEN 13 | sync: false 14 | - key: API_ID 15 | sync: false 16 | - key: API_HASH 17 | sync: false 18 | - key: FORCE_SUB 19 | sync: false 20 | - key: LOG_CHANNEL 21 | sync: false 22 | - key: DB_NAME 23 | sync: false 24 | - key: DB_URL 25 | sync: false 26 | - key: START_PIC 27 | sync: false 28 | - key: ADMIN 29 | sync: false 30 | - key: WEBHOOK 31 | sync: false 32 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyrogram==2.0.83 2 | TgCrypto 3 | motor 4 | dnspython 5 | hachoir 6 | Pillow 7 | aiohttp 8 | pytz 9 | psutil 10 | -------------------------------------------------------------------------------- /route.py: -------------------------------------------------------------------------------- 1 | from aiohttp import web 2 | 3 | routes = web.RouteTableDef() 4 | 5 | @routes.get("/", allow_head=True) 6 | async def root_route_handler(request): 7 | return web.json_response("Madflix_Bots") 8 | 9 | 10 | async def web_server(): 11 | web_app = web.Application(client_max_size=30000000) 12 | web_app.add_routes(routes) 13 | return web_app 14 | 15 | 16 | 17 | # Jishu Developer 18 | # Don't Remove Credit 🥺 19 | # Telegram Channel @Madflix_Bots 20 | # Developer @JishuDeveloper 21 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.10.8 2 | --------------------------------------------------------------------------------