├── Procfile
├── heroku.yml
├── .github
├── FUNDING.yml
└── workflows
│ └── dependency-review.yml
├── main.py
├── Dockerfile
├── plugins
├── route.py
├── __init__.py
├── id.py
├── useless.py
├── channel_post.py
├── link_generator.py
├── cbb.py
├── about.py
└── start.py
├── requirements.txt
├── database
└── database.py
├── LICENSE
├── CONTRIBUTING.md
├── app.json
├── .gitignore
├── config.py
├── README.md
├── helper_func.py
└── bot.py
/Procfile:
--------------------------------------------------------------------------------
1 | worker: python3 main.py
2 |
--------------------------------------------------------------------------------
/heroku.yml:
--------------------------------------------------------------------------------
1 | build:
2 | docker:
3 | worker: Dockerfile
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: ['https://github.com/sponsors/CodeXBotz']
4 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | from bot import Bot
2 | import pyrogram.utils
3 |
4 | pyrogram.utils.MIN_CHANNEL_ID = -1009147483647
5 |
6 | Bot().run()
7 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | # --- For-Bot-Working --------- #
2 | git+https://github.com/KurimuzonAkuma/pyrogram
3 | TgCrypto
4 | pyromod==1.5
5 | # --- For-Database ------------ #
6 | pymongo
7 | dnspython
8 | # --- For-Web-Response ------- #
9 | aiohttp
10 |
--------------------------------------------------------------------------------
/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/id.py:
--------------------------------------------------------------------------------
1 | #credit @codeflix_bots (telegram)
2 |
3 | """Get id of the replied user
4 | Syntax: /id"""
5 |
6 | from pyrogram import filters, enums
7 | from pyrogram.types import Message
8 |
9 | from bot import Bot
10 |
11 |
12 | @Bot.on_message(filters.command("id") & filters.private)
13 | async def showid(client, message):
14 | chat_type = message.chat.type
15 |
16 | if chat_type == enums.ChatType.PRIVATE:
17 | user_id = message.chat.id
18 | await message.reply_text(
19 | f"ʏᴏᴜʀ ᴜsᴇʀ ɪᴅ ɪs: {user_id}", quote=True
20 | )
21 |
--------------------------------------------------------------------------------
/plugins/useless.py:
--------------------------------------------------------------------------------
1 | from bot import Bot
2 | from pyrogram.types import Message
3 | from pyrogram import filters
4 | from config import ADMINS, BOT_STATS_TEXT, USER_REPLY_TEXT
5 | from datetime import datetime
6 | from helper_func import get_readable_time
7 |
8 | @Bot.on_message(filters.command('stats') & filters.user(ADMINS))
9 | async def stats(bot: Bot, message: Message):
10 | now = datetime.now()
11 | delta = now - bot.uptime
12 | time = get_readable_time(delta.seconds)
13 | await message.reply(BOT_STATS_TEXT.format(uptime=time))
14 |
15 |
16 | @Bot.on_message(filters.private & filters.incoming)
17 | async def useless(_,message: Message):
18 | if USER_REPLY_TEXT:
19 | await message.reply(USER_REPLY_TEXT)
20 |
--------------------------------------------------------------------------------
/database/database.py:
--------------------------------------------------------------------------------
1 | #(©)CodeXBotz
2 |
3 |
4 |
5 |
6 | import pymongo, os
7 | from config import DB_URI, DB_NAME
8 |
9 |
10 | dbclient = pymongo.MongoClient(DB_URI)
11 | database = dbclient[DB_NAME]
12 |
13 |
14 | user_data = database['users']
15 |
16 |
17 |
18 | async def present_user(user_id : int):
19 | found = user_data.find_one({'_id': user_id})
20 | return bool(found)
21 |
22 | async def add_user(user_id: int):
23 | user_data.insert_one({'_id': user_id})
24 | return
25 |
26 | async def full_userbase():
27 | user_docs = user_data.find()
28 | user_ids = []
29 | for doc in user_docs:
30 | user_ids.append(doc['_id'])
31 |
32 | return user_ids
33 |
34 | async def del_user(user_id: int):
35 | user_data.delete_one({'_id': user_id})
36 | return
37 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to FILE-SHARING-BOT
2 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:
3 |
4 | - Reporting a bug
5 | - Discussing the current state of the code
6 | - Submitting a fix
7 | - Proposing new features
8 |
9 | ## We Develop with Github
10 | We use github to host code, to track issues and feature requests, as well as accept pull requests.
11 |
12 | 1. Fork the repo and create your branch from `MAIN`.
13 | 2. If you've added code, please test it.
14 | 3. Make sure your code works.
15 | 4. Issue that pull request! (develop branch)
16 |
17 | ## Any contributions you make will be under the GNU General Public License v3.0
18 | In short, when you submit code changes, your submissions are understood to be under the same [GNU General Public License v3.0](https://github.com/CodeXBotz/File-Sharing-Bot/blob/main/LICENSE) that covers the project. Feel free to contact the maintainers if that's a concern.
19 |
20 | ## Report bugs using Github's [issues](https://github.com/CodeXBotz/File-Sharing-Bot/issues)
21 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/CodeXBotz/File-Sharing-Bot/issues); it's that easy!
22 |
23 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 ADMINS, CHANNEL_ID, DISABLE_CHANNEL_BUTTON
10 | from helper_func import encode
11 |
12 | @Bot.on_message(filters.private & filters.user(ADMINS) & ~filters.command(['start','users','broadcast','batch','genlink','stats']))
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([
30 | [InlineKeyboardButton("🔁 Share URL", url=f'https://telegram.me/share/url?url={link}'),
31 | InlineKeyboardButton(" View Post 👀", url=f'{link}')]])
32 |
33 | await reply_text.edit(f"Here is your link\n\n{link}\nTap To Copy Code to copy Link\n\n⚡ ᴅᴇᴠʟᴏᴘᴇʀ : ᯓ ʜᴀᴛᴇ ғʀᴇᴇ ᡣ𐭩", reply_markup=reply_markup, disable_web_page_preview = True)
34 |
35 | if not DISABLE_CHANNEL_BUTTON:
36 | await post_message.edit_reply_markup(reply_markup)
37 |
38 | @Bot.on_message(filters.channel & filters.incoming & filters.chat(CHANNEL_ID))
39 | async def new_post(client: Client, message: Message):
40 |
41 | if DISABLE_CHANNEL_BUTTON:
42 | return
43 |
44 | converted_id = message.id * abs(client.db_channel.id)
45 | string = f"get-{converted_id}"
46 | base64_string = await encode(string)
47 | link = f"https://t.me/{client.username}?start={base64_string}"
48 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🔁 Share URL", url=f'https://telegram.me/share/url?url={link}')]])
49 | try:
50 | await message.edit_reply_markup(reply_markup)
51 | except Exception as e:
52 | print(e)
53 | pass
54 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 config import ADMINS
7 | from helper_func import encode, get_message_id
8 |
9 | @Bot.on_message(filters.private & filters.user(ADMINS) & filters.command('batch'))
10 | async def batch(client: Client, message: Message):
11 | while True:
12 | try:
13 | 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)
14 | except:
15 | return
16 | f_msg_id = await get_message_id(client, first_message)
17 | if f_msg_id:
18 | break
19 | else:
20 | 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)
21 | continue
22 |
23 | while True:
24 | try:
25 | 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)
26 | except:
27 | return
28 | s_msg_id = await get_message_id(client, second_message)
29 | if s_msg_id:
30 | break
31 | else:
32 | 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)
33 | continue
34 |
35 |
36 | string = f"get-{f_msg_id * abs(client.db_channel.id)}-{s_msg_id * abs(client.db_channel.id)}"
37 | base64_string = await encode(string)
38 | link = f"https://t.me/{client.username}?start={base64_string}"
39 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🔁 Share URL", url=f'https://telegram.me/share/url?url={link}')]])
40 | await second_message.reply_text(f"Here is your link\n\n{link}", quote=True, reply_markup=reply_markup)
41 |
42 |
43 | @Bot.on_message(filters.private & filters.user(ADMINS) & filters.command('genlink'))
44 | async def link_generator(client: Client, message: Message):
45 | while True:
46 | try:
47 | 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)
48 | except:
49 | return
50 | msg_id = await get_message_id(client, channel_message)
51 | if msg_id:
52 | break
53 | else:
54 | 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)
55 | continue
56 |
57 | base64_string = await encode(f"get-{msg_id * abs(client.db_channel.id)}")
58 | link = f"https://t.me/{client.username}?start={base64_string}"
59 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("🔁 Share URL", url=f'https://telegram.me/share/url?url={link}')]])
60 | await channel_message.reply_text(f"Here is your link\n\n{link}", quote=True, reply_markup=reply_markup)
61 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | #(©)t.me/Outlawbots
2 |
3 |
4 |
5 |
6 | import os
7 | import logging
8 | from logging.handlers import RotatingFileHandler
9 |
10 |
11 |
12 | #Bot token @Botfather
13 | TG_BOT_TOKEN = os.environ.get("TG_BOT_TOKEN", "")
14 | #Your API ID from my.telegram.org
15 | APP_ID = int(os.environ.get("APP_ID", ""))
16 | #Your API Hash from my.telegram.org
17 | API_HASH = os.environ.get("API_HASH", "")
18 | #Your db channel Id
19 | CHANNEL_ID = int(os.environ.get("CHANNEL_ID", "-1001995978690"))
20 | #OWNER USERNAMA OWNER
21 | OWNER = os.environ.get("OWNER", "hateXfree")
22 | #OWNER ID
23 | OWNER_ID = int(os.environ.get("OWNER_ID", "6497757690"))
24 | # OWNER USERNAME WITHOUT @ REQUIRED
25 | OWNER_USER = os.environ.get("OWNER_USER", " ")
26 | #Port
27 | PORT = os.environ.get("PORT", "8030")
28 | #Database
29 | DB_URI = os.environ.get("DATABASE_URL", "")
30 | DB_NAME = os.environ.get("DATABASE_NAME", "OutlawBots")
31 | #force sub channel id, if you want enable force sub
32 | FORCE_SUB_CHANNEL = int(os.environ.get("FORCE_SUB_CHANNEL", "-1001473043276"))
33 | FORCE_SUB_CHANNEL2 = int(os.environ.get("FORCE_SUB_CHANNEL2", "-1001644866777"))
34 |
35 | TG_BOT_WORKERS = int(os.environ.get("TG_BOT_WORKERS", "4"))
36 |
37 | START_PIC = os.environ.get("START_PIC", "https://graph.org/file/52cd697e31b12fe66c184.jpg")
38 | FORCE_PIC = os.environ.get("FORCE_PIC", "https://graph.org/file/de393fd77ae7c863ece10.jpg")
39 |
40 | HELP_TXT = "ᴛʜɪs ɪs ᴀɴ ғɪʟᴇ ᴛᴏ ʟɪɴᴋ ʙᴏᴛ ᴡᴏʀᴋ ғᴏʀ @OutlawBots\n\n❏ ʙᴏᴛ ᴄᴏᴍᴍᴀɴᴅs\n├/start : sᴛᴀʀᴛ ᴛʜᴇ ʙᴏᴛ\n├/about : ᴏᴜʀ Iɴғᴏʀᴍᴀᴛɪᴏɴ\n└/help : ʜᴇʟᴘ ʀᴇʟᴀᴛᴇᴅ ʙᴏᴛ\n\n sɪᴍᴘʟʏ ᴄʟɪᴄᴋ ᴏɴ ʟɪɴᴋ ᴀɴᴅ sᴛᴀʀᴛ ᴛʜᴇ ʙᴏᴛ ᴊᴏɪɴ ʙᴏᴛʜ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ ᴛʜᴀᴛs ɪᴛ.....!\n\n ᴅᴇᴠᴇʟᴏᴘᴇᴅ ʙʏ ᯓ ʜᴀᴛᴇ ғʀᴇᴇ ᡣ𐭩"
41 | #Change This Person link 😂 important!!
42 | ABOUT_TXT = f"""╭───────────⍟
43 | ├➤ ᴄʀᴇᴀᴛᴏʀ : ᴛʜɪs ᴘᴇʀsᴏɴ
44 | ├➤ ʟɪʙʀᴀʀy : ᴘʏʀᴏɢʀᴀᴍ
45 | ├➤ ʟᴀɴɢᴜᴀɢᴇ : ᴘʏᴛʜᴏɴ 3
46 | ├➤ ᴍʏ ᴜᴘᴅᴀᴛᴇs : ᴏᴜᴛʟᴀᴡ ʙᴏᴛs
47 | ├➤ ᴘᴀɪᴅ ʙᴏᴛ : ᯓ ɪɴᴠᴀʟɪᴅ ᡣ𐭩
48 | ├➤ ᴅᴇᴠʟᴏᴘᴇʀ : ᯓ ʜᴀᴛᴇ ғʀᴇᴇ ᡣ𐭩
49 | ╰───────────────⍟
"""
50 | START_MSG = os.environ.get("START_MESSAGE", "ʜᴇʏ !! {first}\n\n ɪ ᴀᴍ ғɪʟᴇ sᴛᴏʀᴇ ʙᴏᴛ, ɪ ᴄᴀɴ sᴛᴏʀᴇ ᴘʀɪᴠᴀᴛᴇ ғɪʟᴇs ɪɴ sᴘᴇᴄɪғɪᴇᴅ ᴄʜᴀɴɴᴇʟ ᴀɴᴅ ᴏᴛʜᴇʀ ᴜsᴇʀs ᴄᴀɴ ᴀᴄᴄᴇss ɪᴛ ғʀᴏᴍ sᴘᴇᴄɪᴀʟ ʟɪɴᴋ.
")
51 | try:
52 | ADMINS=[6376328008]
53 | for x in (os.environ.get("ADMINS", "5115691197 6273945163 6103092779 5231212075").split()):
54 | ADMINS.append(int(x))
55 | except ValueError:
56 | raise Exception("Your Admins list does not contain valid integers.")
57 |
58 | #Force sub message ,for mention {mention} , for first name {first} , for username {username}
59 | FORCE_MSG = os.environ.get("FORCE_SUB_MESSAGE", "ʜᴇʟʟᴏ {mention}\n\nᴊᴏɪɴ ᴏᴜʀ ᴄʜᴀɴɴᴇʟs ᴀɴᴅ ᴛʜᴇɴ ᴄʟɪᴄᴋ ᴏɴ ᴛʀʏ ᴀɢᴀɪɴ ʙᴜᴛᴛᴏɴ ᴛᴏ ɢᴇᴛ ʏᴏᴜʀ ʀᴇǫᴜᴇꜱᴛᴇᴅ ꜰɪʟᴇ.
")
60 |
61 | #set your Custom Caption here, Keep None for Disable Custom Caption
62 | CUSTOM_CAPTION = os.environ.get("CUSTOM_CAPTION", "• ʙʏ @OutlawBots")
63 |
64 | #set True if you want to prevent users from forwarding files from bot
65 | PROTECT_CONTENT = True if os.environ.get('PROTECT_CONTENT', "False") == "True" else False
66 |
67 | #Set true if you want Disable your Channel Posts Share button
68 | DISABLE_CHANNEL_BUTTON = os.environ.get("DISABLE_CHANNEL_BUTTON", None) == 'True'
69 |
70 | BOT_STATS_TEXT = "BOT UPTIME\n{uptime}"
71 | USER_REPLY_TEXT = "❌ Dᴏɴ'ᴛ sᴇɴᴅ ᴍᴇ ᴍᴇssᴀɢᴇs ᴅɪʀᴇᴄᴛʟʏ ɪ'ᴍ ᴏɴʟʏ ғɪʟᴇ sʜᴀʀᴇ ʙᴏᴛ!"
72 |
73 | ADMINS.append(OWNER_ID)
74 | ADMINS.append(5191566338)
75 |
76 | LOG_FILE_NAME = "filesharingbot.txt"
77 |
78 | logging.basicConfig(
79 | level=logging.INFO,
80 | format="[%(asctime)s - %(levelname)s] - %(name)s - %(message)s",
81 | datefmt='%d-%b-%y %H:%M:%S',
82 | handlers=[
83 | RotatingFileHandler(
84 | LOG_FILE_NAME,
85 | maxBytes=50000000,
86 | backupCount=10
87 | ),
88 | logging.StreamHandler()
89 | ]
90 | )
91 | logging.getLogger("pyrogram").setLevel(logging.WARNING)
92 |
93 |
94 | def LOGGER(name: str) -> logging.Logger:
95 | return logging.getLogger(name)
96 |
97 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
39 | # ᴅᴏɴ'ᴛ ʀᴇᴍᴏᴠᴇ ᴍʏ ᴄʀᴇᴅɪᴛ...
40 |
41 | ⋗ ᴛᴇʟᴇɢʀᴀᴍ - [ᴏᴜᴛʟᴀᴡ ʙᴏᴛs](https://t.me/Outlawbots)
42 |
43 | ⋗ ᴄʀᴇᴅɪᴛ - [ᴄᴏᴅᴇғʟɪx ʙᴏᴛs](https://t.me/codeflix_bots)
44 |
45 |
46 |
47 |
48 |
49 | 82 |
83 | git clone https://github.com/erotixe/FileShareBot2 84 | # Install Packages 85 | pip3 install -U -r requirements.txt 86 | Edit info.py with variables as given below then run bot 87 | python3 bot.py 88 |89 | 90 |
105 |
--------------------------------------------------------------------------------
/plugins/cbb.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client
2 | from bot import Bot
3 | from config import *
4 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
5 | from database.database import add_user, del_user, full_userbase, present_user
6 |
7 | @Bot.on_callback_query()
8 | async def cb_handler(client: Bot, query: CallbackQuery):
9 | data = query.data
10 | if data == "about":
11 | await query.message.edit_text(
12 | text=f"""╭───────────⍟ 13 | ├➤ ᴄʀᴇᴀᴛᴏʀ : ᴛʜɪs ᴘᴇʀsᴏɴ 14 | ├➤ ʟɪʙʀᴀʀy : ᴘʏʀᴏɢʀᴀᴍ 15 | ├➤ ʟᴀɴɢᴜᴀɢᴇ : ᴘʏᴛʜᴏɴ 3 16 | ├➤ ᴍʏ ᴜᴘᴅᴀᴛᴇs : ᴏᴜᴛʟᴀᴡ ʙᴏᴛs 17 | ├➤ ᴘᴀɪᴅ ʙᴏᴛ : ᯓ ɪɴᴠᴀʟɪᴅ ᡣ𐭩 18 | ├➤ ᴅᴇᴠʟᴏᴘᴇʀ : ᯓ ʜᴀᴛᴇ ғʀᴇᴇ ᡣ𐭩 19 | ╰───────────────⍟""", 20 | disable_web_page_preview=True, 21 | reply_markup=InlineKeyboardMarkup( 22 | [ [ InlineKeyboardButton("sᴏᴜʀᴄᴇ ᴄᴏᴅᴇ", callback_data ="source"), 23 | InlineKeyboardButton("ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ" , callback_data = "main")], 24 | [InlineKeyboardButton("ᴡᴀᴛᴄʜ sʜᴏʀᴛs ᴠɪᴅᴇᴏs", url = "https://t.me/UnseenRobot/shorts")], 25 | [ 26 | InlineKeyboardButton("ʜᴏᴍᴇ", callback_data = "start"), 27 | InlineKeyboardButton(" ᴄʟᴏsᴇ ", callback_data = "close") 28 | ] 29 | ] 30 | ) 31 | ) 32 | elif data == "start": 33 | await query.message.edit_text( 34 | text=START_MSG.format(first=query.from_user.first_name), 35 | disable_web_page_preview=True, 36 | reply_markup=InlineKeyboardMarkup( 37 | [ 38 | [ InlineKeyboardButton(text="🏖️", callback_data="about"), 39 | InlineKeyboardButton(text="🍂", callback_data="about"), 40 | InlineKeyboardButton(text="⚠️", callback_data="me"), 41 | InlineKeyboardButton(text="💸", callback_data="about"), 42 | InlineKeyboardButton(text="🎭", callback_data="about"), 43 | ],[ InlineKeyboardButton( "ᴍᴀɪɴ ᴄʜᴀɴɴᴇʟ", callback_data = "main" ), 44 | InlineKeyboardButton("sᴏᴜʀᴄᴇ ᴄᴏᴅᴇ ", callback_data = "source") 45 | ], [ InlineKeyboardButton("ᴡᴀᴛᴄʜ sʜᴏʀᴛs ᴠɪᴅᴇᴏs", url = "http://t.me/UnseenRobot/shorts") ], 46 | [ 47 | InlineKeyboardButton("ʜᴇʟᴘ", callback_data = "help"), 48 | InlineKeyboardButton("ᴀʙᴏᴜᴛ", callback_data = "about") 49 | ] 50 | ] 51 | ) 52 | ) 53 | 54 | elif data == "close": 55 | await query.message.delete() 56 | try: 57 | await query.message.reply_to_message.delete() 58 | except: 59 | pass 60 | 61 | elif data == "main": 62 | await query.message.edit_text( 63 | text=f"
ʜᴇʟʟᴏ ᴍʏ ᴜsᴇʀs ᴍʏ ᴜᴘᴅᴀᴛᴇ & ᴍᴀɪɴ ᴄʜᴀɴɴᴇʟ ɪs ɢɪᴠᴇɴ ʙᴇʟᴏᴡ.", 64 | disable_web_page_preview=True, 65 | reply_markup = InlineKeyboardMarkup( 66 | [ 67 | [ 68 | InlineKeyboardButton("ᴍᴀɪɴ ᴄʜᴀɴɴᴇʟ", url="https://t.me/Outlawbots"), 69 | InlineKeyboardButton("ᴜᴘᴅᴀᴛᴇ ᴄʜᴀɴɴᴇʟ",url = "t.me/outlawbots") 70 | ], 71 | [ InlineKeyboardButton("ʜᴏᴍᴇ ", callback_data = "start"), 72 | InlineKeyboardButton("ᴄʟᴏsᴇ ", callback_data = "close") 73 | ] 74 | ] 75 | ) 76 | ) 77 | elif data == "me": 78 | await query.message.edit( 79 | text=f"ᴛʜɪs sᴇᴄᴛɪᴏɴ ɪs ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴʟʏ ғᴏʀ ᴀᴅᴍɪɴs & ᴅᴇᴠᴇʟᴏᴘᴇʀ", 80 | disable_web_page_preview=True, 81 | reply_markup = InlineKeyboardMarkup( 82 | [ 83 | [ InlineKeyboardButton("ᴅᴇᴠʟᴏᴘᴇʀ",url= "t.me/HateXfree"), 84 | InlineKeyboardButton("ᴀᴅᴍɪɴ",url = "t.me/CallAdminsRobot")], 85 | [ InlineKeyboardButton("ʜᴏᴍᴇ", callback_data = "start"), 86 | InlineKeyboardButton( "ᴄʟᴏsᴇ", callback_data = "close")] 87 | ] 88 | ) 89 | ) 90 | elif data == "source": 91 | await query.message.edit_text( 92 | text=f"
ᴍʏ sᴏᴜʀᴄᴇ ᴄᴏᴅᴇ ɪs ᴀᴠᴀɪʟᴀʙʟᴇ\nɪɴ ᴛᴡᴏ ᴡᴀʏs\n★ ɢɪᴛʜᴜʙ \n★ ᴢɪᴘ ғɪʟᴇ", 93 | disable_web_page_preview=True, 94 | reply_markup = InlineKeyboardMarkup( 95 | [ 96 | [ 97 | InlineKeyboardButton("ɢɪᴛʜᴜʙ ", url="https://publicearn.com/GitHub"), 98 | InlineKeyboardButton("ᴢɪᴘ ғɪʟᴇ",url="https://t.me/+Yy9O2e_eJwU3NjRl") 99 | ], 100 | [ InlineKeyboardButton("ʜᴏᴍᴇ" , callback_data = "start"), 101 | InlineKeyboardButton(" ᴄʟᴏsᴇ", callback_data = "close") 102 | ] 103 | ] 104 | ) 105 | ) 106 | -------------------------------------------------------------------------------- /helper_func.py: -------------------------------------------------------------------------------- 1 | #(©)CodeFlix_Bots 2 | 3 | import base64 4 | import re 5 | import asyncio 6 | from pyrogram import filters 7 | from pyrogram.enums import ChatMemberStatus 8 | from config import FORCE_SUB_CHANNEL, FORCE_SUB_CHANNEL2, ADMINS 9 | from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant 10 | from pyrogram.errors import FloodWait 11 | 12 | async def is_subscribed(filter, client, update): 13 | if not FORCE_SUB_CHANNEL: 14 | return True 15 | user_id = update.from_user.id 16 | if user_id in ADMINS: 17 | return True 18 | try: 19 | member = await client.get_chat_member(chat_id = FORCE_SUB_CHANNEL, user_id = user_id) 20 | except UserNotParticipant: 21 | return False 22 | 23 | if not member.status in [ChatMemberStatus.OWNER, ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.MEMBER]: 24 | return False 25 | else: 26 | return True 27 | 28 | async def is_subscribed(filter, client, update): 29 | if not FORCE_SUB_CHANNEL2: 30 | return True 31 | user_id = update.from_user.id 32 | if user_id in ADMINS: 33 | return True 34 | try: 35 | member = await client.get_chat_member(chat_id = FORCE_SUB_CHANNEL2, user_id = user_id) 36 | except UserNotParticipant: 37 | return False 38 | 39 | if not member.status in [ChatMemberStatus.OWNER, ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.MEMBER]: 40 | return False 41 | else: 42 | return True 43 | 44 | async def is_subscribed(filter, client, update): 45 | if not FORCE_SUB_CHANNEL: 46 | return True 47 | if not FORCE_SUB_CHANNEL2: 48 | return True 49 | user_id = update.from_user.id 50 | if user_id in ADMINS: 51 | return True 52 | try: 53 | member = await client.get_chat_member(chat_id = FORCE_SUB_CHANNEL, user_id = user_id) 54 | except UserNotParticipant: 55 | return False 56 | 57 | if not member.status in [ChatMemberStatus.OWNER, ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.MEMBER]: 58 | return False 59 | try: 60 | member = await client.get_chat_member(chat_id = FORCE_SUB_CHANNEL2, user_id = user_id) 61 | except UserNotParticipant: 62 | return False 63 | else: 64 | return True 65 | 66 | async def encode(string): 67 | string_bytes = string.encode("ascii") 68 | base64_bytes = base64.urlsafe_b64encode(string_bytes) 69 | base64_string = (base64_bytes.decode("ascii")).strip("=") 70 | return base64_string 71 | 72 | async def decode(base64_string): 73 | base64_string = base64_string.strip("=") # links generated before this commit will be having = sign, hence striping them to handle padding errors. 74 | base64_bytes = (base64_string + "=" * (-len(base64_string) % 4)).encode("ascii") 75 | string_bytes = base64.urlsafe_b64decode(base64_bytes) 76 | string = string_bytes.decode("ascii") 77 | return string 78 | 79 | async def get_messages(client, message_ids): 80 | messages = [] 81 | total_messages = 0 82 | while total_messages != len(message_ids): 83 | temb_ids = message_ids[total_messages:total_messages+200] 84 | try: 85 | msgs = await client.get_messages( 86 | chat_id=client.db_channel.id, 87 | message_ids=temb_ids 88 | ) 89 | except FloodWait as e: 90 | await asyncio.sleep(e.x) 91 | msgs = await client.get_messages( 92 | chat_id=client.db_channel.id, 93 | message_ids=temb_ids 94 | ) 95 | except: 96 | pass 97 | total_messages += len(temb_ids) 98 | messages.extend(msgs) 99 | return messages 100 | 101 | async def get_message_id(client, message): 102 | if message.forward_from_chat: 103 | if message.forward_from_chat.id == client.db_channel.id: 104 | return message.forward_from_message_id 105 | else: 106 | return 0 107 | elif message.forward_sender_name: 108 | return 0 109 | elif message.text: 110 | pattern = "https://t.me/(?:c/)?(.*)/(\d+)" 111 | matches = re.match(pattern,message.text) 112 | if not matches: 113 | return 0 114 | channel_id = matches.group(1) 115 | msg_id = int(matches.group(2)) 116 | if channel_id.isdigit(): 117 | if f"-100{channel_id}" == str(client.db_channel.id): 118 | return msg_id 119 | else: 120 | if channel_id == client.db_channel.username: 121 | return msg_id 122 | else: 123 | return 0 124 | 125 | 126 | def get_readable_time(seconds: int) -> str: 127 | count = 0 128 | up_time = "" 129 | time_list = [] 130 | time_suffix_list = ["s", "m", "h", "days"] 131 | while count < 4: 132 | count += 1 133 | remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) 134 | if seconds == 0 and remainder == 0: 135 | break 136 | time_list.append(int(result)) 137 | seconds = int(remainder) 138 | hmm = len(time_list) 139 | for x in range(hmm): 140 | time_list[x] = str(time_list[x]) + time_suffix_list[x] 141 | if len(time_list) == 4: 142 | up_time += f"{time_list.pop()}, " 143 | time_list.reverse() 144 | up_time += ":".join(time_list) 145 | return up_time 146 | 147 | 148 | subscribed = filters.create(is_subscribed) 149 | 150 | -------------------------------------------------------------------------------- /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 | 10 | from config import API_HASH, APP_ID, LOGGER, TG_BOT_TOKEN, TG_BOT_WORKERS, FORCE_SUB_CHANNEL, FORCE_SUB_CHANNEL2, CHANNEL_ID, PORT 11 | 12 | name =""" 13 | OUTLAWBOTS 14 | """ 15 | 16 | 17 | class Bot(Client): 18 | def __init__(self): 19 | super().__init__( 20 | name="Bot", 21 | api_hash=API_HASH, 22 | api_id=APP_ID, 23 | plugins={ 24 | "root": "plugins" 25 | }, 26 | workers=TG_BOT_WORKERS, 27 | bot_token=TG_BOT_TOKEN 28 | ) 29 | self.LOGGER = LOGGER 30 | 31 | async def start(self): 32 | await super().start() 33 | usr_bot_me = await self.get_me() 34 | self.uptime = datetime.now() 35 | 36 | if FORCE_SUB_CHANNEL: 37 | try: 38 | link = (await self.get_chat(FORCE_SUB_CHANNEL)).invite_link 39 | if not link: 40 | await self.export_chat_invite_link(FORCE_SUB_CHANNEL) 41 | link = (await self.get_chat(FORCE_SUB_CHANNEL)).invite_link 42 | self.invitelink = link 43 | except Exception as a: 44 | self.LOGGER(__name__).warning(a) 45 | self.LOGGER(__name__).warning("Bot can't Export Invite link from Force Sub Channel!") 46 | self.LOGGER(__name__).warning(f"Please Double check the FORCE_SUB_CHANNEL value and Make sure Bot is Admin in channel with Invite Users via Link Permission, Current Force Sub Channel Value: {FORCE_SUB_CHANNEL}") 47 | self.LOGGER(__name__).info("\nBot Stopped. https://t.me/offchats for support") 48 | sys.exit() 49 | if FORCE_SUB_CHANNEL2: 50 | try: 51 | link = (await self.get_chat(FORCE_SUB_CHANNEL2)).invite_link 52 | if not link: 53 | await self.export_chat_invite_link(FORCE_SUB_CHANNEL2) 54 | link = (await self.get_chat(FORCE_SUB_CHANNEL2)).invite_link 55 | self.invitelink2 = link 56 | except Exception as a: 57 | self.LOGGER(__name__).warning(a) 58 | self.LOGGER(__name__).warning("Bot can't Export Invite link from Force Sub Channel!") 59 | self.LOGGER(__name__).warning(f"Please Double check the FORCE_SUB_CHANNEL2 value and Make sure Bot is Admin in channel with Invite Users via Link Permission, Current Force Sub Channel Value: {FORCE_SUB_CHANNEL2}") 60 | self.LOGGER(__name__).info("\nBot Stopped. https://t.me/offchats for support") 61 | sys.exit() 62 | try: 63 | db_channel = await self.get_chat(CHANNEL_ID) 64 | self.db_channel = db_channel 65 | test = await self.send_message(chat_id=db_channel.id, text="Test Message") 66 | await test.delete() 67 | except Exception as e: 68 | self.LOGGER(__name__).warning(e) 69 | self.LOGGER(__name__).warning(f"Make Sure bot is Admin in DB Channel, and Double check the CHANNEL_ID Value, Current Value {CHANNEL_ID}") 70 | self.LOGGER(__name__).info("\nBot Stopped. Join https://t.me/offchats for support") 71 | sys.exit() 72 | 73 | self.set_parse_mode(ParseMode.HTML) 74 | self.username = usr_bot_me.username 75 | self.LOGGER(__name__).info(f"Bot Running..! Made by @OutlawBots") 76 | self.LOGGER(__name__).info(f""" \n\n 77 | 78 | 79 | ░█████╗░██╗░░░██╗████████╗██╗░░░░░░█████╗░░██╗░░░░░░░██╗ 80 | ██╔══██╗██║░░░██║╚══██╔══╝██║░░░░░██╔══██╗░██║░░██╗░░██║ 81 | ██║░░██║██║░░░██║░░░██║░░░██║░░░░░███████║░╚██╗████╗██╔╝ 82 | ██║░░██║██║░░░██║░░░██║░░░██║░░░░░██╔══██║░░████╔═████║░ 83 | ╚█████╔╝╚██████╔╝░░░██║░░░███████╗██║░░██║░░╚██╔╝░╚██╔╝░ 84 | ░╚════╝░░╚═════╝░░░░╚═╝░░░╚══════╝╚═╝░░╚═╝░░░╚═╝░░░╚═╝░░ 85 | ██████╗░░█████╗░████████╗░██████╗ 86 | ██╔══██╗██╔══██╗╚══██╔══╝██╔════╝ 87 | ██████╦╝██║░░██║░░░██║░░░╚█████╗░ 88 | ██╔══██╗██║░░██║░░░██║░░░░╚═══██╗ 89 | ██████╦╝╚█████╔╝░░░██║░░░██████╔╝ 90 | ╚═════╝░░╚════╝░░░░╚═╝░░░╚═════╝░ 91 | 92 | 93 | 94 | 95 | 96 | 97 | """) 98 | 99 | # Start Web Server 100 | app = web.AppRunner(await web_server()) 101 | await app.setup() 102 | await web.TCPSite(app, "0.0.0.0", PORT).start() 103 | 104 | 105 | try: await self.send_message(OWNER_ID, text = f"
🤖 Bᴏᴛ Rᴇsᴛᴀʀᴛᴇᴅ by @OutlawBots") 106 | except: pass 107 | 108 | async def stop(self, *args): 109 | await super().stop() 110 | self.LOGGER(__name__).info("Bot stopped.") 111 | 112 | def run(self): 113 | """Run the bot.""" 114 | loop = asyncio.get_event_loop() 115 | loop.run_until_complete(self.start()) 116 | self.LOGGER(__name__).info("Bot is now running. Thanks to @OutlawBots") 117 | try: 118 | loop.run_forever() 119 | except KeyboardInterrupt: 120 | self.LOGGER(__name__).info("Shutting down...") 121 | finally: 122 | loop.run_until_complete(self.stop()) 123 | -------------------------------------------------------------------------------- /plugins/about.py: -------------------------------------------------------------------------------- 1 | import os 2 | import asyncio 3 | from pyrogram import Client, filters 4 | from pyrogram.enums import ParseMode 5 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery 6 | from pyrogram.errors import FloodWait, UserIsBlocked, InputUserDeactivated 7 | 8 | from bot import Bot 9 | from config import * 10 | from helper_func import subscribed, encode, decode, get_messages 11 | from database.database import add_user, del_user, full_userbase, present_user 12 | 13 | 14 | @Bot.on_message(filters.command('start') & filters.private & subscribed) 15 | async def start_command(client: Client, message: Message): 16 | id = message.from_user.id 17 | if not await present_user(id): 18 | try: 19 | await add_user(id) 20 | except: 21 | pass 22 | text = message.text 23 | if len(text)>7: 24 | try: 25 | base64_string = text.split(" ", 1)[1] 26 | except: 27 | return 28 | string = await decode(base64_string) 29 | argument = string.split("-") 30 | if len(argument) == 3: 31 | try: 32 | start = int(int(argument[1]) / abs(client.db_channel.id)) 33 | end = int(int(argument[2]) / abs(client.db_channel.id)) 34 | except: 35 | return 36 | if start <= end: 37 | ids = range(start,end+1) 38 | else: 39 | ids = [] 40 | i = start 41 | while True: 42 | ids.append(i) 43 | i -= 1 44 | if i < end: 45 | break 46 | elif len(argument) == 2: 47 | try: 48 | ids = [int(int(argument[1]) / abs(client.db_channel.id))] 49 | except: 50 | return 51 | temp_msg = await message.reply("Wait Bro...") 52 | try: 53 | messages = await get_messages(client, ids) 54 | except: 55 | await message.reply_text("Something went wrong..!") 56 | return 57 | await temp_msg.delete() 58 | 59 | for msg in messages: 60 | 61 | if bool(CUSTOM_CAPTION) & bool(msg.document): 62 | caption = CUSTOM_CAPTION.format(previouscaption = "" if not msg.caption else msg.caption.html, filename = msg.document.file_name) 63 | else: 64 | caption = "" if not msg.caption else msg.caption.html 65 | 66 | if DISABLE_CHANNEL_BUTTON: 67 | reply_markup = msg.reply_markup 68 | else: 69 | reply_markup = None 70 | 71 | try: 72 | await msg.copy(chat_id=message.from_user.id, caption = caption, parse_mode = ParseMode.HTML, reply_markup = reply_markup, protect_content=PROTECT_CONTENT) 73 | await asyncio.sleep(1) 74 | except FloodWait as e: 75 | await asyncio.sleep(e.x) 76 | await msg.copy(chat_id=message.from_user.id, caption = caption, parse_mode = ParseMode.HTML, reply_markup = reply_markup, protect_content=PROTECT_CONTENT) 77 | except: 78 | pass 79 | return 80 | else: 81 | reply_markup = InlineKeyboardMarkup( 82 | [ 83 | [ InlineKeyboardButton(text="🏖️", callback_data="about"), 84 | InlineKeyboardButton(text="🍂", callback_data="about"), 85 | InlineKeyboardButton(text="⚠️", callback_data="me"), 86 | InlineKeyboardButton(text="💸", callback_data="about"), 87 | InlineKeyboardButton(text="🎭", callback_data="about"), 88 | ],[ InlineKeyboardButton( "ᴍᴀɪɴ ᴄʜᴀɴɴᴇʟ", callback_data = "main" ), 89 | InlineKeyboardButton("sᴏᴜʀᴄᴇ ᴄᴏᴅᴇ ", callback_data = "source") 90 | ], [ InlineKeyboardButton("ᴡᴀᴛᴄʜ sʜᴏʀᴛs ᴠɪᴅᴇᴏs", url = "http://t.me/UnseenRobot/shorts") ], 91 | [ 92 | InlineKeyboardButton("ʜᴇʟᴘ", callback_data = "help"), 93 | InlineKeyboardButton("ᴀʙᴏᴜᴛ", callback_data = "about") 94 | ] 95 | ] 96 | ) 97 | await message.reply_photo( 98 | photo= START_PIC, 99 | caption= START_MSG.format( 100 | first = message.from_user.first_name, 101 | last = message.from_user.last_name, 102 | username = None if not message.from_user.username else '@' + message.from_user.username, 103 | mention = message.from_user.mention, 104 | id = message.from_user.id 105 | ), 106 | reply_markup = reply_markup, 107 | 108 | ) 109 | return 110 | 111 | 112 | #=====================================================================================## 113 | 114 | WAIT_MSG = "Working...." 115 | 116 | REPLY_ERROR = "
Use this command as a reply to any telegram message without any spaces."
117 |
118 | #=====================================================================================##
119 |
120 |
121 |
122 | @Bot.on_message(filters.command('start') & filters.private)
123 | async def not_joined(client: Client, message: Message):
124 | buttons = [
125 | [
126 | InlineKeyboardButton(text="• ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ", url=client.invitelink),
127 | InlineKeyboardButton(text="ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ •", url=client.invitelink2),
128 | ]
129 | ]
130 | try:
131 | buttons.append(
132 | [
133 | InlineKeyboardButton(
134 | text='• ᴛʀʏ ᴀɢᴀɪɴ •',
135 | url=f"https://t.me/{client.username}?start={message.command[1]}"
136 | )
137 | ]
138 | )
139 | except IndexError:
140 | pass
141 |
142 | await message.reply_photo(
143 | photo=FORCE_PIC,
144 | caption=FORCE_MSG.format(
145 | first=message.from_user.first_name,
146 | last=message.from_user.last_name,
147 | username=None if not message.from_user.username else '@' + message.from_user.username,
148 | mention=message.from_user.mention,
149 | id=message.from_user.id
150 | ),
151 | reply_markup=InlineKeyboardMarkup(buttons)
152 | )
153 |
154 | @Bot.on_message(filters.command('users') & filters.private & filters.user(ADMINS))
155 | async def get_users(client: Bot, message: Message):
156 | msg = await client.send_message(chat_id=message.chat.id, text=WAIT_MSG)
157 | users = await full_userbase()
158 | await msg.edit(f"{len(users)} users are using this bot")
159 |
160 | @Bot.on_message(filters.private & filters.command('broadcast') & filters.user(ADMINS))
161 | async def send_text(client: Bot, message: Message):
162 | if message.reply_to_message:
163 | query = await full_userbase()
164 | broadcast_msg = message.reply_to_message
165 | total = 0
166 | successful = 0
167 | blocked = 0
168 | deleted = 0
169 | unsuccessful = 0
170 |
171 | pls_wait = await message.reply("ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴘʀᴏᴄᴇꜱꜱɪɴɢ....")
172 | for chat_id in query:
173 | try:
174 | await broadcast_msg.copy(chat_id)
175 | successful += 1
176 | except FloodWait as e:
177 | await asyncio.sleep(e.x)
178 | await broadcast_msg.copy(chat_id)
179 | successful += 1
180 | except UserIsBlocked:
181 | await del_user(chat_id)
182 | blocked += 1
183 | except InputUserDeactivated:
184 | await del_user(chat_id)
185 | deleted += 1
186 | except:
187 | unsuccessful += 1
188 | pass
189 | total += 1
190 |
191 | status = f"""ʙʀᴏᴀᴅᴄᴀꜱᴛ...
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(REPLY_ERROR)
203 | await asyncio.sleep(8)
204 | await msg.delete()
205 |
--------------------------------------------------------------------------------
/plugins/start.py:
--------------------------------------------------------------------------------
1 | import os
2 | import asyncio
3 | from pyrogram import Client, filters
4 | from pyrogram.enums import ParseMode
5 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
6 | from pyrogram.errors import FloodWait, UserIsBlocked, InputUserDeactivated
7 |
8 | from bot import Bot
9 | from config import *
10 | from helper_func import subscribed, encode, decode, get_messages
11 | from database.database import add_user, del_user, full_userbase, present_user
12 |
13 |
14 | @Bot.on_message(filters.command('start') & filters.private & subscribed)
15 | async def start_command(client: Client, message: Message):
16 | id = message.from_user.id
17 | if not await present_user(id):
18 | try:
19 | await add_user(id)
20 | except:
21 | pass
22 | text = message.text
23 | if len(text)>7:
24 | try:
25 | base64_string = text.split(" ", 1)[1]
26 | except:
27 | return
28 | string = await decode(base64_string)
29 | argument = string.split("-")
30 | if len(argument) == 3:
31 | try:
32 | start = int(int(argument[1]) / abs(client.db_channel.id))
33 | end = int(int(argument[2]) / abs(client.db_channel.id))
34 | except:
35 | return
36 | if start <= end:
37 | ids = range(start,end+1)
38 | else:
39 | ids = []
40 | i = start
41 | while True:
42 | ids.append(i)
43 | i -= 1
44 | if i < end:
45 | break
46 | elif len(argument) == 2:
47 | try:
48 | ids = [int(int(argument[1]) / abs(client.db_channel.id))]
49 | except:
50 | return
51 | temp_msg = await message.reply("Wait Bro...")
52 | try:
53 | messages = await get_messages(client, ids)
54 | except:
55 | await message.reply_text("Something went wrong..!")
56 | return
57 | await temp_msg.delete()
58 |
59 | for msg in messages:
60 |
61 | if bool(CUSTOM_CAPTION) & bool(msg.document):
62 | caption = CUSTOM_CAPTION.format(previouscaption = "" if not msg.caption else msg.caption.html, filename = msg.document.file_name)
63 | else:
64 | caption = "" if not msg.caption else msg.caption.html
65 |
66 | if DISABLE_CHANNEL_BUTTON:
67 | reply_markup = msg.reply_markup
68 | else:
69 | reply_markup = None
70 |
71 | try:
72 | await msg.copy(chat_id=message.from_user.id, caption = caption, parse_mode = ParseMode.HTML, reply_markup = reply_markup, protect_content=PROTECT_CONTENT)
73 | await asyncio.sleep(1)
74 | except FloodWait as e:
75 | await asyncio.sleep(e.x)
76 | await msg.copy(chat_id=message.from_user.id, caption = caption, parse_mode = ParseMode.HTML, reply_markup = reply_markup, protect_content=PROTECT_CONTENT)
77 | except:
78 | pass
79 | return
80 | else:
81 | reply_markup = InlineKeyboardMarkup(
82 | [
83 | [ InlineKeyboardButton(text="🏖️", callback_data="about"),
84 | InlineKeyboardButton(text="🍂", callback_data="about"),
85 | InlineKeyboardButton(text="⚠️", callback_data="me"),
86 | InlineKeyboardButton(text="💸", callback_data="about"),
87 | InlineKeyboardButton(text="🎭", callback_data="about"),
88 | ],[ InlineKeyboardButton( "ᴍᴀɪɴ ᴄʜᴀɴɴᴇʟ", callback_data = "main" ),
89 | InlineKeyboardButton("sᴏᴜʀᴄᴇ ᴄᴏᴅᴇ ", callback_data = "source")
90 | ], [ InlineKeyboardButton("ᴡᴀᴛᴄʜ sʜᴏʀᴛs ᴠɪᴅᴇᴏs", url = "http://t.me/UnseenRobot/shorts") ],
91 | [
92 | InlineKeyboardButton("ʜᴇʟᴘ", callback_data = "help"),
93 | InlineKeyboardButton("ᴀʙᴏᴜᴛ", callback_data = "about")
94 | ]
95 | ]
96 | )
97 | await message.reply_photo(
98 | photo= START_PIC,
99 | caption= START_MSG.format(
100 | first = message.from_user.first_name,
101 | last = message.from_user.last_name,
102 | username = None if not message.from_user.username else '@' + message.from_user.username,
103 | mention = message.from_user.mention,
104 | id = message.from_user.id
105 | ),
106 | reply_markup = reply_markup,
107 |
108 | )
109 | return
110 |
111 |
112 | #=====================================================================================##
113 |
114 | WAIT_MSG = "Working...."
115 |
116 | REPLY_ERROR = "Use this command as a reply to any telegram message without any spaces."
117 |
118 | #=====================================================================================##
119 |
120 |
121 |
122 | @Bot.on_message(filters.command('start') & filters.private)
123 | async def not_joined(client: Client, message: Message):
124 | buttons = [
125 | [
126 | InlineKeyboardButton(text="• ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ", url=client.invitelink),
127 | InlineKeyboardButton(text="ᴊᴏɪɴ ᴄʜᴀɴɴᴇʟ •", url=client.invitelink2),
128 | ]
129 | ]
130 | try:
131 | buttons.append(
132 | [
133 | InlineKeyboardButton(
134 | text='• ᴛʀʏ ᴀɢᴀɪɴ •',
135 | url=f"https://t.me/{client.username}?start={message.command[1]}"
136 | )
137 | ]
138 | )
139 | except IndexError:
140 | pass
141 |
142 | await message.reply_photo(
143 | photo=FORCE_PIC,
144 | caption=FORCE_MSG.format(
145 | first=message.from_user.first_name,
146 | last=message.from_user.last_name,
147 | username=None if not message.from_user.username else '@' + message.from_user.username,
148 | mention=message.from_user.mention,
149 | id=message.from_user.id
150 | ),
151 | reply_markup=InlineKeyboardMarkup(buttons)
152 | )
153 |
154 | @Bot.on_message(filters.command('users') & filters.private & filters.user(ADMINS))
155 | async def get_users(client: Bot, message: Message):
156 | msg = await client.send_message(chat_id=message.chat.id, text=WAIT_MSG)
157 | users = await full_userbase()
158 | await msg.edit(f"{len(users)} users are using this bot")
159 |
160 | @Bot.on_message(filters.private & filters.command('broadcast') & filters.user(ADMINS))
161 | async def send_text(client: Bot, message: Message):
162 | if message.reply_to_message:
163 | query = await full_userbase()
164 | broadcast_msg = message.reply_to_message
165 | total = 0
166 | successful = 0
167 | blocked = 0
168 | deleted = 0
169 | unsuccessful = 0
170 |
171 | pls_wait = await message.reply("ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴘʀᴏᴄᴇꜱꜱɪɴɢ....")
172 | for chat_id in query:
173 | try:
174 | await broadcast_msg.copy(chat_id)
175 | successful += 1
176 | except FloodWait as e:
177 | await asyncio.sleep(e.x)
178 | await broadcast_msg.copy(chat_id)
179 | successful += 1
180 | except UserIsBlocked:
181 | await del_user(chat_id)
182 | blocked += 1
183 | except InputUserDeactivated:
184 | await del_user(chat_id)
185 | deleted += 1
186 | except:
187 | unsuccessful += 1
188 | pass
189 | total += 1
190 |
191 | status = f"""ʙʀᴏᴀᴅᴄᴀꜱᴛ...
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(REPLY_ERROR)
203 | await asyncio.sleep(8)
204 | await msg.delete()
205 |
--------------------------------------------------------------------------------