├── LICENSE ├── Procfile ├── README.md ├── Script.py ├── app.py ├── body ├── Caption.py ├── database.py └── f_sub.py ├── bot.py ├── info.py ├── requirements.txt └── run cmd.txt /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Silicon-Developer 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: python bot.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
24 | start - Start The Bot. 25 | set_cap - To set Custom Caption. 26 | del_cap - Remove Caption. 27 | broadcast - Boadcast Message To Users. 28 | total_users - Total No. Of Users. 29 | restart - Restart The Bot. 30 |31 | 32 | ## Caption Vars 33 |
34 | `{default_caption}` Real Caption. 35 | `{file_name}` To Get File Name. 36 | `{size}` To Get File Size. 37 | `{language}` To Get Language. 38 | `{year}` To get Years. 39 |40 | 41 |
82 |
83 | git clone https://github.com/Silicon-Developer/Advance-Caption-Bot.git 84 | # Install Packages 85 | pip3 install -r requirements.txt 86 | Edit info.py with variables as given below then run bot 87 | python3 bot.py 88 |89 | 90 | 91 |
{file_name}
𝑇𝑜 𝑠ℎ𝑜𝑤 𝑦𝑜𝑢𝑟 𝐹𝑖𝑙𝑒 𝑁𝑎𝑚𝑒.\n\n𝑈𝑠𝑒{file_size}
𝑇𝑜 𝑠ℎ𝑜𝑤 𝑦𝑜𝑢𝑟 𝐹𝑖𝑙𝑒 𝑆𝑖𝑧𝑒/n/n✓ 𝑀𝑎𝑦 𝐵𝑒 𝑁𝑜𝑤 𝑌𝑜𝑢 𝑎𝑟𝑒 𝑐𝑙𝑒𝑎𝑟💫**"
82 | )
83 | chnl_id = message.chat.id
84 | caption = (
85 | message.text.split(" ", 1)[1] if len(message.text.split(" ", 1)) > 1 else None
86 | )
87 | chkData = await chnl_ids.find_one({"chnl_id": chnl_id})
88 | if chkData:
89 | await updateCap(chnl_id, caption)
90 | return await message.reply(f"Your New Caption: {caption}")
91 | else:
92 | await addCap(chnl_id, caption)
93 | return await message.reply(f"Yᴏᴜʀ Nᴇᴡ Cᴀᴘᴛɪᴏɴ Is: {caption}")
94 |
95 | @Client.on_message(filters.command("del_cap") & filters.channel)
96 | async def delCap(_, msg):
97 | chnl_id = msg.chat.id
98 | try:
99 | await chnl_ids.delete_one({"chnl_id": chnl_id})
100 | return await msg.reply("✓ Sᴜᴄᴄᴇssғᴜʟʟʏ... Dᴇʟᴇᴛᴇᴅ Yᴏᴜʀ Cᴀᴘᴛɪᴏɴ Nᴏᴡ I ᴀᴍ Usɪɴɢ Mʏ Dᴇғᴀᴜʟᴛ Cᴀᴘᴛɪᴏɴ ")
101 | except Exception as e:
102 | e_val = await msg.replay(f"ERR I GOT: {e}")
103 | await asyncio.sleep(5)
104 | await e_val.delete()
105 | return
106 |
107 | def extract_language(default_caption):
108 | language_pattern = r'\b(Hindi|English|Tamil|Telugu|Malayalam|Kannada|Hin)\b'#Contribute More Language If You Have
109 | languages = set(re.findall(language_pattern, default_caption, re.IGNORECASE))
110 | if not languages:
111 | return "Hindi-English"
112 | return ", ".join(sorted(languages, key=str.lower))
113 |
114 | def extract_year(default_caption):
115 | match = re.search(r'\b(19\d{2}|20\d{2})\b', default_caption)
116 | return match.group(1) if match else None
117 |
118 | @Client.on_message(filters.channel)
119 | async def reCap(bot, message):
120 | chnl_id = message.chat.id
121 | default_caption = message.caption
122 | if message.media:
123 | for file_type in ("video", "audio", "document", "voice"):
124 | obj = getattr(message, file_type, None)
125 | if obj and hasattr(obj, "file_name"):
126 | file_name = obj.file_name
127 | file_size = obj.file_size
128 | language = extract_language(default_caption)
129 | year = extract_year(default_caption)
130 | file_name = (
131 | re.sub(r"@\w+\s*", "", file_name)
132 | .replace("_", " ")
133 | .replace(".", " ")
134 | )
135 | cap_dets = await chnl_ids.find_one({"chnl_id": chnl_id})
136 | try:
137 | if cap_dets:
138 | cap = cap_dets["caption"]
139 | replaced_caption = cap.format(file_name=file_name, file_size=get_size(file_size), default_caption=default_caption, language=language, year=year)
140 | await message.edit(replaced_caption)
141 | else:
142 | replaced_caption = DEF_CAP.format(file_name=file_name, file_size=get_size(file_size), default_caption=default_caption, language=language, year=year)
143 | await message.edit(replaced_caption)
144 | except FloodWait as e:
145 | await asyncio.sleep(e.x)
146 | continue
147 | return
148 |
149 | # Size conversion function
150 | def get_size(size):
151 | units = ["Bytes", "Kʙ", "Mʙ", "Gʙ", "Tʙ", "Pʙ", "Eʙ"]
152 | size = float(size)
153 | i = 0
154 | while size >= 1024.0 and i < len(units) - 1: # Changed the condition to stop at the last unit
155 | i += 1
156 | size /= 1024.0
157 | return "%.2f %s" % (size, units[i])
158 |
159 | @Client.on_callback_query(filters.regex(r'^start'))
160 | async def start(bot, query):
161 | await query.message.edit_text(
162 | text=script.START_TXT.format(query.from_user.mention),
163 | reply_markup=InlineKeyboardMarkup(
164 | [[
165 | InlineKeyboardButton("➕️ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ᴄʜᴀɴɴᴇʟ ➕️", url=f"http://t.me/CustomCaptionBot?startchannel=true")
166 | ],[
167 | InlineKeyboardButton("Hᴇʟᴘ", callback_data="help"),
168 | InlineKeyboardButton("Aʙᴏᴜᴛ", callback_data="about")
169 | ],[
170 | InlineKeyboardButton("🌐 Uᴘᴅᴀᴛᴇ", url=f"https://t.me/Silicon_Bot_Update"),
171 | InlineKeyboardButton("📜 Sᴜᴘᴘᴏʀᴛ", url=r"https://t.me/Silicon_Botz")
172 | ]]
173 | ),
174 | disable_web_page_preview=True
175 | )
176 |
177 | @Client.on_callback_query(filters.regex(r'^help'))
178 | async def help(bot, query):
179 | await query.message.edit_text(
180 | text=script.HELP_TXT,
181 | reply_markup=InlineKeyboardMarkup(
182 | [[
183 | InlineKeyboardButton('About', callback_data='about')
184 | ],[
185 | InlineKeyboardButton('↩ ʙᴀᴄᴋ', callback_data='start')
186 | ]]
187 | ),
188 | disable_web_page_preview=True
189 | )
190 |
191 |
192 | @Client.on_callback_query(filters.regex(r'^about'))
193 | async def about(bot, query):
194 | await query.message.edit_text(
195 | text=script.ABOUT_TXT,
196 | reply_markup=InlineKeyboardMarkup(
197 | [[
198 | InlineKeyboardButton('ʜᴏᴡ ᴛᴏ ᴜsᴇ ᴍᴇ ❓', callback_data='help')
199 | ],[
200 | InlineKeyboardButton('↩ ʙᴀᴄᴋ', callback_data='start')
201 | ]]
202 | ),
203 | disable_web_page_preview=True
204 |
205 | )
206 |
207 |
--------------------------------------------------------------------------------
/body/database.py:
--------------------------------------------------------------------------------
1 | import motor.motor_asyncio
2 | from info import *
3 |
4 | client = motor.motor_asyncio.AsyncIOMotorClient(MONGO_DB)
5 | db = client.captions_with_chnl
6 | chnl_ids = db.chnl_ids
7 | users = db.users
8 |
9 | async def addCap(chnl_id, caption):
10 | dets = {"chnl_id": chnl_id, "caption": caption}
11 | await chnl_ids.insert_one(dets)
12 |
13 |
14 | async def updateCap(chnl_id, caption):
15 | await chnl_ids.update_one({"chnl_id": chnl_id}, {"$set": {"caption": caption}})
16 |
17 | async def insert(user_id):
18 | user_det = {"_id": user_id}
19 | try:
20 | await users.insert_one(user_det)
21 | except:
22 | pass
23 |
24 | async def total_user():
25 | user = await users.count_documents({})
26 | return user
27 |
28 | async def getid():
29 | all_users = users.find({})
30 | return all_users
31 |
32 | async def delete(id):
33 | await users.delete_one(id)
--------------------------------------------------------------------------------
/body/f_sub.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client, filters, enums
2 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
3 | from pyrogram.errors import UserNotParticipant
4 | from info import *
5 | from .database import insert
6 |
7 | async def not_subscribed(_, client, message):
8 | user_id = int(message.from_user.id)
9 | await insert(user_id)
10 | if not FORCE_SUB:
11 | return False
12 | try:
13 | user = await client.get_chat_member(FORCE_SUB, message.from_user.id)
14 | if user.status == enums.ChatMemberStatus.BANNED:
15 | return True
16 | else:
17 | return False
18 | except UserNotParticipant:
19 | pass
20 | return True
21 |
22 |
23 | @Client.on_message(filters.private & filters.create(not_subscribed))
24 | async def forces_sub(client, message):
25 | buttons = [[InlineKeyboardButton(text="📢 Join Update Channel 📢", url=f"https://t.me/{FORCE_SUB}") ]]
26 | text = "**Sᴏʀʀy Dᴜᴅᴇ Yᴏᴜ'ʀᴇ Nᴏᴛ Jᴏɪɴᴇᴅ My Cʜᴀɴɴᴇʟ 😐. Sᴏ Pʟᴇᴀꜱᴇ Jᴏɪɴ Oᴜʀ Uᴩᴅᴀᴛᴇ Cʜᴀɴɴᴇʟ Tᴏ Cᴄᴏɴᴛɪɴᴜᴇ**"
27 | try:
28 | silicon = await client.get_chat_member(FORCE_SUB, message.from_user.id)
29 | if silicon.status == enums.ChatMemberStatus.BANNED:
30 | return await client.send_message(message.from_user.id, text="Sᴏʀʀy Yᴏᴜ'ʀᴇ Bᴀɴɴᴇᴅ Tᴏ Uꜱᴇ Mᴇ")
31 | except UserNotParticipant:
32 | return await message.reply_text(text=text, reply_markup=InlineKeyboardMarkup(buttons))
33 | return await message.reply_text(text=text, reply_markup=InlineKeyboardMarkup(buttons))
34 |
35 |
--------------------------------------------------------------------------------
/bot.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client
2 | from info import *
3 |
4 |
5 | class Bot(Client):
6 | def __init__(self):
7 | super().__init__(
8 | name="Auto Cap",
9 | api_id=API_ID,
10 | api_hash=API_HASH,
11 | bot_token=BOT_TOKEN,
12 | workers=200,
13 | plugins={"root": "body"},
14 | sleep_threshold=15,
15 | )
16 |
17 | async def start(self):
18 | await super().start()
19 | me = await self.get_me()
20 | self.force_channel = FORCE_SUB
21 | if FORCE_SUB:
22 | try:
23 | link = await self.export_chat_invite_link(FORCE_SUB)
24 | self.invitelink = link
25 | except Exception as e:
26 | print(e)
27 | print("Make Sure Bot admin in force sub channel")
28 | self.force_channel = None
29 | print(f"{me.first_name} Iꜱ Sᴛᴀʀᴛᴇᴅ.....✨️")
30 | await self.send_message(ADMIN, f"**{me.first_name} Iꜱ Sᴛᴀʀᴛᴇᴅ.....✨️**")
31 |
32 |
33 | Bot().run()
--------------------------------------------------------------------------------
/info.py:
--------------------------------------------------------------------------------
1 | from os import environ, getenv
2 | import re
3 | import os
4 |
5 | id_pattern = re.compile(r"^.\d+$")
6 |
7 |
8 | def is_enabled(value, default):
9 | if value.lower() in ["true", "yes", "1", "enable", "y"]:
10 | return True
11 | elif value.lower() in ["false", "no", "0", "disable", "n"]:
12 | return False
13 | else:
14 | return default
15 |
16 |
17 | ADMIN = int(getenv("ADMIN", ""))
18 | SILICON_PIC = os.environ.get("SILICON_PIC", "https://telegra.ph/file/21a8e96b45cd6ac4d3da6.jpg")
19 | API_ID = int(getenv("API_ID", ""))
20 | API_HASH = str(getenv("API_HASH", ""))
21 | BOT_TOKEN = str(getenv("BOT_TOKEN", ""))
22 | FORCE_SUB = os.environ.get("FORCE_SUB", "")
23 | MONGO_DB = str(getenv("MONGO_DB", "mongodb+srv://replacewithyourmongodb:replacewithyourmongodb@cluster0.zi78j51.mongodb.net/?retryWrites=true&w=majority",))
24 | DEF_CAP = str(
25 | getenv(
26 | "DEF_CAP",
27 | "File Name:- `{file_name}`\n\n{file_size}",
28 | )
29 | )
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask
2 | gunicorn
3 | aiohttp
4 | motor
5 | asyncio
6 | pyrofork==2.3.48
7 | tgcrypto
8 | Jinja2==3.0.3
9 | werkzeug==2.0.2
10 | itsdangerous==2.0.1
--------------------------------------------------------------------------------
/run cmd.txt:
--------------------------------------------------------------------------------
1 | gunicorn app:app & python3 bot.py
--------------------------------------------------------------------------------