├── runtime.txt
├── Procfile
├── requirements.txt
├── bot
├── __main__.py
├── user.py
├── __init__.py
├── bot.py
├── translation.py
└── plugins
│ ├── database.py
│ ├── commands.py
│ └── auto_filter.py
├── app.json
├── Readme.md
├── .gitignore
└── LICENSE
/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.9.1
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | worker: python3 -m bot
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Dnspython
2 | Motor
3 | Pyrogram
4 | Pymongo
5 | TgCrypto
6 |
--------------------------------------------------------------------------------
/bot/__main__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | # (c) @AlbertEinsteinTG
4 |
5 | from .bot import Bot
6 |
7 | app = Bot()
8 | app.run()
--------------------------------------------------------------------------------
/bot/user.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | # (c) @AlbertEinsteinTG
4 |
5 | from pyrogram import Client, __version__
6 |
7 | from . import API_HASH, APP_ID, LOGGER, \
8 | USER_SESSION
9 |
10 |
11 | class User(Client):
12 | def __init__(self):
13 | super().__init__(
14 | USER_SESSION,
15 | api_hash=API_HASH,
16 | api_id=APP_ID,
17 | workers=4
18 | )
19 | self.LOGGER = LOGGER
20 |
21 | async def start(self):
22 | await super().start()
23 | usr_bot_me = await self.get_me()
24 | return (self, usr_bot_me.id)
25 |
26 | async def stop(self, *args):
27 | await super().stop()
28 | self.LOGGER(__name__).info("Bot stopped. Bye.")
29 |
--------------------------------------------------------------------------------
/bot/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | # (c) @AlbertEinsteinTG
4 |
5 | import os
6 | import logging
7 | from logging.handlers import RotatingFileHandler
8 |
9 | APP_ID = int(os.environ.get("APP_ID"))
10 |
11 | API_HASH = os.environ.get("API_HASH")
12 |
13 | BOT_TOKEN = os.environ.get("BOT_TOKEN")
14 |
15 | BOT_SESSION = os.environ.get("BOT_SESSION", "bot")
16 |
17 | DB_URI = os.environ.get("DB_URI")
18 |
19 | USER_SESSION = os.environ.get("USER_SESSION")
20 |
21 | LOG_FILE_NAME = "autofilterbot.txt"
22 |
23 | logging.basicConfig(
24 | level=logging.INFO,
25 | format="[%(asctime)s - %(levelname)s] - %(name)s - %(message)s",
26 | datefmt='%d-%b-%y %H:%M:%S',
27 | handlers=[
28 | RotatingFileHandler(
29 | LOG_FILE_NAME,
30 | maxBytes=50000000,
31 | backupCount=10
32 | ),
33 | logging.StreamHandler()
34 | ]
35 | )
36 | logging.getLogger("pyrogram").setLevel(logging.WARNING)
37 |
38 | def LOGGER(name: str) -> logging.Logger:
39 | return logging.getLogger(name)
40 |
--------------------------------------------------------------------------------
/bot/bot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | # (c) @AlbertEinsteinTG
4 |
5 | from pyrogram import Client, __version__
6 |
7 | from . import API_HASH, APP_ID, LOGGER, \
8 | BOT_SESSION, BOT_TOKEN
9 |
10 | from .user import User
11 |
12 |
13 |
14 | class Bot(Client):
15 | USER: User = None
16 | USER_ID: int = None
17 |
18 | def __init__(self):
19 | super().__init__(
20 | BOT_SESSION,
21 | api_hash=API_HASH,
22 | api_id=APP_ID,
23 | plugins={
24 | "root": "bot/plugins"
25 | },
26 | workers=4,
27 | bot_token=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.set_parse_mode("html")
35 | self.LOGGER(__name__).info(
36 | f"@{usr_bot_me.username} started! "
37 | )
38 | self.USER, self.USER_ID = await User().start()
39 |
40 | async def stop(self, *args):
41 | await super().stop()
42 | self.LOGGER(__name__).info("Bot stopped. Bye.")
43 |
--------------------------------------------------------------------------------
/bot/translation.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | # (c) @AlbertEinsteinTG
4 |
5 | class Translation(object):
6 |
7 | START_TEXT = """Hai {}!!
8 | Am Just A Simple Hand Auto Filter Bot_ Bot For Searching Files From Channel...
9 |
10 | Just Sent Any Text I Will Search In All Connected Chat And Reply You With The Message link
11 |
12 | You Can Even Connected To 3 Channels At A Time..."""
13 |
14 | HELP_TEXT = """Usage Guide
15 |
16 | => Add Bot To Any Channel As Admin With Add Members/ Invite Users Via Link
17 |
18 | => Copy Channel ID
19 |
20 | => Use /connect {channel id} In Your Group To Connect With The Group
21 |
22 | => Use /disconnect {channel id} In Your Group To Disconnect From Your Group
23 |
24 | => Use /delall In Your Group To Clear All Your Group Connections (Owner Only)
25 |
26 | Now You Are All Set And Ready To Go...
27 |
28 | Just Send Any Text Will Try To Lookup In Channel And Provide You The Link
29 | """
30 |
31 | ABOUT_TEXT = """➥ Name : Adv Auto Filter Bot
32 |
33 | ➥ Creator : AlbertEinstein_TG
34 |
35 | ➥ Language : Python3
36 |
37 | ➥ Library : Pyrogram Asyncio 1.13.0
38 |
39 | ➥ Source Code : GitHub
40 | """
41 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Auto Filter Bot",
3 | "description": "A Filter Bot Which Doesnt Need Manuall Filter Adding",
4 | "logo": "https://telegra.ph/file/667e15c821117633d07bd.png",
5 | "keywords": [
6 | "Auto",
7 | "Filter",
8 | "Mongo DB"
9 | ],
10 | "website": "https://github.com/AlbertEinsteinTG",
11 | "repository": "https://github.com/AlbertEinsteinTG/Adv-Auto-Filter-Bot",
12 | "success_url": "https://telegram.dog/CrazyBotsz",
13 | "env": {
14 | "APP_ID": {
15 | "description": "Your APP ID From my.telegram.org or @UseTGXBot",
16 | "value": ""
17 | },
18 | "API_HASH": {
19 | "description": "Your API Hash From my.telegram.org or @UseTGXBot",
20 | "value": ""
21 | },
22 | "BOT_TOKEN": {
23 | "description": "Your Bot Token From @BotFather",
24 | "value": ""
25 | },
26 | "DB_URI": {
27 | "description": "Your Mongo DB URL Obtained From mongodb.com",
28 | "value": ""
29 | },
30 | "USER_SESSION": {
31 | "description": "A Pyrogram User Session String. Generated From @PyrogramStringBot",
32 | "value": ""
33 | }
34 | },
35 | "buildpacks": [
36 | {
37 | "url": "heroku/python"
38 | }
39 | ],
40 | "formation": {
41 | "worker": {
42 | "quantity": 1,
43 | "size": "free"
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Adv Auto Filter Bot
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
{channel_id} And Have Permission - `Invite Users via Link`",
84 | parse_mode="html",
85 | reply_to_message_id=update.message_id
86 | )
87 | return
88 |
89 | user = await bot.USER.get_me()
90 | user_id = user.id
91 |
92 | # Tries To Unban The UserBot
93 | try:
94 | await bot.unban_chat_member(
95 | chat_id=channel_id,
96 | user_id=user_id
97 | )
98 | except Exception as e:
99 | pass
100 |
101 | # Userbot Joins The Channel
102 | try:
103 | await bot.USER.join_chat(join_link)
104 | except UserAlreadyParticipant:
105 | pass
106 | except Exception as e:
107 | print (e)
108 |
109 | await bot.send_message(
110 | chat_id=group_id,
111 | text=f"My Userbot `@{user.username}` Cant join Your Channel Make Sure He Is Not Banned There..",
112 | reply_to_message_id=update.message_id
113 | )
114 | return
115 |
116 | chat_name = await bot.get_chat(channel_id)
117 | responce = await db.add_connections(group_id, channel1, channel2, channel3)
118 |
119 | if responce:
120 | await bot.send_message(
121 | chat_id=group_id,
122 | text=f"Sucessfully Connected To {chat_name.title}",
123 | parse_mode="html",
124 | reply_to_message_id=update.message_id
125 | )
126 | return
127 |
128 | else:
129 | await bot.send_message(
130 | chat_id=group_id,
131 | text=f"Having Problem While Connecting...Report @CrazyBotsz",
132 | reply_to_message_id=update.message_id
133 | )
134 | return
135 |
136 |
137 | @Client.on_message(filters.command("disconnect") & filters.group)
138 | async def disconnect(bot, update):
139 | group_id = update.chat.id
140 | text = update.text.split(None, 1)
141 |
142 | x = await bot.get_chat_member(group_id, update.from_user.id)
143 |
144 | if x.status == "member":
145 | return
146 |
147 | if len(text) != 2:
148 | return
149 |
150 | channel_id = int(text[1])
151 |
152 | conn_hist = await db.find_connections(group_id)
153 |
154 | if conn_hist:
155 | channel1 = int(conn_hist["channel_ids"]["channel1"]) if conn_hist["channel_ids"]["channel1"] else None
156 | channel2 = int(conn_hist["channel_ids"]["channel2"]) if conn_hist["channel_ids"]["channel2"] else None
157 | channel3 = int(conn_hist["channel_ids"]["channel3"]) if conn_hist["channel_ids"]["channel3"] else None
158 |
159 | else:
160 | await bot.send_message(
161 | chat_id=group_id,
162 | text="Group Is Not Connected With Any Channel",
163 | reply_to_message_id=update.message_id
164 | )
165 | return
166 |
167 | if channel_id not in (channel1, channel2, channel3):
168 | await bot.send_message(
169 | chat_id=group_id,
170 | text=f"Group Is Not Connected With This Chat : {channel_id}",
171 | parse_mode="html",
172 | reply_to_message_id=update.message_id
173 | )
174 | return
175 |
176 | if channel1 == channel_id:
177 | channel1 = None
178 |
179 | elif channel2 == channel_id:
180 | channel2 = None
181 |
182 | elif channel3 == channel_id:
183 | channel3 = None
184 |
185 | try:
186 | await bot.USER.leave_chat(channel_id)
187 | except:
188 | pass
189 |
190 | chat_name = await bot.get_chat(channel_id)
191 |
192 | try:
193 | await bot.leave_chat(channel_id)
194 | except:
195 | pass
196 |
197 | responce = await db.add_connections(group_id, channel1, channel2, channel3)
198 |
199 | if responce:
200 | await bot.send_message(
201 | chat_id=group_id,
202 | text=f"Sucessfully Disconnected From {chat_name.title}",
203 | parse_mode="html",
204 | reply_to_message_id=update.message_id
205 | )
206 | return
207 |
208 | else:
209 | await bot.send_message(
210 | chat_id=group_id,
211 | text=f"Having Problem While Disconnecting...Report @CrazyBotsz",
212 | reply_to_message_id=update.message_id
213 | )
214 | return
215 |
216 |
217 | @Client.on_message(filters.command("delall") & filters.group)
218 | async def delall(bot, update):
219 | group_id = update.chat.id
220 |
221 | x = await bot.get_chat_member(group_id, update.from_user.id)
222 |
223 | if x.status == "creator":
224 | pass
225 | else:
226 | print(x.status)
227 | return
228 | print("Ok")
229 | conn_hist = await db.find_connections(group_id)
230 | print(conn_hist)
231 | if conn_hist:
232 | channel1 = int(conn_hist["channel_ids"]["channel1"]) if conn_hist["channel_ids"]["channel1"] else None
233 | channel2 = int(conn_hist["channel_ids"]["channel2"]) if conn_hist["channel_ids"]["channel2"] else None
234 | channel3 = int(conn_hist["channel_ids"]["channel3"]) if conn_hist["channel_ids"]["channel3"] else None
235 | channels = [channel1, channel2, channel3]
236 | else:
237 | return
238 |
239 | for channel in channels:
240 | if channel == None:
241 | continue
242 | try:
243 | await bot.USER.leave_chat(channel)
244 | except:
245 | pass
246 | try:
247 | await bot.leave_chat(channel)
248 | except:
249 | pass
250 |
251 | responce = await db.delete_connections(group_id)
252 |
253 | if responce:
254 | await bot.send_message(
255 | chat_id=group_id,
256 | text=f"Sucessfully Disconnected From All Chats",
257 | reply_to_message_id=update.message_id
258 | )
259 | return
260 |
261 |
262 | @Client.on_message(filters.text & filters.group)
263 | async def auto_filter (bot, update):
264 |
265 | group_id = update.chat.id
266 |
267 | if re.findall("((^\/|^,|^\.|^[\U0001F600-\U000E007F]).*)", update.text):
268 | return
269 |
270 | query = update.text
271 |
272 | if len(query) < 3:
273 | return
274 |
275 | results = []
276 |
277 | conn_hist = await db.find_connections(group_id)
278 |
279 | if conn_hist: # TODO: Better Way!? 😕
280 | channel1 = int(conn_hist["channel_ids"]["channel1"]) if conn_hist["channel_ids"]["channel1"] else None
281 | channel2 = int(conn_hist["channel_ids"]["channel2"]) if conn_hist["channel_ids"]["channel2"] else None
282 | channel3 = int(conn_hist["channel_ids"]["channel3"]) if conn_hist["channel_ids"]["channel3"] else None
283 | channels = [channel1, channel2, channel3]
284 | else:
285 | return
286 |
287 | for channel in channels:
288 | if channel == None:
289 | continue
290 |
291 | async for msgs in bot.USER.search_messages(chat_id=channel, query=query, filter="document", limit=150):
292 |
293 | if msgs.video:
294 | name = msgs.video.file_name
295 | elif msgs.document:
296 | name = msgs.document.file_name
297 | elif msgs.audio:
298 | name = msgs.audio.file_name
299 | else:
300 | name = None
301 |
302 | link = msgs.link
303 |
304 | if name is not None:
305 | results.append([InlineKeyboardButton(name, url=link)])
306 |
307 |
308 | async for msgs in bot.USER.search_messages(chat_id=channel, query=query, filter="video", limit=150):
309 |
310 | if msgs.video:
311 | name = msgs.video.file_name
312 | elif msgs.document:
313 | name = msgs.document.file_name
314 | elif msgs.audio:
315 | name = msgs.audio.file_name
316 | else:
317 | name = None
318 |
319 | link = msgs.link
320 |
321 | if name is not None:
322 | results.append([InlineKeyboardButton(name, url=link)])
323 |
324 | if len(results) == 0:
325 | # await bot.send_message(
326 | # chat_id = update.chat.id,
327 | # text=f"Couldn't Find A Matching Result",
328 | # reply_to_message_id=update.message_id
329 | # )
330 | return
331 |
332 | else:
333 | global result
334 | result = []
335 | result += [results[i * 30 :(i + 1) * 30 ] for i in range((len(results) + 30 - 1) // 30 )]
336 |
337 | if len(results) >30:
338 | result[0].append([InlineKeyboardButton("Next ⏩", callback_data=f"0 | {update.from_user.id} | next_btn")])
339 |
340 | reply_markup = InlineKeyboardMarkup(result[0])
341 |
342 | await bot.send_message(
343 | chat_id = update.chat.id,
344 | text=f"Found {(len(results))} Results For Query: {query}",
345 | reply_markup=reply_markup,
346 | parse_mode="html",
347 | reply_to_message_id=update.message_id
348 | )
349 |
350 | @Client.on_callback_query()
351 | async def cb_handler(bot, query:CallbackQuery, group=1):
352 | cb_data = query.data
353 |
354 | if cb_data == "start":
355 | buttons = [[
356 | InlineKeyboardButton('My Dev 👨🔬', url='https://t.me/AlbertEinstein_TG'),
357 | InlineKeyboardButton('Source Code 🧾', url ='https://github.com/AlbertEinsteinTG/Adv-Auto-Filter-Bot')
358 | ],[
359 | InlineKeyboardButton('Support 🛠', url='https://t.me/CrazyBotszGrp')
360 | ],[
361 | InlineKeyboardButton('Help ⚙', callback_data="help")
362 | ]]
363 |
364 | reply_markup = InlineKeyboardMarkup(buttons)
365 |
366 | await query.message.edit_text(
367 | Translation.START_TEXT.format(query.from_user.mention),
368 | reply_markup=reply_markup,
369 | parse_mode="html",
370 | disable_web_page_preview=True
371 | )
372 |
373 | elif cb_data == "help":
374 | buttons = [[
375 | InlineKeyboardButton('Home ⚡', callback_data='start'),
376 | InlineKeyboardButton('About 🚩', callback_data='about')
377 | ],[
378 | InlineKeyboardButton('Close 🔐', callback_data='close')
379 | ]]
380 |
381 | reply_markup = InlineKeyboardMarkup(buttons)
382 |
383 | await query.message.edit_text(
384 | Translation.HELP_TEXT,
385 | reply_markup=reply_markup,
386 | parse_mode="html",
387 | disable_web_page_preview=True
388 | )
389 |
390 | elif cb_data == "about":
391 | buttons = [[
392 | InlineKeyboardButton('Home ⚡', callback_data='start'),
393 | InlineKeyboardButton('Close 🔐', callback_data='close')
394 | ]]
395 |
396 | reply_markup = InlineKeyboardMarkup(buttons)
397 |
398 | await query.message.edit_text(
399 | Translation.ABOUT_TEXT,
400 | reply_markup=reply_markup,
401 | parse_mode="html",
402 | disable_web_page_preview=True
403 | )
404 |
405 | elif cb_data == "close":
406 | await query.message.delete()
407 |
408 |
409 | elif "btn" in cb_data :
410 | cb_data = cb_data.split("|")
411 |
412 | index_val = cb_data[0]
413 | user_id = cb_data[1]
414 | data = cb_data[2].strip()
415 |
416 | if int(query.from_user.id) != int(user_id):
417 | await query.answer("You Arent Worth To Do That!!",show_alert=True) # Lol😆
418 | return
419 | else:
420 | pass
421 |
422 |
423 | if data == "next_btn":
424 | index_val = int(index_val) + 1
425 | elif data == "back_btn":
426 | index_val = int(index_val) - 1
427 |
428 | try:
429 | temp_results = result[index_val].copy()
430 | except IndexError:
431 | return # Quick Fix🏃🏃
432 | except Exception as e:
433 | print(e)
434 | return
435 |
436 | if int(index_val) == (len(result) -1) or int(index_val) == 10: # Max 10 Page
437 | temp_results.append([
438 | InlineKeyboardButton("⏪ Back", callback_data=f"{index_val} | {query.from_user.id} | back_btn")
439 | ])
440 |
441 | elif int(index_val) == 0:
442 | pass
443 |
444 | else:
445 | temp_results.append([
446 | InlineKeyboardButton("⏪ Back", callback_data=f"{index_val} | {query.from_user.id} | back_btn"),
447 | InlineKeyboardButton("Next ⏩", callback_data=f"{index_val} | {query.from_user.id} | next_btn")
448 | ])
449 |
450 | reply_markup = InlineKeyboardMarkup(temp_results)
451 |
452 | if index_val == 0:
453 | text=f"Found {(len(result)*30 - (30 - len(result [-1])))} Results For Query"
454 | else:
455 | text=f"Page `{index_val}` For Your Query....."
456 |
457 | time.sleep(1) # Just A Mesure To Prevent Flood Wait🙁
458 | try:
459 | await query.message.edit(
460 | text,
461 | reply_markup=reply_markup,
462 | parse_mode="md"
463 | )
464 | except FloodWait as f:
465 | await asyncio.sleep(f.x)
466 | await query.message.edit(
467 | text,
468 | reply_markup=reply_markup,
469 | parse_mode="md"
470 | )
471 |
--------------------------------------------------------------------------------