├── .github ├── FUNDING.yml └── workflows │ └── dependency-review.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── Procfile ├── README.md ├── app.json ├── bot.py ├── config.py ├── database └── database.py ├── helper_func.py ├── heroku.yml ├── main.py ├── plugins ├── __init__.py ├── admin.py ├── banuser.py ├── broadcast.py ├── cbb.py ├── channel_post.py ├── link_generator.py ├── request_fsub.py ├── route.py ├── start.py └── useless.py └── requirements.txt /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: ['https://github.com/sponsors/Codflix-bots'] 4 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Dependency Review Action 2 | # 3 | # This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. 4 | # 5 | # Source repository: https://github.com/actions/dependency-review-action 6 | # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement 7 | name: 'Dependency Review' 8 | on: [pull_request] 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | dependency-review: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: 'Checkout Repository' 18 | uses: actions/checkout@v3 19 | - name: 'Dependency Review' 20 | uses: actions/dependency-review-action@v2 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Python template 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | cover/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | .pybuilder/ 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 99 | __pypackages__/ 100 | 101 | # Celery stuff 102 | celerybeat-schedule 103 | celerybeat.pid 104 | 105 | # SageMath parsed files 106 | *.sage.py 107 | 108 | # Environments 109 | .env 110 | .venv 111 | env/ 112 | venv/ 113 | ENV/ 114 | env.bak/ 115 | venv.bak/ 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # mypy 128 | .mypy_cache/ 129 | .dmypy.json 130 | dmypy.json 131 | 132 | # Pyre type checker 133 | .pyre/ 134 | 135 | # pytype static type analyzer 136 | .pytype/ 137 | 138 | # Cython debug symbols 139 | cython_debug/ 140 | 141 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10-slim 2 | WORKDIR /app 3 | 4 | COPY requirements.txt requirements.txt 5 | RUN pip3 install -r requirements.txt 6 | 7 | COPY . . 8 | 9 | CMD python3 main.py 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Codeflix-Bots 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: python3 main.py 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ━━━━━━━━━━━━━━━━━━━━ 2 | 3 |

4 | ──「 ғɪʟᴇ sᴛᴏʀᴇ ᴘʀᴏ 」── 5 |

6 | 7 |

8 | 9 |

10 | 11 | 12 | ![Typing SVG](https://readme-typing-svg.herokuapp.com/?lines=FILE+SHARING+!;CREATED+BY+CODEFLIX+DEVELOPER!;A+ADVANCE+BOT+WITH+COOL+FEATURE!) 13 |

14 | 15 | ━━━━━━━━━━━━━━━━━ 16 | 17 | 18 | 19 |
ғᴇᴀᴛᴜʀᴇs: 20 | 21 | • Batch & Custom Batch Links: Create links for one or multiple posts easily using /batch & /custom_batch 22 | • Link Generator: Instantly generate direct links with /genlink 23 | • Broadcast Tools: Send messages or media to all users using /broadcast, /dbroadcast, or /pbroadcast 24 | • Auto File Deletion: Control auto-delete with /dlt_time & /check_dlt_time 25 | • User Management: Ban/unban users and view banlist via /ban, /unban, and /banlist 26 | • Multi Force Subscription: Add, delete, and manage multiple Force Sub channels with /addchnl, /delchnl, /listchnl 27 | • Admin Control: Add or remove admins with /add_admin, /deladmin, and view list via /admins 28 | 29 | • Bot Analytics: Get stats and uptime via /stats, user info with /users, and database count via /count 30 | • Deployment Ready: Easily deploy on Heroku or Koyeb in minutes 31 | 32 | ✨ More features & enhancements coming soon... 33 |
34 | 35 | 36 |
ᴠᴀʀɪᴀʙʟᴇs : 37 | 38 | ## ᴠᴀʀɪᴀʙʟᴇs 39 | * `API_HASH` Your API Hash from my.telegram.org 40 | * `APP_ID` Your API ID from my.telegram.org 41 | * `TG_BOT_TOKEN` Your bot token from @BotFather 42 | * `OWNER_ID` Must enter Your Telegram Id 43 | * `CHANNEL_ID` Your Channel ID eg:- -100xxxxxxxx 44 | * `DATABASE_URL` Your mongo db url 45 | * `DATABASE_NAME` Your mongo db session name 46 | * `ADMINS` Optional: A space separated list of user_ids of Admins, they can only create links 47 | * `START_MESSAGE` Optional: start message of bot, use HTML and fillings 48 | * `PROTECT_CONTENT` Optional: True if you need to prevent files from forwarding 49 |
50 | 51 | ## 𝐶𝑜𝑚𝑚𝑎𝑛𝑑𝑠 52 | 53 | ``` 54 | /start - start the bot or get posts 55 | /batch - create link for more than one posts 56 | /genlink - create link for one post 57 | /users - view bot statistics 58 | /broadcast - broadcast any messages to bot users 59 | /dbroadcast - broadcast any messages with auto delete. 60 | /stats - checking your bot uptime 61 | /start - start the bot or get posts 62 | /batch - create link for more than one posts 63 | /custom_batch - create custom batch from channel/group 64 | /genlink - create link for one post 65 | /users - view bot statistics 66 | /broadcast - broadcast any messages to bot users 67 | /dbroadcast - broadcast any messages with auto delete 68 | /stats - check your bot uptime 69 | /dlt_time - set auto delete time for files 70 | /check_dlt_time - check current delete time setting 71 | /ban - ban a user from using the bot 72 | /unban - unban a previously banned user 73 | /banlist - get list of banned users 74 | /addchnl - add a channel for force subscription 75 | /delchnl - remove a force subscribe channel 76 | /listchnl - view all added force subscribe channels 77 | /fsub_mode - toggle force subscribe on or off 78 | /pbroadcast - pin a broadcast to all user's chat 79 | /add_admin - add a new admin 80 | /deladmin - remove an admin 81 | /admins - list all current admins 82 | ``` 83 | 84 | 85 | 86 |

「 ᴏᴛʜᴇʀ ʙʀᴀɴᴄʜᴇs 」 87 |

88 | 89 | - [ᴛᴏᴋᴇɴ](https://github.com/Codeflix-Bots/FileStore/tree/token) ➻ [sʜᴏʀᴛɴᴇʀ](https://github.com/Codeflix-Bots/FileStore/tree/Shortner) 90 | 91 | 92 | 93 | 94 |
95 |

96 | - ᴅᴇᴘʟᴏʏᴍᴇɴᴛ ᴍᴇᴛʜᴏᴅs 97 |

98 |

99 | ─「 ᴅᴇᴩʟᴏʏ ᴏɴ ʜᴇʀᴏᴋᴜ 」─ 100 |

101 | 102 |

103 | Deploy On Heroku 104 |

105 |

106 | ─「 ᴅᴇᴩʟᴏʏ ᴏɴ ᴋᴏʏᴇʙ 」─ 107 |

108 |

109 | Deploy On Koyeb 110 |

111 |

112 | ─「 ᴅᴇᴩʟᴏʏ ᴏɴ ʀᴀɪʟᴡᴀʏ 」─ 113 |

114 |

115 | 116 |

117 |

118 | ─「 ᴅᴇᴩʟᴏʏ ᴏɴ ʀᴇɴᴅᴇʀ 」─ 119 |

120 |

121 | Deploy to Render 122 |

123 |

124 | ─「 ᴅᴇᴩʟᴏʏ ᴏɴ ᴠᴘs 」─ 125 |

126 |

127 |

128 | git clone https://github.com/Codeflix-Bots/FileStore
129 | # Install Packages
130 | pip3 install -U -r requirements.txt
131 | Edit info.py with variables as given below then run bot
132 | python3 bot.py
133 | 
134 |

135 |
136 | 137 |

「 ᴄʀᴇᴅɪᴛs 」 138 |

139 | 140 | - [ᴄᴏᴅᴇғʟɪx ʙᴏᴛs](https://t.me/codeflix_bots) ➻ [ᴜᴘᴅᴀᴛᴇs](https://t.me/codeflix_bots) 141 | - [ʏᴀᴛᴏ](https://github.com/sewxiy) ➻ [sᴏᴍᴇᴛʜɪɴɢ](https://t.me/cosmic_freak) 142 | - [ʀᴏʜɪᴛ](https://github.com/rohit3607) ➻ [sᴏᴍᴇᴛʜɪɴɢ](https://t.me/FILE_SHARINGBOTS/17) 143 | 144 | ᴀɴᴅ ᴀʟʟ [ᴛʜᴇ ᴄᴏɴᴛʀɪʙᴜᴛᴏʀs](https://telegram.me/codeflix-bots) ᴡʜᴏ ʜᴇʟᴩᴇᴅ ɪɴ ᴍᴀᴋɪɴɢ file store ʙᴏᴛ ᴜsᴇꜰᴜʟ & ᴩᴏᴡᴇʀꜰᴜʟ 🖤 145 | 146 | ## 📌 𝑵𝒐𝒕𝒆 147 | 148 | ᴊᴜꜱᴛ ꜰᴏʀᴋ ᴛʜᴇ ʀᴇᴘᴏ ᴀɴᴅ ᴇᴅɪᴛ ᴀꜱ ᴘᴇʀ ʏᴏᴜʀ ɴᴇᴇᴅꜱ. 149 | 150 | 151 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TG File Share/Sharing Bot", 3 | "description": "file sharing bot store posts and it can access by special links", 4 | "keywords": [ 5 | "telegram", 6 | "file", 7 | "sharing" 8 | ], 9 | "repository": "https://github.com/Codeflix-Bots/FileStore", 10 | "logo": "https://graph.org/file/6ceef6a98b82b0e0e2f03.jpg", 11 | "env": { 12 | "TG_BOT_TOKEN": { 13 | "description": "Your Bot token, Get it from @Botfather", 14 | "value": "" 15 | }, 16 | "OWNER_ID": { 17 | "description": "An integer of consisting of your owner ID", 18 | "value": "6497757690" 19 | }, 20 | "APP_ID":{ 21 | "description": "your app id, take it from my.telegram.org", 22 | "value": "" 23 | }, 24 | "DATABASE_URL": { 25 | "description": "Paste your mongo db url", 26 | "value": "url" 27 | }, 28 | "DATABASE_NAME":{ 29 | "description": "Enter your DATABASE_NAME ", 30 | "value": "Cluster0" 31 | }, 32 | "API_HASH":{ 33 | "description": "your api hash, take it from my.telegram.org", 34 | "value": "" 35 | }, 36 | "CHANNEL_ID":{ 37 | "description": "make a channel (database channel), then make the bot as admin in channel, and it's id", 38 | "value": "-1001995978690" 39 | }, 40 | "FORCE_SUB_CHANNEL":{ 41 | "description": "id of the channel or group, if you want enable force sub feature else put 0", 42 | "value": "-1001473043276" 43 | }, 44 | "FORCE_SUB_CHANNEL2":{ 45 | "description": "id of the channel or group, if you want enable force sub feature else put 0", 46 | "value": "-1001495022147" 47 | }, 48 | "ADMINS": { 49 | "description": "A space separated list of user_ids of Admins, they can only create links", 50 | "value": "5115691197 6273945163 6103092779 5231212075", 51 | "required": false 52 | }, 53 | "PROTECT_CONTENT": { 54 | "description": "Protect contents from getting forwarded", 55 | "value": "False", 56 | "required": false 57 | } 58 | }, 59 | "buildpacks": [ 60 | { 61 | "url": "heroku/python" 62 | } 63 | ], 64 | "formation": { 65 | "worker": { 66 | "quantity": 1, 67 | "size": "eco" 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | from aiohttp import web 2 | from plugins import web_server 3 | import asyncio 4 | import pyromod.listen 5 | from pyrogram import Client 6 | from pyrogram.enums import ParseMode 7 | import sys 8 | from datetime import datetime 9 | #rohit_1888 on Tg 10 | from config import * 11 | 12 | 13 | name =""" 14 | BY CODEFLIX BOTS 15 | """ 16 | 17 | 18 | class Bot(Client): 19 | def __init__(self): 20 | super().__init__( 21 | name="Bot", 22 | api_hash=API_HASH, 23 | api_id=APP_ID, 24 | plugins={ 25 | "root": "plugins" 26 | }, 27 | workers=TG_BOT_WORKERS, 28 | bot_token=TG_BOT_TOKEN 29 | ) 30 | self.LOGGER = LOGGER 31 | 32 | async def start(self): 33 | await super().start() 34 | usr_bot_me = await self.get_me() 35 | self.uptime = datetime.now() 36 | 37 | try: 38 | db_channel = await self.get_chat(CHANNEL_ID) 39 | self.db_channel = db_channel 40 | test = await self.send_message(chat_id = db_channel.id, text = "Test Message") 41 | await test.delete() 42 | except Exception as e: 43 | self.LOGGER(__name__).warning(e) 44 | self.LOGGER(__name__).warning(f"Make Sure bot is Admin in DB Channel, and Double check the CHANNEL_ID Value, Current Value {CHANNEL_ID}") 45 | self.LOGGER(__name__).info("\nBot Stopped. Join https://t.me/CodeflixSupport for support") 46 | sys.exit() 47 | 48 | self.set_parse_mode(ParseMode.HTML) 49 | self.LOGGER(__name__).info(f"Bot Running..!\n\nCreated by \nhttps://t.me/CodeflixSupport") 50 | self.LOGGER(__name__).info(f"""BOT DEPLOYED BY @CODEFLIX_BOTS""") 51 | 52 | self.set_parse_mode(ParseMode.HTML) 53 | self.username = usr_bot_me.username 54 | self.LOGGER(__name__).info(f"Bot Running..! Made by @Codeflix_Bots") 55 | 56 | # Start Web Server 57 | app = web.AppRunner(await web_server()) 58 | await app.setup() 59 | await web.TCPSite(app, "0.0.0.0", PORT).start() 60 | 61 | 62 | try: await self.send_message(OWNER_ID, text = f"
Bᴏᴛ Rᴇsᴛᴀʀᴛᴇᴅ by @Codeflix_Bots
") 63 | except: pass 64 | 65 | async def stop(self, *args): 66 | await super().stop() 67 | self.LOGGER(__name__).info("Bot stopped.") 68 | 69 | def run(self): 70 | """Run the bot.""" 71 | loop = asyncio.get_event_loop() 72 | loop.run_until_complete(self.start()) 73 | self.LOGGER(__name__).info("Bot is now running. Thanks to @rohit_1888") 74 | try: 75 | loop.run_forever() 76 | except KeyboardInterrupt: 77 | self.LOGGER(__name__).info("Shutting down...") 78 | finally: 79 | loop.run_until_complete(self.stop()) 80 | 81 | # 82 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 83 | # 84 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 85 | # and is released under the MIT License. 86 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 87 | # 88 | # All rights reserved. 89 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 2 | # Ask Doubt on telegram @CodeflixSupport 3 | # 4 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 5 | # 6 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 7 | # and is released under the MIT License. 8 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 9 | # 10 | # All rights reserved. 11 | # 12 | 13 | import os 14 | from os import environ,getenv 15 | import logging 16 | from logging.handlers import RotatingFileHandler 17 | 18 | #rohit_1888 on Tg 19 | #-------------------------------------------- 20 | #Bot token @Botfather 21 | TG_BOT_TOKEN = os.environ.get("TG_BOT_TOKEN", "8154426339") 22 | APP_ID = int(os.environ.get("APP_ID", "")) #Your API ID from my.telegram.org 23 | API_HASH = os.environ.get("API_HASH", "") #Your API Hash from my.telegram.org 24 | #-------------------------------------------- 25 | 26 | CHANNEL_ID = int(os.environ.get("CHANNEL_ID", "-1002170811388")) #Your db channel Id 27 | OWNER = os.environ.get("OWNER", "sewxiy") # Owner username without @ 28 | OWNER_ID = int(os.environ.get("OWNER_ID", "7328629001")) # Owner id 29 | #-------------------------------------------- 30 | PORT = os.environ.get("PORT", "8001") 31 | #-------------------------------------------- 32 | DB_URI = os.environ.get("DATABASE_URL", "") 33 | DB_NAME = os.environ.get("DATABASE_NAME", "Cluooo") 34 | #-------------------------------------------- 35 | FSUB_LINK_EXPIRY = int(os.getenv("FSUB_LINK_EXPIRY", "10")) # 0 means no expiry 36 | BAN_SUPPORT = os.environ.get("BAN_SUPPORT", "https://t.me/CodeflixSupport") 37 | TG_BOT_WORKERS = int(os.environ.get("TG_BOT_WORKERS", "200")) 38 | #-------------------------------------------- 39 | START_PIC = os.environ.get("START_PIC", "https://telegra.ph/file/ec17880d61180d3312d6a.jpg") 40 | FORCE_PIC = os.environ.get("FORCE_PIC", "https://telegra.ph/file/e292b12890b8b4b9dcbd1.jpg") 41 | #-------------------------------------------- 42 | 43 | #-------------------------------------------- 44 | HELP_TXT = "
ᴛʜɪs ɪs ᴀɴ ғɪʟᴇ ᴛᴏ ʟɪɴᴋ ʙᴏᴛ ᴡᴏʀᴋ ғᴏʀ @Nova_Flix\n\n❏ ʙᴏᴛ ᴄᴏᴍᴍᴀɴᴅs\n├/start : sᴛᴀʀᴛ ᴛʜᴇ ʙᴏᴛ\n├/about : ᴏᴜʀ Iɴғᴏʀᴍᴀᴛɪᴏɴ\n└/help : ʜᴇʟᴘ ʀᴇʟᴀᴛᴇᴅ ʙᴏᴛ\n\n sɪᴍᴘʟʏ ᴄʟɪᴄᴋ ᴏɴ ʟɪɴᴋ ᴀɴᴅ sᴛᴀʀᴛ ᴛʜᴇ ʙᴏᴛ ᴊᴏɪɴ ʙᴏᴛʜ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ ᴛʜᴀᴛs ɪᴛ.....!\n\n ᴅᴇᴠᴇʟᴏᴘᴇᴅ ʙʏ sᴜʙᴀʀᴜ
" 45 | ABOUT_TXT = "
◈ ᴄʀᴇᴀᴛᴏʀ: Yato\n◈ ꜰᴏᴜɴᴅᴇʀ ᴏꜰ : ᴏᴛᴀᴋᴜғʟɪx ɴᴇᴛᴡᴏʀᴋ\n◈ ᴀɴɪᴍᴇ ᴄʜᴀɴɴᴇʟ : ᴀɴɪᴍᴇ ᴄʀᴜɪsᴇ\n◈ sᴇʀɪᴇs ᴄʜᴀɴɴᴇʟ : ᴡᴇʙsᴇʀɪᴇs ғʟɪx\n◈ ᴀᴅᴜʟᴛ ᴍᴀɴʜᴡᴀ : ᴘᴏʀɴʜᴡᴀs\n◈ ᴅᴇᴠᴇʟᴏᴘᴇʀ : subaru
" 46 | #-------------------------------------------- 47 | #-------------------------------------------- 48 | START_MSG = os.environ.get("START_MESSAGE", "ʜᴇʟʟᴏ {first}\n\n
ɪ ᴀᴍ ғɪʟᴇ sᴛᴏʀᴇ ʙᴏᴛ, ɪ ᴄᴀɴ sᴛᴏʀᴇ ᴘʀɪᴠᴀᴛᴇ ғɪʟᴇs ɪɴ sᴘᴇᴄɪғɪᴇᴅ ᴄʜᴀɴɴᴇʟ ᴀɴᴅ ᴏᴛʜᴇʀ ᴜsᴇʀs ᴄᴀɴ ᴀᴄᴄᴇss ɪᴛ ғʀᴏᴍ sᴘᴇᴄɪᴀʟ ʟɪɴᴋ.
") 49 | FORCE_MSG = os.environ.get("FORCE_SUB_MESSAGE", "ʜᴇʟʟᴏ {first}\n\nᴊᴏɪɴ ᴏᴜʀ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʜᴇɴ ᴄʟɪᴄᴋ ᴏɴ ʀᴇʟᴏᴀᴅ button ᴛᴏ ɢᴇᴛ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛᴇᴅ ꜰɪʟᴇ.") 50 | 51 | CMD_TXT = """
» ᴀᴅᴍɪɴ ᴄᴏᴍᴍᴀɴᴅs:
52 | 53 | ›› /dlt_time : sᴇᴛ ᴀᴜᴛᴏ ᴅᴇʟᴇᴛᴇ ᴛɪᴍᴇ 54 | ›› /check_dlt_time : ᴄʜᴇᴄᴋ ᴄᴜʀʀᴇɴᴛ ᴅᴇʟᴇᴛᴇ ᴛɪᴍᴇ 55 | ›› /dbroadcast : ʙʀᴏᴀᴅᴄᴀsᴛ ᴅᴏᴄᴜᴍᴇɴᴛ / ᴠɪᴅᴇᴏ 56 | ›› /ban : ʙᴀɴ ᴀ ᴜꜱᴇʀ 57 | ›› /unban : ᴜɴʙᴀɴ ᴀ ᴜꜱᴇʀ 58 | ›› /banlist : ɢᴇᴛ ʟɪsᴛ ᴏꜰ ʙᴀɴɴᴇᴅ ᴜꜱᴇʀs 59 | ›› /addchnl : ᴀᴅᴅ ꜰᴏʀᴄᴇ sᴜʙ ᴄʜᴀɴɴᴇʟ 60 | ›› /delchnl : ʀᴇᴍᴏᴠᴇ ꜰᴏʀᴄᴇ sᴜʙ ᴄʜᴀɴɴᴇʟ 61 | ›› /listchnl : ᴠɪᴇᴡ ᴀᴅᴅᴇᴅ ᴄʜᴀɴɴᴇʟs 62 | ›› /fsub_mode : ᴛᴏɢɢʟᴇ ꜰᴏʀᴄᴇ sᴜʙ ᴍᴏᴅᴇ 63 | ›› /pbroadcast : sᴇɴᴅ ᴘʜᴏᴛᴏ ᴛᴏ ᴀʟʟ ᴜꜱᴇʀs 64 | ›› /add_admin : ᴀᴅᴅ ᴀɴ ᴀᴅᴍɪɴ 65 | ›› /deladmin : ʀᴇᴍᴏᴠᴇ ᴀɴ ᴀᴅᴍɪɴ 66 | ›› /admins : ɢᴇᴛ ʟɪsᴛ ᴏꜰ ᴀᴅᴍɪɴs 67 | """ 68 | #-------------------------------------------- 69 | CUSTOM_CAPTION = os.environ.get("CUSTOM_CAPTION", "• ʙʏ @nova_flix") #set your Custom Caption here, Keep None for Disable Custom Caption 70 | PROTECT_CONTENT = True if os.environ.get('PROTECT_CONTENT', "False") == "True" else False #set True if you want to prevent users from forwarding files from bot 71 | #-------------------------------------------- 72 | #Set true if you want Disable your Channel Posts Share button 73 | DISABLE_CHANNEL_BUTTON = os.environ.get("DISABLE_CHANNEL_BUTTON", None) == 'True' 74 | #-------------------------------------------- 75 | BOT_STATS_TEXT = "BOT UPTIME\n{uptime}" 76 | USER_REPLY_TEXT = "ʙᴀᴋᴋᴀ ! ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴍʏ ꜱᴇɴᴘᴀɪ!!" 77 | #-------------------------------------------- 78 | 79 | 80 | LOG_FILE_NAME = "filesharingbot.txt" 81 | 82 | logging.basicConfig( 83 | level=logging.INFO, 84 | format="[%(asctime)s - %(levelname)s] - %(name)s - %(message)s", 85 | datefmt='%d-%b-%y %H:%M:%S', 86 | handlers=[ 87 | RotatingFileHandler( 88 | LOG_FILE_NAME, 89 | maxBytes=50000000, 90 | backupCount=10 91 | ), 92 | logging.StreamHandler() 93 | ] 94 | ) 95 | logging.getLogger("pyrogram").setLevel(logging.WARNING) 96 | 97 | 98 | def LOGGER(name: str) -> logging.Logger: 99 | return logging.getLogger(name) 100 | 101 | -------------------------------------------------------------------------------- /database/database.py: -------------------------------------------------------------------------------- 1 | #Codeflix_Botz 2 | #rohit_1888 on Tg 3 | 4 | import motor, asyncio 5 | import motor.motor_asyncio 6 | import time 7 | import pymongo, os 8 | from config import DB_URI, DB_NAME 9 | from bot import Bot 10 | import logging 11 | from datetime import datetime, timedelta 12 | 13 | dbclient = pymongo.MongoClient(DB_URI) 14 | database = dbclient[DB_NAME] 15 | 16 | logging.basicConfig(level=logging.INFO) 17 | 18 | 19 | class Rohit: 20 | 21 | def __init__(self, DB_URI, DB_NAME): 22 | self.dbclient = motor.motor_asyncio.AsyncIOMotorClient(DB_URI) 23 | self.database = self.dbclient[DB_NAME] 24 | 25 | self.channel_data = self.database['channels'] 26 | self.admins_data = self.database['admins'] 27 | self.user_data = self.database['users'] 28 | self.banned_user_data = self.database['banned_user'] 29 | self.autho_user_data = self.database['autho_user'] 30 | self.del_timer_data = self.database['del_timer'] 31 | self.fsub_data = self.database['fsub'] 32 | self.rqst_fsub_data = self.database['request_forcesub'] 33 | self.rqst_fsub_Channel_data = self.database['request_forcesub_channel'] 34 | 35 | 36 | 37 | # USER DATA 38 | async def present_user(self, user_id: int): 39 | found = await self.user_data.find_one({'_id': user_id}) 40 | return bool(found) 41 | 42 | async def add_user(self, user_id: int): 43 | await self.user_data.insert_one({'_id': user_id}) 44 | return 45 | 46 | async def full_userbase(self): 47 | user_docs = await self.user_data.find().to_list(length=None) 48 | user_ids = [doc['_id'] for doc in user_docs] 49 | return user_ids 50 | 51 | async def del_user(self, user_id: int): 52 | await self.user_data.delete_one({'_id': user_id}) 53 | return 54 | 55 | 56 | # ADMIN DATA 57 | async def admin_exist(self, admin_id: int): 58 | found = await self.admins_data.find_one({'_id': admin_id}) 59 | return bool(found) 60 | 61 | async def add_admin(self, admin_id: int): 62 | if not await self.admin_exist(admin_id): 63 | await self.admins_data.insert_one({'_id': admin_id}) 64 | return 65 | 66 | async def del_admin(self, admin_id: int): 67 | if await self.admin_exist(admin_id): 68 | await self.admins_data.delete_one({'_id': admin_id}) 69 | return 70 | 71 | async def get_all_admins(self): 72 | users_docs = await self.admins_data.find().to_list(length=None) 73 | user_ids = [doc['_id'] for doc in users_docs] 74 | return user_ids 75 | 76 | 77 | # BAN USER DATA 78 | async def ban_user_exist(self, user_id: int): 79 | found = await self.banned_user_data.find_one({'_id': user_id}) 80 | return bool(found) 81 | 82 | async def add_ban_user(self, user_id: int): 83 | if not await self.ban_user_exist(user_id): 84 | await self.banned_user_data.insert_one({'_id': user_id}) 85 | return 86 | 87 | async def del_ban_user(self, user_id: int): 88 | if await self.ban_user_exist(user_id): 89 | await self.banned_user_data.delete_one({'_id': user_id}) 90 | return 91 | 92 | async def get_ban_users(self): 93 | users_docs = await self.banned_user_data.find().to_list(length=None) 94 | user_ids = [doc['_id'] for doc in users_docs] 95 | return user_ids 96 | 97 | 98 | 99 | # AUTO DELETE TIMER SETTINGS 100 | async def set_del_timer(self, value: int): 101 | existing = await self.del_timer_data.find_one({}) 102 | if existing: 103 | await self.del_timer_data.update_one({}, {'$set': {'value': value}}) 104 | else: 105 | await self.del_timer_data.insert_one({'value': value}) 106 | 107 | async def get_del_timer(self): 108 | data = await self.del_timer_data.find_one({}) 109 | if data: 110 | return data.get('value', 600) 111 | return 0 112 | 113 | 114 | # CHANNEL MANAGEMENT 115 | async def channel_exist(self, channel_id: int): 116 | found = await self.fsub_data.find_one({'_id': channel_id}) 117 | return bool(found) 118 | 119 | async def add_channel(self, channel_id: int): 120 | if not await self.channel_exist(channel_id): 121 | await self.fsub_data.insert_one({'_id': channel_id}) 122 | return 123 | 124 | async def rem_channel(self, channel_id: int): 125 | if await self.channel_exist(channel_id): 126 | await self.fsub_data.delete_one({'_id': channel_id}) 127 | return 128 | 129 | async def show_channels(self): 130 | channel_docs = await self.fsub_data.find().to_list(length=None) 131 | channel_ids = [doc['_id'] for doc in channel_docs] 132 | return channel_ids 133 | 134 | 135 | # Get current mode of a channel 136 | async def get_channel_mode(self, channel_id: int): 137 | data = await self.fsub_data.find_one({'_id': channel_id}) 138 | return data.get("mode", "off") if data else "off" 139 | 140 | # Set mode of a channel 141 | async def set_channel_mode(self, channel_id: int, mode: str): 142 | await self.fsub_data.update_one( 143 | {'_id': channel_id}, 144 | {'$set': {'mode': mode}}, 145 | upsert=True 146 | ) 147 | 148 | # REQUEST FORCE-SUB MANAGEMENT 149 | 150 | # Add the user to the set of users for a specific channel 151 | async def req_user(self, channel_id: int, user_id: int): 152 | try: 153 | await self.rqst_fsub_Channel_data.update_one( 154 | {'_id': int(channel_id)}, 155 | {'$addToSet': {'user_ids': int(user_id)}}, 156 | upsert=True 157 | ) 158 | except Exception as e: 159 | print(f"[DB ERROR] Failed to add user to request list: {e}") 160 | 161 | 162 | # Method 2: Remove a user from the channel set 163 | async def del_req_user(self, channel_id: int, user_id: int): 164 | # Remove the user from the set of users for the channel 165 | await self.rqst_fsub_Channel_data.update_one( 166 | {'_id': channel_id}, 167 | {'$pull': {'user_ids': user_id}} 168 | ) 169 | 170 | # Check if the user exists in the set of the channel's users 171 | async def req_user_exist(self, channel_id: int, user_id: int): 172 | try: 173 | found = await self.rqst_fsub_Channel_data.find_one({ 174 | '_id': int(channel_id), 175 | 'user_ids': int(user_id) 176 | }) 177 | return bool(found) 178 | except Exception as e: 179 | print(f"[DB ERROR] Failed to check request list: {e}") 180 | return False 181 | 182 | 183 | # Method to check if a channel exists using show_channels 184 | async def reqChannel_exist(self, channel_id: int): 185 | # Get the list of all channel IDs from the database 186 | channel_ids = await self.show_channels() 187 | #print(f"All channel IDs in the database: {channel_ids}") 188 | 189 | # Check if the given channel_id is in the list of channel IDs 190 | if channel_id in channel_ids: 191 | #print(f"Channel {channel_id} found in the database.") 192 | return True 193 | else: 194 | #print(f"Channel {channel_id} NOT found in the database.") 195 | return False 196 | 197 | 198 | db = Rohit(DB_URI, DB_NAME) 199 | -------------------------------------------------------------------------------- /helper_func.py: -------------------------------------------------------------------------------- 1 | #(©)CodeFlix_Bots 2 | #rohit_1888 on Tg #Dont remove this line 3 | 4 | import base64 5 | import re 6 | import asyncio 7 | import time 8 | from pyrogram import filters 9 | from pyrogram.enums import ChatMemberStatus 10 | from config import * 11 | from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant 12 | from pyrogram.errors import FloodWait 13 | from database.database import * 14 | 15 | 16 | 17 | #used for cheking if a user is admin ~Owner also treated as admin level 18 | async def check_admin(filter, client, update): 19 | try: 20 | user_id = update.from_user.id 21 | return any([user_id == OWNER_ID, await db.admin_exist(user_id)]) 22 | except Exception as e: 23 | print(f"! Exception in check_admin: {e}") 24 | return False 25 | 26 | async def is_subscribed(client, user_id): 27 | channel_ids = await db.show_channels() 28 | 29 | if not channel_ids: 30 | return True 31 | 32 | if user_id == OWNER_ID: 33 | return True 34 | 35 | for cid in channel_ids: 36 | if not await is_sub(client, user_id, cid): 37 | # Retry once if join request might be processing 38 | mode = await db.get_channel_mode(cid) 39 | if mode == "on": 40 | await asyncio.sleep(2) # give time for @on_chat_join_request to process 41 | if await is_sub(client, user_id, cid): 42 | continue 43 | return False 44 | 45 | return True 46 | 47 | 48 | async def is_sub(client, user_id, channel_id): 49 | try: 50 | member = await client.get_chat_member(channel_id, user_id) 51 | status = member.status 52 | #print(f"[SUB] User {user_id} in {channel_id} with status {status}") 53 | return status in { 54 | ChatMemberStatus.OWNER, 55 | ChatMemberStatus.ADMINISTRATOR, 56 | ChatMemberStatus.MEMBER 57 | } 58 | 59 | except UserNotParticipant: 60 | mode = await db.get_channel_mode(channel_id) 61 | if mode == "on": 62 | exists = await db.req_user_exist(channel_id, user_id) 63 | #print(f"[REQ] User {user_id} join request for {channel_id}: {exists}") 64 | return exists 65 | #print(f"[NOT SUB] User {user_id} not in {channel_id} and mode != on") 66 | return False 67 | 68 | except Exception as e: 69 | print(f"[!] Error in is_sub(): {e}") 70 | return False 71 | 72 | 73 | async def encode(string): 74 | string_bytes = string.encode("ascii") 75 | base64_bytes = base64.urlsafe_b64encode(string_bytes) 76 | base64_string = (base64_bytes.decode("ascii")).strip("=") 77 | return base64_string 78 | 79 | async def decode(base64_string): 80 | base64_string = base64_string.strip("=") # links generated before this commit will be having = sign, hence striping them to handle padding errors. 81 | base64_bytes = (base64_string + "=" * (-len(base64_string) % 4)).encode("ascii") 82 | string_bytes = base64.urlsafe_b64decode(base64_bytes) 83 | string = string_bytes.decode("ascii") 84 | return string 85 | 86 | async def get_messages(client, message_ids): 87 | messages = [] 88 | total_messages = 0 89 | while total_messages != len(message_ids): 90 | temb_ids = message_ids[total_messages:total_messages+200] 91 | try: 92 | msgs = await client.get_messages( 93 | chat_id=client.db_channel.id, 94 | message_ids=temb_ids 95 | ) 96 | except FloodWait as e: 97 | await asyncio.sleep(e.x) 98 | msgs = await client.get_messages( 99 | chat_id=client.db_channel.id, 100 | message_ids=temb_ids 101 | ) 102 | except: 103 | pass 104 | total_messages += len(temb_ids) 105 | messages.extend(msgs) 106 | return messages 107 | 108 | async def get_message_id(client, message): 109 | if message.forward_from_chat: 110 | if message.forward_from_chat.id == client.db_channel.id: 111 | return message.forward_from_message_id 112 | else: 113 | return 0 114 | elif message.forward_sender_name: 115 | return 0 116 | elif message.text: 117 | pattern = "https://t.me/(?:c/)?(.*)/(\d+)" 118 | matches = re.match(pattern,message.text) 119 | if not matches: 120 | return 0 121 | channel_id = matches.group(1) 122 | msg_id = int(matches.group(2)) 123 | if channel_id.isdigit(): 124 | if f"-100{channel_id}" == str(client.db_channel.id): 125 | return msg_id 126 | else: 127 | if channel_id == client.db_channel.username: 128 | return msg_id 129 | else: 130 | return 0 131 | 132 | 133 | def get_readable_time(seconds: int) -> str: 134 | count = 0 135 | up_time = "" 136 | time_list = [] 137 | time_suffix_list = ["s", "m", "h", "days"] 138 | while count < 4: 139 | count += 1 140 | remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) 141 | if seconds == 0 and remainder == 0: 142 | break 143 | time_list.append(int(result)) 144 | seconds = int(remainder) 145 | hmm = len(time_list) 146 | for x in range(hmm): 147 | time_list[x] = str(time_list[x]) + time_suffix_list[x] 148 | if len(time_list) == 4: 149 | up_time += f"{time_list.pop()}, " 150 | time_list.reverse() 151 | up_time += ":".join(time_list) 152 | return up_time 153 | 154 | 155 | def get_exp_time(seconds): 156 | periods = [('days', 86400), ('hours', 3600), ('mins', 60), ('secs', 1)] 157 | result = '' 158 | for period_name, period_seconds in periods: 159 | if seconds >= period_seconds: 160 | period_value, seconds = divmod(seconds, period_seconds) 161 | result += f'{int(period_value)} {period_name}' 162 | return result 163 | 164 | subscribed = filters.create(is_subscribed) 165 | admin = filters.create(check_admin) 166 | 167 | #rohit_1888 on Tg : -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | worker: Dockerfile 4 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from bot import Bot 2 | import pyrogram.utils 3 | 4 | pyrogram.utils.MIN_CHANNEL_ID = -1009147483647 5 | 6 | if __name__ == "__main__": 7 | Bot().run() 8 | -------------------------------------------------------------------------------- /plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #(©)Codexbotz 2 | #@iryme 3 | 4 | 5 | 6 | 7 | 8 | from aiohttp import web 9 | from .route import routes 10 | 11 | 12 | async def web_server(): 13 | web_app = web.Application(client_max_size=30000000) 14 | web_app.add_routes(routes) 15 | return web_app 16 | -------------------------------------------------------------------------------- /plugins/admin.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | import random 4 | import sys 5 | import time 6 | from pyrogram import Client, filters, __version__ 7 | from pyrogram.enums import ParseMode, ChatAction, ChatMemberStatus, ChatType 8 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, ReplyKeyboardMarkup, ChatMemberUpdated, ChatPermissions 9 | from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant, InviteHashEmpty, ChatAdminRequired, PeerIdInvalid, UserIsBlocked, InputUserDeactivated 10 | from bot import Bot 11 | from config import * 12 | from helper_func import * 13 | from database.database import * 14 | 15 | 16 | 17 | # Commands for adding admins by owner 18 | @Bot.on_message(filters.command('add_admin') & filters.private & filters.user(OWNER_ID)) 19 | async def add_admins(client: Client, message: Message): 20 | pro = await message.reply("ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..", quote=True) 21 | check = 0 22 | admin_ids = await db.get_all_admins() 23 | admins = message.text.split()[1:] 24 | 25 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]]) 26 | 27 | if not admins: 28 | return await pro.edit( 29 | "You need to provide user ID(s) to add as admin.\n\n" 30 | "Usage:\n" 31 | "/add_admin [user_id] — Add one or more user IDs\n\n" 32 | "Example:\n" 33 | "/add_admin 1234567890 9876543210", 34 | reply_markup=reply_markup 35 | ) 36 | 37 | admin_list = "" 38 | for id in admins: 39 | try: 40 | id = int(id) 41 | except: 42 | admin_list += f"
Invalid ID: {id}
\n" 43 | continue 44 | 45 | if id in admin_ids: 46 | admin_list += f"
ID {id} already exists.
\n" 47 | continue 48 | 49 | id = str(id) 50 | if id.isdigit() and len(id) == 10: 51 | admin_list += f"
(ID: {id}) added.
\n" 52 | check += 1 53 | else: 54 | admin_list += f"
Invalid ID: {id}
\n" 55 | 56 | if check == len(admins): 57 | for id in admins: 58 | await db.add_admin(int(id)) 59 | await pro.edit(f"✅ Admin(s) added successfully:\n\n{admin_list}", reply_markup=reply_markup) 60 | else: 61 | await pro.edit( 62 | f"❌ Some errors occurred while adding admins:\n\n{admin_list.strip()}\n\n" 63 | "Please check and try again.", 64 | reply_markup=reply_markup 65 | ) 66 | 67 | 68 | @Bot.on_message(filters.command('deladmin') & filters.private & filters.user(OWNER_ID)) 69 | async def delete_admins(client: Client, message: Message): 70 | pro = await message.reply("ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..", quote=True) 71 | admin_ids = await db.get_all_admins() 72 | admins = message.text.split()[1:] 73 | 74 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]]) 75 | 76 | if not admins: 77 | return await pro.edit( 78 | "Please provide valid admin ID(s) to remove.\n\n" 79 | "Usage:\n" 80 | "/deladmin [user_id] — Remove specific IDs\n" 81 | "/deladmin all — Remove all admins", 82 | reply_markup=reply_markup 83 | ) 84 | 85 | if len(admins) == 1 and admins[0].lower() == "all": 86 | if admin_ids: 87 | for id in admin_ids: 88 | await db.del_admin(id) 89 | ids = "\n".join(f"
{admin}
" for admin in admin_ids) 90 | return await pro.edit(f"⛔️ All admin IDs have been removed:\n{ids}", reply_markup=reply_markup) 91 | else: 92 | return await pro.edit("
No admin IDs to remove.
", reply_markup=reply_markup) 93 | 94 | if admin_ids: 95 | passed = '' 96 | for admin_id in admins: 97 | try: 98 | id = int(admin_id) 99 | except: 100 | passed += f"
Invalid ID: {admin_id}
\n" 101 | continue 102 | 103 | if id in admin_ids: 104 | await db.del_admin(id) 105 | passed += f"
{id} ✅ Removed
\n" 106 | else: 107 | passed += f"
ID {id} not found in admin list.
\n" 108 | 109 | await pro.edit(f"⛔️ Admin removal result:\n\n{passed}", reply_markup=reply_markup) 110 | else: 111 | await pro.edit("
No admin IDs available to delete.
", reply_markup=reply_markup) 112 | 113 | 114 | @Bot.on_message(filters.command('admins') & filters.private & admin) 115 | async def get_admins(client: Client, message: Message): 116 | pro = await message.reply("ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..", quote=True) 117 | admin_ids = await db.get_all_admins() 118 | 119 | if not admin_ids: 120 | admin_list = "
❌ No admins found.
" 121 | else: 122 | admin_list = "\n".join(f"
ID: {id}
" for id in admin_ids) 123 | 124 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("ᴄʟᴏsᴇ", callback_data="close")]]) 125 | await pro.edit(f"⚡ Current Admin List:\n\n{admin_list}", reply_markup=reply_markup) 126 | -------------------------------------------------------------------------------- /plugins/banuser.py: -------------------------------------------------------------------------------- 1 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 2 | # Ask Doubt on telegram @CodeflixSupport 3 | # 4 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 5 | # 6 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 7 | # and is released under the MIT License. 8 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 9 | # 10 | # All rights reserved. 11 | # 12 | 13 | import asyncio 14 | import os 15 | import random 16 | import sys 17 | import time 18 | from datetime import datetime, timedelta 19 | from pyrogram import Client, filters, __version__ 20 | from pyrogram.enums import ParseMode, ChatAction 21 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, ReplyKeyboardMarkup, ChatInviteLink, ChatPrivileges 22 | from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant 23 | from pyrogram.errors import FloodWait, UserIsBlocked, InputUserDeactivated, UserNotParticipant 24 | from bot import Bot 25 | from config import * 26 | from helper_func import * 27 | from database.database import * 28 | 29 | 30 | 31 | #BAN-USER-SYSTEM 32 | @Bot.on_message(filters.private & filters.command('ban') & admin) 33 | async def add_banuser(client: Client, message: Message): 34 | pro = await message.reply("⏳ Pʀᴏᴄᴇssɪɴɢ ʀᴇǫᴜᴇsᴛ...", quote=True) 35 | banuser_ids = await db.get_ban_users() 36 | banusers = message.text.split()[1:] 37 | 38 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("❌ Cʟᴏsᴇ", callback_data="close")]]) 39 | 40 | if not banusers: 41 | return await pro.edit( 42 | "❗ Yᴏᴜ ᴍᴜsᴛ ᴘʀᴏᴠɪᴅᴇ ᴜsᴇʀ IDs ᴛᴏ ʙᴀɴ.\n\n" 43 | "📌 Usᴀɢᴇ:\n" 44 | "/ban [user_id] — Ban one or more users by ID.", 45 | reply_markup=reply_markup 46 | ) 47 | 48 | report, success_count = "", 0 49 | for uid in banusers: 50 | try: 51 | uid_int = int(uid) 52 | except: 53 | report += f"⚠️ Iɴᴠᴀʟɪᴅ ID: {uid}\n" 54 | continue 55 | 56 | if uid_int in await db.get_all_admins() or uid_int == OWNER_ID: 57 | report += f"⛔ Sᴋɪᴘᴘᴇᴅ ᴀᴅᴍɪɴ/ᴏᴡɴᴇʀ ID: {uid_int}\n" 58 | continue 59 | 60 | if uid_int in banuser_ids: 61 | report += f"⚠️ Aʟʀᴇᴀᴅʏ : {uid_int}\n" 62 | continue 63 | 64 | if len(str(uid_int)) == 10: 65 | await db.add_ban_user(uid_int) 66 | report += f"✅ Bᴀɴɴᴇᴅ: {uid_int}\n" 67 | success_count += 1 68 | else: 69 | report += f"⚠️ Invalid Telegram ID length: {uid_int}\n" 70 | 71 | if success_count: 72 | await pro.edit(f"✅ Bᴀɴɴᴇᴅ Usᴇʀs Uᴘᴅᴀᴛᴇᴅ:\n\n{report}", reply_markup=reply_markup) 73 | else: 74 | await pro.edit(f"❌ Nᴏ ᴜsᴇʀs ᴡᴇʀᴇ ʙᴀɴɴᴇᴅ.\n\n{report}", reply_markup=reply_markup) 75 | 76 | @Bot.on_message(filters.private & filters.command('unban') & admin) 77 | async def delete_banuser(client: Client, message: Message): 78 | pro = await message.reply("⏳ Pʀᴏᴄᴇssɪɴɢ ʀᴇǫᴜᴇsᴛ...", quote=True) 79 | banuser_ids = await db.get_ban_users() 80 | banusers = message.text.split()[1:] 81 | 82 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("❌ Cʟᴏsᴇ", callback_data="close")]]) 83 | 84 | if not banusers: 85 | return await pro.edit( 86 | "❗ Pʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ ᴜsᴇʀ IDs ᴛᴏ ᴜɴʙᴀɴ.\n\n" 87 | "📌 Usage:\n" 88 | "/unban [user_id] — Unban specific user(s)\n" 89 | "/unban all — Remove all banned users", 90 | reply_markup=reply_markup 91 | ) 92 | 93 | if banusers[0].lower() == "all": 94 | if not banuser_ids: 95 | return await pro.edit("✅ NO ᴜsᴇʀs ɪɴ ᴛʜᴇ ʙᴀɴ ʟɪsᴛ.", reply_markup=reply_markup) 96 | for uid in banuser_ids: 97 | await db.del_ban_user(uid) 98 | listed = "\n".join([f"✅ Uɴʙᴀɴɴᴇᴅ: {uid}" for uid in banuser_ids]) 99 | return await pro.edit(f"🚫 Cʟᴇᴀʀᴇᴅ Bᴀɴ Lɪsᴛ:\n\n{listed}", reply_markup=reply_markup) 100 | 101 | report = "" 102 | for uid in banusers: 103 | try: 104 | uid_int = int(uid) 105 | except: 106 | report += f"⚠️ Iɴᴀᴠʟɪᴅ ID: {uid}\n" 107 | continue 108 | 109 | if uid_int in banuser_ids: 110 | await db.del_ban_user(uid_int) 111 | report += f"✅ Uɴʙᴀɴɴᴇᴅ: {uid_int}\n" 112 | else: 113 | report += f"⚠️ Nᴏᴛ ɪɴ ʙᴀɴ ʟɪsᴛ: {uid_int}\n" 114 | 115 | await pro.edit(f"🚫 Uɴʙᴀɴ Rᴇᴘᴏʀᴛ:\n\n{report}", reply_markup=reply_markup) 116 | 117 | @Bot.on_message(filters.private & filters.command('banlist') & admin) 118 | async def get_banuser_list(client: Client, message: Message): 119 | pro = await message.reply("⏳ Fᴇᴛᴄʜɪɴɢ Bᴀɴ Lɪsᴛ...", quote=True) 120 | banuser_ids = await db.get_ban_users() 121 | 122 | if not banuser_ids: 123 | return await pro.edit("✅ NO ᴜsᴇʀs ɪɴ ᴛʜᴇ ʙᴀɴ Lɪsᴛ.", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("❌ Cʟᴏsᴇ", callback_data="close")]])) 124 | 125 | result = "🚫 Bᴀɴɴᴇᴅ Usᴇʀs:\n\n" 126 | for uid in banuser_ids: 127 | await message.reply_chat_action(ChatAction.TYPING) 128 | try: 129 | user = await client.get_users(uid) 130 | user_link = f'{user.first_name}' 131 | result += f"• {user_link} — {uid}\n" 132 | except: 133 | result += f"• {uid}Could not fetch name\n" 134 | 135 | await pro.edit(result, disable_web_page_preview=True, reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("❌ Cʟᴏsᴇ", callback_data="close")]])) 136 | -------------------------------------------------------------------------------- /plugins/broadcast.py: -------------------------------------------------------------------------------- 1 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 2 | # Ask Doubt on telegram @CodeflixSupport 3 | # 4 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 5 | # 6 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 7 | # and is released under the MIT License. 8 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 9 | # 10 | # All rights reserved. 11 | # 12 | 13 | import asyncio 14 | import os 15 | import random 16 | import sys 17 | import time 18 | from datetime import datetime, timedelta 19 | from pyrogram import Client, filters, __version__ 20 | from pyrogram.enums import ParseMode, ChatAction 21 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, ReplyKeyboardMarkup, ChatInviteLink, ChatPrivileges 22 | from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant 23 | from pyrogram.errors import FloodWait, UserIsBlocked, InputUserDeactivated, UserNotParticipant 24 | from bot import Bot 25 | from config import * 26 | from helper_func import * 27 | from database.database import * 28 | 29 | 30 | #=====================================================================================## 31 | 32 | REPLY_ERROR = "Use this command as a reply to any telegram message without any spaces." 33 | 34 | #=====================================================================================## 35 | 36 | 37 | @Bot.on_message(filters.private & filters.command('pbroadcast') & admin) 38 | async def send_pin_text(client: Bot, message: Message): 39 | if message.reply_to_message: 40 | query = await db.full_userbase() 41 | broadcast_msg = message.reply_to_message 42 | total = 0 43 | successful = 0 44 | blocked = 0 45 | deleted = 0 46 | unsuccessful = 0 47 | 48 | pls_wait = await message.reply("ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴘʀᴏᴄᴇꜱꜱɪɴɢ....") 49 | for chat_id in query: 50 | try: 51 | # Send and pin the message 52 | sent_msg = await broadcast_msg.copy(chat_id) 53 | await client.pin_chat_message(chat_id=chat_id, message_id=sent_msg.id, both_sides=True) 54 | successful += 1 55 | except FloodWait as e: 56 | await asyncio.sleep(e.x) 57 | sent_msg = await broadcast_msg.copy(chat_id) 58 | await client.pin_chat_message(chat_id=chat_id, message_id=sent_msg.id, both_sides=True) 59 | successful += 1 60 | except UserIsBlocked: 61 | await db.del_user(chat_id) 62 | blocked += 1 63 | except InputUserDeactivated: 64 | await db.del_user(chat_id) 65 | deleted += 1 66 | except Exception as e: 67 | print(f"Failed to send or pin message to {chat_id}: {e}") 68 | unsuccessful += 1 69 | total += 1 70 | 71 | status = f"""ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴄᴏᴍᴘʟᴇᴛᴇᴅ 72 | 73 | Total Users: {total} 74 | Successful: {successful} 75 | Blocked Users: {blocked} 76 | Deleted Accounts: {deleted} 77 | Unsuccessful: {unsuccessful}""" 78 | 79 | return await pls_wait.edit(status) 80 | 81 | else: 82 | msg = await message.reply("Reply to a message to broadcast and pin it.") 83 | await asyncio.sleep(8) 84 | await msg.delete() 85 | 86 | #=====================================================================================## 87 | 88 | 89 | @Bot.on_message(filters.private & filters.command('broadcast') & admin) 90 | async def send_text(client: Bot, message: Message): 91 | if message.reply_to_message: 92 | query = await db.full_userbase() 93 | broadcast_msg = message.reply_to_message 94 | total = 0 95 | successful = 0 96 | blocked = 0 97 | deleted = 0 98 | unsuccessful = 0 99 | 100 | pls_wait = await message.reply("ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴘʀᴏᴄᴇꜱꜱɪɴɢ....") 101 | for chat_id in query: 102 | try: 103 | await broadcast_msg.copy(chat_id) 104 | successful += 1 105 | except FloodWait as e: 106 | await asyncio.sleep(e.x) 107 | await broadcast_msg.copy(chat_id) 108 | successful += 1 109 | except UserIsBlocked: 110 | await db.del_user(chat_id) 111 | blocked += 1 112 | except InputUserDeactivated: 113 | await db.del_user(chat_id) 114 | deleted += 1 115 | except: 116 | unsuccessful += 1 117 | pass 118 | total += 1 119 | 120 | status = f"""ʙʀᴏᴀᴅᴄᴀꜱᴛ... 121 | 122 | Total Users: {total} 123 | Successful: {successful} 124 | Blocked Users: {blocked} 125 | Deleted Accounts: {deleted} 126 | Unsuccessful: {unsuccessful}""" 127 | 128 | return await pls_wait.edit(status) 129 | 130 | else: 131 | msg = await message.reply(REPLY_ERROR) 132 | await asyncio.sleep(8) 133 | await msg.delete() 134 | 135 | #=====================================================================================## 136 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 137 | # Ask Doubt on telegram @CodeflixSupport 138 | # 139 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 140 | # 141 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 142 | # and is released under the MIT License. 143 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 144 | # 145 | # All rights reserved. 146 | # 147 | 148 | # broadcast with auto-del 149 | 150 | @Bot.on_message(filters.private & filters.command('dbroadcast') & admin) 151 | async def delete_broadcast(client: Bot, message: Message): 152 | if message.reply_to_message: 153 | try: 154 | duration = int(message.command[1]) # Get the duration in seconds 155 | except (IndexError, ValueError): 156 | await message.reply("Pʟᴇᴀsᴇ ᴜsᴇ ᴀ ᴠᴀʟɪᴅ ᴅᴜʀᴀᴛɪᴏɴ ɪɴ sᴇᴄᴏɴᴅs. Usᴀɢᴇ: /dbroadcast {duration}") 157 | return 158 | 159 | query = await db.full_userbase() 160 | broadcast_msg = message.reply_to_message 161 | total = 0 162 | successful = 0 163 | blocked = 0 164 | deleted = 0 165 | unsuccessful = 0 166 | 167 | pls_wait = await message.reply("Broadcast with auto-delete processing....") 168 | for chat_id in query: 169 | try: 170 | sent_msg = await broadcast_msg.copy(chat_id) 171 | await asyncio.sleep(duration) # Wait for the specified duration 172 | await sent_msg.delete() # Delete the message after the duration 173 | successful += 1 174 | except FloodWait as e: 175 | await asyncio.sleep(e.x) 176 | sent_msg = await broadcast_msg.copy(chat_id) 177 | await asyncio.sleep(duration) 178 | await sent_msg.delete() 179 | successful += 1 180 | except UserIsBlocked: 181 | await db.del_user(chat_id) 182 | blocked += 1 183 | except InputUserDeactivated: 184 | await db.del_user(chat_id) 185 | deleted += 1 186 | except: 187 | unsuccessful += 1 188 | pass 189 | total += 1 190 | 191 | status = f"""Bʀᴏᴀᴅᴄᴀsᴛɪɴɢ ᴡɪᴛʜ Aᴜᴛᴏ-Dᴇʟᴇᴛᴇ... 192 | 193 | Total Users: {total} 194 | Successful: {successful} 195 | Blocked Users: {blocked} 196 | Deleted Accounts: {deleted} 197 | Unsuccessful: {unsuccessful}""" 198 | 199 | return await pls_wait.edit(status) 200 | 201 | else: 202 | msg = await message.reply("Pʟᴇᴀsᴇ ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ ʙʀᴏᴀᴅᴄᴀsᴛ ɪᴛ ᴡɪᴛʜ Aᴜᴛᴏ-Dᴇʟᴇᴛᴇ.") 203 | await asyncio.sleep(8) 204 | await msg.delete() 205 | 206 | 207 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 208 | # Ask Doubt on telegram @CodeflixSupport 209 | # 210 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 211 | # 212 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 213 | # and is released under the MIT License. 214 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 215 | # 216 | # All rights reserved. 217 | # -------------------------------------------------------------------------------- /plugins/cbb.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 3 | # 4 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 5 | # and is released under the MIT License. 6 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 7 | # 8 | # All rights reserved. 9 | 10 | from pyrogram import Client 11 | from bot import Bot 12 | from config import * 13 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery 14 | from database.database import * 15 | 16 | @Bot.on_callback_query() 17 | async def cb_handler(client: Bot, query: CallbackQuery): 18 | data = query.data 19 | 20 | if data == "help": 21 | await query.message.edit_text( 22 | text=HELP_TXT.format(first=query.from_user.first_name), 23 | disable_web_page_preview=True, 24 | reply_markup=InlineKeyboardMarkup([ 25 | [InlineKeyboardButton('ʜᴏᴍᴇ', callback_data='start'), 26 | InlineKeyboardButton("ᴄʟᴏꜱᴇ", callback_data='close')] 27 | ]) 28 | ) 29 | 30 | elif data == "about": 31 | await query.message.edit_text( 32 | text=ABOUT_TXT.format(first=query.from_user.first_name), 33 | disable_web_page_preview=True, 34 | reply_markup=InlineKeyboardMarkup([ 35 | [InlineKeyboardButton('ʜᴏᴍᴇ', callback_data='start'), 36 | InlineKeyboardButton('ᴄʟᴏꜱᴇ', callback_data='close')] 37 | ]) 38 | ) 39 | 40 | elif data == "start": 41 | await query.message.edit_text( 42 | text=START_MSG.format(first=query.from_user.first_name), 43 | disable_web_page_preview=True, 44 | reply_markup=InlineKeyboardMarkup([ 45 | [InlineKeyboardButton("ʜᴇʟᴘ", callback_data='help'), 46 | InlineKeyboardButton("ᴀʙᴏᴜᴛ", callback_data='about')] 47 | ]) 48 | ) 49 | 50 | elif data == "close": 51 | await query.message.delete() 52 | try: 53 | await query.message.reply_to_message.delete() 54 | except: 55 | pass 56 | 57 | elif data.startswith("rfs_ch_"): 58 | cid = int(data.split("_")[2]) 59 | try: 60 | chat = await client.get_chat(cid) 61 | mode = await db.get_channel_mode(cid) 62 | status = "🟢 ᴏɴ" if mode == "on" else "🔴 ᴏғғ" 63 | new_mode = "ᴏғғ" if mode == "on" else "on" 64 | buttons = [ 65 | [InlineKeyboardButton(f"ʀᴇǫ ᴍᴏᴅᴇ {'OFF' if mode == 'on' else 'ON'}", callback_data=f"rfs_toggle_{cid}_{new_mode}")], 66 | [InlineKeyboardButton("‹ ʙᴀᴄᴋ", callback_data="fsub_back")] 67 | ] 68 | await query.message.edit_text( 69 | f"Channel: {chat.title}\nCurrent Force-Sub Mode: {status}", 70 | reply_markup=InlineKeyboardMarkup(buttons) 71 | ) 72 | except Exception: 73 | await query.answer("Failed to fetch channel info", show_alert=True) 74 | 75 | elif data.startswith("rfs_toggle_"): 76 | cid, action = data.split("_")[2:] 77 | cid = int(cid) 78 | mode = "on" if action == "on" else "off" 79 | 80 | await db.set_channel_mode(cid, mode) 81 | await query.answer(f"Force-Sub set to {'ON' if mode == 'on' else 'OFF'}") 82 | 83 | # Refresh the same channel's mode view 84 | chat = await client.get_chat(cid) 85 | status = "🟢 ON" if mode == "on" else "🔴 OFF" 86 | new_mode = "off" if mode == "on" else "on" 87 | buttons = [ 88 | [InlineKeyboardButton(f"ʀᴇǫ ᴍᴏᴅᴇ {'OFF' if mode == 'on' else 'ON'}", callback_data=f"rfs_toggle_{cid}_{new_mode}")], 89 | [InlineKeyboardButton("‹ ʙᴀᴄᴋ", callback_data="fsub_back")] 90 | ] 91 | await query.message.edit_text( 92 | f"Channel: {chat.title}\nCurrent Force-Sub Mode: {status}", 93 | reply_markup=InlineKeyboardMarkup(buttons) 94 | ) 95 | 96 | elif data == "fsub_back": 97 | channels = await db.show_channels() 98 | buttons = [] 99 | for cid in channels: 100 | try: 101 | chat = await client.get_chat(cid) 102 | mode = await db.get_channel_mode(cid) 103 | status = "🟢" if mode == "on" else "🔴" 104 | buttons.append([InlineKeyboardButton(f"{status} {chat.title}", callback_data=f"rfs_ch_{cid}")]) 105 | except: 106 | continue 107 | 108 | await query.message.edit_text( 109 | "sᴇʟᴇᴄᴛ ᴀ ᴄʜᴀɴɴᴇʟ ᴛᴏ ᴛᴏɢɢʟᴇ ɪᴛs ғᴏʀᴄᴇ-sᴜʙ ᴍᴏᴅᴇ:", 110 | reply_markup=InlineKeyboardMarkup(buttons) 111 | ) 112 | -------------------------------------------------------------------------------- /plugins/channel_post.py: -------------------------------------------------------------------------------- 1 | #(©)Codexbotz 2 | 3 | import asyncio 4 | from pyrogram import filters, Client 5 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton 6 | from pyrogram.errors import FloodWait 7 | 8 | from bot import Bot 9 | from config import * 10 | from helper_func import encode, admin 11 | 12 | @Bot.on_message(filters.private & admin & ~filters.command(['start', 'commands','users','broadcast','batch', 'custom_batch', 'genlink','stats', 'dlt_time', 'check_dlt_time', 'dbroadcast', 'ban', 'unban', 'banlist', 'addchnl', 'delchnl', 'listchnl', 'fsub_mode', 'pbroadcast', 'add_admin', 'deladmin', 'admins'])) 13 | async def channel_post(client: Client, message: Message): 14 | reply_text = await message.reply_text("Please Wait...!", quote = True) 15 | try: 16 | post_message = await message.copy(chat_id = client.db_channel.id, disable_notification=True) 17 | except FloodWait as e: 18 | await asyncio.sleep(e.x) 19 | post_message = await message.copy(chat_id = client.db_channel.id, disable_notification=True) 20 | except Exception as e: 21 | print(e) 22 | await reply_text.edit_text("Something went Wrong..!") 23 | return 24 | converted_id = post_message.id * abs(client.db_channel.id) 25 | string = f"get-{converted_id}" 26 | base64_string = await encode(string) 27 | link = f"https://t.me/{client.username}?start={base64_string}" 28 | 29 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🔁 Share URL", url=f'https://telegram.me/share/url?url={link}')]]) 30 | 31 | await reply_text.edit(f"Here is your link\n\n{link}", reply_markup=reply_markup, disable_web_page_preview = True) 32 | 33 | if not DISABLE_CHANNEL_BUTTON: 34 | await post_message.edit_reply_markup(reply_markup) 35 | -------------------------------------------------------------------------------- /plugins/link_generator.py: -------------------------------------------------------------------------------- 1 | #(©)Codexbotz 2 | 3 | from pyrogram import Client, filters 4 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton 5 | from bot import Bot 6 | from pyrogram.types import ReplyKeyboardMarkup, ReplyKeyboardRemove 7 | from asyncio import TimeoutError 8 | from helper_func import encode, get_message_id, admin 9 | 10 | @Bot.on_message(filters.private & admin & filters.command('batch')) 11 | async def batch(client: Client, message: Message): 12 | while True: 13 | try: 14 | first_message = await client.ask(text = "Forward the First Message from DB Channel (with Quotes)..\n\nor Send the DB Channel Post Link", chat_id = message.from_user.id, filters=(filters.forwarded | (filters.text & ~filters.forwarded)), timeout=60) 15 | except: 16 | return 17 | f_msg_id = await get_message_id(client, first_message) 18 | if f_msg_id: 19 | break 20 | else: 21 | await first_message.reply("❌ Error\n\nthis Forwarded Post is not from my DB Channel or this Link is taken from DB Channel", quote = True) 22 | continue 23 | 24 | while True: 25 | try: 26 | second_message = await client.ask(text = "Forward the Last Message from DB Channel (with Quotes)..\nor Send the DB Channel Post link", chat_id = message.from_user.id, filters=(filters.forwarded | (filters.text & ~filters.forwarded)), timeout=60) 27 | except: 28 | return 29 | s_msg_id = await get_message_id(client, second_message) 30 | if s_msg_id: 31 | break 32 | else: 33 | await second_message.reply("❌ Error\n\nthis Forwarded Post is not from my DB Channel or this Link is taken from DB Channel", quote = True) 34 | continue 35 | 36 | 37 | string = f"get-{f_msg_id * abs(client.db_channel.id)}-{s_msg_id * abs(client.db_channel.id)}" 38 | base64_string = await encode(string) 39 | link = f"https://t.me/{client.username}?start={base64_string}" 40 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🔁 Share URL", url=f'https://telegram.me/share/url?url={link}')]]) 41 | await second_message.reply_text(f"Here is your link\n\n{link}", quote=True, reply_markup=reply_markup) 42 | 43 | 44 | @Bot.on_message(filters.private & admin & filters.command('genlink')) 45 | async def link_generator(client: Client, message: Message): 46 | while True: 47 | try: 48 | channel_message = await client.ask(text = "Forward Message from the DB Channel (with Quotes)..\nor Send the DB Channel Post link", chat_id = message.from_user.id, filters=(filters.forwarded | (filters.text & ~filters.forwarded)), timeout=60) 49 | except: 50 | return 51 | msg_id = await get_message_id(client, channel_message) 52 | if msg_id: 53 | break 54 | else: 55 | await channel_message.reply("❌ Error\n\nthis Forwarded Post is not from my DB Channel or this Link is not taken from DB Channel", quote = True) 56 | continue 57 | 58 | base64_string = await encode(f"get-{msg_id * abs(client.db_channel.id)}") 59 | link = f"https://t.me/{client.username}?start={base64_string}" 60 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🔁 Share URL", url=f'https://telegram.me/share/url?url={link}')]]) 61 | await channel_message.reply_text(f"Here is your link\n\n{link}", quote=True, reply_markup=reply_markup) 62 | 63 | 64 | @Bot.on_message(filters.private & admin & filters.command("custom_batch")) 65 | async def custom_batch(client: Client, message: Message): 66 | collected = [] 67 | STOP_KEYBOARD = ReplyKeyboardMarkup([["STOP"]], resize_keyboard=True) 68 | 69 | await message.reply("Send all messages you want to include in batch.\n\nPress STOP when you're done.", reply_markup=STOP_KEYBOARD) 70 | 71 | while True: 72 | try: 73 | user_msg = await client.ask( 74 | chat_id=message.chat.id, 75 | text="Waiting for files/messages...\nPress STOP to finish.", 76 | timeout=60 77 | ) 78 | except asyncio.TimeoutError: 79 | break 80 | 81 | if user_msg.text and user_msg.text.strip().upper() == "STOP": 82 | break 83 | 84 | try: 85 | sent = await user_msg.copy(client.db_channel.id, disable_notification=True) 86 | collected.append(sent.id) 87 | except Exception as e: 88 | await message.reply(f"❌ Failed to store a message:\n{e}") 89 | continue 90 | 91 | await message.reply("✅ Batch collection complete.", reply_markup=ReplyKeyboardRemove()) 92 | 93 | if not collected: 94 | await message.reply("❌ No messages were added to batch.") 95 | return 96 | 97 | start_id = collected[0] * abs(client.db_channel.id) 98 | end_id = collected[-1] * abs(client.db_channel.id) 99 | string = f"get-{start_id}-{end_id}" 100 | base64_string = await encode(string) 101 | link = f"https://t.me/{client.username}?start={base64_string}" 102 | 103 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🔁 Share URL", url=f'https://telegram.me/share/url?url={link}')]]) 104 | await message.reply(f"Here is your custom batch link:\n\n{link}", reply_markup=reply_markup) -------------------------------------------------------------------------------- /plugins/request_fsub.py: -------------------------------------------------------------------------------- 1 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 2 | # Ask Doubt on telegram @CodeflixSupport 3 | # 4 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 5 | # 6 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 7 | # and is released under the MIT License. 8 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 9 | # 10 | # All rights reserved. 11 | # 12 | import asyncio 13 | import os 14 | import random 15 | import sys 16 | import time 17 | from pyrogram import Client, filters, __version__ 18 | from pyrogram.enums import ParseMode, ChatAction, ChatMemberStatus, ChatType 19 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, ReplyKeyboardMarkup, ChatMemberUpdated, ChatPermissions 20 | from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant, InviteHashEmpty, ChatAdminRequired, PeerIdInvalid, UserIsBlocked, InputUserDeactivated, UserNotParticipant 21 | from bot import Bot 22 | from config import * 23 | from helper_func import * 24 | from database.database import * 25 | 26 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 27 | # Ask Doubt on telegram @CodeflixSupport 28 | # 29 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 30 | # 31 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 32 | # and is released under the MIT License. 33 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 34 | # 35 | # All rights reserved. 36 | # 37 | 38 | #Request force sub mode commad,,,,,, 39 | @Bot.on_message(filters.command('fsub_mode') & filters.private & admin) 40 | async def change_force_sub_mode(client: Client, message: Message): 41 | temp = await message.reply("ᴡᴀɪᴛ ᴀ sᴇᴄ..", quote=True) 42 | channels = await db.show_channels() 43 | 44 | if not channels: 45 | return await temp.edit("❌ No force-sub channels found.") 46 | 47 | buttons = [] 48 | for ch_id in channels: 49 | try: 50 | chat = await client.get_chat(ch_id) 51 | mode = await db.get_channel_mode(ch_id) 52 | status = "🟢" if mode == "on" else "🔴" 53 | title = f"{status} {chat.title}" 54 | buttons.append([InlineKeyboardButton(title, callback_data=f"rfs_ch_{ch_id}")]) 55 | except: 56 | buttons.append([InlineKeyboardButton(f"⚠️ {ch_id} (Unavailable)", callback_data=f"rfs_ch_{ch_id}")]) 57 | 58 | buttons.append([InlineKeyboardButton("Close ✖️", callback_data="close")]) 59 | 60 | await temp.edit( 61 | "⚡ Select a channel to toggle Force-Sub Mode:", 62 | reply_markup=InlineKeyboardMarkup(buttons), 63 | disable_web_page_preview=True 64 | ) 65 | 66 | # This handler captures membership updates (like when a user leaves, banned) 67 | @Bot.on_chat_member_updated() 68 | async def handle_Chatmembers(client, chat_member_updated: ChatMemberUpdated): 69 | chat_id = chat_member_updated.chat.id 70 | 71 | if await db.reqChannel_exist(chat_id): 72 | old_member = chat_member_updated.old_chat_member 73 | 74 | if not old_member: 75 | return 76 | 77 | if old_member.status == ChatMemberStatus.MEMBER: 78 | user_id = old_member.user.id 79 | 80 | if await db.req_user_exist(chat_id, user_id): 81 | await db.del_req_user(chat_id, user_id) 82 | 83 | 84 | # This handler will capture any join request to the channel/group where the bot is an admin 85 | @Bot.on_chat_join_request() 86 | async def handle_join_request(client, chat_join_request): 87 | chat_id = chat_join_request.chat.id 88 | user_id = chat_join_request.from_user.id 89 | 90 | #print(f"[JOIN REQUEST] User {user_id} sent join request to {chat_id}") 91 | 92 | # Print the result of db.reqChannel_exist to check if the channel exists 93 | channel_exists = await db.reqChannel_exist(chat_id) 94 | #print(f"Channel {chat_id} exists in the database: {channel_exists}") 95 | 96 | if channel_exists: 97 | if not await db.req_user_exist(chat_id, user_id): 98 | await db.req_user(chat_id, user_id) 99 | #print(f"Added user {user_id} to request list for {chat_id}") 100 | 101 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 102 | # Ask Doubt on telegram @CodeflixSupport 103 | # 104 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 105 | # 106 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 107 | # and is released under the MIT License. 108 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 109 | # 110 | # All rights reserved. 111 | # 112 | 113 | # Add channel 114 | @Bot.on_message(filters.command('addchnl') & filters.private & admin) 115 | async def add_force_sub(client: Client, message: Message): 116 | temp = await message.reply("Wait a sec...", quote=True) 117 | args = message.text.split(maxsplit=1) 118 | 119 | if len(args) != 2: 120 | return await temp.edit( 121 | "Usage:\n/addchnl -100xxxxxxxxxx" 122 | ) 123 | 124 | try: 125 | chat_id = int(args[1]) 126 | except ValueError: 127 | return await temp.edit("❌ Invalid chat ID!") 128 | 129 | all_chats = await db.show_channels() 130 | if chat_id in [c if isinstance(c, int) else c[0] for c in all_chats]: 131 | return await temp.edit(f"Already exists:\n{chat_id}") 132 | 133 | try: 134 | chat = await client.get_chat(chat_id) 135 | if chat.type not in [ChatType.CHANNEL, ChatType.SUPERGROUP]: 136 | return await temp.edit("❌ Only channels/supergroups allowed.") 137 | 138 | bot_member = await client.get_chat_member(chat.id, "me") 139 | if bot_member.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]: 140 | return await temp.edit("❌ Bot must be admin in that chat.") 141 | 142 | # Try to get invite link 143 | try: 144 | link = await client.export_chat_invite_link(chat.id) 145 | except Exception: 146 | link = f"https://t.me/{chat.username}" if chat.username else f"https://t.me/c/{str(chat.id)[4:]}" 147 | 148 | await db.add_channel(chat_id) 149 | return await temp.edit( 150 | f"✅ Added Successfully!\n\n" 151 | f"Name: {chat.title}\n" 152 | f"ID: {chat_id}", 153 | disable_web_page_preview=True 154 | ) 155 | 156 | except Exception as e: 157 | return await temp.edit(f"❌ Failed to add chat:\n{chat_id}\n\n{e}") 158 | 159 | 160 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 161 | # Ask Doubt on telegram @CodeflixSupport 162 | # 163 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 164 | # 165 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 166 | # and is released under the MIT License. 167 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 168 | # 169 | # All rights reserved. 170 | # 171 | 172 | # Delete channel 173 | @Bot.on_message(filters.command('delchnl') & filters.private & admin) 174 | async def del_force_sub(client: Client, message: Message): 175 | temp = await message.reply("ᴡᴀɪᴛ ᴀ sᴇᴄ..", quote=True) 176 | args = message.text.split(maxsplit=1) 177 | all_channels = await db.show_channels() 178 | 179 | if len(args) != 2: 180 | return await temp.edit("Usage: /delchnl ") 181 | 182 | if args[1].lower() == "all": 183 | if not all_channels: 184 | return await temp.edit("❌ No force-sub channels found.") 185 | for ch_id in all_channels: 186 | await db.del_channel(ch_id) 187 | return await temp.edit("✅ All force-sub channels have been removed.") 188 | 189 | try: 190 | ch_id = int(args[1]) 191 | except ValueError: 192 | return await temp.edit("❌ Invalid Channel ID") 193 | 194 | if ch_id in all_channels: 195 | await db.rem_channel(ch_id) 196 | return await temp.edit(f"✅ Channel removed: {ch_id}") 197 | else: 198 | return await temp.edit(f"❌ Channel not found in force-sub list: {ch_id}") 199 | 200 | # View all channels 201 | @Bot.on_message(filters.command('listchnl') & filters.private & admin) 202 | async def list_force_sub_channels(client: Client, message: Message): 203 | temp = await message.reply("ᴡᴀɪᴛ ᴀ sᴇᴄ..", quote=True) 204 | channels = await db.show_channels() 205 | 206 | if not channels: 207 | return await temp.edit("❌ No force-sub channels found.") 208 | 209 | result = "⚡ Force-sub Channels:\n\n" 210 | for ch_id in channels: 211 | try: 212 | chat = await client.get_chat(ch_id) 213 | link = chat.invite_link or await client.export_chat_invite_link(chat.id) 214 | result += f" {chat.title} [{ch_id}]\n" 215 | except Exception: 216 | result += f" {ch_id}Unavailable\n" 217 | 218 | await temp.edit(result, disable_web_page_preview=True, reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Close ✖️", callback_data="close")]])) 219 | 220 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 221 | # Ask Doubt on telegram @CodeflixSupport 222 | # 223 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 224 | # 225 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 226 | # and is released under the MIT License. 227 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 228 | # 229 | # All rights reserved. 230 | # 231 | -------------------------------------------------------------------------------- /plugins/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("Codeflix FileStore") 8 | -------------------------------------------------------------------------------- /plugins/start.py: -------------------------------------------------------------------------------- 1 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 2 | # Ask Doubt on telegram @CodeflixSupport 3 | # 4 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 5 | # 6 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 7 | # and is released under the MIT License. 8 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 9 | # 10 | # All rights reserved. 11 | # 12 | 13 | import asyncio 14 | import os 15 | import random 16 | import sys 17 | import time 18 | from datetime import datetime, timedelta 19 | from pyrogram import Client, filters, __version__ 20 | from pyrogram.enums import ParseMode, ChatAction 21 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, ReplyKeyboardMarkup, ChatInviteLink, ChatPrivileges 22 | from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant 23 | from pyrogram.errors import FloodWait, UserIsBlocked, InputUserDeactivated, UserNotParticipant 24 | from bot import Bot 25 | from config import * 26 | from helper_func import * 27 | from database.database import * 28 | 29 | BAN_SUPPORT = f"{BAN_SUPPORT}" 30 | 31 | @Bot.on_message(filters.command('start') & filters.private) 32 | async def start_command(client: Client, message: Message): 33 | user_id = message.from_user.id 34 | 35 | # Check if user is banned 36 | banned_users = await db.get_ban_users() 37 | if user_id in banned_users: 38 | return await message.reply_text( 39 | "⛔️ You are Bᴀɴɴᴇᴅ from using this bot.\n\n" 40 | "Contact support if you think this is a mistake.", 41 | reply_markup=InlineKeyboardMarkup( 42 | [[InlineKeyboardButton("Contact Support", url=BAN_SUPPORT)]] 43 | ) 44 | ) 45 | # ✅ Check Force Subscription 46 | if not await is_subscribed(client, user_id): 47 | #await temp.delete() 48 | return await not_joined(client, message) 49 | 50 | # File auto-delete time in seconds (Set your desired time in seconds here) 51 | FILE_AUTO_DELETE = await db.get_del_timer() # Example: 3600 seconds (1 hour) 52 | 53 | # Add user if not already present 54 | if not await db.present_user(user_id): 55 | try: 56 | await db.add_user(user_id) 57 | except: 58 | pass 59 | 60 | # Handle normal message flow 61 | text = message.text 62 | if len(text) > 7: 63 | try: 64 | base64_string = text.split(" ", 1)[1] 65 | except IndexError: 66 | return 67 | 68 | string = await decode(base64_string) 69 | argument = string.split("-") 70 | 71 | ids = [] 72 | if len(argument) == 3: 73 | try: 74 | start = int(int(argument[1]) / abs(client.db_channel.id)) 75 | end = int(int(argument[2]) / abs(client.db_channel.id)) 76 | ids = range(start, end + 1) if start <= end else list(range(start, end - 1, -1)) 77 | except Exception as e: 78 | print(f"Error decoding IDs: {e}") 79 | return 80 | 81 | elif len(argument) == 2: 82 | try: 83 | ids = [int(int(argument[1]) / abs(client.db_channel.id))] 84 | except Exception as e: 85 | print(f"Error decoding ID: {e}") 86 | return 87 | 88 | temp_msg = await message.reply("Please wait...") 89 | try: 90 | messages = await get_messages(client, ids) 91 | except Exception as e: 92 | await message.reply_text("Something went wrong!") 93 | print(f"Error getting messages: {e}") 94 | return 95 | finally: 96 | await temp_msg.delete() 97 | 98 | codeflix_msgs = [] 99 | 100 | for msg in messages: 101 | original_caption = msg.caption.html if msg.caption else "" 102 | caption = f"{original_caption}\n\n{CUSTOM_CAPTION}" if CUSTOM_CAPTION else original_caption 103 | reply_markup = msg.reply_markup if DISABLE_CHANNEL_BUTTON else None 104 | 105 | try: 106 | snt_msg = await msg.copy( 107 | chat_id=message.from_user.id, 108 | caption=caption, 109 | parse_mode=ParseMode.HTML, 110 | reply_markup=reply_markup, 111 | protect_content=PROTECT_CONTENT 112 | ) 113 | await asyncio.sleep(0.5) 114 | codeflix_msgs.append(snt_msg) 115 | except FloodWait as e: 116 | await asyncio.sleep(e.x) 117 | copied_msg = await msg.copy( 118 | chat_id=message.from_user.id, 119 | caption=caption, 120 | parse_mode=ParseMode.HTML, 121 | reply_markup=reply_markup, 122 | protect_content=PROTECT_CONTENT 123 | ) 124 | codeflix_msgs.append(copied_msg) 125 | except: 126 | pass 127 | 128 | if FILE_AUTO_DELETE > 0: 129 | notification_msg = await message.reply( 130 | f"Tʜɪs Fɪʟᴇ ᴡɪʟʟ ʙᴇ Dᴇʟᴇᴛᴇᴅ ɪɴ {get_exp_time(FILE_AUTO_DELETE)}. Pʟᴇᴀsᴇ sᴀᴠᴇ ᴏʀ ғᴏʀᴡᴀʀᴅ ɪᴛ ᴛᴏ ʏᴏᴜʀ sᴀᴠᴇᴅ ᴍᴇssᴀɢᴇs ʙᴇғᴏʀᴇ ɪᴛ ɢᴇᴛs Dᴇʟᴇᴛᴇᴅ." 131 | ) 132 | 133 | await asyncio.sleep(FILE_AUTO_DELETE) 134 | 135 | for snt_msg in codeflix_msgs: 136 | if snt_msg: 137 | try: 138 | await snt_msg.delete() 139 | except Exception as e: 140 | print(f"Error deleting message {snt_msg.id}: {e}") 141 | 142 | try: 143 | reload_url = ( 144 | f"https://t.me/{client.username}?start={message.command[1]}" 145 | if message.command and len(message.command) > 1 146 | else None 147 | ) 148 | keyboard = InlineKeyboardMarkup( 149 | [[InlineKeyboardButton("ɢᴇᴛ ғɪʟᴇ ᴀɢᴀɪɴ!", url=reload_url)]] 150 | ) if reload_url else None 151 | 152 | await notification_msg.edit( 153 | "ʏᴏᴜʀ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ ɪꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ !!\n\nᴄʟɪᴄᴋ ʙᴇʟᴏᴡ ʙᴜᴛᴛᴏɴ ᴛᴏ ɢᴇᴛ ʏᴏᴜʀ ᴅᴇʟᴇᴛᴇᴅ ᴠɪᴅᴇᴏ / ꜰɪʟᴇ 👇", 154 | reply_markup=keyboard 155 | ) 156 | except Exception as e: 157 | print(f"Error updating notification with 'Get File Again' button: {e}") 158 | else: 159 | reply_markup = InlineKeyboardMarkup( 160 | [ 161 | [InlineKeyboardButton("• ᴍᴏʀᴇ ᴄʜᴀɴɴᴇʟs •", url="https://t.me/Nova_Flix/50")], 162 | 163 | [ 164 | InlineKeyboardButton("• ᴀʙᴏᴜᴛ", callback_data = "about"), 165 | InlineKeyboardButton('ʜᴇʟᴘ •', callback_data = "help") 166 | 167 | ] 168 | ] 169 | ) 170 | await message.reply_photo( 171 | photo=START_PIC, 172 | caption=START_MSG.format( 173 | first=message.from_user.first_name, 174 | last=message.from_user.last_name, 175 | username=None if not message.from_user.username else '@' + message.from_user.username, 176 | mention=message.from_user.mention, 177 | id=message.from_user.id 178 | ), 179 | reply_markup=reply_markup, 180 | message_effect_id=5104841245755180586) # 🔥 181 | 182 | return 183 | 184 | 185 | 186 | #=====================================================================================## 187 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 188 | # Ask Doubt on telegram @CodeflixSupport 189 | 190 | 191 | 192 | # Create a global dictionary to store chat data 193 | chat_data_cache = {} 194 | 195 | async def not_joined(client: Client, message: Message): 196 | temp = await message.reply("ᴡᴀɪᴛ ᴀ sᴇᴄ..") 197 | 198 | user_id = message.from_user.id 199 | buttons = [] 200 | count = 0 201 | 202 | try: 203 | all_channels = await db.show_channels() # Should return list of (chat_id, mode) tuples 204 | for total, chat_id in enumerate(all_channels, start=1): 205 | mode = await db.get_channel_mode(chat_id) # fetch mode 206 | 207 | await message.reply_chat_action(ChatAction.TYPING) 208 | 209 | if not await is_sub(client, user_id, chat_id): 210 | try: 211 | # Cache chat info 212 | if chat_id in chat_data_cache: 213 | data = chat_data_cache[chat_id] 214 | else: 215 | data = await client.get_chat(chat_id) 216 | chat_data_cache[chat_id] = data 217 | 218 | name = data.title 219 | 220 | # Generate proper invite link based on the mode 221 | if mode == "on" and not data.username: 222 | invite = await client.create_chat_invite_link( 223 | chat_id=chat_id, 224 | creates_join_request=True, 225 | expire_date=datetime.utcnow() + timedelta(seconds=FSUB_LINK_EXPIRY) if FSUB_LINK_EXPIRY else None 226 | ) 227 | link = invite.invite_link 228 | 229 | else: 230 | if data.username: 231 | link = f"https://t.me/{data.username}" 232 | else: 233 | invite = await client.create_chat_invite_link( 234 | chat_id=chat_id, 235 | expire_date=datetime.utcnow() + timedelta(seconds=FSUB_LINK_EXPIRY) if FSUB_LINK_EXPIRY else None) 236 | link = invite.invite_link 237 | 238 | buttons.append([InlineKeyboardButton(text=name, url=link)]) 239 | count += 1 240 | await temp.edit(f"{'! ' * count}") 241 | 242 | except Exception as e: 243 | print(f"Error with chat {chat_id}: {e}") 244 | return await temp.edit( 245 | f"! Eʀʀᴏʀ, Cᴏɴᴛᴀᴄᴛ ᴅᴇᴠᴇʟᴏᴘᴇʀ ᴛᴏ sᴏʟᴠᴇ ᴛʜᴇ ɪssᴜᴇs @rohit_1888\n" 246 | f"
Rᴇᴀsᴏɴ: {e}
" 247 | ) 248 | 249 | # Retry Button 250 | try: 251 | buttons.append([ 252 | InlineKeyboardButton( 253 | text='♻️ Tʀʏ Aɢᴀɪɴ', 254 | url=f"https://t.me/{client.username}?start={message.command[1]}" 255 | ) 256 | ]) 257 | except IndexError: 258 | pass 259 | 260 | await message.reply_photo( 261 | photo=FORCE_PIC, 262 | caption=FORCE_MSG.format( 263 | first=message.from_user.first_name, 264 | last=message.from_user.last_name, 265 | username=None if not message.from_user.username else '@' + message.from_user.username, 266 | mention=message.from_user.mention, 267 | id=message.from_user.id 268 | ), 269 | reply_markup=InlineKeyboardMarkup(buttons), 270 | ) 271 | 272 | except Exception as e: 273 | print(f"Final Error: {e}") 274 | await temp.edit( 275 | f"! Eʀʀᴏʀ, Cᴏɴᴛᴀᴄᴛ ᴅᴇᴠᴇʟᴏᴘᴇʀ ᴛᴏ sᴏʟᴠᴇ ᴛʜᴇ ɪssᴜᴇs @rohit_1888\n" 276 | f"
Rᴇᴀsᴏɴ: {e}
" 277 | ) 278 | 279 | #=====================================================================================## 280 | 281 | @Bot.on_message(filters.command('commands') & filters.private & admin) 282 | async def bcmd(bot: Bot, message: Message): 283 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("• ᴄʟᴏsᴇ •", callback_data = "close")]]) 284 | await message.reply(text=CMD_TXT, reply_markup = reply_markup, quote= True) 285 | -------------------------------------------------------------------------------- /plugins/useless.py: -------------------------------------------------------------------------------- 1 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 2 | # Ask Doubt on telegram @CodeflixSupport 3 | # 4 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 5 | # 6 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 7 | # and is released under the MIT License. 8 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 9 | # 10 | # All rights reserved. 11 | # 12 | 13 | import asyncio 14 | import os 15 | import random 16 | import sys 17 | import time 18 | from datetime import datetime, timedelta 19 | from pyrogram import Client, filters, __version__ 20 | from pyrogram.enums import ParseMode, ChatAction 21 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, ReplyKeyboardMarkup, ChatInviteLink, ChatPrivileges 22 | from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant 23 | from pyrogram.errors import FloodWait, UserIsBlocked, InputUserDeactivated, UserNotParticipant 24 | from bot import Bot 25 | from config import * 26 | from helper_func import * 27 | from database.database import * 28 | 29 | #=====================================================================================## 30 | 31 | @Bot.on_message(filters.command('stats') & admin) 32 | async def stats(bot: Bot, message: Message): 33 | now = datetime.now() 34 | delta = now - bot.uptime 35 | time = get_readable_time(delta.seconds) 36 | await message.reply(BOT_STATS_TEXT.format(uptime=time)) 37 | 38 | 39 | #=====================================================================================## 40 | 41 | WAIT_MSG = "Working...." 42 | 43 | #=====================================================================================## 44 | 45 | 46 | @Bot.on_message(filters.command('users') & filters.private & admin) 47 | async def get_users(client: Bot, message: Message): 48 | msg = await client.send_message(chat_id=message.chat.id, text=WAIT_MSG) 49 | users = await db.full_userbase() 50 | await msg.edit(f"{len(users)} users are using this bot") 51 | 52 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 53 | # Ask Doubt on telegram @CodeflixSupport 54 | # 55 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 56 | # 57 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 58 | # and is released under the MIT License. 59 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 60 | # 61 | # All rights reserved. 62 | # 63 | 64 | #=====================================================================================## 65 | 66 | #AUTO-DELETE 67 | 68 | @Bot.on_message(filters.private & filters.command('dlt_time') & admin) 69 | async def set_delete_time(client: Bot, message: Message): 70 | try: 71 | duration = int(message.command[1]) 72 | 73 | await db.set_del_timer(duration) 74 | 75 | await message.reply(f"Dᴇʟᴇᴛᴇ Tɪᴍᴇʀ ʜᴀs ʙᴇᴇɴ sᴇᴛ ᴛᴏ
{duration} sᴇᴄᴏɴᴅs.
") 76 | 77 | except (IndexError, ValueError): 78 | await message.reply("Pʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ ᴀ ᴠᴀʟɪᴅ ᴅᴜʀᴀᴛɪᴏɴ ɪɴ sᴇᴄᴏɴᴅs. Usage: /dlt_time {duration}") 79 | 80 | @Bot.on_message(filters.private & filters.command('check_dlt_time') & admin) 81 | async def check_delete_time(client: Bot, message: Message): 82 | duration = await db.get_del_timer() 83 | 84 | await message.reply(f"
Cᴜʀʀᴇɴᴛ ᴅᴇʟᴇᴛᴇ ᴛɪᴍᴇʀ ɪs sᴇᴛ ᴛᴏ {duration}sᴇᴄᴏɴᴅs.
") 85 | 86 | #=====================================================================================## 87 | 88 | # Don't Remove Credit @CodeFlix_Bots, @rohit_1888 89 | # Ask Doubt on telegram @CodeflixSupport 90 | # 91 | # Copyright (C) 2025 by Codeflix-Bots@Github, < https://github.com/Codeflix-Bots >. 92 | # 93 | # This file is part of < https://github.com/Codeflix-Bots/FileStore > project, 94 | # and is released under the MIT License. 95 | # Please see < https://github.com/Codeflix-Bots/FileStore/blob/master/LICENSE > 96 | # 97 | # All rights reserved. 98 | # -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | #https://codeload.github.com/KurimuzonAkuma/pyrogram/zip/refs/heads/dev 2 | pyrofork==2.3.61 3 | TgCrypto 4 | pyromod==1.5 5 | schedule 6 | APscheduler 7 | # --- For-Database ------------ # 8 | pymongo 9 | motor 10 | dnspython 11 | # --- For-Web-Response ------- # 12 | aiohttp 13 | python-dotenv 14 | # --- For-Web-Response ------- # 15 | pytz 16 | requests 17 | bs4 18 | aiofiles 19 | asyncio 20 | --------------------------------------------------------------------------------