├── Procfile
├── runtime.txt
├── plugins
├── __init__.py
├── route.py
├── channel.py
├── banned.py
├── files_delete.py
├── broadcast.py
├── inline.py
├── gfilters.py
├── genlink.py
├── connection.py
├── ExtraMods
│ └── font.py
├── misc.py
├── index.py
├── filters.py
├── p_ttishow.txt
└── commands.py
├── Dockerfile
├── requirements.txt
├── render.yaml
├── start.sh
├── logging.conf
├── app.py
├── app.json
├── README.md
├── database
├── gfilters_mdb.py
├── filters_mdb.py
├── connections_mdb.py
├── users_chats_db.py
└── ia_filterdb.py
├── bot.py
├── info.py
├── Script.py
└── utils.py
/Procfile:
--------------------------------------------------------------------------------
1 | web: python3 bot.py
2 |
--------------------------------------------------------------------------------
/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.10.7
2 |
--------------------------------------------------------------------------------
/plugins/__init__.py:
--------------------------------------------------------------------------------
1 | from aiohttp import web
2 | from .route import routes
3 |
4 |
5 | async def web_server():
6 | web_app = web.Application(client_max_size=30000000)
7 | web_app.add_routes(routes)
8 | return web_app
9 |
--------------------------------------------------------------------------------
/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("Bot Deployed join us - @kissuxbots on telegram")
8 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.10
2 | RUN apt update && apt upgrade -y
3 | RUN apt install git -y
4 | COPY requirements.txt /requirements.txt
5 |
6 | RUN cd /
7 | RUN pip install -U pip && pip install -U -r requirements.txt
8 | WORKDIR /app
9 |
10 | COPY . .
11 | CMD ["bash", "start.sh"]
12 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | # ⚙️ Core Dependencies
2 | pyrofork
3 | tgcrypto
4 | pymongo[srv]==3.12.3
5 | motor==2.5.1
6 | marshmallow==3.14.1
7 | umongo==3.0.1
8 | requests
9 | beautifulsoup4
10 | shortzy
11 | pytz
12 |
13 | # 🌐 Flask App Server
14 | Flask==2.2.2
15 | gunicorn==20.1.0
16 | aiohttp==3.8.1
17 | aiofiles==22.1.0
18 |
19 | # 📦 Telegram & Media Handling
20 | telegraph==2.2.0
21 | Pillow==9.4.0
22 | qrcode
23 |
24 | # 🎥 External Git Repo
25 | git+https://github.com/Joelkb/cinemagoer
26 |
--------------------------------------------------------------------------------
/render.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | - type: web
3 | name: tele-filter-bot
4 | env: python
5 | plan: free
6 | buildCommand: "pip install -r requirements.txt"
7 | startCommand: "python3 bot.py"
8 | envVars:
9 | - key: API_ID
10 | sync: false
11 | - key: API_HASH
12 | sync: false
13 | - key: BOT_TOKEN
14 | sync: false
15 | - key: DATABASE_URL
16 | sync: false
17 | - key: LOG_CHANNEL
18 | sync: false
19 | - key: ADMINS
20 | sync: false
21 |
22 |
--------------------------------------------------------------------------------
/plugins/channel.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client, filters
2 | from info import CHANNELS
3 | from database.ia_filterdb import save_file
4 |
5 | media_filter = filters.document | filters.video | filters.audio
6 |
7 |
8 | @Client.on_message(filters.chat(CHANNELS) & media_filter)
9 | async def media(bot, message):
10 | """Media Handler"""
11 | for file_type in ("document", "video", "audio"):
12 | media = getattr(message, file_type, None)
13 | if media is not None:
14 | break
15 | else:
16 | return
17 |
18 | media.file_type = file_type
19 | media.caption = message.caption
20 | await save_file(media)
21 |
--------------------------------------------------------------------------------
/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Update & upgrade system
4 | apt update && apt upgrade -y
5 |
6 | apt install git -y
7 | pip install -U pip
8 |
9 | # Clone the repo
10 | if [ -z $UPSTREAM_REPO ]
11 | then
12 | echo "Cloning main Repository"
13 | git clone https://github.com/pyKinsu/Tele-Filter-Bot /Tele-Filter-Bot
14 | else
15 | echo "Cloning Custom Repo from $UPSTREAM_REPO "
16 | git clone $UPSTREAM_REPO /Tele-Filter-Bot
17 | fi
18 |
19 | # Upgrade pip and install requirements
20 | cd /Tele-Filter-Bot
21 | pip install -U -r requirements.txt --force-reinstall
22 |
23 | # Start bot
24 | echo "Starting Bot...."
25 | python3 bot.py
26 |
--------------------------------------------------------------------------------
/logging.conf:
--------------------------------------------------------------------------------
1 | [loggers]
2 | keys=root
3 |
4 | [handlers]
5 | keys=consoleHandler,fileHandler
6 |
7 | [formatters]
8 | keys=consoleFormatter,fileFormatter
9 |
10 | [logger_root]
11 | level=DEBUG
12 | handlers=consoleHandler,fileHandler
13 |
14 | [handler_consoleHandler]
15 | class=StreamHandler
16 | level=INFO
17 | formatter=consoleFormatter
18 | args=(sys.stdout,)
19 |
20 | [handler_fileHandler]
21 | class=FileHandler
22 | level=ERROR
23 | formatter=fileFormatter
24 | args=('TelegramBot.log','w',)
25 |
26 | [formatter_consoleFormatter]
27 | format=%(asctime)s - %(lineno)d - %(name)s - %(module)s - %(levelname)s - %(message)s
28 | datefmt=%I:%M:%S %p
29 |
30 | [formatter_fileFormatter]
31 | format=[%(asctime)s:%(name)s:%(lineno)d:%(levelname)s] %(message)s
32 | datefmt=%m/%d/%Y %I:%M:%S %p
33 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | from flask import Flask
2 | from time import sleep, time
3 | from psutil import boot_time, disk_usage, net_io_counters
4 | from subprocess import check_output
5 | from os import path as ospath
6 | app = Flask(__name__)
7 | botStartTime = time()
8 | if ospath.exists('.git'):
9 | commit_date = check_output(["git log -1 --date=format:'%y/%m/%d %H:%M' --pretty=format:'%cd'"], shell=True).decode()
10 | else:
11 | commit_date = 'No UPSTREAM_REPO'
12 |
13 | @app.route('/status', methods=['GET'])
14 | def status():
15 | bot_uptime = time() - botStartTime
16 | uptime = time() - boot_time()
17 | sent = net_io_counters().bytes_sent
18 | recv = net_io_counters().bytes_recv
19 | return {
20 | 'commit_date': commit_date,
21 | 'uptime': uptime,
22 | 'on_time': bot_uptime,
23 | 'free_disk': disk_usage('.').free,
24 | 'total_disk': disk_usage('.').total,
25 | 'network': {
26 | 'sent': sent,
27 | 'recv': recv,
28 | },
29 | }
30 | @app.route('/')
31 | def hello_world():
32 | return 'TGNVS'
33 |
34 |
35 | if __name__ == "__main__":
36 | app.run()
37 |
--------------------------------------------------------------------------------
/plugins/banned.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client, filters
2 | from utils import temp
3 | from pyrogram.types import Message
4 | from database.users_chats_db import db
5 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
6 | from info import SUPPORT_CHAT
7 |
8 | async def banned_users(_, client, message: Message):
9 | return (
10 | message.from_user is not None or not message.sender_chat
11 | ) and message.from_user.id in temp.BANNED_USERS
12 |
13 | banned_user = filters.create(banned_users)
14 |
15 | async def disabled_chat(_, client, message: Message):
16 | return message.chat.id in temp.BANNED_CHATS
17 |
18 | disabled_group=filters.create(disabled_chat)
19 |
20 |
21 | @Client.on_message(filters.private & banned_user & filters.incoming)
22 | async def ban_reply(bot, message):
23 | ban = await db.get_ban_status(message.from_user.id)
24 | await message.reply(f'Sorry Dude, You are Banned to use Me. \nBan Reason: {ban["ban_reason"]}')
25 |
26 | @Client.on_message(filters.group & disabled_group & filters.incoming)
27 | async def grp_bd(bot, message):
28 | buttons = [[
29 | InlineKeyboardButton('Support', url=f'https://t.me/kissuhelp')
30 | ]]
31 | reply_markup=InlineKeyboardMarkup(buttons)
32 | vazha = await db.get_chat(message.chat.id)
33 | k = await message.reply(
34 | text=f"CHAT NOT ALLOWED 🐞\n\nMy admins has restricted me from working here ! If you want to know more about it contact support..\nReason : {vazha['reason']}.",
35 | reply_markup=reply_markup)
36 | try:
37 | await k.pin()
38 | except:
39 | pass
40 | await bot.leave_chat(message.chat.id)
41 |
--------------------------------------------------------------------------------
/plugins/files_delete.py:
--------------------------------------------------------------------------------
1 | import re
2 | import logging
3 | from pyrogram import Client, filters
4 | from info import DELETE_CHANNELS
5 | from database.ia_filterdb import Media, unpack_new_file_id
6 |
7 | logger = logging.getLogger(__name__)
8 |
9 | media_filter = filters.document | filters.video | filters.audio
10 |
11 |
12 | @Client.on_message(filters.chat(DELETE_CHANNELS) & media_filter)
13 | async def deletemultiplemedia(bot, message):
14 | """Delete Multiple files from database"""
15 |
16 | for file_type in ("document", "video", "audio"):
17 | media = getattr(message, file_type, None)
18 | if media is not None:
19 | break
20 | else:
21 | return
22 |
23 | file_id, file_ref = unpack_new_file_id(media.file_id)
24 |
25 | result = await Media.collection.delete_one({
26 | '_id': file_id,
27 | })
28 | if result.deleted_count:
29 | logger.info('File is successfully deleted from database.')
30 | else:
31 | file_name = re.sub(r"(_|\-|\.|\+)", " ", str(media.file_name))
32 | result = await Media.collection.delete_many({
33 | 'file_name': file_name,
34 | 'file_size': media.file_size,
35 | 'mime_type': media.mime_type
36 | })
37 | if result.deleted_count:
38 | logger.info('File is successfully deleted from database.')
39 | else:
40 | result = await Media.collection.delete_many({
41 | 'file_name': media.file_name,
42 | 'file_size': media.file_size,
43 | 'mime_type': media.mime_type
44 | })
45 | if result.deleted_count:
46 | logger.info('File is successfully deleted from database.')
47 | else:
48 | logger.info('File not found in database.')
49 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Tele-Filter-Bot",
3 | "description": "A simple telefilter bot created by @pykinsu.",
4 | "stack": "container",
5 | "keywords": [
6 | "telegram",
7 | "auto-filter",
8 | "filter",
9 | "best",
10 | "indian",
11 | "pyrogram",
12 | "media",
13 | "search",
14 | "channel",
15 | "index",
16 | "inline"
17 | ],
18 | "website": "https://t.me/kissuxbots",
19 | "repository": "https://github.com/pyKinsu/Tele-Filter-Bot/",
20 | "env": {
21 | "BOT_TOKEN": {
22 | "description": "Your bot token.",
23 | "required": true
24 | },
25 | "API_ID": {
26 | "description": "Get this value from https://my.telegram.org",
27 | "required": true
28 | },
29 | "API_HASH": {
30 | "description": "Get this value from https://my.telegram.org",
31 | "required": true
32 | },
33 | "CHANNELS": {
34 | "description": "Username or ID of channel or group. Separate multiple IDs by space.",
35 | "required": false
36 | },
37 | "ADMINS": {
38 | "description": "Username or ID of Admin. Separate multiple Admins by space.",
39 | "required": true
40 | },
41 | "PICS": {
42 | "description": "Add some telegraph link of pictures.",
43 | "required": false
44 | },
45 | "LOG_CHANNEL": {
46 | "description": "Bot Logs, give a channel id with -100xxxxxxx.",
47 | "required": true
48 | },
49 | "DATABASE_URI": {
50 | "description": "MongoDB URI. Get this value from https://www.mongodb.com. For more help, watch this video - https://youtu.be/dsuTn4qV2GA",
51 | "required": true
52 | },
53 | "DATABASE_NAME": {
54 | "description": "Name of the database in MongoDB. For more help, watch this video - https://youtu.be/dsuTn4qV2GA",
55 | "value": "AutoFilter",
56 | "required": false
57 | },
58 | "COLLECTION_NAME": {
59 | "description": "Name of the collections. Defaults to Telegram_files. If you are using the same database, then use a different collection name for each bot.",
60 | "value": "AutoFilter",
61 | "required": false
62 | }
63 | },
64 | "addons": [],
65 | "buildpacks": [{
66 | "url": "heroku/python"
67 | }],
68 | "formation": {
69 | "worker": {
70 | "quantity": 1,
71 | "size": "eco"
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Please [Star](https://github.com/pykinsu/tele-filter-bot/) This Repository and [Follow Me](https://github.com/pykinsu/)
2 |
3 | ## check bot [sanya movies bot](https://t.me/sanyamoviesbot/)
4 |
5 | ### Required Variables
6 | * `BOT_TOKEN`: Create a bot using [@BotFather](https://telegram.dog/BotFather), and get the Telegram API token.
7 | * `API_ID`: Get this value from [telegram.org](https://my.telegram.org/apps)
8 | * `API_HASH`: Get this value from [telegram.org](https://my.telegram.org/apps)
9 | * `CHANNELS`: Username or ID of channel or group. Separate multiple IDs by space
10 | * `ADMINS`: Username or ID of Admin. Separate multiple Admins by space
11 | * `DATABASE_URI`: [mongoDB](https://www.mongodb.com) URI. Get this value from [mongoDB](https://www.mongodb.com). For more help watch this [video](https://youtu.be/1G1XwEOnxxo)
12 | * `DATABASE_NAME`: Name of the database in [mongoDB](https://www.mongodb.com).
13 | * `LOG_CHANNEL` : A channel to log the activities of bot. Make sure bot is an admin in the channel.
14 |
15 | * Check [info.py](https://github.com/pykinsu/tele-filter-bot/blob/main/info.py) for more optional variables
16 |
17 | ---
18 |
19 | ## 🎯 Getting Started — Setup Guides
20 |
21 | - 📽️ [How to Create a MongoDB Database](https://youtube.com/shorts/pIHvoXkwmq4)
22 | - 📽️ [How to Create a Telegram Bot with BotFather](https://youtube.com/shorts/HhSIHIbFTF4)
23 | - 📽️ [Get Telegram API ID and Hash](https://youtube.com/shorts/DtaShUUlxrs)
24 | - 📽️ [Deploy Python Telegram Bot on Render](https://youtu.be/kYDTu1UYOzM)
25 |
26 | ---
27 |
28 | ## Deploy On Koyeb
29 | [](https://app.koyeb.com/deploy?name=tele-filter-bot&repository=pyKinsu%2FTele-Filter-Bot&branch=main&instance_type=free&instances_min=0&autoscaling_sleep_idle_delay=300&env%5BADMINS%5D=&env%5BAPI_HASH%5D=&env%5BAPI_ID%5D=&env%5BBOT_TOKEN%5D=&env%5BDATABASE_URI%5D=&env%5BLOG_CHANNEL%5D=)
30 |
31 | ---
32 |
33 | ## 🚀 Deploy on Render
34 |
35 | [](https://render.com/deploy?repo=https://github.com/pyKinsu/Tele-Filter-Bot)
36 |
37 | > 🛠️ **Note:** Please make sure to **fork** the repository and use your own copy.
38 |
39 | ---
40 |
41 |
42 | ## 🔘 Connect With Me
43 |
44 | [](https://t.me/kissuxbots)
45 | [](https://t.me/ur_movie_group)
46 | [](https://github.com/pyKinsu)
47 |
48 | ---
49 |
--------------------------------------------------------------------------------
/plugins/broadcast.py:
--------------------------------------------------------------------------------
1 |
2 | from pyrogram import Client, filters
3 | import datetime
4 | import time
5 | from database.users_chats_db import db
6 | from info import ADMINS
7 | from utils import broadcast_messages, broadcast_messages_group
8 | import asyncio
9 |
10 | @Client.on_message(filters.command("broadcast") & filters.user(ADMINS) & filters.reply)
11 | # https://t.me/GetTGLink/4178
12 | async def verupikkals(bot, message):
13 | users = await db.get_all_users()
14 | b_msg = message.reply_to_message
15 | sts = await message.reply_text(
16 | text='Broadcasting your messages...'
17 | )
18 | start_time = time.time()
19 | total_users = await db.total_users_count()
20 | done = 0
21 | blocked = 0
22 | deleted = 0
23 | failed =0
24 |
25 | success = 0
26 | async for user in users:
27 | pti, sh = await broadcast_messages(int(user['id']), b_msg)
28 | if pti:
29 | success += 1
30 | elif pti == False:
31 | if sh == "Blocked":
32 | blocked+=1
33 | elif sh == "Deleted":
34 | deleted += 1
35 | elif sh == "Error":
36 | failed += 1
37 | done += 1
38 | await asyncio.sleep(2)
39 | if not done % 20:
40 | await sts.edit(f"Broadcast in progress:\n\nTotal Users {total_users}\nCompleted: {done} / {total_users}\nSuccess: {success}\nBlocked: {blocked}\nDeleted: {deleted}")
41 | time_taken = datetime.timedelta(seconds=int(time.time()-start_time))
42 | await sts.edit(f"Broadcast Completed:\nCompleted in {time_taken} seconds.\n\nTotal Users {total_users}\nCompleted: {done} / {total_users}\nSuccess: {success}\nBlocked: {blocked}\nDeleted: {deleted}")
43 |
44 | @Client.on_message(filters.command("group_broadcast") & filters.user(ADMINS) & filters.reply)
45 | async def broadcast_group(bot, message):
46 | groups = await db.get_all_chats()
47 | b_msg = message.reply_to_message
48 | sts = await message.reply_text(
49 | text='Broadcasting your messages To Groups...'
50 | )
51 | start_time = time.time()
52 | total_groups = await db.total_chat_count()
53 | done = 0
54 | failed =0
55 |
56 | success = 0
57 | async for group in groups:
58 | pti, sh = await broadcast_messages_group(int(group['id']), b_msg)
59 | if pti:
60 | success += 1
61 | elif sh == "Error":
62 | failed += 1
63 | done += 1
64 | if not done % 20:
65 | await sts.edit(f"Broadcast in progress:\n\nTotal Groups {total_groups}\nCompleted: {done} / {total_groups}\nSuccess: {success}")
66 | time_taken = datetime.timedelta(seconds=int(time.time()-start_time))
67 | await sts.edit(f"Broadcast Completed:\nCompleted in {time_taken} seconds.\n\nTotal Groups {total_groups}\nCompleted: {done} / {total_groups}\nSuccess: {success}")
68 |
69 |
--------------------------------------------------------------------------------
/database/gfilters_mdb.py:
--------------------------------------------------------------------------------
1 | import pymongo
2 | from info import DATABASE_URI, DATABASE_NAME
3 | from pyrogram import enums
4 | import logging
5 | logger = logging.getLogger(__name__)
6 | logger.setLevel(logging.ERROR)
7 |
8 | myclient = pymongo.MongoClient(DATABASE_URI)
9 | mydb = myclient[DATABASE_NAME]
10 |
11 |
12 |
13 | async def add_gfilter(gfilters, text, reply_text, btn, file, alert):
14 | mycol = mydb[str(gfilters)]
15 | # mycol.create_index([('text', 'text')])
16 |
17 | data = {
18 | 'text':str(text),
19 | 'reply':str(reply_text),
20 | 'btn':str(btn),
21 | 'file':str(file),
22 | 'alert':str(alert)
23 | }
24 |
25 | try:
26 | mycol.update_one({'text': str(text)}, {"$set": data}, upsert=True)
27 | except:
28 | logger.exception('Some error occured!', exc_info=True)
29 |
30 |
31 | async def find_gfilter(gfilters, name):
32 | mycol = mydb[str(gfilters)]
33 |
34 | query = mycol.find( {"text":name})
35 | # query = mycol.find( { "$text": {"$search": name}})
36 | try:
37 | for file in query:
38 | reply_text = file['reply']
39 | btn = file['btn']
40 | fileid = file['file']
41 | try:
42 | alert = file['alert']
43 | except:
44 | alert = None
45 | return reply_text, btn, alert, fileid
46 | except:
47 | return None, None, None, None
48 |
49 |
50 | async def get_gfilters(gfilters):
51 | mycol = mydb[str(gfilters)]
52 |
53 | texts = []
54 | query = mycol.find()
55 | try:
56 | for file in query:
57 | text = file['text']
58 | texts.append(text)
59 | except:
60 | pass
61 | return texts
62 |
63 |
64 | async def delete_gfilter(message, text, gfilters):
65 | mycol = mydb[str(gfilters)]
66 |
67 | myquery = {'text':text }
68 | query = mycol.count_documents(myquery)
69 | if query == 1:
70 | mycol.delete_one(myquery)
71 | await message.reply_text(
72 | f"'`{text}`' deleted. I'll not respond to that gfilter anymore.",
73 | quote=True,
74 | parse_mode=enums.ParseMode.MARKDOWN
75 | )
76 | else:
77 | await message.reply_text("Couldn't find that gfilter!", quote=True)
78 |
79 | async def del_allg(message, gfilters):
80 | if str(gfilters) not in mydb.list_collection_names():
81 | await message.edit_text("Nothing to Remove !")
82 | return
83 |
84 | mycol = mydb[str(gfilters)]
85 | try:
86 | mycol.drop()
87 | await message.edit_text(f"All gfilters has been removed !")
88 | except:
89 | await message.edit_text("Couldn't remove all gfilters !")
90 | return
91 |
92 | async def count_gfilters(gfilters):
93 | mycol = mydb[str(gfilters)]
94 |
95 | count = mycol.count()
96 | return False if count == 0 else count
97 |
98 |
99 | async def gfilter_stats():
100 | collections = mydb.list_collection_names()
101 |
102 | if "CONNECTION" in collections:
103 | collections.remove("CONNECTION")
104 |
105 | totalcount = 0
106 | for collection in collections:
107 | mycol = mydb[collection]
108 | count = mycol.count()
109 | totalcount += count
110 |
111 | totalcollections = len(collections)
112 |
113 | return totalcollections, totalcount
114 |
--------------------------------------------------------------------------------
/database/filters_mdb.py:
--------------------------------------------------------------------------------
1 | import pymongo
2 | from info import DATABASE_URI, DATABASE_NAME
3 | from pyrogram import enums
4 | import logging
5 | logger = logging.getLogger(__name__)
6 | logger.setLevel(logging.ERROR)
7 |
8 | myclient = pymongo.MongoClient(DATABASE_URI)
9 | mydb = myclient[DATABASE_NAME]
10 |
11 |
12 |
13 | async def add_filter(grp_id, text, reply_text, btn, file, alert):
14 | mycol = mydb[str(grp_id)]
15 | # mycol.create_index([('text', 'text')])
16 |
17 | data = {
18 | 'text':str(text),
19 | 'reply':str(reply_text),
20 | 'btn':str(btn),
21 | 'file':str(file),
22 | 'alert':str(alert)
23 | }
24 |
25 | try:
26 | mycol.update_one({'text': str(text)}, {"$set": data}, upsert=True)
27 | except:
28 | logger.exception('Some error occured!', exc_info=True)
29 |
30 |
31 | async def find_filter(group_id, name):
32 | mycol = mydb[str(group_id)]
33 |
34 | query = mycol.find( {"text":name})
35 | # query = mycol.find( { "$text": {"$search": name}})
36 | try:
37 | for file in query:
38 | reply_text = file['reply']
39 | btn = file['btn']
40 | fileid = file['file']
41 | try:
42 | alert = file['alert']
43 | except:
44 | alert = None
45 | return reply_text, btn, alert, fileid
46 | except:
47 | return None, None, None, None
48 |
49 |
50 | async def get_filters(group_id):
51 | mycol = mydb[str(group_id)]
52 |
53 | texts = []
54 | query = mycol.find()
55 | try:
56 | for file in query:
57 | text = file['text']
58 | texts.append(text)
59 | except:
60 | pass
61 | return texts
62 |
63 |
64 | async def delete_filter(message, text, group_id):
65 | mycol = mydb[str(group_id)]
66 |
67 | myquery = {'text':text }
68 | query = mycol.count_documents(myquery)
69 | if query == 1:
70 | mycol.delete_one(myquery)
71 | await message.reply_text(
72 | f"'`{text}`' deleted. I'll not respond to that filter anymore.",
73 | quote=True,
74 | parse_mode=enums.ParseMode.MARKDOWN
75 | )
76 | else:
77 | await message.reply_text("Couldn't find that filter!", quote=True)
78 |
79 |
80 | async def del_all(message, group_id, title):
81 | if str(group_id) not in mydb.list_collection_names():
82 | await message.edit_text(f"Nothing to remove in {title}!")
83 | return
84 |
85 | mycol = mydb[str(group_id)]
86 | try:
87 | mycol.drop()
88 | await message.edit_text(f"All filters from {title} has been removed")
89 | except:
90 | await message.edit_text("Couldn't remove all filters from group!")
91 | return
92 |
93 |
94 | async def count_filters(group_id):
95 | mycol = mydb[str(group_id)]
96 |
97 | count = mycol.count()
98 | return False if count == 0 else count
99 |
100 |
101 | async def filter_stats():
102 | collections = mydb.list_collection_names()
103 |
104 | if "CONNECTION" in collections:
105 | collections.remove("CONNECTION")
106 |
107 | totalcount = 0
108 | for collection in collections:
109 | mycol = mydb[collection]
110 | count = mycol.count()
111 | totalcount += count
112 |
113 | totalcollections = len(collections)
114 |
115 | return totalcollections, totalcount
116 |
--------------------------------------------------------------------------------
/database/connections_mdb.py:
--------------------------------------------------------------------------------
1 | import pymongo
2 |
3 | from info import DATABASE_URI, DATABASE_NAME
4 |
5 | import logging
6 | logger = logging.getLogger(__name__)
7 | logger.setLevel(logging.ERROR)
8 |
9 | myclient = pymongo.MongoClient(DATABASE_URI)
10 | mydb = myclient[DATABASE_NAME]
11 | mycol = mydb['CONNECTION']
12 |
13 |
14 | async def add_connection(group_id, user_id):
15 | query = mycol.find_one(
16 | { "_id": user_id },
17 | { "_id": 0, "active_group": 0 }
18 | )
19 | if query is not None:
20 | group_ids = [x["group_id"] for x in query["group_details"]]
21 | if group_id in group_ids:
22 | return False
23 |
24 | group_details = {
25 | "group_id" : group_id
26 | }
27 |
28 | data = {
29 | '_id': user_id,
30 | 'group_details' : [group_details],
31 | 'active_group' : group_id,
32 | }
33 |
34 | if mycol.count_documents( {"_id": user_id} ) == 0:
35 | try:
36 | mycol.insert_one(data)
37 | return True
38 | except:
39 | logger.exception('Some error occurred!', exc_info=True)
40 |
41 | else:
42 | try:
43 | mycol.update_one(
44 | {'_id': user_id},
45 | {
46 | "$push": {"group_details": group_details},
47 | "$set": {"active_group" : group_id}
48 | }
49 | )
50 | return True
51 | except:
52 | logger.exception('Some error occurred!', exc_info=True)
53 |
54 |
55 | async def active_connection(user_id):
56 |
57 | query = mycol.find_one(
58 | { "_id": user_id },
59 | { "_id": 0, "group_details": 0 }
60 | )
61 | if not query:
62 | return None
63 |
64 | group_id = query['active_group']
65 | return int(group_id) if group_id != None else None
66 |
67 |
68 | async def all_connections(user_id):
69 | query = mycol.find_one(
70 | { "_id": user_id },
71 | { "_id": 0, "active_group": 0 }
72 | )
73 | if query is not None:
74 | return [x["group_id"] for x in query["group_details"]]
75 | else:
76 | return None
77 |
78 |
79 | async def if_active(user_id, group_id):
80 | query = mycol.find_one(
81 | { "_id": user_id },
82 | { "_id": 0, "group_details": 0 }
83 | )
84 | return query is not None and query['active_group'] == group_id
85 |
86 |
87 | async def make_active(user_id, group_id):
88 | update = mycol.update_one(
89 | {'_id': user_id},
90 | {"$set": {"active_group" : group_id}}
91 | )
92 | return update.modified_count != 0
93 |
94 |
95 | async def make_inactive(user_id):
96 | update = mycol.update_one(
97 | {'_id': user_id},
98 | {"$set": {"active_group" : None}}
99 | )
100 | return update.modified_count != 0
101 |
102 |
103 | async def delete_connection(user_id, group_id):
104 |
105 | try:
106 | update = mycol.update_one(
107 | {"_id": user_id},
108 | {"$pull" : { "group_details" : {"group_id":group_id} } }
109 | )
110 | if update.modified_count == 0:
111 | return False
112 | query = mycol.find_one(
113 | { "_id": user_id },
114 | { "_id": 0 }
115 | )
116 | if len(query["group_details"]) >= 1:
117 | if query['active_group'] == group_id:
118 | prvs_group_id = query["group_details"][len(query["group_details"]) - 1]["group_id"]
119 |
120 | mycol.update_one(
121 | {'_id': user_id},
122 | {"$set": {"active_group" : prvs_group_id}}
123 | )
124 | else:
125 | mycol.update_one(
126 | {'_id': user_id},
127 | {"$set": {"active_group" : None}}
128 | )
129 | return True
130 | except Exception as e:
131 | logger.exception(f'Some error occurred! {e}', exc_info=True)
132 | return False
133 |
134 |
135 |
--------------------------------------------------------------------------------
/bot.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import logging.config
3 |
4 | # Get logging configurations
5 | logging.config.fileConfig('logging.conf')
6 | logging.getLogger().setLevel(logging.INFO)
7 | logging.getLogger("pyrogram").setLevel(logging.ERROR)
8 | logging.getLogger("imdbpy").setLevel(logging.ERROR)
9 |
10 | from pyrogram import Client, __version__
11 | from pyrogram.raw.all import layer
12 | from database.ia_filterdb import Media
13 | from database.users_chats_db import db
14 | from info import SESSION, API_ID, API_HASH, BOT_TOKEN, LOG_STR, LOG_CHANNEL, PORT
15 | from utils import temp
16 | from typing import Union, Optional, AsyncGenerator
17 | from pyrogram import types
18 | from Script import script
19 | from datetime import date, datetime
20 | import pytz
21 | from aiohttp import web
22 | from plugins import web_server
23 |
24 | class Bot(Client):
25 |
26 | def __init__(self):
27 | super().__init__(
28 | name=SESSION,
29 | api_id=API_ID,
30 | api_hash=API_HASH,
31 | bot_token=BOT_TOKEN,
32 | workers=50,
33 | plugins={"root": "plugins"},
34 | sleep_threshold=5,
35 | )
36 |
37 | async def start(self):
38 | b_users, b_chats = await db.get_banned()
39 | temp.BANNED_USERS = b_users
40 | temp.BANNED_CHATS = b_chats
41 | await super().start()
42 | await Media.ensure_indexes()
43 | me = await self.get_me()
44 | temp.ME = me.id
45 | temp.U_NAME = me.username
46 | temp.B_NAME = me.first_name
47 | self.username = '@' + me.username
48 | logging.info(f"{me.first_name} with for Pyrogram v{__version__} (Layer {layer}) started on {me.username}.")
49 | logging.info(LOG_STR)
50 | logging.info(script.LOGO)
51 | tz = pytz.timezone('Asia/Kolkata')
52 | today = date.today()
53 | now = datetime.now(tz)
54 | time = now.strftime("%H:%M:%S %p")
55 | await self.send_message(chat_id=LOG_CHANNEL, text=script.RESTART_TXT.format(today, time))
56 | app = web.AppRunner(await web_server())
57 | await app.setup()
58 | bind_address = "0.0.0.0"
59 | await web.TCPSite(app, bind_address, PORT).start()
60 |
61 | async def stop(self, *args):
62 | await super().stop()
63 | logging.info("Bot stopped. Bye.")
64 |
65 | async def iter_messages(
66 | self,
67 | chat_id: Union[int, str],
68 | limit: int,
69 | offset: int = 0,
70 | ) -> Optional[AsyncGenerator["types.Message", None]]:
71 | """Iterate through a chat sequentially.
72 | This convenience method does the same as repeatedly calling :meth:`~pyrogram.Client.get_messages` in a loop, thus saving
73 | you from the hassle of setting up boilerplate code. It is useful for getting the whole chat messages with a
74 | single call.
75 | Parameters:
76 | chat_id (``int`` | ``str``):
77 | Unique identifier (int) or username (str) of the target chat.
78 | For your personal cloud (Saved Messages) you can simply use "me" or "self".
79 | For a contact that exists in your Telegram address book you can use his phone number (str).
80 |
81 | limit (``int``):
82 | Identifier of the last message to be returned.
83 |
84 | offset (``int``, *optional*):
85 | Identifier of the first message to be returned.
86 | Defaults to 0.
87 | Returns:
88 | ``Generator``: A generator yielding :obj:`~pyrogram.types.Message` objects.
89 | Example:
90 | .. code-block:: python
91 | for message in app.iter_messages("pyrogram", 1, 15000):
92 | print(message.text)
93 | """
94 | current = offset
95 | while True:
96 | new_diff = min(200, limit - current)
97 | if new_diff <= 0:
98 | return
99 | messages = await self.get_messages(chat_id, list(range(current, current+new_diff+1)))
100 | for message in messages:
101 | yield message
102 | current += 1
103 |
104 |
105 | app = Bot()
106 | app.run()
107 |
--------------------------------------------------------------------------------
/plugins/inline.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from pyrogram import Client, emoji, filters
3 | from pyrogram.errors.exceptions.bad_request_400 import QueryIdInvalid
4 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, InlineQueryResultCachedDocument, InlineQuery
5 | from database.ia_filterdb import get_search_results
6 | from utils import is_subscribed, get_size, temp
7 | from info import CACHE_TIME, AUTH_USERS, AUTH_CHANNEL, CUSTOM_FILE_CAPTION
8 | from database.connections_mdb import active_connection
9 |
10 | logger = logging.getLogger(__name__)
11 | cache_time = 0 if AUTH_USERS or AUTH_CHANNEL else CACHE_TIME
12 |
13 | async def inline_users(query: InlineQuery):
14 | if AUTH_USERS:
15 | if query.from_user and query.from_user.id in AUTH_USERS:
16 | return True
17 | else:
18 | return False
19 | if query.from_user and query.from_user.id not in temp.BANNED_USERS:
20 | return True
21 | return False
22 |
23 | @Client.on_inline_query()
24 | async def answer(bot, query):
25 | """Show search results for given inline query"""
26 | chat_id = await active_connection(str(query.from_user.id))
27 |
28 | if not await inline_users(query):
29 | await query.answer(results=[],
30 | cache_time=0,
31 | switch_pm_text='okDa',
32 | switch_pm_parameter="hehe")
33 | return
34 |
35 | if AUTH_CHANNEL and not await is_subscribed(bot, query):
36 | await query.answer(results=[],
37 | cache_time=0,
38 | switch_pm_text='You have to subscribe my channel to use the bot',
39 | switch_pm_parameter="subscribe")
40 | return
41 |
42 | results = []
43 | if '|' in query.query:
44 | string, file_type = query.query.split('|', maxsplit=1)
45 | string = string.strip()
46 | file_type = file_type.strip().lower()
47 | else:
48 | string = query.query.strip()
49 | file_type = None
50 |
51 | offset = int(query.offset or 0)
52 | reply_markup = get_reply_markup(query=string)
53 | files, next_offset, total = await get_search_results(
54 | chat_id,
55 | string,
56 | file_type=file_type,
57 | max_results=10,
58 | offset=offset)
59 |
60 | for file in files:
61 | title=file.file_name
62 | size=get_size(file.file_size)
63 | f_caption=file.caption
64 | if CUSTOM_FILE_CAPTION:
65 | try:
66 | f_caption=CUSTOM_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption)
67 | except Exception as e:
68 | logger.exception(e)
69 | f_caption=f_caption
70 | if f_caption is None:
71 | f_caption = f"{file.file_name}"
72 | results.append(
73 | InlineQueryResultCachedDocument(
74 | title=file.file_name,
75 | document_file_id=file.file_id,
76 | caption=f_caption,
77 | description=f'Size: {get_size(file.file_size)}\nType: {file.file_type}',
78 | reply_markup=reply_markup))
79 |
80 | if results:
81 | switch_pm_text = f"{emoji.FILE_FOLDER} Results - {total}"
82 | if string:
83 | switch_pm_text += f" for {string}"
84 | try:
85 | await query.answer(results=results,
86 | is_personal = True,
87 | cache_time=cache_time,
88 | switch_pm_text=switch_pm_text,
89 | switch_pm_parameter="start",
90 | next_offset=str(next_offset))
91 | except QueryIdInvalid:
92 | pass
93 | except Exception as e:
94 | logging.exception(str(e))
95 | else:
96 | switch_pm_text = f'{emoji.CROSS_MARK} No results'
97 | if string:
98 | switch_pm_text += f' for "{string}"'
99 |
100 | await query.answer(results=[],
101 | is_personal = True,
102 | cache_time=cache_time,
103 | switch_pm_text=switch_pm_text,
104 | switch_pm_parameter="okay")
105 |
106 |
107 | def get_reply_markup(query):
108 | buttons = [
109 | [
110 | InlineKeyboardButton('Search again', switch_inline_query_current_chat=query)
111 | ]
112 | ]
113 | return InlineKeyboardMarkup(buttons)
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/plugins/gfilters.py:
--------------------------------------------------------------------------------
1 | import io
2 | from pyrogram import filters, Client, enums
3 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
4 | from database.gfilters_mdb import(
5 | add_gfilter,
6 | get_gfilters,
7 | delete_gfilter,
8 | count_gfilters
9 | )
10 |
11 | from database.connections_mdb import active_connection
12 | from utils import get_file_id, gfilterparser, split_quotes
13 | from info import ADMINS
14 |
15 |
16 | @Client.on_message(filters.command(['gfilter', 'addg']) & filters.incoming & filters.user(ADMINS))
17 | async def addgfilter(client, message):
18 | args = message.text.html.split(None, 1)
19 |
20 | if len(args) < 2:
21 | await message.reply_text("Command Incomplete :(", quote=True)
22 | return
23 |
24 | extracted = split_quotes(args[1])
25 | text = extracted[0].lower()
26 |
27 | if not message.reply_to_message and len(extracted) < 2:
28 | await message.reply_text("Add some content to save your filter!", quote=True)
29 | return
30 |
31 | if (len(extracted) >= 2) and not message.reply_to_message:
32 | reply_text, btn, alert = gfilterparser(extracted[1], text)
33 | fileid = None
34 | if not reply_text:
35 | await message.reply_text("You cannot have buttons alone, give some text to go with it!", quote=True)
36 | return
37 |
38 | elif message.reply_to_message and message.reply_to_message.reply_markup:
39 | try:
40 | rm = message.reply_to_message.reply_markup
41 | btn = rm.inline_keyboard
42 | msg = get_file_id(message.reply_to_message)
43 | if msg:
44 | fileid = msg.file_id
45 | reply_text = message.reply_to_message.caption.html
46 | else:
47 | reply_text = message.reply_to_message.text.html
48 | fileid = None
49 | alert = None
50 | except:
51 | reply_text = ""
52 | btn = "[]"
53 | fileid = None
54 | alert = None
55 |
56 | elif message.reply_to_message and message.reply_to_message.media:
57 | try:
58 | msg = get_file_id(message.reply_to_message)
59 | fileid = msg.file_id if msg else None
60 | reply_text, btn, alert = gfilterparser(extracted[1], text) if message.reply_to_message.sticker else gfilterparser(message.reply_to_message.caption.html, text)
61 | except:
62 | reply_text = ""
63 | btn = "[]"
64 | alert = None
65 | elif message.reply_to_message and message.reply_to_message.text:
66 | try:
67 | fileid = None
68 | reply_text, btn, alert = gfilterparser(message.reply_to_message.text.html, text)
69 | except:
70 | reply_text = ""
71 | btn = "[]"
72 | alert = None
73 | else:
74 | return
75 |
76 | await add_gfilter('gfilters', text, reply_text, btn, fileid, alert)
77 |
78 | await message.reply_text(
79 | f"GFilter for `{text}` added",
80 | quote=True,
81 | parse_mode=enums.ParseMode.MARKDOWN
82 | )
83 |
84 |
85 | @Client.on_message(filters.command(['viewgfilters', 'gfilters']) & filters.incoming & filters.user(ADMINS))
86 | async def get_all_gfilters(client, message):
87 | texts = await get_gfilters('gfilters')
88 | count = await count_gfilters('gfilters')
89 | if count:
90 | gfilterlist = f"Total number of gfilters : {count}\n\n"
91 |
92 | for text in texts:
93 | keywords = " × `{}`\n".format(text)
94 |
95 | gfilterlist += keywords
96 |
97 | if len(gfilterlist) > 4096:
98 | with io.BytesIO(str.encode(gfilterlist.replace("`", ""))) as keyword_file:
99 | keyword_file.name = "keywords.txt"
100 | await message.reply_document(
101 | document=keyword_file,
102 | quote=True
103 | )
104 | return
105 | else:
106 | gfilterlist = f"There are no active gfilters."
107 |
108 | await message.reply_text(
109 | text=gfilterlist,
110 | quote=True,
111 | parse_mode=enums.ParseMode.MARKDOWN
112 | )
113 |
114 | @Client.on_message(filters.command('delg') & filters.incoming & filters.user(ADMINS))
115 | async def deletegfilter(client, message):
116 | try:
117 | cmd, text = message.text.split(" ", 1)
118 | except:
119 | await message.reply_text(
120 | "Mention the gfiltername which you wanna delete!\n\n"
121 | "/delg gfiltername\n\n"
122 | "Use /viewgfilters to view all available gfilters",
123 | quote=True
124 | )
125 | return
126 |
127 | query = text.lower()
128 |
129 | await delete_gfilter(message, query, 'gfilters')
130 |
131 | @Client.on_message(filters.command('delallg') & filters.user(ADMINS))
132 | async def delallgfilters(client, message):
133 | await message.reply_text(
134 | f"Do you want to continue??",
135 | reply_markup=InlineKeyboardMarkup([
136 | [InlineKeyboardButton(text="YES",callback_data="gfiltersdeleteallconfirm")],
137 | [InlineKeyboardButton(text="CANCEL",callback_data="gfiltersdeleteallcancel")]
138 | ]),
139 | quote=True
140 | )
141 |
--------------------------------------------------------------------------------
/database/users_chats_db.py:
--------------------------------------------------------------------------------
1 | # https://github.com/odysseusmax/animated-lamp/blob/master/bot/database/database.py
2 | import motor.motor_asyncio
3 | from info import DATABASE_NAME, DATABASE_URI, IMDB, IMDB_TEMPLATE, MELCOW_NEW_USERS, P_TTI_SHOW_OFF, SINGLE_BUTTON, SPELL_CHECK_REPLY, PROTECT_CONTENT, AUTO_DELETE, MAX_BTN, AUTO_FFILTER, SHORTLINK_API, SHORTLINK_URL, IS_SHORTLINK, TUTORIAL, IS_TUTORIAL
4 |
5 | class Database:
6 |
7 | def __init__(self, uri, database_name):
8 | self._client = motor.motor_asyncio.AsyncIOMotorClient(uri)
9 | self.db = self._client[database_name]
10 | self.col = self.db.users
11 | self.grp = self.db.groups
12 |
13 |
14 | def new_user(self, id, name):
15 | return dict(
16 | id = id,
17 | name = name,
18 | ban_status=dict(
19 | is_banned=False,
20 | ban_reason="",
21 | ),
22 | )
23 |
24 |
25 | def new_group(self, id, title):
26 | return dict(
27 | id = id,
28 | title = title,
29 | chat_status=dict(
30 | is_disabled=False,
31 | reason="",
32 | ),
33 | )
34 |
35 | async def add_user(self, id, name):
36 | user = self.new_user(id, name)
37 | await self.col.insert_one(user)
38 |
39 | async def is_user_exist(self, id):
40 | user = await self.col.find_one({'id':int(id)})
41 | return bool(user)
42 |
43 | async def total_users_count(self):
44 | count = await self.col.count_documents({})
45 | return count
46 |
47 | async def remove_ban(self, id):
48 | ban_status = dict(
49 | is_banned=False,
50 | ban_reason=''
51 | )
52 | await self.col.update_one({'id': id}, {'$set': {'ban_status': ban_status}})
53 |
54 | async def ban_user(self, user_id, ban_reason="No Reason"):
55 | ban_status = dict(
56 | is_banned=True,
57 | ban_reason=ban_reason
58 | )
59 | await self.col.update_one({'id': user_id}, {'$set': {'ban_status': ban_status}})
60 |
61 | async def get_ban_status(self, id):
62 | default = dict(
63 | is_banned=False,
64 | ban_reason=''
65 | )
66 | user = await self.col.find_one({'id':int(id)})
67 | if not user:
68 | return default
69 | return user.get('ban_status', default)
70 |
71 | async def get_all_users(self):
72 | return self.col.find({})
73 |
74 |
75 | async def delete_user(self, user_id):
76 | await self.col.delete_many({'id': int(user_id)})
77 |
78 |
79 | async def get_banned(self):
80 | users = self.col.find({'ban_status.is_banned': True})
81 | chats = self.grp.find({'chat_status.is_disabled': True})
82 | b_chats = [chat['id'] async for chat in chats]
83 | b_users = [user['id'] async for user in users]
84 | return b_users, b_chats
85 |
86 |
87 |
88 | async def add_chat(self, chat, title):
89 | chat = self.new_group(chat, title)
90 | await self.grp.insert_one(chat)
91 |
92 |
93 | async def get_chat(self, chat):
94 | chat = await self.grp.find_one({'id':int(chat)})
95 | return False if not chat else chat.get('chat_status')
96 |
97 |
98 | async def re_enable_chat(self, id):
99 | chat_status=dict(
100 | is_disabled=False,
101 | reason="",
102 | )
103 | await self.grp.update_one({'id': int(id)}, {'$set': {'chat_status': chat_status}})
104 |
105 | async def update_settings(self, id, settings):
106 | await self.grp.update_one({'id': int(id)}, {'$set': {'settings': settings}})
107 |
108 |
109 | async def get_settings(self, id):
110 | default = {
111 | 'button': SINGLE_BUTTON,
112 | 'botpm': P_TTI_SHOW_OFF,
113 | 'file_secure': PROTECT_CONTENT,
114 | 'imdb': IMDB,
115 | 'spell_check': SPELL_CHECK_REPLY,
116 | 'welcome': MELCOW_NEW_USERS,
117 | 'auto_delete': AUTO_DELETE,
118 | 'auto_ffilter': AUTO_FFILTER,
119 | 'max_btn': MAX_BTN,
120 | 'template': IMDB_TEMPLATE,
121 | 'shortlink': SHORTLINK_URL,
122 | 'shortlink_api': SHORTLINK_API,
123 | 'is_shortlink': IS_SHORTLINK,
124 | 'tutorial': TUTORIAL,
125 | 'is_tutorial': IS_TUTORIAL
126 | }
127 | chat = await self.grp.find_one({'id':int(id)})
128 | if chat:
129 | return chat.get('settings', default)
130 | return default
131 |
132 |
133 | async def disable_chat(self, chat, reason="No Reason"):
134 | chat_status=dict(
135 | is_disabled=True,
136 | reason=reason,
137 | )
138 | await self.grp.update_one({'id': int(chat)}, {'$set': {'chat_status': chat_status}})
139 |
140 |
141 | async def total_chat_count(self):
142 | count = await self.grp.count_documents({})
143 | return count
144 |
145 |
146 | async def get_all_chats(self):
147 | return self.grp.find({})
148 |
149 |
150 | async def get_db_size(self):
151 | return (await self.db.command("dbstats"))['dataSize']
152 |
153 |
154 | db = Database(DATABASE_URI, DATABASE_NAME)
155 |
--------------------------------------------------------------------------------
/plugins/genlink.py:
--------------------------------------------------------------------------------
1 | import re
2 | from pyrogram import filters, Client, enums
3 | from pyrogram.errors.exceptions.bad_request_400 import ChannelInvalid, UsernameInvalid, UsernameNotModified
4 | from info import ADMINS, LOG_CHANNEL, FILE_STORE_CHANNEL, PUBLIC_FILE_STORE
5 | from database.ia_filterdb import unpack_new_file_id
6 | from utils import temp
7 | import re
8 | import os
9 | import json
10 | import base64
11 | import logging
12 |
13 | logger = logging.getLogger(__name__)
14 | logger.setLevel(logging.INFO)
15 |
16 | async def allowed(_, __, message):
17 | if PUBLIC_FILE_STORE:
18 | return True
19 | if message.from_user and message.from_user.id in ADMINS:
20 | return True
21 | return False
22 |
23 | @Client.on_message(filters.command(['link', 'plink']) & filters.create(allowed))
24 | async def gen_link_s(bot, message):
25 | replied = message.reply_to_message
26 | if not replied:
27 | return await message.reply('Reply to a message to get a shareable link.')
28 | file_type = replied.media
29 | if file_type not in [enums.MessageMediaType.VIDEO, enums.MessageMediaType.AUDIO, enums.MessageMediaType.DOCUMENT]:
30 | return await message.reply("Reply to a supported media")
31 | if message.has_protected_content and message.chat.id not in ADMINS:
32 | return await message.reply("okDa")
33 | file_id, ref = unpack_new_file_id((getattr(replied, file_type.value)).file_id)
34 | string = 'filep_' if message.text.lower().strip() == "/plink" else 'file_'
35 | string += file_id
36 | outstr = base64.urlsafe_b64encode(string.encode("ascii")).decode().strip("=")
37 | await message.reply(f"Here is your Link:\nhttps://t.me/{temp.U_NAME}?start={outstr}")
38 |
39 |
40 | @Client.on_message(filters.command(['batch', 'pbatch']) & filters.create(allowed))
41 | async def gen_link_batch(bot, message):
42 | if " " not in message.text:
43 | return await message.reply("Use correct format.\nExample /batch https://t.me/TeamEvamaria/10 https://t.me/TeamEvamaria/20.")
44 | links = message.text.strip().split(" ")
45 | if len(links) != 3:
46 | return await message.reply("Use correct format.\nExample /batch https://t.me/TeamEvamaria/10 https://t.me/TeamEvamaria/20.")
47 | cmd, first, last = links
48 | regex = re.compile("(https://)?(t\.me/|telegram\.me/|telegram\.dog/)(c/)?(\d+|[a-zA-Z_0-9]+)/(\d+)$")
49 | match = regex.match(first)
50 | if not match:
51 | return await message.reply('Invalid link')
52 | f_chat_id = match.group(4)
53 | f_msg_id = int(match.group(5))
54 | if f_chat_id.isnumeric():
55 | f_chat_id = int(("-100" + f_chat_id))
56 |
57 | match = regex.match(last)
58 | if not match:
59 | return await message.reply('Invalid link')
60 | l_chat_id = match.group(4)
61 | l_msg_id = int(match.group(5))
62 | if l_chat_id.isnumeric():
63 | l_chat_id = int(("-100" + l_chat_id))
64 |
65 | if f_chat_id != l_chat_id:
66 | return await message.reply("Chat ids not matched.")
67 | try:
68 | chat_id = (await bot.get_chat(f_chat_id)).id
69 | except ChannelInvalid:
70 | return await message.reply('This may be a private channel / group. Make me an admin over there to index the files.')
71 | except (UsernameInvalid, UsernameNotModified):
72 | return await message.reply('Invalid Link specified.')
73 | except Exception as e:
74 | return await message.reply(f'Errors - {e}')
75 |
76 | sts = await message.reply("Generating link for your message.\nThis may take time depending upon number of messages")
77 | if chat_id in FILE_STORE_CHANNEL:
78 | string = f"{f_msg_id}_{l_msg_id}_{chat_id}_{cmd.lower().strip()}"
79 | b_64 = base64.urlsafe_b64encode(string.encode("ascii")).decode().strip("=")
80 | return await sts.edit(f"Here is your link https://t.me/{temp.U_NAME}?start=DSTORE-{b_64}")
81 |
82 | FRMT = "Generating Link...\nTotal Messages: `{total}`\nDone: `{current}`\nRemaining: `{rem}`\nStatus: `{sts}`"
83 |
84 | outlist = []
85 |
86 | # file store without db channel
87 | og_msg = 0
88 | tot = 0
89 | async for msg in bot.iter_messages(f_chat_id, l_msg_id, f_msg_id):
90 | tot += 1
91 | if msg.empty or msg.service:
92 | continue
93 | if not msg.media:
94 | # only media messages supported.
95 | continue
96 | try:
97 | file_type = msg.media
98 | file = getattr(msg, file_type.value)
99 | caption = getattr(msg, 'caption', '')
100 | if caption:
101 | caption = caption.html
102 | if file:
103 | file = {
104 | "file_id": file.file_id,
105 | "caption": caption,
106 | "title": getattr(file, "file_name", ""),
107 | "size": file.file_size,
108 | "protect": cmd.lower().strip() == "/pbatch",
109 | }
110 |
111 | og_msg +=1
112 | outlist.append(file)
113 | except:
114 | pass
115 | if not og_msg % 20:
116 | try:
117 | await sts.edit(FRMT.format(total=l_msg_id-f_msg_id, current=tot, rem=((l_msg_id-f_msg_id) - tot), sts="Saving Messages"))
118 | except:
119 | pass
120 | with open(f"batchmode_{message.from_user.id}.json", "w+") as out:
121 | json.dump(outlist, out)
122 | post = await bot.send_document(LOG_CHANNEL, f"batchmode_{message.from_user.id}.json", file_name="Batch.json", caption="⚠️Generated for filestore.")
123 | os.remove(f"batchmode_{message.from_user.id}.json")
124 | file_id, ref = unpack_new_file_id(post.document.file_id)
125 | await sts.edit(f"Here is your link\nContains `{og_msg}` files.\n https://t.me/{temp.U_NAME}?start=BATCH-{file_id}")
126 |
--------------------------------------------------------------------------------
/plugins/connection.py:
--------------------------------------------------------------------------------
1 | from pyrogram import filters, Client, enums
2 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
3 | from database.connections_mdb import add_connection, all_connections, if_active, delete_connection
4 | from info import ADMINS
5 | import logging
6 |
7 | logger = logging.getLogger(__name__)
8 | logger.setLevel(logging.ERROR)
9 |
10 |
11 | @Client.on_message((filters.private | filters.group) & filters.command('connect'))
12 | async def addconnection(client, message):
13 | userid = message.from_user.id if message.from_user else None
14 | if not userid:
15 | return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
16 | chat_type = message.chat.type
17 |
18 | if chat_type == enums.ChatType.PRIVATE:
19 | try:
20 | cmd, group_id = message.text.split(" ", 1)
21 | except:
22 | await message.reply_text(
23 | "Enter in correct format!\n\n"
24 | "/connect groupid\n\n"
25 | "Get your Group id by adding this bot to your group and use /id",
26 | quote=True
27 | )
28 | return
29 |
30 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
31 | group_id = message.chat.id
32 |
33 | try:
34 | st = await client.get_chat_member(group_id, userid)
35 | if (
36 | st.status != enums.ChatMemberStatus.ADMINISTRATOR
37 | and st.status != enums.ChatMemberStatus.OWNER
38 | and userid not in ADMINS
39 | ):
40 | await message.reply_text("You should be an admin in Given group!", quote=True)
41 | return
42 | except Exception as e:
43 | logger.exception(e)
44 | await message.reply_text(
45 | "Invalid Group ID!\n\nIf correct, Make sure I'm present in your group!!",
46 | quote=True,
47 | )
48 |
49 | return
50 | try:
51 | st = await client.get_chat_member(group_id, "me")
52 | if st.status == enums.ChatMemberStatus.ADMINISTRATOR:
53 | ttl = await client.get_chat(group_id)
54 | title = ttl.title
55 |
56 | addcon = await add_connection(str(group_id), str(userid))
57 | if addcon:
58 | await message.reply_text(
59 | f"Successfully connected to **{title}**\nNow manage your group from my pm !",
60 | quote=True,
61 | parse_mode=enums.ParseMode.MARKDOWN
62 | )
63 | if chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
64 | await client.send_message(
65 | userid,
66 | f"Connected to **{title}** !",
67 | parse_mode=enums.ParseMode.MARKDOWN
68 | )
69 | else:
70 | await message.reply_text(
71 | "You're already connected to this chat!",
72 | quote=True
73 | )
74 | else:
75 | await message.reply_text("Add me as an admin in group", quote=True)
76 | except Exception as e:
77 | logger.exception(e)
78 | await message.reply_text('Some error occurred! Try again later.', quote=True)
79 | return
80 |
81 |
82 | @Client.on_message((filters.private | filters.group) & filters.command('disconnect'))
83 | async def deleteconnection(client, message):
84 | userid = message.from_user.id if message.from_user else None
85 | if not userid:
86 | return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
87 | chat_type = message.chat.type
88 |
89 | if chat_type == enums.ChatType.PRIVATE:
90 | await message.reply_text("Run /connections to view or disconnect from groups!", quote=True)
91 |
92 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
93 | group_id = message.chat.id
94 |
95 | st = await client.get_chat_member(group_id, userid)
96 | if (
97 | st.status != enums.ChatMemberStatus.ADMINISTRATOR
98 | and st.status != enums.ChatMemberStatus.OWNER
99 | and str(userid) not in ADMINS
100 | ):
101 | return
102 |
103 | delcon = await delete_connection(str(userid), str(group_id))
104 | if delcon:
105 | await message.reply_text("Successfully disconnected from this chat", quote=True)
106 | else:
107 | await message.reply_text("This chat isn't connected to me!\nDo /connect to connect.", quote=True)
108 |
109 |
110 | @Client.on_message(filters.private & filters.command(["connections"]))
111 | async def connections(client, message):
112 | userid = message.from_user.id
113 |
114 | groupids = await all_connections(str(userid))
115 | if groupids is None:
116 | await message.reply_text(
117 | "There are no active connections!! Connect to some groups first.",
118 | quote=True
119 | )
120 | return
121 | buttons = []
122 | for groupid in groupids:
123 | try:
124 | ttl = await client.get_chat(int(groupid))
125 | title = ttl.title
126 | active = await if_active(str(userid), str(groupid))
127 | act = " - ACTIVE" if active else ""
128 | buttons.append(
129 | [
130 | InlineKeyboardButton(
131 | text=f"{title}{act}", callback_data=f"groupcb:{groupid}:{act}"
132 | )
133 | ]
134 | )
135 | except:
136 | pass
137 | if buttons:
138 | await message.reply_text(
139 | "Your connected group details ;\n\n",
140 | reply_markup=InlineKeyboardMarkup(buttons),
141 | quote=True
142 | )
143 | else:
144 | await message.reply_text(
145 | "There are no active connections!! Connect to some groups first.",
146 | quote=True
147 | )
148 |
--------------------------------------------------------------------------------
/database/ia_filterdb.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from struct import pack
3 | import re
4 | import base64
5 | from pyrogram.file_id import FileId
6 | from pymongo.errors import DuplicateKeyError
7 | from umongo import Instance, Document, fields
8 | from motor.motor_asyncio import AsyncIOMotorClient
9 | from marshmallow.exceptions import ValidationError
10 | from info import DATABASE_URI, DATABASE_NAME, COLLECTION_NAME, USE_CAPTION_FILTER, MAX_B_TN
11 | from utils import get_settings, save_group_settings
12 |
13 | logger = logging.getLogger(__name__)
14 | logger.setLevel(logging.INFO)
15 |
16 |
17 | client = AsyncIOMotorClient(DATABASE_URI)
18 | db = client[DATABASE_NAME]
19 | instance = Instance.from_db(db)
20 |
21 | @instance.register
22 | class Media(Document):
23 | file_id = fields.StrField(attribute='_id')
24 | file_ref = fields.StrField(allow_none=True)
25 | file_name = fields.StrField(required=True)
26 | file_size = fields.IntField(required=True)
27 | file_type = fields.StrField(allow_none=True)
28 | mime_type = fields.StrField(allow_none=True)
29 | caption = fields.StrField(allow_none=True)
30 |
31 | class Meta:
32 | indexes = ('$file_name', )
33 | collection_name = COLLECTION_NAME
34 |
35 |
36 | async def save_file(media):
37 | """Save file in database"""
38 |
39 | # TODO: Find better way to get same file_id for same media to avoid duplicates
40 | file_id, file_ref = unpack_new_file_id(media.file_id)
41 | file_name = re.sub(r"(_|\-|\.|\+)", " ", str(media.file_name))
42 | try:
43 | file = Media(
44 | file_id=file_id,
45 | file_ref=file_ref,
46 | file_name=file_name,
47 | file_size=media.file_size,
48 | file_type=media.file_type,
49 | mime_type=media.mime_type,
50 | caption=media.caption.html if media.caption else None,
51 | )
52 | except ValidationError:
53 | logger.exception('Error occurred while saving file in database')
54 | return False, 2
55 | else:
56 | try:
57 | await file.commit()
58 | except DuplicateKeyError:
59 | logger.warning(
60 | f'{getattr(media, "file_name", "NO_FILE")} is already saved in database'
61 | )
62 |
63 | return False, 0
64 | else:
65 | logger.info(f'{getattr(media, "file_name", "NO_FILE")} is saved to database')
66 | return True, 1
67 |
68 |
69 |
70 | async def get_search_results(chat_id, query, file_type=None, max_results=10, offset=0, filter=False):
71 | """For given query return (results, next_offset)"""
72 | if chat_id is not None:
73 | settings = await get_settings(int(chat_id))
74 | try:
75 | if settings['max_btn']:
76 | max_results = 10
77 | else:
78 | max_results = int(MAX_B_TN)
79 | except KeyError:
80 | await save_group_settings(int(chat_id), 'max_btn', False)
81 | settings = await get_settings(int(chat_id))
82 | if settings['max_btn']:
83 | max_results = 10
84 | else:
85 | max_results = int(MAX_B_TN)
86 | query = query.strip()
87 | #if filter:
88 | #better ?
89 | #query = query.replace(' ', r'(\s|\.|\+|\-|_)')
90 | #raw_pattern = r'(\s|_|\-|\.|\+)' + query + r'(\s|_|\-|\.|\+)'
91 | if not query:
92 | raw_pattern = '.'
93 | elif ' ' not in query:
94 | raw_pattern = r'(\b|[\.\+\-_])' + query + r'(\b|[\.\+\-_])'
95 | else:
96 | raw_pattern = query.replace(' ', r'.*[\s\.\+\-_]')
97 |
98 | try:
99 | regex = re.compile(raw_pattern, flags=re.IGNORECASE)
100 | except:
101 | return []
102 |
103 | if USE_CAPTION_FILTER:
104 | filter = {'$or': [{'file_name': regex}, {'caption': regex}]}
105 | else:
106 | filter = {'file_name': regex}
107 |
108 | if file_type:
109 | filter['file_type'] = file_type
110 |
111 | total_results = await Media.count_documents(filter)
112 | next_offset = offset + max_results
113 |
114 | if next_offset > total_results:
115 | next_offset = ''
116 |
117 | cursor = Media.find(filter)
118 | # Sort by recent
119 | cursor.sort('$natural', -1)
120 | # Slice files according to offset and max results
121 | cursor.skip(offset).limit(max_results)
122 | # Get list of files
123 | files = await cursor.to_list(length=max_results)
124 |
125 | return files, next_offset, total_results
126 |
127 | async def get_bad_files(query, file_type=None, filter=False):
128 | """For given query return (results, next_offset)"""
129 | query = query.strip()
130 | #if filter:
131 | #better ?
132 | #query = query.replace(' ', r'(\s|\.|\+|\-|_)')
133 | #raw_pattern = r'(\s|_|\-|\.|\+)' + query + r'(\s|_|\-|\.|\+)'
134 | if not query:
135 | raw_pattern = '.'
136 | elif ' ' not in query:
137 | raw_pattern = r'(\b|[\.\+\-_])' + query + r'(\b|[\.\+\-_])'
138 | else:
139 | raw_pattern = query.replace(' ', r'.*[\s\.\+\-_]')
140 |
141 | try:
142 | regex = re.compile(raw_pattern, flags=re.IGNORECASE)
143 | except:
144 | return []
145 |
146 | if USE_CAPTION_FILTER:
147 | filter = {'$or': [{'file_name': regex}, {'caption': regex}]}
148 | else:
149 | filter = {'file_name': regex}
150 |
151 | if file_type:
152 | filter['file_type'] = file_type
153 |
154 | total_results = await Media.count_documents(filter)
155 |
156 | cursor = Media.find(filter)
157 | # Sort by recent
158 | cursor.sort('$natural', -1)
159 | # Get list of files
160 | files = await cursor.to_list(length=total_results)
161 |
162 | return files, total_results
163 |
164 | async def get_file_details(query):
165 | filter = {'file_id': query}
166 | cursor = Media.find(filter)
167 | filedetails = await cursor.to_list(length=1)
168 | return filedetails
169 |
170 |
171 | def encode_file_id(s: bytes) -> str:
172 | r = b""
173 | n = 0
174 |
175 | for i in s + bytes([22]) + bytes([4]):
176 | if i == 0:
177 | n += 1
178 | else:
179 | if n:
180 | r += b"\x00" + bytes([n])
181 | n = 0
182 |
183 | r += bytes([i])
184 |
185 | return base64.urlsafe_b64encode(r).decode().rstrip("=")
186 |
187 |
188 | def encode_file_ref(file_ref: bytes) -> str:
189 | return base64.urlsafe_b64encode(file_ref).decode().rstrip("=")
190 |
191 |
192 | def unpack_new_file_id(new_file_id):
193 | """Return file_id, file_ref"""
194 | decoded = FileId.decode(new_file_id)
195 | file_id = encode_file_id(
196 | pack(
197 | "➲ First Name: {first}\n➲ Last Name: {last}\n➲ Username: {username}\n➲ Telegram ID: {user_id}\n➲ Data Centre: {dc_id}",
24 | quote=True
25 | )
26 |
27 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
28 | _id = ""
29 | _id += (
30 | "➲ Chat ID: "
31 | f"{message.chat.id}\n"
32 | )
33 | if message.reply_to_message:
34 | _id += (
35 | "➲ User ID: "
36 | f"{message.from_user.id if message.from_user else 'Anonymous'}\n"
37 | "➲ Replied User ID: "
38 | f"{message.reply_to_message.from_user.id if message.reply_to_message.from_user else 'Anonymous'}\n"
39 | )
40 | file_info = get_file_id(message.reply_to_message)
41 | else:
42 | _id += (
43 | "➲ User ID: "
44 | f"{message.from_user.id if message.from_user else 'Anonymous'}\n"
45 | )
46 | file_info = get_file_id(message)
47 | if file_info:
48 | _id += (
49 | f"{file_info.message_type}: "
50 | f"{file_info.file_id}\n"
51 | )
52 | await message.reply_text(
53 | _id,
54 | quote=True
55 | )
56 |
57 | @Client.on_message(filters.command(["info"]))
58 | async def who_is(client, message):
59 | # https://github.com/SpEcHiDe/PyroGramBot/blob/master/pyrobot/plugins/admemes/whois.py#L19
60 | status_message = await message.reply_text(
61 | "`Fetching user info...`"
62 | )
63 | await status_message.edit(
64 | "`Processing user info...`"
65 | )
66 | from_user = None
67 | from_user_id, _ = extract_user(message)
68 | try:
69 | from_user = await client.get_users(from_user_id)
70 | except Exception as error:
71 | await status_message.edit(str(error))
72 | return
73 | if from_user is None:
74 | return await status_message.edit("no valid user_id / message specified")
75 | message_out_str = ""
76 | message_out_str += f"➲First Name: {from_user.first_name}\n"
77 | last_name = from_user.last_name or "None"
78 | message_out_str += f"➲Last Name: {last_name}\n"
79 | message_out_str += f"➲Telegram ID: {from_user.id}\n"
80 | username = from_user.username or "None"
81 | dc_id = from_user.dc_id or "[User Doesn't Have A Valid DP]"
82 | message_out_str += f"➲Data Centre: {dc_id}\n"
83 | message_out_str += f"➲User Name: @{username}\n"
84 | message_out_str += f"➲User 𝖫𝗂𝗇𝗄: Click Here\n"
85 | if message.chat.type in ((enums.ChatType.SUPERGROUP, enums.ChatType.CHANNEL)):
86 | try:
87 | chat_member_p = await message.chat.get_member(from_user.id)
88 | joined_date = (
89 | chat_member_p.joined_date or datetime.now()
90 | ).strftime("%Y.%m.%d %H:%M:%S")
91 | message_out_str += (
92 | "➲Joined this Chat on: "
93 | f"{joined_date}"
94 | "\n"
95 | )
96 | except UserNotParticipant:
97 | pass
98 | chat_photo = from_user.photo
99 | if chat_photo:
100 | local_user_photo = await client.download_media(
101 | message=chat_photo.big_file_id
102 | )
103 | buttons = [[
104 | InlineKeyboardButton('🔐 Close', callback_data='close_data')
105 | ]]
106 | reply_markup = InlineKeyboardMarkup(buttons)
107 | await message.reply_photo(
108 | photo=local_user_photo,
109 | quote=True,
110 | reply_markup=reply_markup,
111 | caption=message_out_str,
112 | parse_mode=enums.ParseMode.HTML,
113 | disable_notification=True
114 | )
115 | os.remove(local_user_photo)
116 | else:
117 | buttons = [[
118 | InlineKeyboardButton('🔐 Close', callback_data='close_data')
119 | ]]
120 | reply_markup = InlineKeyboardMarkup(buttons)
121 | await message.reply_text(
122 | text=message_out_str,
123 | reply_markup=reply_markup,
124 | quote=True,
125 | parse_mode=enums.ParseMode.HTML,
126 | disable_notification=True
127 | )
128 | await status_message.delete()
129 |
130 | @Client.on_message(filters.command(["imdb", 'search']))
131 | async def imdb_search(client, message):
132 | if ' ' in message.text:
133 | k = await message.reply('Searching ImDB')
134 | r, title = message.text.split(None, 1)
135 | movies = await get_poster(title, bulk=True)
136 | if not movies:
137 | return await message.reply("No results Found")
138 | btn = [
139 | [
140 | InlineKeyboardButton(
141 | text=f"{movie.get('title')} - {movie.get('year')}",
142 | callback_data=f"imdb#{movie.movieID}",
143 | )
144 | ]
145 | for movie in movies
146 | ]
147 | await k.edit('Here is what i found on IMDb', reply_markup=InlineKeyboardMarkup(btn))
148 | else:
149 | await message.reply('Give me a movie / series Name')
150 |
151 | @Client.on_callback_query(filters.regex('^imdb'))
152 | async def imdb_callback(bot: Client, quer_y: CallbackQuery):
153 | i, movie = quer_y.data.split('#')
154 | imdb = await get_poster(query=movie, id=True)
155 | btn = [
156 | [
157 | InlineKeyboardButton(
158 | text=f"{imdb.get('title')}",
159 | url=imdb['url'],
160 | )
161 | ]
162 | ]
163 | message = quer_y.message.reply_to_message or quer_y.message
164 | if imdb:
165 | caption = IMDB_TEMPLATE.format(
166 | query = imdb['title'],
167 | title = imdb['title'],
168 | votes = imdb['votes'],
169 | aka = imdb["aka"],
170 | seasons = imdb["seasons"],
171 | box_office = imdb['box_office'],
172 | localized_title = imdb['localized_title'],
173 | kind = imdb['kind'],
174 | imdb_id = imdb["imdb_id"],
175 | cast = imdb["cast"],
176 | runtime = imdb["runtime"],
177 | countries = imdb["countries"],
178 | certificates = imdb["certificates"],
179 | languages = imdb["languages"],
180 | director = imdb["director"],
181 | writer = imdb["writer"],
182 | producer = imdb["producer"],
183 | composer = imdb["composer"],
184 | cinematographer = imdb["cinematographer"],
185 | music_team = imdb["music_team"],
186 | distributors = imdb["distributors"],
187 | release_date = imdb['release_date'],
188 | year = imdb['year'],
189 | genres = imdb['genres'],
190 | poster = imdb['poster'],
191 | plot = imdb['plot'],
192 | rating = imdb['rating'],
193 | url = imdb['url'],
194 | **locals()
195 | )
196 | else:
197 | caption = "No Results"
198 | if imdb.get('poster'):
199 | try:
200 | await quer_y.message.reply_photo(photo=imdb['poster'], caption=caption, reply_markup=InlineKeyboardMarkup(btn))
201 | except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty):
202 | pic = imdb.get('poster')
203 | poster = pic.replace('.jpg', "._V1_UX360.jpg")
204 | await quer_y.message.reply_photo(photo=poster, caption=caption, reply_markup=InlineKeyboardMarkup(btn))
205 | except Exception as e:
206 | logger.exception(e)
207 | await quer_y.message.reply(caption, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=False)
208 | await quer_y.message.delete()
209 | else:
210 | await quer_y.message.edit(caption, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=False)
211 | await quer_y.answer()
212 |
213 |
214 |
215 |
--------------------------------------------------------------------------------
/plugins/index.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import asyncio
3 | from pyrogram import Client, filters, enums
4 | from pyrogram.errors import FloodWait
5 | from pyrogram.errors.exceptions.bad_request_400 import ChannelInvalid, ChatAdminRequired, UsernameInvalid, UsernameNotModified
6 | from info import ADMINS
7 | from info import INDEX_REQ_CHANNEL as LOG_CHANNEL
8 | from database.ia_filterdb import save_file
9 | from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
10 | from utils import temp
11 | import re
12 | logger = logging.getLogger(__name__)
13 | logger.setLevel(logging.INFO)
14 | lock = asyncio.Lock()
15 |
16 |
17 | @Client.on_callback_query(filters.regex(r'^index'))
18 | async def index_files(bot, query):
19 | if query.data.startswith('index_cancel'):
20 | temp.CANCEL = True
21 | return await query.answer("Cancelling Indexing")
22 | _, raju, chat, lst_msg_id, from_user = query.data.split("#")
23 | if raju == 'reject':
24 | await query.message.delete()
25 | await bot.send_message(int(from_user),
26 | f'Your Submission for indexing {chat} has been decliened by our moderators.',
27 | reply_to_message_id=int(lst_msg_id))
28 | return
29 |
30 | if lock.locked():
31 | return await query.answer('Wait until previous process complete.', show_alert=True)
32 | msg = query.message
33 |
34 | await query.answer('Processing...⏳', show_alert=True)
35 | if int(from_user) not in ADMINS:
36 | await bot.send_message(int(from_user),
37 | f'Your Submission for indexing {chat} has been accepted by our moderators and will be added soon.',
38 | reply_to_message_id=int(lst_msg_id))
39 | await msg.edit(
40 | "Starting Indexing",
41 | reply_markup=InlineKeyboardMarkup(
42 | [[InlineKeyboardButton('Cancel', callback_data='index_cancel')]]
43 | )
44 | )
45 | try:
46 | chat = int(chat)
47 | except:
48 | chat = chat
49 | await index_files_to_db(int(lst_msg_id), chat, msg, bot)
50 |
51 |
52 | @Client.on_message((filters.forwarded | (filters.regex("(https://)?(t\.me/|telegram\.me/|telegram\.dog/)(c/)?(\d+|[a-zA-Z_0-9]+)/(\d+)$")) & filters.text ) & filters.private & filters.incoming)
53 | async def send_for_index(bot, message):
54 | if message.text:
55 | regex = re.compile("(https://)?(t\.me/|telegram\.me/|telegram\.dog/)(c/)?(\d+|[a-zA-Z_0-9]+)/(\d+)$")
56 | match = regex.match(message.text)
57 | if not match:
58 | return await message.reply('Invalid link')
59 | chat_id = match.group(4)
60 | last_msg_id = int(match.group(5))
61 | if chat_id.isnumeric():
62 | chat_id = int(("-100" + chat_id))
63 | elif message.forward_from_chat.type == enums.ChatType.CHANNEL:
64 | last_msg_id = message.forward_from_message_id
65 | chat_id = message.forward_from_chat.username or message.forward_from_chat.id
66 | else:
67 | return
68 | try:
69 | await bot.get_chat(chat_id)
70 | except ChannelInvalid:
71 | return await message.reply('This may be a private channel / group. Make me an admin over there to index the files.')
72 | except (UsernameInvalid, UsernameNotModified):
73 | return await message.reply('Invalid Link specified.')
74 | except Exception as e:
75 | logger.exception(e)
76 | return await message.reply(f'Errors - {e}')
77 | try:
78 | k = await bot.get_messages(chat_id, last_msg_id)
79 | except:
80 | return await message.reply('Make Sure That Iam An Admin In The Channel, if channel is private')
81 | if k.empty:
82 | return await message.reply('This may be group and iam not a admin of the group.')
83 |
84 | if message.from_user.id in ADMINS:
85 | buttons = [
86 | [
87 | InlineKeyboardButton('Yᴇs ✓',
88 | callback_data=f'index#accept#{chat_id}#{last_msg_id}#{message.from_user.id}')
89 | ],
90 | [
91 | InlineKeyboardButton('Cʟᴏsᴇ ', callback_data='close_data'),
92 | ]
93 | ]
94 | reply_markup = InlineKeyboardMarkup(buttons)
95 | return await message.reply(
96 | f'Do you Want To Index This Channel/ Group ?\n\nChat ID/ Username: {chat_id}\nLast Message ID: {last_msg_id}',
97 | reply_markup=reply_markup)
98 |
99 | if type(chat_id) is int:
100 | try:
101 | link = (await bot.create_chat_invite_link(chat_id)).invite_link
102 | except ChatAdminRequired:
103 | return await message.reply('Make sure iam an admin in the chat and have permission to invite users.')
104 | else:
105 | link = f"@{message.forward_from_chat.username}"
106 | buttons = [
107 | [
108 | InlineKeyboardButton('Accept Index',
109 | callback_data=f'index#accept#{chat_id}#{last_msg_id}#{message.from_user.id}')
110 | ],
111 | [
112 | InlineKeyboardButton('Reject Index',
113 | callback_data=f'index#reject#{chat_id}#{message.id}#{message.from_user.id}'),
114 | ]
115 | ]
116 | reply_markup = InlineKeyboardMarkup(buttons)
117 | await bot.send_message(LOG_CHANNEL,
118 | f'#IndexRequest\n\nBy : {message.from_user.mention} ({message.from_user.id})\nChat ID/ Username - {chat_id}\nLast Message ID - {last_msg_id}\nInviteLink - {link}',
119 | reply_markup=reply_markup)
120 | await message.reply('ThankYou For the Contribution, Wait For My Moderators to verify the files.')
121 |
122 |
123 | @Client.on_message(filters.command('setskip') & filters.user(ADMINS))
124 | async def set_skip_number(bot, message):
125 | if ' ' in message.text:
126 | _, skip = message.text.split(" ")
127 | try:
128 | skip = int(skip)
129 | except:
130 | return await message.reply("Skip number should be an integer.")
131 | await message.reply(f"Successfully set SKIP number as {skip}")
132 | temp.CURRENT = int(skip)
133 | else:
134 | await message.reply("Give me a skip number")
135 |
136 |
137 | async def index_files_to_db(lst_msg_id, chat, msg, bot):
138 | total_files = 0
139 | duplicate = 0
140 | errors = 0
141 | deleted = 0
142 | no_media = 0
143 | unsupported = 0
144 | async with lock:
145 | try:
146 | current = temp.CURRENT
147 | temp.CANCEL = False
148 | async for message in bot.iter_messages(chat, lst_msg_id, temp.CURRENT):
149 | if temp.CANCEL:
150 | await msg.edit(f"Successfully Cancelled!!\n\nSaved {total_files} files to dataBase!\nDuplicate Files Skipped: {duplicate}\nDeleted Messages Skipped: {deleted}\nNon-Media messages skipped: {no_media + unsupported}(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}")
151 | break
152 | current += 1
153 | if current % 20 == 0:
154 | can = [[InlineKeyboardButton('Cancel', callback_data='index_cancel')]]
155 | reply = InlineKeyboardMarkup(can)
156 | await msg.edit_text(
157 | text=f"Total messages fetched: {current}\nTotal messages saved: {total_files}\nDuplicate Files Skipped: {duplicate}\nDeleted Messages Skipped: {deleted}\nNon-Media messages skipped: {no_media + unsupported}(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}",
158 | reply_markup=reply)
159 | if message.empty:
160 | deleted += 1
161 | continue
162 | elif not message.media:
163 | no_media += 1
164 | continue
165 | elif message.media not in [enums.MessageMediaType.VIDEO, enums.MessageMediaType.AUDIO, enums.MessageMediaType.DOCUMENT]:
166 | unsupported += 1
167 | continue
168 | media = getattr(message, message.media.value, None)
169 | if not media:
170 | unsupported += 1
171 | continue
172 | media.file_type = message.media.value
173 | media.caption = message.caption
174 | aynav, vnay = await save_file(media)
175 | if aynav:
176 | total_files += 1
177 | elif vnay == 0:
178 | duplicate += 1
179 | elif vnay == 2:
180 | errors += 1
181 | except Exception as e:
182 | logger.exception(e)
183 | await msg.edit(f'Error: {e}')
184 | else:
185 | await msg.edit(f'Succesfully saved {total_files} to dataBase!\nDuplicate Files Skipped: {duplicate}\nDeleted Messages Skipped: {deleted}\nNon-Media messages skipped: {no_media + unsupported}(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}')
186 |
--------------------------------------------------------------------------------
/plugins/filters.py:
--------------------------------------------------------------------------------
1 | import io
2 | from pyrogram import filters, Client, enums
3 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
4 | from database.filters_mdb import(
5 | add_filter,
6 | get_filters,
7 | delete_filter,
8 | count_filters
9 | )
10 |
11 | from database.connections_mdb import active_connection
12 | from utils import get_file_id, parser, split_quotes
13 | from info import ADMINS
14 |
15 |
16 | @Client.on_message(filters.command(['filter', 'add']) & filters.incoming)
17 | async def addfilter(client, message):
18 | userid = message.from_user.id if message.from_user else None
19 | if not userid:
20 | return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
21 | chat_type = message.chat.type
22 | args = message.text.html.split(None, 1)
23 |
24 | if chat_type == enums.ChatType.PRIVATE:
25 | grpid = await active_connection(str(userid))
26 | if grpid is not None:
27 | grp_id = grpid
28 | try:
29 | chat = await client.get_chat(grpid)
30 | title = chat.title
31 | except:
32 | await message.reply_text("Make sure I'm present in your group!!", quote=True)
33 | return
34 | else:
35 | await message.reply_text("I'm not connected to any groups!", quote=True)
36 | return
37 |
38 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
39 | grp_id = message.chat.id
40 | title = message.chat.title
41 |
42 | else:
43 | return
44 |
45 | st = await client.get_chat_member(grp_id, userid)
46 | if (
47 | st.status != enums.ChatMemberStatus.ADMINISTRATOR
48 | and st.status != enums.ChatMemberStatus.OWNER
49 | and str(userid) not in ADMINS
50 | ):
51 | return
52 |
53 |
54 | if len(args) < 2:
55 | await message.reply_text("Command Incomplete :(", quote=True)
56 | return
57 |
58 | extracted = split_quotes(args[1])
59 | text = extracted[0].lower()
60 |
61 | if not message.reply_to_message and len(extracted) < 2:
62 | await message.reply_text("Add some content to save your filter!", quote=True)
63 | return
64 |
65 | if (len(extracted) >= 2) and not message.reply_to_message:
66 | reply_text, btn, alert = parser(extracted[1], text)
67 | fileid = None
68 | if not reply_text:
69 | await message.reply_text("You cannot have buttons alone, give some text to go with it!", quote=True)
70 | return
71 |
72 | elif message.reply_to_message and message.reply_to_message.reply_markup:
73 | try:
74 | rm = message.reply_to_message.reply_markup
75 | btn = rm.inline_keyboard
76 | msg = get_file_id(message.reply_to_message)
77 | if msg:
78 | fileid = msg.file_id
79 | reply_text = message.reply_to_message.caption.html
80 | else:
81 | reply_text = message.reply_to_message.text.html
82 | fileid = None
83 | alert = None
84 | except:
85 | reply_text = ""
86 | btn = "[]"
87 | fileid = None
88 | alert = None
89 |
90 | elif message.reply_to_message and message.reply_to_message.media:
91 | try:
92 | msg = get_file_id(message.reply_to_message)
93 | fileid = msg.file_id if msg else None
94 | reply_text, btn, alert = parser(extracted[1], text) if message.reply_to_message.sticker else parser(message.reply_to_message.caption.html, text)
95 | except:
96 | reply_text = ""
97 | btn = "[]"
98 | alert = None
99 | elif message.reply_to_message and message.reply_to_message.text:
100 | try:
101 | fileid = None
102 | reply_text, btn, alert = parser(message.reply_to_message.text.html, text)
103 | except:
104 | reply_text = ""
105 | btn = "[]"
106 | alert = None
107 | else:
108 | return
109 |
110 | await add_filter(grp_id, text, reply_text, btn, fileid, alert)
111 |
112 | await message.reply_text(
113 | f"Filter for `{text}` added in **{title}**",
114 | quote=True,
115 | parse_mode=enums.ParseMode.MARKDOWN
116 | )
117 |
118 |
119 | @Client.on_message(filters.command(['viewfilters', 'filters']) & filters.incoming)
120 | async def get_all(client, message):
121 |
122 | chat_type = message.chat.type
123 | userid = message.from_user.id if message.from_user else None
124 | if not userid:
125 | return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
126 | if chat_type == enums.ChatType.PRIVATE:
127 | userid = message.from_user.id
128 | grpid = await active_connection(str(userid))
129 | if grpid is not None:
130 | grp_id = grpid
131 | try:
132 | chat = await client.get_chat(grpid)
133 | title = chat.title
134 | except:
135 | await message.reply_text("Make sure I'm present in your group!!", quote=True)
136 | return
137 | else:
138 | await message.reply_text("I'm not connected to any groups!", quote=True)
139 | return
140 |
141 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
142 | grp_id = message.chat.id
143 | title = message.chat.title
144 |
145 | else:
146 | return
147 |
148 | st = await client.get_chat_member(grp_id, userid)
149 | if (
150 | st.status != enums.ChatMemberStatus.ADMINISTRATOR
151 | and st.status != enums.ChatMemberStatus.OWNER
152 | and str(userid) not in ADMINS
153 | ):
154 | return
155 |
156 | texts = await get_filters(grp_id)
157 | count = await count_filters(grp_id)
158 | if count:
159 | filterlist = f"Total number of filters in **{title}** : {count}\n\n"
160 |
161 | for text in texts:
162 | keywords = " × `{}`\n".format(text)
163 |
164 | filterlist += keywords
165 |
166 | if len(filterlist) > 4096:
167 | with io.BytesIO(str.encode(filterlist.replace("`", ""))) as keyword_file:
168 | keyword_file.name = "keywords.txt"
169 | await message.reply_document(
170 | document=keyword_file,
171 | quote=True
172 | )
173 | return
174 | else:
175 | filterlist = f"There are no active filters in **{title}**"
176 |
177 | await message.reply_text(
178 | text=filterlist,
179 | quote=True,
180 | parse_mode=enums.ParseMode.MARKDOWN
181 | )
182 |
183 | @Client.on_message(filters.command('del') & filters.incoming)
184 | async def deletefilter(client, message):
185 | userid = message.from_user.id if message.from_user else None
186 | if not userid:
187 | return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
188 | chat_type = message.chat.type
189 |
190 | if chat_type == enums.ChatType.PRIVATE:
191 | grpid = await active_connection(str(userid))
192 | if grpid is not None:
193 | grp_id = grpid
194 | try:
195 | chat = await client.get_chat(grpid)
196 | title = chat.title
197 | except:
198 | await message.reply_text("Make sure I'm present in your group!!", quote=True)
199 | return
200 | else:
201 | await message.reply_text("I'm not connected to any groups!", quote=True)
202 |
203 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
204 | grp_id = message.chat.id
205 | title = message.chat.title
206 |
207 | else:
208 | return
209 |
210 | st = await client.get_chat_member(grp_id, userid)
211 | if (
212 | st.status != enums.ChatMemberStatus.ADMINISTRATOR
213 | and st.status != enums.ChatMemberStatus.OWNER
214 | and str(userid) not in ADMINS
215 | ):
216 | return
217 |
218 | try:
219 | cmd, text = message.text.split(" ", 1)
220 | except:
221 | await message.reply_text(
222 | "Mention the filtername which you wanna delete!\n\n"
223 | "/del filtername\n\n"
224 | "Use /viewfilters to view all available filters",
225 | quote=True
226 | )
227 | return
228 |
229 | query = text.lower()
230 |
231 | await delete_filter(message, query, grp_id)
232 |
233 |
234 | @Client.on_message(filters.command('delall') & filters.incoming)
235 | async def delallconfirm(client, message):
236 | userid = message.from_user.id if message.from_user else None
237 | if not userid:
238 | return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
239 | chat_type = message.chat.type
240 |
241 | if chat_type == enums.ChatType.PRIVATE:
242 | grpid = await active_connection(str(userid))
243 | if grpid is not None:
244 | grp_id = grpid
245 | try:
246 | chat = await client.get_chat(grpid)
247 | title = chat.title
248 | except:
249 | await message.reply_text("Make sure I'm present in your group!!", quote=True)
250 | return
251 | else:
252 | await message.reply_text("I'm not connected to any groups!", quote=True)
253 | return
254 |
255 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
256 | grp_id = message.chat.id
257 | title = message.chat.title
258 |
259 | else:
260 | return
261 |
262 | st = await client.get_chat_member(grp_id, userid)
263 | if (st.status == enums.ChatMemberStatus.OWNER) or (str(userid) in ADMINS):
264 | await message.reply_text(
265 | f"This will delete all filters from '{title}'.\nDo you want to continue??",
266 | reply_markup=InlineKeyboardMarkup([
267 | [InlineKeyboardButton(text="YES",callback_data="delallconfirm")],
268 | [InlineKeyboardButton(text="CANCEL",callback_data="delallcancel")]
269 | ]),
270 | quote=True
271 | )
272 |
273 |
--------------------------------------------------------------------------------
/plugins/p_ttishow.txt:
--------------------------------------------------------------------------------
1 | from pyrogram import Client, filters, enums
2 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, CallbackQuery
3 | from pyrogram.errors.exceptions.bad_request_400 import MessageTooLong, PeerIdInvalid
4 | from info import ADMINS, LOG_CHANNEL, SPRT_CHNL, SUPPORT_CHAT, MELCOW_NEW_USERS, MELCOW_VID, CHNL_LNK, GRP_LNK
5 | from database.users_chats_db import db
6 | from database.ia_filterdb import Media
7 | from utils import get_size, temp, get_settings
8 | from Script import script
9 | from pyrogram.errors import ChatAdminRequired
10 | import asyncio
11 |
12 | """-----------------------------------------https://t.me/GetTGLink/4179 --------------------------------------"""
13 |
14 | @Client.on_message(filters.new_chat_members & filters.group)
15 | async def save_group(bot, message):
16 | r_j_check = [u.id for u in message.new_chat_members]
17 | if temp.ME in r_j_check:
18 | if not await db.get_chat(message.chat.id):
19 | total=await bot.get_chat_members_count(message.chat.id)
20 | r_j = message.from_user.mention if message.from_user else "Anonymous"
21 | await bot.send_message(LOG_CHANNEL, script.LOG_TEXT_G.format(message.chat.title, message.chat.id, total, r_j))
22 | await db.add_chat(message.chat.id, message.chat.title)
23 | if message.chat.id in temp.BANNED_CHATS:
24 | # Inspired from a boat of a banana tree
25 | buttons = [[
26 | InlineKeyboardButton('Support', url=f'https://t.me/{SUPPORT_CHAT}')
27 | ]]
28 | reply_markup=InlineKeyboardMarkup(buttons)
29 | k = await message.reply(
30 | text='CHAT NOT ALLOWED 🐞\n\nMy admins has restricted me from working here ! If you want to know more about it contact support..',
31 | reply_markup=reply_markup,
32 | )
33 |
34 | try:
35 | await k.pin()
36 | except:
37 | pass
38 | await bot.leave_chat(message.chat.id)
39 | return
40 | buttons = [[
41 | InlineKeyboardButton('Sᴜᴘᴘᴏʀᴛ', url=GRP_LNK),
42 | InlineKeyboardButton('Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇʟ', url=CHNL_LNK)
43 | ],[
44 | InlineKeyboardButton("Bᴏᴛ Oᴡɴᴇʀ", url="t.me/UNKNOWN_MAN_ON_MISSION")
45 | ]]
46 | reply_markup=InlineKeyboardMarkup(buttons)
47 | await message.reply_text(
48 | text=f"Thankyou For Adding Me In {message.chat.title} ❣️\n\nIf you have any questions & doubts about using me contact support.",
49 | reply_markup=reply_markup)
50 | else:
51 | settings = await get_settings(message.chat.id)
52 | if settings["welcome"]:
53 | for u in message.new_chat_members:
54 | if (temp.MELCOW).get('welcome') is not None:
55 | try:
56 | await (temp.MELCOW['welcome']).delete()
57 | except:
58 | pass
59 | temp.MELCOW['welcome'] = await message.reply_video(
60 | video=(MELCOW_VID),
61 | caption=(script.MELCOW_ENG.format(u.mention, message.chat.title)),
62 | reply_markup=InlineKeyboardMarkup(
63 | [[
64 | InlineKeyboardButton('Sᴜᴘᴘᴏʀᴛ Gʀᴏᴜᴘ', url=GRP_LNK),
65 | InlineKeyboardButton('Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇʟ', url=CHNL_LNK)
66 | ],[
67 | InlineKeyboardButton("Bᴏᴛ Oᴡɴᴇʀ", url="t.me/UNKNOWN_MAN_ON_MISSION")
68 | ]]
69 | ),
70 | parse_mode=enums.ParseMode.HTML
71 | )
72 |
73 | if settings["auto_delete"]:
74 | await asyncio.sleep(600)
75 | await (temp.MELCOW['welcome']).delete()
76 |
77 |
78 |
79 |
80 |
81 | @Client.on_message(filters.command('leave') & filters.user(ADMINS))
82 | async def leave_a_chat(bot, message):
83 | if len(message.command) == 1:
84 | return await message.reply('Give me a chat id')
85 | chat = message.command[1]
86 | try:
87 | chat = int(chat)
88 | except:
89 | chat = chat
90 | try:
91 | buttons = [[
92 | InlineKeyboardButton('Support ', url=SPRT_CHNL),
93 | InlineKeyboardButton('Owner', url="t.me/UNKNOWN_MAN_ON_MISSION")
94 | ],[
95 | InlineKeyboardButton('Use Me Here', url=f'https://t.me/{SUPPORT_CHAT}')
96 | ]]
97 | reply_markup=InlineKeyboardMarkup(buttons)
98 | await bot.send_message(
99 | chat_id=chat,
100 | text='Hello Friends, \nMy admin has told me to leave from group, so i go! If you wanna add me again contact my Support Group or My Owner',
101 | reply_markup=reply_markup,
102 | )
103 |
104 | await bot.leave_chat(chat)
105 | await message.reply(f"left the chat `{chat}`")
106 | except Exception as e:
107 | await message.reply(f'Error - {e}')
108 |
109 | @Client.on_message(filters.command('disable') & filters.user(ADMINS))
110 | async def disable_chat(bot, message):
111 | if len(message.command) == 1:
112 | return await message.reply('Give me a chat id')
113 | r = message.text.split(None)
114 | if len(r) > 2:
115 | reason = message.text.split(None, 2)[2]
116 | chat = message.text.split(None, 2)[1]
117 | else:
118 | chat = message.command[1]
119 | reason = "No reason Provided"
120 | try:
121 | chat_ = int(chat)
122 | except:
123 | return await message.reply('Give Me A Valid Chat ID')
124 | cha_t = await db.get_chat(int(chat_))
125 | if not cha_t:
126 | return await message.reply("Chat Not Found In DB")
127 | if cha_t['is_disabled']:
128 | return await message.reply(f"This chat is already disabled:\nReason- {cha_t['reason']} ")
129 | await db.disable_chat(int(chat_), reason)
130 | temp.BANNED_CHATS.append(int(chat_))
131 | await message.reply('Chat Successfully Disabled')
132 | try:
133 | buttons = [[
134 | InlineKeyboardButton('Support', url=f'https://t.me/{SUPPORT_CHAT}')
135 | ]]
136 | reply_markup=InlineKeyboardMarkup(buttons)
137 | await bot.send_message(
138 | chat_id=chat_,
139 | text=f'Hello Friends, \nMy admin has told me to leave from group so i go! If you wanna add me again contact my support group. \nReason : {reason}',
140 | reply_markup=reply_markup)
141 | await bot.leave_chat(chat_)
142 | except Exception as e:
143 | await message.reply(f"Error - {e}")
144 |
145 |
146 | @Client.on_message(filters.command('enable') & filters.user(ADMINS))
147 | async def re_enable_chat(bot, message):
148 | if len(message.command) == 1:
149 | return await message.reply('Give me a chat id')
150 | chat = message.command[1]
151 | try:
152 | chat_ = int(chat)
153 | except:
154 | return await message.reply('Give Me A Valid Chat ID')
155 | sts = await db.get_chat(int(chat))
156 | if not sts:
157 | return await message.reply("Chat Not Found In DB !")
158 | if not sts.get('is_disabled'):
159 | return await message.reply('This chat is not yet disabled.')
160 | await db.re_enable_chat(int(chat_))
161 | temp.BANNED_CHATS.remove(int(chat_))
162 | await message.reply("Chat Successfully re-enabled")
163 |
164 |
165 | @Client.on_message(filters.command('stats') & filters.incoming)
166 | async def get_ststs(bot, message):
167 | rju = await message.reply('Fetching stats..')
168 | total_users = await db.total_users_count()
169 | totl_chats = await db.total_chat_count()
170 | files = await Media.count_documents()
171 | size = await db.get_db_size()
172 | free = 536870912 - size
173 | size = get_size(size)
174 | free = get_size(free)
175 | await rju.edit(script.STATUS_TXT.format(files, total_users, totl_chats, size, free))
176 |
177 |
178 | @Client.on_message(filters.command('invite') & filters.user(ADMINS))
179 | async def gen_invite(bot, message):
180 | if len(message.command) == 1:
181 | return await message.reply('Give me a chat id')
182 | chat = message.command[1]
183 | try:
184 | chat = int(chat)
185 | except:
186 | return await message.reply('Give Me A Valid Chat ID')
187 | try:
188 | link = await bot.create_chat_invite_link(chat)
189 | except ChatAdminRequired:
190 | return await message.reply("Invite Link Generation Failed, Iam Not Having Sufficient Rights")
191 | except Exception as e:
192 | return await message.reply(f'Error {e}')
193 | await message.reply(f'Here is your Invite Link {link.invite_link}')
194 |
195 | @Client.on_message(filters.command('ban') & filters.user(ADMINS))
196 | async def ban_a_user(bot, message):
197 | # https://t.me/GetTGLink/4185
198 | if len(message.command) == 1:
199 | return await message.reply('Give me a user id / username')
200 | r = message.text.split(None)
201 | if len(r) > 2:
202 | reason = message.text.split(None, 2)[2]
203 | chat = message.text.split(None, 2)[1]
204 | else:
205 | chat = message.command[1]
206 | reason = "No reason Provided"
207 | try:
208 | chat = int(chat)
209 | except:
210 | pass
211 | try:
212 | k = await bot.get_users(chat)
213 | except PeerIdInvalid:
214 | return await message.reply("This is an invalid user, make sure ia have met him before.")
215 | except IndexError:
216 | return await message.reply("This might be a channel, make sure its a user.")
217 | except Exception as e:
218 | return await message.reply(f'Error - {e}')
219 | else:
220 | jar = await db.get_ban_status(k.id)
221 | if jar['is_banned']:
222 | return await message.reply(f"{k.mention} is already banned\nReason: {jar['ban_reason']}")
223 | await db.ban_user(k.id, reason)
224 | temp.BANNED_USERS.append(k.id)
225 | await message.reply(f"Successfully banned {k.mention}")
226 |
227 |
228 |
229 | @Client.on_message(filters.command('unban') & filters.user(ADMINS))
230 | async def unban_a_user(bot, message):
231 | if len(message.command) == 1:
232 | return await message.reply('Give me a user id / username')
233 | r = message.text.split(None)
234 | if len(r) > 2:
235 | reason = message.text.split(None, 2)[2]
236 | chat = message.text.split(None, 2)[1]
237 | else:
238 | chat = message.command[1]
239 | reason = "No reason Provided"
240 | try:
241 | chat = int(chat)
242 | except:
243 | pass
244 | try:
245 | k = await bot.get_users(chat)
246 | except PeerIdInvalid:
247 | return await message.reply("This is an invalid user, make sure ia have met him before.")
248 | except IndexError:
249 | return await message.reply("Thismight be a channel, make sure its a user.")
250 | except Exception as e:
251 | return await message.reply(f'Error - {e}')
252 | else:
253 | jar = await db.get_ban_status(k.id)
254 | if not jar['is_banned']:
255 | return await message.reply(f"{k.mention} is not yet banned.")
256 | await db.remove_ban(k.id)
257 | temp.BANNED_USERS.remove(k.id)
258 | await message.reply(f"Successfully unbanned {k.mention}")
259 |
260 |
261 |
262 | @Client.on_message(filters.command('users') & filters.user(ADMINS))
263 | async def list_users(bot, message):
264 | # https://t.me/GetTGLink/4184
265 | raju = await message.reply('Getting List Of Users')
266 | users = await db.get_all_users()
267 | out = "Users Saved In DB Are:\n\n"
268 | async for user in users:
269 | out += f"{user['name']}"
270 | if user['ban_status']['is_banned']:
271 | out += '( Banned User )'
272 | out += '\n'
273 | try:
274 | await raju.edit_text(out)
275 | except MessageTooLong:
276 | with open('users.txt', 'w+') as outfile:
277 | outfile.write(out)
278 | await message.reply_document('users.txt', caption="List Of Users")
279 |
280 | @Client.on_message(filters.command('chats') & filters.user(ADMINS))
281 | async def list_chats(bot, message):
282 | raju = await message.reply('Getting List Of chats')
283 | chats = await db.get_all_chats()
284 | out = "Chats Saved In DB Are:\n\n"
285 | async for chat in chats:
286 | out += f"**Title:** `{chat['title']}`\n**- ID:** `{chat['id']}`"
287 | if chat['chat_status']['is_disabled']:
288 | out += '( Disabled Chat )'
289 | out += '\n'
290 | try:
291 | await raju.edit_text(out)
292 | except MessageTooLong:
293 | with open('chats.txt', 'w+') as outfile:
294 | outfile.write(out)
295 | await message.reply_document('chats.txt', caption="List Of Chats")
296 |
--------------------------------------------------------------------------------
/Script.py:
--------------------------------------------------------------------------------
1 | class script(object):
2 |
3 | START_TXT = """
4 | Hello {},
5 | Mʏ ɴᴀᴍᴇ ɪs {}. I ᴄᴀɴ ᴘʀᴏᴠɪᴅᴇ ᴍᴏᴠɪᴇs – ᴊᴜsᴛ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ ᴀs ᴀɴ ᴀᴅᴍɪɴ ᴀɴᴅ ᴇɴᴊᴏʏ! 😍
6 | Mᴀɪɴᴛᴀɪɴᴇᴅ ʙʏ @kissuxbots
7 | """
8 |
9 | HELP_TXT = """Hᴇʏ {}
10 | Hᴇʀᴇ Is Tʜᴇ Hᴇʟᴘ Fᴏʀ Mʏ Cᴏᴍᴍᴀɴᴅs."""
11 |
12 | ABOUT_TXT = """• Mʏ Nᴀᴍᴇ: {}
13 | • Oᴡɴᴇʀ : 𓆩•𝐊𝐢𝐬𝐬𝐮 💞•𓆪
14 | • Lɪʙʀᴀʀʏ: Pʏʀᴏɢʀᴀᴍ
15 | • Lᴀɴɢᴜᴀɢᴇ: Pʏᴛʜᴏɴ 3
16 | • DᴀᴛᴀBᴀsᴇ: MᴏɴɢᴏDB"""
17 |
18 |
19 | MANUELFILTER_TXT = """ʜᴇʟᴘ: ꜰɪʟᴛᴇʀꜱ
20 | - ꜰɪʟᴛᴇʀ ɪꜱ ᴀ ꜰᴇᴀᴛᴜʀᴇ ᴡᴇʀᴇ ᴜꜱᴇʀꜱ ᴄᴀɴ ꜱᴇᴛ ᴀᴜᴛᴏᴍᴀᴛᴇᴅ ʀᴇᴘʟɪᴇꜱ ꜰᴏʀ ᴀ ᴘᴀʀᴛɪᴄᴜʟᴀʀ ᴋᴇʏᴡᴏʀᴅ ᴀɴᴅ ɪ ᴡɪʟʟ ʀᴇꜱᴘᴏɴᴅ ᴡʜᴇɴᴇᴠᴇʀ ᴀ ᴋᴇʏᴡᴏʀᴅ ɪꜱ ꜰᴏᴜɴᴅ ɪɴ ᴛʜᴇ ᴍᴇꜱꜱᴀɢᴇ
21 | ɴᴏᴛᴇ:
22 | 1. ᴛʜɪꜱ ʙᴏᴛ ꜱʜᴏᴜʟᴅ ʜᴀᴠᴇ ᴀᴅᴍɪɴ ᴘʀɪᴠɪʟᴇɢᴇ.
23 | 2. ᴏɴʟʏ ᴀᴅᴍɪɴꜱ ᴄᴀɴ ᴀᴅᴅ ꜰɪʟᴛᴇʀꜱ ɪɴ ᴀ ᴄʜᴀᴛ.
24 | 3. ᴀʟᴇʀᴛ ʙᴜᴛᴛᴏɴꜱ ʜᴀᴠᴇ ᴀ ʟɪᴍɪᴛ ᴏꜰ 64 ᴄʜᴀʀᴀᴄᴛᴇʀꜱ.
25 | Cᴏᴍᴍᴀɴᴅs Aɴᴅ Usᴀɢᴇ:
26 | • /filter - ᴀᴅᴅ ᴀ ꜰɪʟᴛᴇʀ ɪɴ ᴀ ᴄʜᴀᴛ
27 | • /filters - ʟɪꜱᴛ ᴀʟʟ ᴛʜᴇ ꜰɪʟᴛᴇʀꜱ ᴏꜰ ᴀ ᴄʜᴀᴛ
28 | • /del - ᴅᴇʟᴇᴛᴇ ᴀ ꜱᴘᴇᴄɪꜰɪᴄ ꜰɪʟᴛᴇʀ ɪɴ ᴀ ᴄʜᴀᴛ
29 | • /delall - ᴅᴇʟᴇᴛᴇ ᴛʜᴇ ᴡʜᴏʟᴇ ꜰɪʟᴛᴇʀꜱ ɪɴ ᴀ ᴄʜᴀᴛ (ᴄʜᴀᴛ ᴏᴡɴᴇʀ ᴏɴʟʏ)"""
30 |
31 | BUTTON_TXT = """ʜᴇʟᴘ: ʙᴜᴛᴛᴏɴꜱ
32 | - ᴛʜɪꜱ ʙᴏᴛ ꜱᴜᴘᴘᴏʀᴛꜱ ʙᴏᴛʜ ᴜʀʟ ᴀɴᴅ ᴀʟᴇʀᴛ ɪɴʟɪɴᴇ ʙᴜᴛᴛᴏɴꜱ.
33 | ɴᴏᴛᴇ:
34 | 1. ᴛᴇʟᴇɢʀᴀᴍ ᴡɪʟʟ ɴᴏᴛ ᴀʟʟᴏᴡꜱ ʏᴏᴜ ᴛᴏ ꜱᴇɴᴅ ʙᴜᴛᴛᴏɴꜱ ᴡɪᴛʜᴏᴜᴛ ᴀɴʏ ᴄᴏɴᴛᴇɴᴛ, ꜱᴏ ᴄᴏɴᴛᴇɴᴛ ɪꜱ ᴍᴀɴᴅᴀᴛᴏʀʏ.
35 | 2. ᴛʜɪꜱ ʙᴏᴛ ꜱᴜᴘᴘᴏʀᴛꜱ ʙᴜᴛᴛᴏɴꜱ ᴡɪᴛʜ ᴀɴʏ ᴛᴇʟᴇɢʀᴀᴍ ᴍᴇᴅɪᴀ ᴛʏᴘᴇ.
36 | 3. ʙᴜᴛᴛᴏɴꜱ ꜱʜᴏᴜʟᴅ ʙᴇ ᴘʀᴏᴘᴇʀʟʏ ᴘᴀʀꜱᴇᴅ ᴀꜱ ᴍᴀʀᴋᴅᴏᴡɴ ꜰᴏʀᴍᴀᴛ
37 | ᴜʀʟ ʙᴜᴛᴛᴏɴꜱ:
38 | [Button Text](buttonurl:https://t.me/kissuxbots)
39 | ᴀʟᴇʀᴛ ʙᴜᴛᴛᴏɴꜱ:
40 | [Button Text](buttonalert:ᴛʜɪꜱ ɪꜱ ᴀɴ ᴀʟᴇʀᴛ ᴍᴇꜱꜱᴀɢᴇ)"""
41 |
42 | AUTOFILTER_TXT = """ʜᴇʟᴘ: ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ
43 | ɴᴏᴛᴇ: Fɪʟᴇ Iɴᴅᴇx
44 | 1. ᴍᴀᴋᴇ ᴍᴇ ᴛʜᴇ ᴀᴅᴍɪɴ ᴏꜰ ʏᴏᴜʀ ᴄʜᴀɴɴᴇʟ ɪꜰ ɪᴛ'ꜱ ᴘʀɪᴠᴀᴛᴇ.
45 | 2. ᴍᴀᴋᴇ ꜱᴜʀᴇ ᴛʜᴀᴛ ʏᴏᴜʀ ᴄʜᴀɴɴᴇʟ ᴅᴏᴇꜱ ɴᴏᴛ ᴄᴏɴᴛᴀɪɴꜱ ᴄᴀᴍʀɪᴘꜱ, ᴘᴏʀɴ ᴀɴᴅ ꜰᴀᴋᴇ ꜰɪʟᴇꜱ.
46 | 3. ꜰᴏʀᴡᴀʀᴅ ᴛʜᴇ ʟᴀꜱᴛ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴍᴇ ᴡɪᴛʜ Qᴜᴏᴛᴇꜱ. ɪ'ʟʟ ᴀᴅᴅ ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ ᴛᴏ ᴍʏ ᴅʙ.
47 |
48 | Nᴏᴛᴇ: AᴜᴛᴏFɪʟᴛᴇʀ
49 | 1. Aᴅᴅ ᴛʜᴇ ʙᴏᴛ ᴀs ᴀᴅᴍɪɴ ᴏɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ.
50 | 2. Usᴇ /connect ᴀɴᴅ ᴄᴏɴɴᴇᴄᴛ ʏᴏᴜʀ ɢʀᴏᴜᴘ ᴛᴏ ᴛʜᴇ ʙᴏᴛ.
51 | 3. Usᴇ /settings ᴏɴ ʙᴏᴛ's PM ᴀɴᴅ ᴛᴜʀɴ ᴏɴ AᴜᴛᴏFɪʟᴛᴇʀ ᴏɴ ᴛʜᴇ sᴇᴛᴛɪɴɢs ᴍᴇɴᴜ."""
52 |
53 | CONNECTION_TXT = """ʜᴇʟᴘ: ᴄᴏɴɴᴇᴄᴛɪᴏɴꜱ
54 | - ᴜꜱᴇᴅ ᴛᴏ ᴄᴏɴɴᴇᴄᴛ ʙᴏᴛ ᴛᴏ ᴘᴍ ꜰᴏʀ ᴍᴀɴᴀɢɪɴɢ ꜰɪʟᴛᴇʀꜱ
55 | - ɪᴛ ʜᴇʟᴘꜱ ᴛᴏ ᴀᴠᴏɪᴅ ꜱᴘᴀᴍᴍɪɴɢ ɪɴ ɢʀᴏᴜᴘꜱ.
56 | ɴᴏᴛᴇ:
57 | 1. ᴏɴʟʏ ᴀᴅᴍɪɴꜱ ᴄᴀɴ ᴀᴅᴅ ᴀ ᴄᴏɴɴᴇᴄᴛɪᴏɴ.
58 | 2. ꜱᴇɴᴅ /ᴄᴏɴɴᴇᴄᴛ ꜰᴏʀ ᴄᴏɴɴᴇᴄᴛɪɴɢ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ᴘᴍ
59 | Cᴏᴍᴍᴀɴᴅs Aɴᴅ Usᴀɢᴇ:
60 | • /connect - ᴄᴏɴɴᴇᴄᴛ ᴀ ᴘᴀʀᴛɪᴄᴜʟᴀʀ ᴄʜᴀᴛ ᴛᴏ ʏᴏᴜʀ ᴘᴍ
61 | • /disconnect - ᴅɪꜱᴄᴏɴɴᴇᴄᴛ ꜰʀᴏᴍ ᴀ ᴄʜᴀᴛ
62 | • /connections - ʟɪꜱᴛ ᴀʟʟ ʏᴏᴜʀ ᴄᴏɴɴᴇᴄᴛɪᴏɴꜱ"""
63 |
64 | EXTRAMOD_TXT = """ʜᴇʟᴘ: Exᴛʀᴀ Mᴏᴅᴜʟᴇs
65 | ɴᴏᴛᴇ:
66 | ᴛʜᴇꜱᴇ ᴀʀᴇ ᴛʜᴇ ᴇxᴛʀᴀ ꜰᴇᴀᴛᴜʀᴇꜱ ᴏꜰ ᴛʜɪꜱ ʙᴏᴛ
67 | Cᴏᴍᴍᴀɴᴅs Aɴᴅ Usᴀɢᴇ:
68 | • /id - ɢᴇᴛ ɪᴅ ᴏꜰ ᴀ ꜱᴘᴇᴄɪꜰɪᴇᴅ ᴜꜱᴇʀ.
69 | • /info - ɢᴇᴛ ɪɴꜰᴏʀᴍᴀᴛɪᴏɴ ᴀʙᴏᴜᴛ ᴀ ᴜꜱᴇʀ.
70 | • /imdb - ɢᴇᴛ ᴛʜᴇ ꜰɪʟᴍ ɪɴꜰᴏʀᴍᴀᴛɪᴏɴ ꜰʀᴏᴍ ɪᴍᴅʙ ꜱᴏᴜʀᴄᴇ.
71 | • /search - ɢᴇᴛ ᴛʜᴇ ꜰɪʟᴍ ɪɴꜰᴏʀᴍᴀᴛɪᴏɴ ꜰʀᴏᴍ ᴠᴀʀɪᴏᴜꜱ ꜱᴏᴜʀᴄᴇꜱ."""
72 |
73 | ADMIN_TXT = """ʜᴇʟᴘ: Aᴅᴍɪɴ Mᴏᴅs
74 | ɴᴏᴛᴇ:
75 | Tʜɪs Mᴏᴅᴜʟᴇ Oɴʟʏ Wᴏʀᴋs Fᴏʀ Mʏ Aᴅᴍɪɴs
76 | Cᴏᴍᴍᴀɴᴅs Aɴᴅ Usᴀɢᴇ:
77 | • /logs - ᴛᴏ ɢᴇᴛ ᴛʜᴇ ʀᴇᴄᴇɴᴛ ᴇʀʀᴏʀꜱ
78 | • /stats - ᴛᴏ ɢᴇᴛ ꜱᴛᴀᴛᴜꜱ ᴏꜰ ꜰɪʟᴇꜱ ɪɴ ᴅʙ. [Tʜɪs Cᴏᴍᴍᴀɴᴅ Cᴀɴ Bᴇ Usᴇᴅ Bʏ Aɴʏᴏɴᴇ]
79 | • /delete - ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴀ ꜱᴘᴇᴄɪꜰɪᴄ ꜰɪʟᴇ ꜰʀᴏᴍ ᴅʙ.
80 | • /users - ᴛᴏ ɢᴇᴛ ʟɪꜱᴛ ᴏꜰ ᴍʏ ᴜꜱᴇʀꜱ ᴀɴᴅ ɪᴅꜱ.
81 | • /chats - ᴛᴏ ɢᴇᴛ ʟɪꜱᴛ ᴏꜰ ᴍʏ ᴄʜᴀᴛꜱ ᴀɴᴅ ɪᴅꜱ
82 | • /leave - ᴛᴏ ʟᴇᴀᴠᴇ ꜰʀᴏᴍ ᴀ ᴄʜᴀᴛ.
83 | • /disable - ᴛᴏ ᴅɪꜱᴀʙʟᴇ ᴀ ᴄʜᴀᴛ.
84 | • /ban - ᴛᴏ ʙᴀɴ ᴀ ᴜꜱᴇʀ.
85 | • /unban - ᴛᴏ ᴜɴʙᴀɴ ᴀ ᴜꜱᴇʀ.
86 | • /channel - ᴛᴏ ɢᴇᴛ ʟɪꜱᴛ ᴏꜰ ᴛᴏᴛᴀʟ ᴄᴏɴɴᴇᴄᴛᴇᴅ ᴄʜᴀɴɴᴇʟꜱ
87 | • /broadcast - ᴛᴏ ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴀ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴀʟʟ ᴜꜱᴇʀꜱ
88 | • /grp_broadcast - Tᴏ ʙʀᴏᴀᴅᴄᴀsᴛ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ ᴀʟʟ ᴄᴏɴɴᴇᴄᴛᴇᴅ ɢʀᴏᴜᴘs.
89 | • /gfilter - ᴛᴏ ᴀᴅᴅ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀs
90 | • /gfilters - ᴛᴏ ᴠɪᴇᴡ ʟɪsᴛ ᴏғ ᴀʟʟ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀs
91 | • /delg - ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴀ sᴘᴇᴄɪғɪᴄ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀ
92 | • /request - Tᴏ sᴇɴᴅ ᴀ Mᴏᴠɪᴇ/Sᴇʀɪᴇs ʀᴇᴏ̨ᴜᴇsᴛ ᴛᴏ ʙᴏᴛ ᴀᴅᴍɪɴs. Oɴʟʏ ᴡᴏʀᴋs ᴏɴ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ. [Tʜɪs Cᴏᴍᴍᴀɴᴅ Cᴀɴ Bᴇ Usᴇᴅ Bʏ Aɴʏᴏɴᴇ]
93 | • /delallg - Tᴏ ᴅᴇʟᴇᴛᴇ ᴀʟʟ Gғɪʟᴛᴇʀs ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ's ᴅᴀᴛᴀʙᴀsᴇ.
94 | • /deletefiles - Tᴏ ᴅᴇʟᴇᴛᴇ CᴀᴍRɪᴘ ᴀɴᴅ PʀᴇDVD Fɪʟᴇs ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ's ᴅᴀᴛᴀʙᴀsᴇ."""
95 |
96 | STATUS_TXT = """⍟────[ ʙᴏᴛ sᴛᴀᴛᴜ𝗌 ]────⍟
97 | • Tᴏᴛᴀʟ Fɪʟᴇs: {}
98 | • Tᴏᴛᴀʟ Usᴇʀs: {}
99 | • Tᴏᴛᴀʟ Cʜᴀᴛs: {}
100 | • Usᴇᴅ Sᴛᴏʀᴀɢᴇ: {}
101 | • Fʀᴇᴇ Sᴛᴏʀᴀɢᴇ: {}
102 |
103 | •❅─────✧❅✦❅✧─────❅•"""
104 |
105 | LOG_TEXT_G = """#NewGroup
106 | Gʀᴏᴜᴘ = {}({})
107 | Tᴏᴛᴀʟ Mᴇᴍʙᴇʀs = {}
108 | Aᴅᴅᴇᴅ Bʏ - {}"""
109 |
110 | LOG_TEXT_P = """#NewUser
111 | ID - {}
112 | Nᴀᴍᴇ - {}"""
113 |
114 | ALRT_TXT = """ʜᴇʟʟᴏ {},
115 | ᴛʜɪꜱ ɪꜱ ɴᴏᴛ ʏᴏᴜʀ ᴍᴏᴠɪᴇ ʀᴇQᴜᴇꜱᴛ,
116 | ʀᴇQᴜᴇꜱᴛ ʏᴏᴜʀ'ꜱ..."""
117 |
118 | OLD_ALRT_TXT = """ʜᴇʏ {},
119 | ʏᴏᴜ ᴀʀᴇ ᴜꜱɪɴɢ ᴏɴᴇ ᴏꜰ ᴍʏ ᴏʟᴅ ᴍᴇꜱꜱᴀɢᴇꜱ,
120 | ᴘʟᴇᴀꜱᴇ ꜱᴇɴᴅ ᴛʜᴇ ʀᴇQᴜᴇꜱᴛ ᴀɢᴀɪɴ."""
121 |
122 | CUDNT_FND = """Sᴘᴇʟʟɪɴɢ Mɪsᴛᴀᴋᴇ Bʀᴏ ‼️
123 | Dᴏɴ'ᴛ Wᴏʀʀʏ 😊, Cʜᴏᴏsᴇ Tʜᴇ Cᴏʀʀᴇᴄᴛ Oɴᴇ Bᴇʟᴏᴡ👇"""
124 |
125 | I_CUDNT = """sᴏʀʀʏ ɪ ᴄᴏᴜʟᴅɴ'ᴛ ғɪɴᴅ ᴀɴʏ ᴍᴏᴠɪᴇ/sᴇʀɪᴇs ʀᴇʟᴀᴛᴇᴅ ᴛᴏ ᴛʜᴇ ɢɪᴠᴇɴ ᴡᴏʀᴅ ~~{}~~ 😕
126 |
127 | ᴄʜᴇᴄᴋ ʏᴏᴜʀ sᴘᴇʟʟɪɴɢ ɪɴ ɢᴏᴏɢʟᴇ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ 😃
128 |
129 | ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇
130 |
131 | ᴇxᴀᴍᴘʟᴇ : Maalik or maalik 2025 or Infinity War 2019 Hindi
132 |
133 | ꜱᴇʀɪᴇꜱ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ 👇
134 |
135 | ᴇxᴀᴍᴘʟᴇ : Squid Game S02 or Squid Game S01E04
136 |
137 | 🚯 Dᴏɴᴛ ᴜꜱᴇ ➠ ':(!,./)"""
138 |
139 | I_CUD_NT = """ɪ ᴄᴏᴜʟᴅɴ'ᴛ ꜰɪɴᴅ ᴀɴʏ ᴍᴏᴠɪᴇ ʀᴇʟᴀᴛᴇᴅ ᴛᴏ {}.
140 | ᴘʟᴇᴀꜱᴇ ᴄʜᴇᴄᴋ ᴛʜᴇ ꜱᴘᴇʟʟɪɴɢ ᴏɴ ɢᴏᴏɢʟᴇ ᴏʀ ɪᴍᴅʙ..."""
141 |
142 | MVE_NT_FND = """ᴍᴏᴠɪᴇ ɴᴏᴛ ꜰᴏᴜɴᴅ ɪɴ ᴅᴀᴛᴀʙᴀꜱᴇ..."""
143 |
144 | TOP_ALRT_MSG = """Cʜᴇᴄᴋɪɴɢ Fᴏʀ Mᴏᴠɪᴇ Iɴ Dᴀᴛᴀʙᴀsᴇ..."""
145 |
146 | MELCOW_ENG = """Hᴇʟʟᴏ {} 😍, Aɴᴅ Wᴇʟᴄᴏᴍᴇ Tᴏ {} Gʀᴏᴜᴘ ❤️"""
147 |
148 | SHORTLINK_INFO = """
149 | ─────「 Hᴏᴡ ᴛᴏ Eᴀʀɴ Mᴏɴᴇʏ 」─────
150 |
151 | Yᴏᴜ ᴄᴀɴ Eᴀʀɴ Mᴏɴᴇʏ Fʀᴏᴍ Tʜɪs Bᴏᴛ Uɴᴛɪʟ ᴛʜɪs ʙᴏᴛ ɪs ᴀʟɪᴠᴇ.
152 |
153 | Wᴀɴᴛ ᴛᴏ Kɴᴏᴡ Hᴏᴡ? Fᴏʟʟᴏᴡ Tʜᴇsᴇ Sᴛᴇᴘs:-
154 |
155 | sᴛᴇᴘ 𝟷 : ʏᴏᴜ ᴍᴜsᴛ ʜᴀᴠᴇ ᴀᴛʟᴇᴀsᴛ ᴏɴᴇ ɢʀᴏᴜᴘ ᴡɪᴛʜ ᴍɪɴɪᴍᴜᴍ 1𝟶𝟶 ᴍᴇᴍʙᴇʀs.
156 |
157 | sᴛᴇᴘ 𝟸 : ᴍᴀᴋᴇ ᴀᴄᴄᴏᴜɴᴛ ᴏɴ Aɴʏ Sʜᴏʀᴛᴇɴᴇʀ Wᴇʙsɪᴛᴇ.
158 |
159 | sᴛᴇᴘ 𝟹 : ꜰᴏʟʟᴏᴡ ᴛʜᴇsᴇ ɪɴꜱᴛʀᴜᴄᴛɪᴏɴꜱ Tᴏ ᴄᴏɴɴᴇᴄᴛ sʜᴏʀᴛᴇɴᴇʀ.
160 |
161 | ➣ Yᴏᴜ ᴄᴀɴ ᴄᴏɴɴᴇᴄᴛ ᴀs ᴍᴀɴʏ ɢʀᴏᴜᴘ ʏᴏᴜ ʜᴀᴠᴇ.
162 |
163 | ᴀɴʏ ᴅᴏᴜʙᴛs ᴏʀ ɴᴏᴛ ᴄᴏɴɴᴇᴄᴛɪɴɢ? ᴄᴏɴᴛᴀᴄᴛ ᴏᴡɴᴇʀ
164 | """
165 |
166 | REQINFO = """
167 | ⚠ ɪɴꜰᴏʀᴍᴀᴛɪᴏɴ ⚠
168 |
169 | ᴀꜰᴛᴇʀ 5 ᴍɪɴᴜᴛᴇꜱ ᴛʜɪꜱ ᴍᴇꜱꜱᴀɢᴇ ᴡɪʟʟ ʙᴇ ᴀᴜᴛᴏᴍᴀᴛɪᴄᴀʟʟʏ ᴅᴇʟᴇᴛᴇᴅ
170 |
171 | ɪꜰ ʏᴏᴜ ᴅᴏ ɴᴏᴛ ꜱᴇᴇ ᴛʜᴇ ʀᴇǫᴜᴇsᴛᴇᴅ ᴍᴏᴠɪᴇ / sᴇʀɪᴇs ꜰɪʟᴇ, ʟᴏᴏᴋ ᴀᴛ ᴛʜᴇ ɴᴇxᴛ ᴘᴀɢᴇ"""
172 |
173 | SELECT = """
174 | MOVIES ➢ Sᴇʟᴇᴄᴛ "Lᴀɴɢᴜᴀɢᴇs"
175 |
176 | SERIES ➢ Sᴇʟᴇᴄᴛ "Sᴇᴀsᴏɴs"
177 |
178 | Tɪᴘ: Sᴇʟᴇᴄᴛ "Lᴀɴɢᴜᴀɢᴇs" ᴏʀ "Sᴇᴀsᴏɴs" Bᴜᴛᴛᴏɴ ᴀɴᴅ Cʟɪᴄᴋ "Sᴇɴᴅ Aʟʟ" Tᴏ ɢᴇᴛ Aʟʟ Fɪʟᴇ Lɪɴᴋs ɪɴ ᴀ Sɪɴɢʟᴇ ᴄʟɪᴄᴋ"""
179 |
180 | SINFO = """
181 | ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯
182 | ꜱᴇʀɪᴇꜱ ʀᴇǫᴜᴇꜱᴛ ꜰᴏʀᴍᴀᴛ
183 | ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯
184 |
185 | ɢᴏ ᴛᴏ ɢᴏᴏɢʟᴇ ➠ ᴛʏᴘᴇ ꜱᴇʀɪᴇꜱ ɴᴀᴍᴇ ➠ ᴄᴏᴘʏ ᴄᴏʀʀᴇᴄᴛ ɴᴀᴍᴇ ➠ ᴘᴀꜱᴛᴇ ᴛʜɪꜱ ɢʀᴏᴜᴘ
186 |
187 | ᴇxᴀᴍᴘʟᴇ : Loki S01E01
188 |
189 | 🚯 ᴅᴏɴᴛ ᴜꜱᴇ ➠ ':(!,./)"""
190 |
191 | NORSLTS = """
192 | ★ #NoResult ★
193 |
194 | 𝗜𝗗 : {}
195 |
196 | 𝗡𝗮𝗺𝗲 : {}
197 |
198 | 𝗠𝗲𝘀𝘀𝗮𝗴𝗲 : {}"""
199 |
200 | CAPTION = """
201 | {file_caption}"""
202 |
203 | FORCE_SUB = """
204 | **⚠️ Pʟᴇᴀsᴇ ғᴏʟʟᴏᴡ ᴛʜɪs ʀᴜʟe ⚠️
205 |
206 | Iɴ ᴏʀᴅᴇʀ ᴛᴏ ɢᴇᴛ ᴛʜᴇ ᴍᴏᴠɪᴇ ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ ʏᴏᴜ.
207 |
208 | Yᴏᴜ ᴡɪʟʟ ʜᴀᴠᴇ ᴛᴏ ᴊᴏɪɴ ᴏᴜʀ ᴏғғɪᴄɪᴀʟ ᴏʀ ʙᴀᴄᴋ-ᴜᴘ ᴄʜᴀɴɴᴇʟ ғɪʀsᴛ.
209 |
210 | Tʜᴇɴ ᴄʟɪᴄᴋ ᴏɴ ᴛʜᴇ '🔄 Tʀʏ Aɢᴀɪɴ' ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ.
211 |
212 | Aғᴛᴇʀ ᴛʜᴀᴛ ɪ'ʟʟ sᴇɴᴅ ʏᴏᴜ ᴛʜᴀᴛ ᴍᴏᴠɪᴇ ᴘʀɪᴠᴀᴛᴇʟʏ.**"""
213 |
214 | IMDB_TEMPLATE_TXT = """
215 | Query: {qurey}
216 |
217 | IMDb Data:
218 | 🏷 Title: {title}
219 | 🎭 Genres: {genres}
220 | 📆 Year: {year}
221 | ⏱️ Result Shown in: {remaining_seconds} seconds 🔥
222 | 🌟 Rating: {rating} / 10"""
223 |
224 |
225 | ALL_FILTERS = """
226 | Hᴇʏ {}, Tʜᴇsᴇ ᴀʀᴇ ᴍʏ ᴛʜʀᴇᴇ ᴛʏᴘᴇs ᴏғ ғɪʟᴛᴇʀs."""
227 |
228 | GFILTER_TXT = """
229 | Wᴇʟᴄᴏᴍᴇ ᴛᴏ Gʟᴏʙᴀʟ Fɪʟᴛᴇʀs. Gʟᴏʙᴀʟ Fɪʟᴛᴇʀs ᴀʀᴇ ᴛʜᴇ ғɪʟᴛᴇʀs sᴇᴛ ʙʏ ʙᴏᴛ ᴀᴅᴍɪɴs ᴡʜɪᴄʜ ᴡɪʟʟ ᴡᴏʀᴋ ᴏɴ ᴀʟʟ ɢʀᴏᴜᴘs.
230 |
231 | Aᴠᴀɪʟᴀʙʟᴇ ᴄᴏᴍᴍᴀɴᴅs:
232 | • /gfilter - Tᴏ ᴄʀᴇᴀᴛᴇ ᴀ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀ.
233 | • /gfilters - Tᴏ ᴠɪᴇᴡ ᴀʟʟ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀs.
234 | • /delg - Tᴏ ᴅᴇʟᴇᴛᴇ ᴀ ᴘᴀʀᴛɪᴄᴜʟᴀʀ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀ.
235 | • /delallg - ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴀʟʟ ɢʟᴏʙᴀʟ ꜰɪʟᴛᴇʀꜱ."""
236 |
237 | FILE_STORE_TXT = """
238 | Fɪʟᴇ sᴛᴏʀᴇ ɪs ᴛʜᴇ ғᴇᴀᴛᴜʀᴇ ᴡʜɪᴄʜ ᴡɪʟʟ ᴄʀᴇᴀᴛᴇ ᴀ sʜᴀʀᴇᴀʙʟᴇ ʟɪɴᴋ ᴏғ ᴀ sɪɴɢʟᴇ ᴏʀ ᴍᴜʟᴛɪᴘʟᴇ ғɪʟᴇs.
239 |
240 | Aᴠᴀɪʟᴀʙʟᴇ ᴄᴏᴍᴍᴀɴᴅs:
241 | • /batch - Tᴏ ᴄʀᴇᴀᴛᴇ ᴀ ʙᴀᴛᴄʜ ʟɪɴᴋ ᴏғ ᴍᴜʟᴛɪᴘʟᴇ ғɪʟᴇs.
242 | • /link - Tᴏ ᴄʀᴇᴀᴛᴇ ᴀ sɪɴɢʟᴇ ғɪʟᴇ sᴛᴏʀᴇ ʟɪɴᴋ.
243 | • /pbatch - Jᴜsᴛ ʟɪᴋᴇ /batch, ʙᴜᴛ ᴛʜᴇ ғɪʟᴇs ᴡɪʟʟ ʙᴇ sᴇɴᴅ ᴡɪᴛʜ ғᴏʀᴡᴀʀᴅ ʀᴇsᴛʀɪᴄᴛɪᴏɴs.
244 | • /plink - Jᴜsᴛ ʟɪᴋᴇ /link, ʙᴜᴛ ᴛʜᴇ ғɪʟᴇ ᴡɪʟʟ ʙᴇ sᴇɴᴅ ᴡɪᴛʜ ғᴏʀᴡᴀʀᴅ ʀᴇsᴛʀɪᴄᴛɪᴏɴ."""
245 |
246 | OWNER_INFO = """
247 | ⍟───[ ᴏᴡɴᴇʀ ᴅᴇᴛᴀɪʟꜱ ]───⍟
248 | ◈ ꜰᴜʟʟ ɴᴀᴍᴇ : 𓆩•𝐊𝐢𝐬𝐬𝐮 💞•𓆪
249 | ◈ ʜᴇʀᴇ ɪs ᴘᴜʙʟɪᴄ sᴏᴜʀᴄᴇ ᴄᴏᴅᴇ ᴀɴᴅ ɪɴsᴛʀᴜᴄᴛɪᴏɴs — ᴛᴀᴘ ʙᴇʟᴏᴡ ᴏʀ ʜᴇʀᴇ ᴛᴏ sᴇᴇ.
250 | """
251 |
252 | DISL_TXT = """
253 |
254 | ᴛʜɪꜱ ɪꜱ ᴀɴ ᴏᴘᴇɴ ꜱᴏᴜʀᴄᴇ ᴘʀᴏᴊᴇᴄᴛ.
255 | ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜɪꜱ ʙᴏᴛ ᴀʀᴇ ꜰʀᴇᴇʟʏ ᴀᴠᴀɪʟᴀʙʟᴇ ᴏɴ ᴛʜᴇ ɪɴᴛᴇʀɴᴇᴛ ᴏʀ ᴘᴏꜱᴛᴇᴅ ʙʏ ꜱᴏᴍᴇʙᴏᴅʏ ᴇʟꜱᴇ. ᴊᴜꜱᴛ ꜰᴏʀ ᴇᴀꜱʏ ꜱᴇᴀʀᴄʜɪɴɢ, ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ɪɴᴅᴇxɪɴɢ ꜰɪʟᴇꜱ ᴡʜɪᴄʜ ᴀʀᴇ ᴀʟʀᴇᴀᴅʏ ᴜᴘʟᴏᴀᴅᴇᴅ ᴏɴ ᴛᴇʟᴇɢʀᴀᴍ.
256 | ᴡᴇ ʀᴇꜱᴘᴇᴄᴛ ᴀʟʟ ᴛʜᴇ ᴄᴏᴘʏʀɪɢʜᴛ ʟᴀᴡꜱ ᴀɴᴅ ᴡᴏʀᴋ ɪɴ ᴄᴏᴍᴘʟɪᴀɴᴄᴇ ᴡɪᴛʜ DMCA ᴀɴᴅ EUCD. ɪꜰ ᴀɴʏᴛʜɪɴɢ ɪꜱ ᴀɢᴀɪɴꜱᴛ ʟᴀᴡ, ᴘʟᴇᴀꜱᴇ ᴄᴏɴᴛᴀᴄᴛ ᴍᴇ ꜱᴏ ɪᴛ ᴄᴀɴ ʙᴇ ʀᴇᴍᴏᴠᴇᴅ ᴀꜱᴀᴘ.
257 | ɪᴛ ɪꜱ ꜰᴏʀʙɪᴅᴅᴇɴ ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ, ꜱᴛʀᴇᴀᴍ, ʀᴇᴘʀᴏᴅᴜᴄᴇ, ꜱʜᴀʀᴇ, ᴏʀ ᴄᴏɴꜱᴜᴍᴇ ᴄᴏɴᴛᴇɴᴛ ᴡɪᴛʜᴏᴜᴛ ᴇxᴘʟɪᴄɪᴛ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ꜰʀᴏᴍ ᴛʜᴇ ᴄᴏɴᴛᴇɴᴛ ᴄʀᴇᴀᴛᴏʀ ᴏʀ ᴄᴏᴘʏʀɪɢʜᴛ ʜᴏʟᴅᴇʀ.
258 | ɪꜰ ʏᴏᴜ ʙᴇʟɪᴇᴠᴇ ᴛʜɪꜱ ʙᴏᴛ ɪꜱ ᴠɪᴏʟᴀᴛɪɴɢ ʏᴏᴜʀ ɪɴᴛᴇʟʟᴇᴄᴛᴜᴀʟ ᴘʀᴏᴘᴇʀᴛʏ, ᴄᴏɴᴛᴀᴄᴛ ᴛʜᴇ ʀᴇꜱᴘᴇᴄᴛɪᴠᴇ ᴄʜᴀɴɴᴇʟꜱ ꜰᴏʀ ʀᴇᴍᴏᴠᴀʟ.
259 | ᴛʜᴇ ʙᴏᴛ ᴅᴏᴇꜱ ɴᴏᴛ ᴏᴡɴ ᴀɴʏ ᴏꜰ ᴛʜᴇꜱᴇ ᴄᴏɴᴛᴇɴᴛꜱ — ɪᴛ ᴏɴʟʏ ɪɴᴅᴇxᴇꜱ ꜰɪʟᴇꜱ ꜰʀᴏᴍ ᴛᴇʟᴇɢʀᴀᴍ.
260 | 🔗 View Public Source Code
261 |
262 | """
263 |
264 | MODS_TXT = """Yᴏᴜ Cᴀɴ Tʀʏ Aʟʟ Tʜᴇsᴇ Fᴇᴀᴛᴜʀᴇ Fʀᴏᴍ Bᴇʟᴏᴡ Oᴘᴛɪᴏɴ..!!!"""
265 |
266 | STICKER_TXT = """𝚈𝙾ᴜ 𝙲𝙰ɴ 𝚄𝚂𝙴 𝚃𝙷𝙸𝚂 𝙼𝙾𝙳𝚄𝙻𝙴 𝚃𝙾 𝙵𝙸𝙽𝙳 𝙰𝙽𝚈 𝚂𝚃𝙸𝙲𝙺𝙴𝚁𝚂 𝙸𝙳.
267 | • 𝐔𝐒𝐀𝐆𝐄
268 | To Get Sticker ID
269 |
270 | ⭕ 𝙃𝙤𝙬 𝙏𝙤 𝙐𝙨𝙚
271 |
272 | ◉ ʀᴇᴘʟʏ ᴛᴏ ᴀɴʏ sᴛɪᴄᴋᴇʀ [/stickerid]"""
273 |
274 |
275 | FONT_TXT= """ 𝐔𝐒𝐀𝐆ᴇ
276 |
277 | 𝐘𝐎ᴜ ᴄᴀɴ 𝐔𝐒𝐄 𝐓𝐇𝐈𝐒 𝐌𝐎𝐃𝐔𝐋𝐄 𝐓𝐎 𝐂𝐇𝐀𝐍𝐆𝐄 𝐅𝐎𝐍𝐓 𝐒𝐓𝐘𝐋𝐄
278 |
279 | ᴄᴏᴍᴍᴀɴᴅ : /font ʏᴏᴜʀ ᴛᴇxᴛ ( ᴏᴘᴛɪᴏɴᴀʟ)
280 | Eg:- /font ʜᴇʟʟᴏʙ>"""
281 |
282 | TELE_TXT = """▫️Hᴇʟᴘ: ▪️ Tᴇʟᴇɢʀᴀᴘʜ ▪️
283 | Tᴇʟᴇɢʀᴀᴘʜ Lɪɴᴋ Gᴇɴᴇʀᴀᴛᴏʀ
284 | Usᴀɢᴇ
285 | 🤧 /telegraph - Sᴇɴᴅ Mᴇ Pʜᴏᴛᴏ Oʀ Vɪᴅᴇᴏ Uɴᴅᴇʀ(5ᴍʙ) Aɴᴅ Rᴇᴘʟʏ Wɪᴛʜ Cᴏᴍᴍᴀᴍɴᴅ"""
286 |
287 | CON_TXT = """ᴄᴏᴜɴᴛʀʏ ɪɴғᴏ
288 | Tʜɪs ᴍᴏᴅᴜʟᴇ ɪs ᴛᴏ ғɪɴᴅ ɪɴғᴏʀᴍᴀᴛɪᴏɴ ᴀʙᴏᴜᴛ ᴄᴏᴜɴᴛʀɪᴇs
289 | • /country [𝖼𝗈𝗎𝗇𝗍𝗋𝗒 𝗇𝖺𝗆𝖾]
290 | 𝖤𝗑𝖺𝗆𝗉𝗅𝖾 :- /country India"""
291 |
292 | SOURCE_TXT = """
293 | ✭ ғᴏʀ ᴀɴʏ ǫᴜᴇʀʏ ᴄᴏɴᴛᴀᴄᴛ ᴛᴏ ᴛʜᴇ 𓆩•𝐊𝐢𝐬𝐬𝐮 💞•𓆪
294 | ✭ ʜᴇʀᴇ ɪs ᴘᴜʙʟɪᴄ sᴏᴜʀᴄᴇ ᴄᴏᴅᴇ ᴀɴᴅ ɪɴsᴛʀᴜᴄᴛɪᴏɴs — ᴛᴀᴘ ʙᴇʟᴏᴡ ᴏʀ ʜᴇʀᴇ ᴛᴏ sᴇᴇ.
295 |
296 | """
297 |
298 |
299 | RULE_TXT = """
300 | ♨️ 𝗚𝗥𝗢𝗨𝗣 𝗥𝗨𝗟𝗘𝗦 ♨️
301 |
302 | 🔹 Sᴇᴀʀᴄʜ Mᴏᴠɪᴇ Wɪᴛʜ Cᴏʀʀᴇᴄᴛ Sᴘᴇʟʟɪɴɢ :
303 | › ᴀᴠᴀᴛᴀʀ 2009 ✅
304 | › ᴀᴠᴀᴛᴀʀ ʜɪɴᴅɪ ✅
305 | › ᴀᴠᴀᴛᴀʀ ᴍᴏᴠɪᴇ ❌
306 | › ᴀᴠᴀᴛᴀʀ ʜɪɴᴅɪ ᴅᴜʙʙᴇᴅ.. ❌
307 |
308 | 🔹 Sᴇᴀʀᴄʜ Wᴇʙ Sᴇʀɪᴇs Iɴ ᴛʜɪs Fᴏʀᴍᴀᴛ :
309 | › ᴠɪᴋɪɴɢs S01 ✅
310 | › ᴠɪᴋɪɴɢs S01E01 ✅
311 | › ᴠɪᴋɪɴɢs S01 ʜɪɴᴅɪ ✅
312 | › ᴠɪᴋɪɴɢs S01 ʜɪɴᴅɪ ᴅᴜʙʙ. ❌
313 | › ᴠɪᴋɪɴɢs sᴇᴀsᴏɴ 1 ❌
314 | › ᴠɪᴋɪɴɢs ᴡᴇʙ sᴇʀɪᴇs ❌
315 |
316 | 🔹 ᴅᴏɴ'ᴛ ᴅᴏ ᴀɴʏ sᴇʟғ ᴘʀᴏᴍᴏᴛɪᴏɴ.
317 | 🔹 ᴅᴏɴ'ᴛ sᴇɴᴅ ᴀɴʏ ᴋɪɴᴅ ᴏғ ᴘʜᴏᴛᴏ, ᴠɪᴅᴇᴏ, ᴅᴏᴄᴜᴍᴇɴᴛꜱ, ᴜʀʟꜱ, ᴇᴛᴄ.
318 | 🔹 ᴅᴏɴ'ᴛ ʀᴇǫᴜᴇsᴛ ᴀɴʏᴛʜɪɴɢ ᴏᴛʜᴇʀ ᴛʜᴀɴ ᴍᴏᴠɪᴇs, ꜱᴇʀɪᴇꜱ, ᴀɴɪᴍᴇꜱ.
319 |
320 | ⚙️ 𝖭ᴏᴛᴇ : 𝖠ʟʟ ᴍᴇ𝘀𝘀ᴀɢᴇ𝘀 ᴡɪʟʟ ʙᴇ ᴀᴜᴛᴏ-ᴅᴇʟᴇᴛᴇᴅ ᴀғᴛᴇʀ 𝟷𝟶 ᴍɪɴᴜᴛᴇ𝘀 ᴛᴏ ᴀᴠᴏɪᴅ ᴄᴏᴘʏʀɪɢʜᴛ ɪ𝘀𝘀ᴜᴇ𝘀."""
321 |
322 | SETTING_TXT = """
323 | ѕeттιngѕ
324 | ~ sᴇᴛᴛɪɴɢs ɪs ᴍᴏsᴛ ɪᴍᴘᴏʀᴛᴀɴᴛ ғᴇᴀᴛᴜʀᴇs ɪɴ ᴛʜɪs ʙᴏᴛ.
325 | ~ ʏᴏᴜ ᴄᴀɴ ᴇᴀsɪʟʏ ᴄᴜsᴛᴏᴍɪᴢᴇ ᴛʜɪs ʙᴏᴛ ғᴏʀ ʏᴏᴜʀ ɢʀᴏᴜᴘ.
326 |
327 | noтe
328 | 1. ᴏɴʟʏ ɢʀᴏᴜᴘ ᴀᴅᴍɪɴ ᴄᴀɴ ᴜsᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴀɴᴅ ᴄʜᴀɴɢᴇs sᴇᴛᴛɪɴɢs.
329 | 2. ɪᴛ ᴡᴏʀᴋs ᴏɴʟʏ ᴡʜᴇɴ ʏᴏᴜ ᴀʟʀᴇᴀᴅʏ ᴄᴏɴɴᴇᴄᴛ ʏᴏᴜʀ ɢʀᴏᴜᴘ.
330 |
331 | coммand and υѕeѕ
332 | • /settings - ᴄʜᴀɴɢᴇ sᴇᴛᴛɪɴɢs ᴀs ʏᴏᴜʀ ᴡɪsʜ"""
333 |
334 | CHNL_INFO = """
335 | ɢʀᴏᴜᴘs & ᴄʜᴀɴɴᴇʟs ɪɴғᴏ \(°o°)/
336 |
337 | ▫ ᴄᴏᴍᴘʟᴇᴛᴇ ᴍᴏᴠɪᴇs ʀᴇǫᴜᴇsᴛɪɴɢ ɢʀᴏᴜᴘ.
338 | ▫ ᴀʟʟ ʟᴀɴɢᴜᴀɢᴇ ᴍᴏᴠɪᴇs & sᴇʀɪᴇs.
339 | ▫ ғᴀsᴛᴇsᴛ ʙᴏᴛs ᴀʀᴇ ᴀᴅᴅᴇᴅ.
340 | ▫ ғʀᴇᴇ & ᴇᴀsʏ ᴛᴏ ᴜsᴇ.
341 | ▫ 𝟸𝟺x𝟽 sᴇʀᴠɪᴄᴇs ᴀᴠᴀɪʟᴀʙʟᴇ. """
342 |
343 | VERIFED_TXT = """ʜᴇʏ {},
344 | ʏᴏᴜ ᴀʀᴇ sᴜᴄᴄᴇssғᴜʟʟʏ ᴠᴇʀɪғɪᴇᴅ !
345 | ɴᴏᴡ ʏᴏᴜ ʜᴀᴠᴇ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇss ғᴏʀ ᴀʟʟ ᴍᴏᴠɪᴇs ᴛɪʟʟ ᴛᴏᴅᴀʏ ᴍɪᴅɴɪɢʜᴛ."""
346 |
347 | VERIFY_TXT = """ʜᴇʟʟᴏ {},
348 | ʏᴏᴜʀ ᴀʀᴇ ɴᴏᴛ ᴠᴇʀɪғɪᴇᴅ ᴛᴏᴅᴀʏ,ᴘʟᴇᴀꜱᴇ ᴠᴇʀɪғʏ ɴᴏᴡ ᴀɴᴅ ɢᴇᴛ ᴜɴʟɪᴍɪᴛᴇᴅ ᴀᴄᴄᴇꜱꜱ ғᴏʀ ɴᴇxᴛ ᴠᴇʀɪғɪᴄᴀᴛɪᴏɴ...
349 | इस बाॅट को इस्तेमाल करने के लिए आपको ᴠᴇʀɪғʏ करना होगा नहीं तो आप इसका इस्तेमाल नहीं कर पाएंगे |"""
350 |
351 | VERIFY2_TXT = """
352 | Vᴇʀɪғʏ Sᴛᴀᴛᴜꜱ
353 | Nᴀᴍᴇ : {}
354 | Uꜱᴇʀ Sᴛᴀᴛᴜꜱ : Vᴇʀɪғɪᴇᴅ
355 | """
356 |
357 | RESTART_TXT = """
358 | Bᴏᴛ Rᴇsᴛᴀʀᴛᴇᴅ !
359 |
360 | 📅 Dᴀᴛᴇ : {}
361 | ⏰ Tɪᴍᴇ : {}
362 | 🌐 Tɪᴍᴇᴢᴏɴᴇ : Asia/Kolkata
363 | 🛠️ Bᴜɪʟᴅ Sᴛᴀᴛᴜs: v2.7.1 [ Sᴛᴀʙʟᴇ ]"""
364 |
365 | LOGO = """┏━━━━━━━━━━━━━━┓
366 | ┃ Made by → @KissuBots ┃
367 | ┗━━━━━━━━━━━━━━┛"""
368 |
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from pyrogram.errors import InputUserDeactivated, UserNotParticipant, FloodWait, UserIsBlocked, PeerIdInvalid
3 | from info import AUTH_CHANNEL, LONG_IMDB_DESCRIPTION, MAX_LIST_ELM, SHORTLINK_URL, SHORTLINK_API, IS_SHORTLINK, LOG_CHANNEL, TUTORIAL, GRP_LNK, CHNL_LNK, CUSTOM_FILE_CAPTION, HOW_TO_VERIFY
4 | from imdb import Cinemagoer
5 | import asyncio
6 | from pyrogram.types import Message, InlineKeyboardButton, InlineKeyboardMarkup
7 | from pyrogram.errors import FloodWait, UserIsBlocked, MessageNotModified, PeerIdInvalid
8 | from pyrogram import enums
9 | from typing import Union
10 | from Script import script
11 | import pytz
12 | import random
13 | import re
14 | import os
15 | from datetime import datetime, date
16 | import string
17 | from typing import List
18 | from database.users_chats_db import db
19 | from bs4 import BeautifulSoup
20 | import requests
21 | import aiohttp
22 | from shortzy import Shortzy
23 | import http.client
24 | import json
25 |
26 | logger = logging.getLogger(__name__)
27 | logger.setLevel(logging.INFO)
28 |
29 | BTN_URL_REGEX = re.compile(
30 | r"(\[([^\[]+?)\]\((buttonurl|buttonalert):(?:/{0,2})(.+?)(:same)?\))"
31 | )
32 |
33 | imdb = Cinemagoer()
34 | TOKENS = {}
35 | VERIFIED = {}
36 | BANNED = {}
37 | SECOND_SHORTENER = {}
38 | SMART_OPEN = '“'
39 | SMART_CLOSE = '”'
40 | START_CHAR = ('\'', '"', SMART_OPEN)
41 |
42 | # temp db for banned
43 | class temp(object):
44 | BANNED_USERS = []
45 | BANNED_CHATS = []
46 | ME = None
47 | CURRENT=int(os.environ.get("SKIP", 2))
48 | CANCEL = False
49 | MELCOW = {}
50 | U_NAME = None
51 | B_NAME = None
52 | GETALL = {}
53 | SHORT = {}
54 | SETTINGS = {}
55 | CAP = {}
56 |
57 | async def is_subscribed(bot, query):
58 | try:
59 | user = await bot.get_chat_member(AUTH_CHANNEL, query.from_user.id)
60 | except UserNotParticipant:
61 | pass
62 | except Exception as e:
63 | logger.exception(e)
64 | else:
65 | if user.status != enums.ChatMemberStatus.BANNED:
66 | return True
67 |
68 | return False
69 |
70 | async def get_poster(query, bulk=False, id=False, file=None):
71 | if not id:
72 | # https://t.me/GetTGLink/4183
73 | query = (query.strip()).lower()
74 | title = query
75 | year = re.findall(r'[1-2]\d{3}$', query, re.IGNORECASE)
76 | if year:
77 | year = list_to_str(year[:1])
78 | title = (query.replace(year, "")).strip()
79 | elif file is not None:
80 | year = re.findall(r'[1-2]\d{3}', file, re.IGNORECASE)
81 | if year:
82 | year = list_to_str(year[:1])
83 | else:
84 | year = None
85 | movieid = imdb.search_movie(title.lower(), results=10)
86 | if not movieid:
87 | return None
88 | if year:
89 | filtered=list(filter(lambda k: str(k.get('year')) == str(year), movieid))
90 | if not filtered:
91 | filtered = movieid
92 | else:
93 | filtered = movieid
94 | movieid=list(filter(lambda k: k.get('kind') in ['movie', 'tv series'], filtered))
95 | if not movieid:
96 | movieid = filtered
97 | if bulk:
98 | return movieid
99 | movieid = movieid[0].movieID
100 | else:
101 | movieid = query
102 | movie = imdb.get_movie(movieid)
103 | if movie.get("original air date"):
104 | date = movie["original air date"]
105 | elif movie.get("year"):
106 | date = movie.get("year")
107 | else:
108 | date = "N/A"
109 | plot = ""
110 | if not LONG_IMDB_DESCRIPTION:
111 | plot = movie.get('plot')
112 | if plot and len(plot) > 0:
113 | plot = plot[0]
114 | else:
115 | plot = movie.get('plot outline')
116 | if plot and len(plot) > 800:
117 | plot = plot[0:800] + "..."
118 |
119 | return {
120 | 'title': movie.get('title'),
121 | 'votes': movie.get('votes'),
122 | "aka": list_to_str(movie.get("akas")),
123 | "seasons": movie.get("number of seasons"),
124 | "box_office": movie.get('box office'),
125 | 'localized_title': movie.get('localized title'),
126 | 'kind': movie.get("kind"),
127 | "imdb_id": f"tt{movie.get('imdbID')}",
128 | "cast": list_to_str(movie.get("cast")),
129 | "runtime": list_to_str(movie.get("runtimes")),
130 | "countries": list_to_str(movie.get("countries")),
131 | "certificates": list_to_str(movie.get("certificates")),
132 | "languages": list_to_str(movie.get("languages")),
133 | "director": list_to_str(movie.get("director")),
134 | "writer":list_to_str(movie.get("writer")),
135 | "producer":list_to_str(movie.get("producer")),
136 | "composer":list_to_str(movie.get("composer")) ,
137 | "cinematographer":list_to_str(movie.get("cinematographer")),
138 | "music_team": list_to_str(movie.get("music department")),
139 | "distributors": list_to_str(movie.get("distributors")),
140 | 'release_date': date,
141 | 'year': movie.get('year'),
142 | 'genres': list_to_str(movie.get("genres")),
143 | 'poster': movie.get('full-size cover url'),
144 | 'plot': plot,
145 | 'rating': str(movie.get("rating")),
146 | 'url':f'https://www.imdb.com/title/tt{movieid}'
147 | }
148 | # https://github.com/odysseusmax/animated-lamp/blob/2ef4730eb2b5f0596ed6d03e7b05243d93e3415b/bot/utils/broadcast.py#L37
149 |
150 | async def broadcast_messages(user_id, message):
151 | try:
152 | await message.copy(chat_id=user_id)
153 | return True, "Success"
154 | except FloodWait as e:
155 | await asyncio.sleep(e.x)
156 | return await broadcast_messages(user_id, message)
157 | except InputUserDeactivated:
158 | await db.delete_user(int(user_id))
159 | logging.info(f"{user_id}-Removed from Database, since deleted account.")
160 | return False, "Deleted"
161 | except UserIsBlocked:
162 | logging.info(f"{user_id} -Blocked the bot.")
163 | return False, "Blocked"
164 | except PeerIdInvalid:
165 | await db.delete_user(int(user_id))
166 | logging.info(f"{user_id} - PeerIdInvalid")
167 | return False, "Error"
168 | except Exception as e:
169 | return False, "Error"
170 |
171 | async def broadcast_messages_group(chat_id, message):
172 | try:
173 | kd = await message.copy(chat_id=chat_id)
174 | try:
175 | await kd.pin()
176 | except:
177 | pass
178 | return True, "Success"
179 | except FloodWait as e:
180 | await asyncio.sleep(e.x)
181 | return await broadcast_messages_group(chat_id, message)
182 | except Exception as e:
183 | return False, "Error"
184 |
185 | async def search_gagala(text):
186 | usr_agent = {
187 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
188 | 'Chrome/61.0.3163.100 Safari/537.36'
189 | }
190 | text = text.replace(" ", '+')
191 | url = f'https://www.google.com/search?q={text}'
192 | response = requests.get(url, headers=usr_agent)
193 | response.raise_for_status()
194 | soup = BeautifulSoup(response.text, 'html.parser')
195 | titles = soup.find_all( 'h3' )
196 | return [title.getText() for title in titles]
197 |
198 | async def get_settings(group_id):
199 | settings = temp.SETTINGS.get(group_id)
200 | if not settings:
201 | settings = await db.get_settings(group_id)
202 | temp.SETTINGS[group_id] = settings
203 | return settings
204 |
205 | async def save_group_settings(group_id, key, value):
206 | current = await get_settings(group_id)
207 | current[key] = value
208 | temp.SETTINGS[group_id] = current
209 | await db.update_settings(group_id, current)
210 |
211 | def get_size(size):
212 | """Get size in readable format"""
213 |
214 | units = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB"]
215 | size = float(size)
216 | i = 0
217 | while size >= 1024.0 and i < len(units):
218 | i += 1
219 | size /= 1024.0
220 | return "%.2f %s" % (size, units[i])
221 |
222 | def split_list(l, n):
223 | for i in range(0, len(l), n):
224 | yield l[i:i + n]
225 |
226 | def get_file_id(msg: Message):
227 | if msg.media:
228 | for message_type in (
229 | "photo",
230 | "animation",
231 | "audio",
232 | "document",
233 | "video",
234 | "video_note",
235 | "voice",
236 | "sticker"
237 | ):
238 | obj = getattr(msg, message_type)
239 | if obj:
240 | setattr(obj, "message_type", message_type)
241 | return obj
242 |
243 | def extract_user(message: Message) -> Union[int, str]:
244 | """extracts the user from a message"""
245 | # https://github.com/SpEcHiDe/PyroGramBot/blob/f30e2cca12002121bad1982f68cd0ff9814ce027/pyrobot/helper_functions/extract_user.py#L7
246 | user_id = None
247 | user_first_name = None
248 | if message.reply_to_message:
249 | user_id = message.reply_to_message.from_user.id
250 | user_first_name = message.reply_to_message.from_user.first_name
251 |
252 | elif len(message.command) > 1:
253 | if (
254 | len(message.entities) > 1 and
255 | message.entities[1].type == enums.MessageEntityType.TEXT_MENTION
256 | ):
257 |
258 | required_entity = message.entities[1]
259 | user_id = required_entity.user.id
260 | user_first_name = required_entity.user.first_name
261 | else:
262 | user_id = message.command[1]
263 | # don't want to make a request -_-
264 | user_first_name = user_id
265 | try:
266 | user_id = int(user_id)
267 | except ValueError:
268 | pass
269 | else:
270 | user_id = message.from_user.id
271 | user_first_name = message.from_user.first_name
272 | return (user_id, user_first_name)
273 |
274 | def list_to_str(k):
275 | if not k:
276 | return "N/A"
277 | elif len(k) == 1:
278 | return str(k[0])
279 | elif MAX_LIST_ELM:
280 | k = k[:int(MAX_LIST_ELM)]
281 | return ' '.join(f'{elem}, ' for elem in k)
282 | else:
283 | return ' '.join(f'{elem}, ' for elem in k)
284 |
285 | def last_online(from_user):
286 | time = ""
287 | if from_user.is_bot:
288 | time += "🤖 Bot :("
289 | elif from_user.status == enums.UserStatus.RECENTLY:
290 | time += "Recently"
291 | elif from_user.status == enums.UserStatus.LAST_WEEK:
292 | time += "Within the last week"
293 | elif from_user.status == enums.UserStatus.LAST_MONTH:
294 | time += "Within the last month"
295 | elif from_user.status == enums.UserStatus.LONG_AGO:
296 | time += "A long time ago :("
297 | elif from_user.status == enums.UserStatus.ONLINE:
298 | time += "Currently Online"
299 | elif from_user.status == enums.UserStatus.OFFLINE:
300 | time += from_user.last_online_date.strftime("%a, %d %b %Y, %H:%M:%S")
301 | return time
302 |
303 |
304 | def split_quotes(text: str) -> List:
305 | if not any(text.startswith(char) for char in START_CHAR):
306 | return text.split(None, 1)
307 | counter = 1 # ignore first char -> is some kind of quote
308 | while counter < len(text):
309 | if text[counter] == "\\":
310 | counter += 1
311 | elif text[counter] == text[0] or (text[0] == SMART_OPEN and text[counter] == SMART_CLOSE):
312 | break
313 | counter += 1
314 | else:
315 | return text.split(None, 1)
316 |
317 | # 1 to avoid starting quote, and counter is exclusive so avoids ending
318 | key = remove_escapes(text[1:counter].strip())
319 | # index will be in range, or `else` would have been executed and returned
320 | rest = text[counter + 1:].strip()
321 | if not key:
322 | key = text[0] + text[0]
323 | return list(filter(None, [key, rest]))
324 |
325 | def gfilterparser(text, keyword):
326 | if "buttonalert" in text:
327 | text = (text.replace("\n", "\\n").replace("\t", "\\t"))
328 | buttons = []
329 | note_data = ""
330 | prev = 0
331 | i = 0
332 | alerts = []
333 | for match in BTN_URL_REGEX.finditer(text):
334 | # Check if btnurl is escaped
335 | n_escapes = 0
336 | to_check = match.start(1) - 1
337 | while to_check > 0 and text[to_check] == "\\":
338 | n_escapes += 1
339 | to_check -= 1
340 |
341 | # if even, not escaped -> create button
342 | if n_escapes % 2 == 0:
343 | note_data += text[prev:match.start(1)]
344 | prev = match.end(1)
345 | if match.group(3) == "buttonalert":
346 | # create a thruple with button label, url, and newline status
347 | if bool(match.group(5)) and buttons:
348 | buttons[-1].append(InlineKeyboardButton(
349 | text=match.group(2),
350 | callback_data=f"gfilteralert:{i}:{keyword}"
351 | ))
352 | else:
353 | buttons.append([InlineKeyboardButton(
354 | text=match.group(2),
355 | callback_data=f"gfilteralert:{i}:{keyword}"
356 | )])
357 | i += 1
358 | alerts.append(match.group(4))
359 | elif bool(match.group(5)) and buttons:
360 | buttons[-1].append(InlineKeyboardButton(
361 | text=match.group(2),
362 | url=match.group(4).replace(" ", "")
363 | ))
364 | else:
365 | buttons.append([InlineKeyboardButton(
366 | text=match.group(2),
367 | url=match.group(4).replace(" ", "")
368 | )])
369 |
370 | else:
371 | note_data += text[prev:to_check]
372 | prev = match.start(1) - 1
373 | else:
374 | note_data += text[prev:]
375 |
376 | try:
377 | return note_data, buttons, alerts
378 | except:
379 | return note_data, buttons, None
380 |
381 | def parser(text, keyword):
382 | if "buttonalert" in text:
383 | text = (text.replace("\n", "\\n").replace("\t", "\\t"))
384 | buttons = []
385 | note_data = ""
386 | prev = 0
387 | i = 0
388 | alerts = []
389 | for match in BTN_URL_REGEX.finditer(text):
390 | # Check if btnurl is escaped
391 | n_escapes = 0
392 | to_check = match.start(1) - 1
393 | while to_check > 0 and text[to_check] == "\\":
394 | n_escapes += 1
395 | to_check -= 1
396 |
397 | # if even, not escaped -> create button
398 | if n_escapes % 2 == 0:
399 | note_data += text[prev:match.start(1)]
400 | prev = match.end(1)
401 | if match.group(3) == "buttonalert":
402 | # create a thruple with button label, url, and newline status
403 | if bool(match.group(5)) and buttons:
404 | buttons[-1].append(InlineKeyboardButton(
405 | text=match.group(2),
406 | callback_data=f"alertmessage:{i}:{keyword}"
407 | ))
408 | else:
409 | buttons.append([InlineKeyboardButton(
410 | text=match.group(2),
411 | callback_data=f"alertmessage:{i}:{keyword}"
412 | )])
413 | i += 1
414 | alerts.append(match.group(4))
415 | elif bool(match.group(5)) and buttons:
416 | buttons[-1].append(InlineKeyboardButton(
417 | text=match.group(2),
418 | url=match.group(4).replace(" ", "")
419 | ))
420 | else:
421 | buttons.append([InlineKeyboardButton(
422 | text=match.group(2),
423 | url=match.group(4).replace(" ", "")
424 | )])
425 |
426 | else:
427 | note_data += text[prev:to_check]
428 | prev = match.start(1) - 1
429 | else:
430 | note_data += text[prev:]
431 |
432 | try:
433 | return note_data, buttons, alerts
434 | except:
435 | return note_data, buttons, None
436 |
437 | def remove_escapes(text: str) -> str:
438 | res = ""
439 | is_escaped = False
440 | for counter in range(len(text)):
441 | if is_escaped:
442 | res += text[counter]
443 | is_escaped = False
444 | elif text[counter] == "\\":
445 | is_escaped = True
446 | else:
447 | res += text[counter]
448 | return res
449 |
450 |
451 | def humanbytes(size):
452 | if not size:
453 | return ""
454 | power = 2**10
455 | n = 0
456 | Dic_powerN = {0: ' ', 1: 'Ki', 2: 'Mi', 3: 'Gi', 4: 'Ti'}
457 | while size > power:
458 | size /= power
459 | n += 1
460 | return str(round(size, 2)) + " " + Dic_powerN[n] + 'B'
461 |
462 | async def get_shortlink(chat_id, link):
463 | settings = await get_settings(chat_id) #fetching settings for group
464 | if 'shortlink' in settings.keys():
465 | URL = settings['shortlink']
466 | API = settings['shortlink_api']
467 | else:
468 | URL = SHORTLINK_URL
469 | API = SHORTLINK_API
470 | if URL.startswith("shorturllink") or URL.startswith("terabox.in") or URL.startswith("urlshorten.in"):
471 | URL = SHORTLINK_URL
472 | API = SHORTLINK_API
473 | if URL == "api.shareus.io":
474 | # method 1:
475 | # https = link.split(":")[0] #splitting https or http from link
476 | # if "http" == https: #if https == "http":
477 | # https = "https"
478 | # link = link.replace("http", https) #replacing http to https
479 | # conn = http.client.HTTPSConnection("api.shareus.io")
480 | # payload = json.dumps({
481 | # "api_key": "4c1YTBacB6PTuwogBiEIFvZN5TI3",
482 | # "monetization": True,
483 | # "destination": link,
484 | # "ad_page": 3,
485 | # "category": "Entertainment",
486 | # "tags": ["trendinglinks"],
487 | # "monetize_with_money": False,
488 | # "price": 0,
489 | # "currency": "INR",
490 | # "purchase_note":""
491 |
492 | # })
493 | # headers = {
494 | # 'Keep-Alive': '',
495 | # 'Content-Type': 'application/json'
496 | # }
497 | # conn.request("POST", "/generate_link", payload, headers)
498 | # res = conn.getresponse()
499 | # data = res.read().decode("utf-8")
500 | # parsed_data = json.loads(data)
501 | # if parsed_data["status"] == "success":
502 | # return parsed_data["link"]
503 | #method 2
504 | url = f'https://{URL}/easy_api'
505 | params = {
506 | "key": API,
507 | "link": link,
508 | }
509 | try:
510 | async with aiohttp.ClientSession() as session:
511 | async with session.get(url, params=params, raise_for_status=True, ssl=False) as response:
512 | data = await response.text()
513 | return data
514 | except Exception as e:
515 | logger.error(e)
516 | return link
517 | else:
518 | shortzy = Shortzy(api_key=API, base_site=URL)
519 | link = await shortzy.convert(link)
520 | return link
521 |
522 | async def get_tutorial(chat_id):
523 | settings = await get_settings(chat_id) #fetching settings for group
524 | if 'tutorial' in settings.keys():
525 | if settings['is_tutorial']:
526 | TUTORIAL_URL = settings['tutorial']
527 | else:
528 | TUTORIAL_URL = TUTORIAL
529 | else:
530 | TUTORIAL_URL = TUTORIAL
531 | return TUTORIAL_URL
532 |
533 | async def get_verify_shorted_link(link):
534 | API = SHORTLINK_API
535 | URL = SHORTLINK_URL
536 | https = link.split(":")[0]
537 | if "http" == https:
538 | https = "https"
539 | link = link.replace("http", https)
540 |
541 | if URL == "api.shareus.in":
542 | url = f"https://{URL}/shortLink"
543 | params = {"token": API,
544 | "format": "json",
545 | "link": link,
546 | }
547 | try:
548 | async with aiohttp.ClientSession() as session:
549 | async with session.get(url, params=params, raise_for_status=True, ssl=False) as response:
550 | data = await response.json(content_type="text/html")
551 | if data["status"] == "success":
552 | return data["shortlink"]
553 | else:
554 | logger.error(f"Error: {data['message']}")
555 | return f'https://{URL}/shortLink?token={API}&format=json&link={link}'
556 |
557 | except Exception as e:
558 | logger.error(e)
559 | return f'https://{URL}/shortLink?token={API}&format=json&link={link}'
560 | else:
561 | url = f'https://{URL}/api'
562 | params = {'api': API,
563 | 'url': link,
564 | }
565 | try:
566 | async with aiohttp.ClientSession() as session:
567 | async with session.get(url, params=params, raise_for_status=True, ssl=False) as response:
568 | data = await response.json()
569 | if data["status"] == "success":
570 | return data['shortenedUrl']
571 | else:
572 | logger.error(f"Error: {data['message']}")
573 | return f'https://{URL}/api?api={API}&link={link}'
574 |
575 | except Exception as e:
576 | logger.error(e)
577 | return f'{URL}/api?api={API}&link={link}'
578 |
579 | async def check_token(bot, userid, token):
580 | user = await bot.get_users(userid)
581 | if not await db.is_user_exist(user.id):
582 | await db.add_user(user.id, user.first_name)
583 | await bot.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(user.id, user.mention))
584 | if user.id in TOKENS.keys():
585 | TKN = TOKENS[user.id]
586 | if token in TKN.keys():
587 | is_used = TKN[token]
588 | if is_used == True:
589 | return False
590 | else:
591 | return True
592 | else:
593 | return False
594 |
595 | async def get_token(bot, userid, link):
596 | user = await bot.get_users(userid)
597 | if not await db.is_user_exist(user.id):
598 | await db.add_user(user.id, user.first_name)
599 | await bot.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(user.id, user.mention))
600 | token = ''.join(random.choices(string.ascii_letters + string.digits, k=7))
601 | TOKENS[user.id] = {token: False}
602 | link = f"{link}verify-{user.id}-{token}"
603 | shortened_verify_url = await get_verify_shorted_link(link)
604 | return str(shortened_verify_url)
605 |
606 | async def verify_user(bot, userid, token):
607 | user = await bot.get_users(userid)
608 | if not await db.is_user_exist(user.id):
609 | await db.add_user(user.id, user.first_name)
610 | await bot.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(user.id, user.mention))
611 | TOKENS[user.id] = {token: True}
612 | tz = pytz.timezone('Asia/Kolkata')
613 | today = date.today()
614 | VERIFIED[user.id] = str(today)
615 |
616 | async def check_verification(bot, userid):
617 | user = await bot.get_users(userid)
618 | if not await db.is_user_exist(user.id):
619 | await db.add_user(user.id, user.first_name)
620 | await bot.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(user.id, user.mention))
621 | tz = pytz.timezone('Asia/Kolkata')
622 | today = date.today()
623 | if user.id in VERIFIED.keys():
624 | EXP = VERIFIED[user.id]
625 | years, month, day = EXP.split('-')
626 | comp = date(int(years), int(month), int(day))
627 | if compHᴇʏ ᴛʜᴇʀᴇ {user_name} 👋🏽 \n\n✅ Sᴇᴄᴜʀᴇ ʟɪɴᴋ ᴛᴏ ʏᴏᴜʀ ғɪʟᴇ ʜᴀs sᴜᴄᴄᴇssғᴜʟʟʏ ʙᴇᴇɴ ɢᴇɴᴇʀᴀᴛᴇᴅ ᴘʟᴇᴀsᴇ ᴄʟɪᴄᴋ ᴅᴏᴡɴʟᴏᴀᴅ ʙᴜᴛᴛᴏɴ\n\n🗃️ Fɪʟᴇ Nᴀᴍᴇ : {title}\n🔖 Fɪʟᴇ Sɪᴢᴇ : {size}", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("📤 Dᴏᴡɴʟᴏᴀᴅ 📥", url=await get_shortlink(chat_id, f"https://telegram.me/{temp.U_NAME}?start=files_{file.file_id}"))]]))
648 | else:
649 | for file in files:
650 | f_caption = file.caption
651 | title = file.file_name
652 | size = get_size(file.file_size)
653 | if CUSTOM_FILE_CAPTION:
654 | try:
655 | f_caption = CUSTOM_FILE_CAPTION.format(file_name='' if title is None else title,
656 | file_size='' if size is None else size,
657 | file_caption='' if f_caption is None else f_caption)
658 | except Exception as e:
659 | print(e)
660 | f_caption = f_caption
661 | if f_caption is None:
662 | f_caption = f"{title}"
663 | await bot.send_cached_media(
664 | chat_id=userid,
665 | file_id=file.file_id,
666 | caption=f_caption,
667 | protect_content=True if ident == "filep" else False,
668 | reply_markup=InlineKeyboardMarkup(
669 | [
670 | [
671 | InlineKeyboardButton('Sᴜᴘᴘᴏʀᴛ Gʀᴏᴜᴘ', url="https://t.me/kissuhelp"),
672 | InlineKeyboardButton('Uᴘᴅᴀᴛᴇs Cʜᴀɴɴᴇʟ', url="https://t.me/kissuxbots")
673 | ],[
674 | InlineKeyboardButton("Bᴏᴛ Oᴡɴᴇʀ", url="t.me/xaekks")
675 | ]
676 | ]
677 | )
678 | )
679 | except UserIsBlocked:
680 | await query.answer('Uɴʙʟᴏᴄᴋ ᴛʜᴇ ʙᴏᴛ ᴍᴀʜɴ !', show_alert=True)
681 | except PeerIdInvalid:
682 | await query.answer('Hᴇʏ, Sᴛᴀʀᴛ Bᴏᴛ Fɪʀsᴛ Aɴᴅ Cʟɪᴄᴋ Sᴇɴᴅ Aʟʟ', show_alert=True)
683 | except Exception as e:
684 | await query.answer('Hᴇʏ, Sᴛᴀʀᴛ Bᴏᴛ Fɪʀsᴛ Aɴᴅ Cʟɪᴄᴋ Sᴇɴᴅ Aʟʟ', show_alert=True)
685 |
--------------------------------------------------------------------------------
/plugins/commands.py:
--------------------------------------------------------------------------------
1 | import os
2 | import logging
3 | import random
4 | import asyncio
5 | from Script import script
6 | from pyrogram import Client, filters, enums
7 | from pyrogram.errors import ChatAdminRequired, FloodWait
8 | from pyrogram.types import *
9 | from database.ia_filterdb import Media, get_file_details, unpack_new_file_id, get_bad_files
10 | from database.users_chats_db import db
11 | from info import CHANNELS, ADMINS, AUTH_CHANNEL, LOG_CHANNEL, PICS, VRFIED_IMG, VRFY_IMG, BATCH_FILE_CAPTION, CUSTOM_FILE_CAPTION, PROTECT_CONTENT, CHNL_LNK, GRP_LNK, SPRT_CHNL, REQ_GRP, REQST_CHANNEL, SUPPORT_CHAT_ID, SUPPORT_CHAT, MAX_B_TN, VERIFY, SHORTLINK_API, SHORTLINK_URL, TUTORIAL, IS_TUTORIAL, HOW_TO_VERIFY, PREMIUM_USER
12 | from utils import get_settings, get_size, is_subscribed, save_group_settings, temp, verify_user, check_token, check_verification, get_token, get_shortlink, get_tutorial
13 | from database.connections_mdb import active_connection
14 | # from plugins.pm_filter import ENABLE_SHORTLINK
15 | import re, asyncio, os, sys
16 | import json
17 | import base64
18 | logger = logging.getLogger(__name__)
19 |
20 |
21 | BATCH_FILES = {}
22 |
23 | @Client.on_message(filters.command("start") & filters.incoming)
24 | async def start(client, message):
25 | if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
26 | buttons = [[
27 | InlineKeyboardButton('🛡️ Aᴅᴅ Mᴇ Tᴏ Yᴏᴜʀ Gʀᴏᴜᴘ 🛡️', url=f'http://t.me/{temp.U_NAME}?startgroup=true')
28 | ],[
29 | InlineKeyboardButton('↼ Sᴜᴘᴘᴏʀᴛ Gʀᴏᴜᴘ', url=SPRT_CHNL),
30 | InlineKeyboardButton('Sᴇᴀʀᴄʜ 🔎 ', url=GRP_LNK)
31 | ]]
32 | reply_markup = InlineKeyboardMarkup(buttons)
33 | await message.reply(script.START_TXT.format(message.from_user.mention if message.from_user else message.chat.title, temp.U_NAME, temp.B_NAME), reply_markup=reply_markup, disable_web_page_preview=True)
34 | await asyncio.sleep(2) # 😢 https://github.com/EvamariaTG/EvaMaria/blob/master/plugins/p_ttishow.py#L17 😬 wait a bit, before checking.
35 | if not await db.get_chat(message.chat.id):
36 | total=await client.get_chat_members_count(message.chat.id)
37 | await client.send_message(LOG_CHANNEL, script.LOG_TEXT_G.format(message.chat.title, message.chat.id, total, "Unknown"))
38 | await db.add_chat(message.chat.id, message.chat.title)
39 | return
40 | if not await db.is_user_exist(message.from_user.id):
41 | await db.add_user(message.from_user.id, message.from_user.first_name)
42 | await client.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(message.from_user.id, message.from_user.mention))
43 | if len(message.command) != 2:
44 | buttons = [[
45 | InlineKeyboardButton('➕ Aᴅᴅ Mᴇ Tᴏ Yᴏᴜʀ Gʀᴏᴜᴘ ➕', url=f'http://t.me/{temp.U_NAME}?startgroup=true')
46 | ],[
47 | InlineKeyboardButton("Sᴇᴀʀᴄʜ 🔎",url=REQ_GRP),
48 | InlineKeyboardButton("📌 Uᴘᴅᴀᴛᴇs", url="https://t.me/kissuxbots")
49 | ],[
50 | InlineKeyboardButton("Hᴇʟᴩ 💡", callback_data="help"),
51 | InlineKeyboardButton("Aʙᴏᴜᴛ 📰", callback_data="about")
52 | ],[
53 | InlineKeyboardButton(" Make Your Own Bot", url="https://GitHub.com/pykinsu/tele-filter-bot/")
54 | ]]
55 | reply_markup = InlineKeyboardMarkup(buttons)
56 | m=await message.reply_sticker("CAACAgQAAxkBAAEOHdZn2piuieMXbUOL_7I2Iqb9ArF19QACKwoAArAqAVIMufqlVovwXzYE")
57 | await asyncio.sleep(1)
58 | await m.delete()
59 | await message.reply_photo(
60 | photo=random.choice(PICS),
61 | caption=script.START_TXT.format(message.from_user.mention, temp.U_NAME, temp.B_NAME),
62 | reply_markup=reply_markup,
63 | parse_mode=enums.ParseMode.HTML
64 | )
65 | return
66 |
67 | if AUTH_CHANNEL and not await is_subscribed(client, message):
68 | try:
69 | invite_link = await client.create_chat_invite_link(int(AUTH_CHANNEL))
70 | except ChatAdminRequired:
71 | logger.error("Make sure Bot is admin in Forcesub channel")
72 | return
73 | btn = [
74 | [
75 | InlineKeyboardButton(
76 | "↺ Jᴏɪɴ Oᴜʀ Bᴀᴄᴋ-ᴜᴘ Cʜᴀɴɴᴇʟ ↺", url=invite_link.invite_link
77 | )
78 | ]
79 | ]
80 |
81 | if message.command[1] != "subscribe":
82 | try:
83 | kk, file_id = message.command[1].split("_", 1)
84 | btn.append([InlineKeyboardButton("↺ Tʀʏ Aɢᴀɪɴ", callback_data=f"checksub#{kk}#{file_id}")])
85 | except (IndexError, ValueError):
86 | btn.append([InlineKeyboardButton("↺ Tʀʏ Aɢᴀɪɴ", url=f"https://t.me/{temp.U_NAME}?start={message.command[1]}")])
87 | await client.send_photo(
88 | photo=random.choice(PICS),
89 | chat_id=message.from_user.id,
90 | # text="**You are not in our channel given below so you don't get the movie file...\n\nIf you want the movie file, click on the '🍿ᴊᴏɪɴ ᴏᴜʀ ʙᴀᴄᴋ-ᴜᴘ ᴄʜᴀɴɴᴇʟ🍿' button below and join our back-up channel, then click on the '🔄 Try Again' button below...\n\nThen you will get the movie files...**",
91 | caption=script.FORCE_SUB,
92 | reply_markup=InlineKeyboardMarkup(btn),
93 | parse_mode=enums.ParseMode.MARKDOWN
94 | )
95 | return
96 | if len(message.command) == 2 and message.command[1] in ["subscribe", "error", "okay", "help"]:
97 | buttons = [[
98 | InlineKeyboardButton('➕ Aᴅᴅ Mᴇ Tᴏ Yᴏᴜʀ Gʀᴏᴜᴘ ➕', url=f'http://t.me/{temp.U_NAME}?startgroup=true')
99 | ],[
100 | InlineKeyboardButton("Sᴇᴀʀᴄʜ 🔎",url=REQ_GRP),
101 | InlineKeyboardButton("📌 Uᴘᴅᴀᴛᴇs", url="https://t.me/kissuxbots")
102 | ],[
103 | InlineKeyboardButton("Hᴇʟᴩ 💡", callback_data="help"),
104 | InlineKeyboardButton("Aʙᴏᴜᴛ 📰", callback_data="about")
105 | ],[
106 | InlineKeyboardButton(" Make Your Own Bot", url="https://GitHub.com/pykinsu/tele-filter-bot/")
107 | ]]
108 | reply_markup = InlineKeyboardMarkup(buttons)
109 | await message.reply_photo(
110 | photo=random.choice(PICS),
111 | caption=script.START_TXT.format(message.from_user.mention, temp.U_NAME, temp.B_NAME),
112 | reply_markup=reply_markup,
113 | parse_mode=enums.ParseMode.HTML
114 | )
115 | return
116 | data = message.command[1]
117 | try:
118 | pre, file_id = data.split('_', 1)
119 | except:
120 | file_id = data
121 | pre = ""
122 | if data.split("-", 1)[0] == "BATCH":
123 | sts = await message.reply("Please wait...")
124 | file_id = data.split("-", 1)[1]
125 | msgs = BATCH_FILES.get(file_id)
126 | if not msgs:
127 | file = await client.download_media(file_id)
128 | try:
129 | with open(file) as file_data:
130 | msgs=json.loads(file_data.read())
131 | except:
132 | await sts.edit("FAILED")
133 | return await client.send_message(LOG_CHANNEL, "UNABLE TO OPEN FILE.")
134 | os.remove(file)
135 | BATCH_FILES[file_id] = msgs
136 | for msg in msgs:
137 | title = msg.get("title")
138 | size=get_size(int(msg.get("size", 0)))
139 | f_caption=msg.get("caption", "")
140 | if BATCH_FILE_CAPTION:
141 | try:
142 | f_caption=BATCH_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption)
143 | except Exception as e:
144 | logger.exception(e)
145 | f_caption=f_caption
146 | if f_caption is None:
147 | f_caption = f"{title}"
148 | try:
149 | await client.send_cached_media(
150 | chat_id=message.from_user.id,
151 | file_id=msg.get("file_id"),
152 | caption=f_caption,
153 | protect_content=msg.get('protect', False))
154 | except FloodWait as e:
155 | await asyncio.sleep(e.x)
156 | logger.warning(f"Floodwait of {e.x} sec.")
157 | await client.send_cached_media(
158 | chat_id=message.from_user.id,
159 | file_id=msg.get("file_id"),
160 | caption=f_caption,
161 | protect_content=msg.get('protect', False),
162 | )
163 | except Exception as e:
164 | logger.warning(e, exc_info=True)
165 | continue
166 | await asyncio.sleep(1)
167 | await sts.delete()
168 | return
169 |
170 | elif data.split("-", 1)[0] == "DSTORE":
171 | sts = await message.reply("Please wait...")
172 | b_string = data.split("-", 1)[1]
173 | decoded = (base64.urlsafe_b64decode(b_string + "=" * (-len(b_string) % 4))).decode("ascii")
174 | try:
175 | f_msg_id, l_msg_id, f_chat_id, protect = decoded.split("_", 3)
176 | except:
177 | f_msg_id, l_msg_id, f_chat_id = decoded.split("_", 2)
178 | protect = "/pbatch" if PROTECT_CONTENT else "batch"
179 | diff = int(l_msg_id) - int(f_msg_id)
180 | async for msg in client.iter_messages(int(f_chat_id), int(l_msg_id), int(f_msg_id)):
181 | if msg.media:
182 | media = getattr(msg, msg.media.value)
183 | if BATCH_FILE_CAPTION:
184 | try:
185 | f_caption=BATCH_FILE_CAPTION.format(file_name=getattr(media, 'file_name', ''), file_size=getattr(media, 'file_size', ''), file_caption=getattr(msg, 'caption', ''))
186 | except Exception as e:
187 | logger.exception(e)
188 | f_caption = getattr(msg, 'caption', '')
189 | else:
190 | media = getattr(msg, msg.media.value)
191 | file_name = getattr(media, 'file_name', '')
192 | f_caption = getattr(msg, 'caption', file_name)
193 | try:
194 | await msg.copy(message.chat.id, caption=f_caption, protect_content=True if protect == "/pbatch" else False)
195 | except FloodWait as e:
196 | await asyncio.sleep(e.x)
197 | await msg.copy(message.chat.id, caption=f_caption, protect_content=True if protect == "/pbatch" else False)
198 | except Exception as e:
199 | logger.exception(e)
200 | continue
201 | elif msg.empty:
202 | continue
203 | else:
204 | try:
205 | await msg.copy(message.chat.id, protect_content=True if protect == "/pbatch" else False)
206 | except FloodWait as e:
207 | await asyncio.sleep(e.x)
208 | await msg.copy(message.chat.id, protect_content=True if protect == "/pbatch" else False)
209 | except Exception as e:
210 | logger.exception(e)
211 | continue
212 | await asyncio.sleep(1)
213 | return await sts.delete()
214 |
215 | elif data.split("-", 1)[0] == "verify":
216 | userid = data.split("-", 2)[1]
217 | token = data.split("-", 3)[2]
218 | if str(message.from_user.id) != str(userid):
219 | return await message.reply_text(
220 | text="Iɴᴠᴀʟɪᴅ Lɪɴᴋ ᴏʀ Exᴘɪʀᴇᴅ Lɪɴᴋ !",
221 | protect_content=True
222 | )
223 | is_valid = await check_token(client, userid, token)
224 | if is_valid == True:
225 | await message.reply_photo(
226 | photo = VRFIED_IMG,
227 | caption = script.VERIFED_TXT.format(message.from_user.mention, temp.U_NAME, temp.B_NAME),
228 | # protect_content=True
229 | )
230 | await verify_user(client, userid, token)
231 | else:
232 | return await message.reply_text(
233 | text="Iɴᴠᴀʟɪᴅ Lɪɴᴋ ᴏʀ Exᴘɪʀᴇᴅ Lɪɴᴋ !",
234 | # protect_content=True
235 | )
236 | if data.startswith("sendfiles"):
237 | chat_id = int("-" + file_id.split("-")[1])
238 | userid = message.from_user.id if message.from_user else None
239 | g = await get_shortlink(chat_id, f"https://telegram.me/{temp.U_NAME}?start=allfiles_{file_id}")
240 | k = await client.send_message(chat_id=message.from_user.id,text=f"Get All Files in a Single Click!!!\n\n📂 ʟɪɴᴋ ➠ : {g}\n\nNote: This message is deleted in 5 mins to avoid copyrights. Save the link to Somewhere else", reply_markup=InlineKeyboardMarkup(
241 | [
242 | [
243 | InlineKeyboardButton('📂 Dᴏᴡɴʟᴏᴀᴅ Nᴏᴡ 📂', url=g)
244 | ], [
245 | InlineKeyboardButton('🤔 Hᴏᴡ Tᴏ Dᴏᴡɴʟᴏᴀᴅ 🤔', url=await get_tutorial(chat_id))
246 | ]
247 | ]
248 | )
249 | )
250 | await asyncio.sleep(300)
251 | await k.edit("Yᴏᴜʀ ᴍᴇssᴀɢᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ!!!")
252 | return
253 |
254 |
255 | elif data.startswith("short"):
256 | user = message.from_user.id
257 | chat_id = temp.SHORT.get(user)
258 | files_ = await get_file_details(file_id)
259 | files = files_[0]
260 | g = await get_shortlink(chat_id, f"https://telegram.me/{temp.U_NAME}?start=file_{file_id}")
261 | k = await client.send_message(chat_id=user,text=f"📕Nᴀᴍᴇ ➠ : {files.file_name} \n\n🔗Sɪᴢᴇ ➠ : {get_size(files.file_size)}\n\n📂Fɪʟᴇ ʟɪɴᴋ ➠ : {g}\n\nNote: This message is deleted in 20 mins to avoid copyrights. Save the link to Somewhere else", reply_markup=InlineKeyboardMarkup(
262 | [
263 | [
264 | InlineKeyboardButton('📂 Dᴏᴡɴʟᴏᴀᴅ Nᴏᴡ 📂', url=g)
265 | ], [
266 | InlineKeyboardButton('🤔 Hᴏᴡ Tᴏ Dᴏᴡɴʟᴏᴀᴅ 🤔', url=await get_tutorial(chat_id))
267 | ]
268 | ]
269 | )
270 | )
271 | await asyncio.sleep(1200)
272 | await k.edit("Yᴏᴜʀ ᴍᴇssᴀɢᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ!!!")
273 | return
274 |
275 | elif data.startswith("all"):
276 | files = temp.GETALL.get(file_id)
277 | if not files:
278 | return await message.reply('Nᴏ Sᴜᴄʜ Fɪʟᴇ Eᴇxɪsᴛ.')
279 | filesarr = []
280 | for file in files:
281 | file_id = file.file_id
282 | files_ = await get_file_details(file_id)
283 | files1 = files_[0]
284 | title = ' '.join(filter(lambda x: not x.startswith('[') and not x.startswith('@'), files1.file_name.split()))
285 | size=get_size(files1.file_size)
286 | f_caption=files1.caption
287 | if CUSTOM_FILE_CAPTION:
288 | try:
289 | f_caption=CUSTOM_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption)
290 | except Exception as e:
291 | logger.exception(e)
292 | f_caption=f_caption
293 | if f_caption is None:
294 | f_caption = f"{' '.join(filter(lambda x: not x.startswith('[') and not x.startswith('@'), files1.file_name.split()))}"
295 | if not await check_verification(client, message.from_user.id) and VERIFY == True:
296 | btn = [[
297 | InlineKeyboardButton("♻️ Vᴇʀɪғʏ ♻️", url=await get_token(client, message.from_user.id, f"https://telegram.me/{temp.U_NAME}?start=")),
298 | InlineKeyboardButton("⚠️ Hᴏᴡ Tᴏ Vᴇʀɪғʏ ⚠️", url=HOW_TO_VERIFY)
299 | ]]
300 | await message.reply_photo(
301 | photo = VRFY_IMG,
302 | caption=script.VERIFY_TXT.format(message.from_user.mention, temp.U_NAME, temp.B_NAME),
303 | # protect_content=True,
304 | reply_markup=InlineKeyboardMarkup(btn)
305 | )
306 | return
307 | msg = await client.send_cached_media(
308 | chat_id=message.from_user.id,
309 | file_id=file_id,
310 | caption=f_caption,
311 | protect_content=True if pre == 'filep' else False,
312 | )
313 | # filesarr.append(msg)
314 | # k = await client.send_message(chat_id = message.from_user.id, text=f"❗️❗️❗️IMPORTANT❗️️❗️❗️\n\nThis Movie Files/Videos will be deleted in 10 mins 🫥 (Due to Copyright Issues).\n\nPlease forward this ALL Files/Videos to your Saved Messages and Start Download there")
315 | # await asyncio.sleep(600)
316 | # for x in filesarr:
317 | # await x.delete()
318 | # await k.edit_text("Your All Files/Videos is successfully deleted!!!")
319 | # return
320 |
321 | elif data.startswith("files"):
322 | user = message.from_user.id
323 | if temp.SHORT.get(user)==None:
324 | await message.reply_text(text="Please Search Again in Group")
325 | else:
326 | chat_id = temp.SHORT.get(user)
327 | settings = await get_settings(chat_id)
328 | if settings['is_shortlink'] and user not in PREMIUM_USER:
329 | files_ = await get_file_details(file_id)
330 | files = files_[0]
331 | g = await get_shortlink(chat_id, f"https://telegram.me/{temp.U_NAME}?start=file_{file_id}")
332 | k = await client.send_message(chat_id=message.from_user.id,text=f"📕Nᴀᴍᴇ ➠ : {files.file_name} \n\n🔗Sɪᴢᴇ ➠ : {get_size(files.file_size)}\n\n📂Fɪʟᴇ ʟɪɴᴋ ➠ : {g}\n\nNote: This message is deleted in 20 mins to avoid copyrights. Save the link to Somewhere else", reply_markup=InlineKeyboardMarkup(
333 | [
334 | [
335 | InlineKeyboardButton('📂 Dᴏᴡɴʟᴏᴀᴅ Nᴏᴡ 📂', url=g)
336 | ], [
337 | InlineKeyboardButton('🤔 Hᴏᴡ Tᴏ Dᴏᴡɴʟᴏᴀᴅ 🤔', url=await get_tutorial(chat_id))
338 | ]
339 | ]
340 | )
341 | )
342 | await asyncio.sleep(1200)
343 | await k.edit("Yᴏᴜʀ ᴍᴇssᴀɢᴇ ɪs sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ!!!")
344 | return
345 | user = message.from_user.id
346 | files_ = await get_file_details(file_id)
347 | if not files_:
348 | pre, file_id = ((base64.urlsafe_b64decode(data + "=" * (-len(data) % 4))).decode("ascii")).split("_", 1)
349 | try:
350 | if not await check_verification(client, message.from_user.id) and VERIFY == True:
351 | btn = [[
352 | InlineKeyboardButton("♻️ Vᴇʀɪғʏ ♻️", url=await get_token(client, message.from_user.id, f"https://telegram.me/{temp.U_NAME}?start=")),
353 | InlineKeyboardButton("⚠️ Hᴏᴡ Tᴏ Vᴇʀɪғʏ ⚠️", url=HOW_TO_VERIFY)
354 | ]]
355 | await message.reply_photo(
356 | photo = VRFY_IMG,
357 | caption=script.VERIFY_TXT.format(message.from_user.mention, temp.U_NAME, temp.B_NAME),
358 | # protect_content=True,
359 | reply_markup=InlineKeyboardMarkup(btn)
360 | )
361 | return
362 | msg = await client.send_cached_media(
363 | chat_id=message.from_user.id,
364 | file_id=file_id,
365 | protect_content=True if pre == 'filep' else False,
366 | )
367 | filetype = msg.media
368 | file = getattr(msg, filetype.value)
369 | title = ''.join(filter(lambda x: not x.startswith('[') and not x.startswith('@'), files.file_name.split()))
370 | size=get_size(file.file_size)
371 | f_caption = f"{title}"
372 | if CUSTOM_FILE_CAPTION:
373 | try:
374 | f_caption=CUSTOM_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='')
375 | except:
376 | return
377 | # await msg.edit_caption(f_caption)
378 | # btn = [[
379 | # InlineKeyboardButton("Get File Again", callback_data=f'delfile#{file_id}')
380 | # ]]
381 | # k = await msg.reply("❗️❗️❗️IMPORTANT❗️️❗️❗️\n\nThis Movie File/Video will be deleted in 10 mins 🫥 (Due to Copyright Issues).\n\nPlease forward this File/Video to your Saved Messages and Start Download there",quote=True)
382 | # await asyncio.sleep(600)
383 | # await msg.delete()
384 | # await k.edit_text("Your File/Video is successfully deleted!!!\n\nClick below button to get your deleted file 👇",reply_markup=InlineKeyboardMarkup(btn))
385 | # return
386 | except:
387 | pass
388 | return await message.reply('Nᴏ Sᴜᴄʜ Fɪʟᴇ Eᴇxɪsᴛ.')
389 | files = files_[0]
390 | title = ''.join(filter(lambda x: not x.startswith('[') and not x.startswith('@'), files.file_name.split()))
391 | size=get_size(files.file_size)
392 | f_caption=files.caption
393 | if CUSTOM_FILE_CAPTION:
394 | try:
395 | f_caption=CUSTOM_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption)
396 | except Exception as e:
397 | logger.exception(e)
398 | f_caption=f_caption
399 | if f_caption is None:
400 | f_caption = f"{' '.join(filter(lambda x: not x.startswith('[') and not x.startswith('@'), files.file_name.split()))}"
401 | if not await check_verification(client, message.from_user.id) and VERIFY == True:
402 | btn = [[
403 | InlineKeyboardButton("♻️ Vᴇʀɪғʏ ♻️", url=await get_token(client, message.from_user.id, f"https://telegram.me/{temp.U_NAME}?start=")),
404 | InlineKeyboardButton("⚠️ Hᴏᴡ Tᴏ Vᴇʀɪғʏ ⚠️", url=HOW_TO_VERIFY)
405 | ]]
406 | await message.reply_photo(
407 | photo = VRFY_IMG,
408 | caption=script.VERIFY_TXT.format(message.from_user.mention, temp.U_NAME, temp.B_NAME),
409 | # protect_content=True,
410 | reply_markup=InlineKeyboardMarkup(btn)
411 | )
412 | return
413 | msg = await client.send_cached_media(
414 | chat_id=message.from_user.id,
415 | file_id=file_id,
416 | caption=f_caption,
417 | protect_content=True if pre == 'filep' else False,
418 | )
419 | # btn = [[
420 | # InlineKeyboardButton("Get File Again", callback_data=f'delfile#{file_id}')
421 | # ]]
422 | # k = await msg.reply("❗️❗️❗️IMPORTANT❗️️❗️❗️\n\nThis Movie File/Video will be deleted in 10 mins 🫥 (Due to Copyright Issues).\n\nPlease forward this File/Video to your Saved Messages and Start Download there",quote=True)
423 | # await asyncio.sleep(600)
424 | # await msg.delete()
425 | # await k.edit_text("Your File/Video is successfully deleted!!!\n\nClick below button to get your deleted file 👇",reply_markup=InlineKeyboardMarkup(btn))
426 | # return
427 |
428 | @Client.on_message(filters.command('channel') & filters.user(ADMINS))
429 | async def channel_info(bot, message):
430 |
431 | """Send basic information of channel"""
432 | if isinstance(CHANNELS, (int, str)):
433 | channels = [CHANNELS]
434 | elif isinstance(CHANNELS, list):
435 | channels = CHANNELS
436 | else:
437 | raise ValueError("Unexpected type of CHANNELS")
438 |
439 | text = '📑 **Indexed channels/groups**\n'
440 | for channel in channels:
441 | chat = await bot.get_chat(channel)
442 | if chat.username:
443 | text += '\n@' + chat.username
444 | else:
445 | text += '\n' + chat.title or chat.first_name
446 |
447 | text += f'\n\n**Total:** {len(CHANNELS)}'
448 |
449 | if len(text) < 4096:
450 | await message.reply(text)
451 | else:
452 | file = 'Indexed channels.txt'
453 | with open(file, 'w') as f:
454 | f.write(text)
455 | await message.reply_document(file)
456 | os.remove(file)
457 |
458 |
459 | @Client.on_message(filters.command('logs') & filters.user(ADMINS))
460 | async def log_file(bot, message):
461 | """Send log file"""
462 | try:
463 | await message.reply_document('TelegramBot.log')
464 | except Exception as e:
465 | await message.reply(str(e))
466 |
467 | @Client.on_message(filters.command('delete') & filters.user(ADMINS))
468 | async def delete(bot, message):
469 | """Delete file from database"""
470 | reply = message.reply_to_message
471 | if reply and reply.media:
472 | msg = await message.reply("Processing...⏳", quote=True)
473 | else:
474 | await message.reply('Reply to file with /delete which you want to delete', quote=True)
475 | return
476 |
477 | for file_type in ("document", "video", "audio"):
478 | media = getattr(reply, file_type, None)
479 | if media is not None:
480 | break
481 | else:
482 | await msg.edit('This is not supported file format')
483 | return
484 |
485 | file_id, file_ref = unpack_new_file_id(media.file_id)
486 |
487 | result = await Media.collection.delete_one({
488 | '_id': file_id,
489 | })
490 | if result.deleted_count:
491 | await msg.edit('File is successfully deleted from database')
492 | else:
493 | file_name = re.sub(r"(_|\-|\.|\+)", " ", str(media.file_name))
494 | result = await Media.collection.delete_many({
495 | 'file_name': file_name,
496 | 'file_size': media.file_size,
497 | 'mime_type': media.mime_type
498 | })
499 | if result.deleted_count:
500 | await msg.edit('File is successfully deleted from database')
501 | else:
502 | # files indexed before https://github.com/EvamariaTG/EvaMaria/commit/f3d2a1bcb155faf44178e5d7a685a1b533e714bf#diff-86b613edf1748372103e94cacff3b578b36b698ef9c16817bb98fe9ef22fb669R39
503 | # have original file name.
504 | result = await Media.collection.delete_many({
505 | 'file_name': media.file_name,
506 | 'file_size': media.file_size,
507 | 'mime_type': media.mime_type
508 | })
509 | if result.deleted_count:
510 | await msg.edit('File is successfully deleted from database')
511 | else:
512 | await msg.edit('File not found in database')
513 |
514 |
515 | @Client.on_message(filters.command('deleteall') & filters.user(ADMINS))
516 | async def delete_all_index(bot, message):
517 | await message.reply_text(
518 | 'This will delete all indexed files.\nDo you want to continue??',
519 | reply_markup=InlineKeyboardMarkup(
520 | [
521 | [
522 | InlineKeyboardButton(
523 | text="YES", callback_data="autofilter_delete"
524 | )
525 | ],
526 | [
527 | InlineKeyboardButton(
528 | text="CANCEL", callback_data="close_data"
529 | )
530 | ],
531 | ]
532 | ),
533 | quote=True,
534 | )
535 |
536 |
537 | @Client.on_callback_query(filters.regex(r'^autofilter_delete'))
538 | async def delete_all_index_confirm(bot, message):
539 | await Media.collection.drop()
540 | await message.answer('Piracy Is Crime')
541 | await message.message.edit('Succesfully Deleted All The Indexed Files.')
542 |
543 |
544 | @Client.on_message(filters.command('settings'))
545 | async def settings(client, message):
546 | userid = message.from_user.id if message.from_user else None
547 | if not userid:
548 | return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
549 | chat_type = message.chat.type
550 |
551 | if chat_type == enums.ChatType.PRIVATE:
552 | grpid = await active_connection(str(userid))
553 | if grpid is not None:
554 | grp_id = grpid
555 | try:
556 | chat = await client.get_chat(grpid)
557 | title = chat.title
558 | except:
559 | await message.reply_text("Make sure I'm present in your group!!", quote=True)
560 | return
561 | else:
562 | await message.reply_text("I'm not connected to any groups!", quote=True)
563 | return
564 |
565 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
566 | grp_id = message.chat.id
567 | title = message.chat.title
568 |
569 | else:
570 | return
571 |
572 | st = await client.get_chat_member(grp_id, userid)
573 | if (
574 | st.status != enums.ChatMemberStatus.ADMINISTRATOR
575 | and st.status != enums.ChatMemberStatus.OWNER
576 | and str(userid) not in ADMINS
577 | ):
578 | return
579 |
580 | settings = await get_settings(grp_id)
581 |
582 | try:
583 | if settings['max_btn']:
584 | settings = await get_settings(grp_id)
585 | except KeyError:
586 | await save_group_settings(grp_id, 'max_btn', False)
587 | settings = await get_settings(grp_id)
588 | if 'is_shortlink' not in settings.keys():
589 | await save_group_settings(grp_id, 'is_shortlink', False)
590 | else:
591 | pass
592 |
593 | if settings is not None:
594 | buttons = [
595 | [
596 | InlineKeyboardButton(
597 | 'Rᴇsᴜʟᴛ Pᴀɢᴇ',
598 | callback_data=f'setgs#button#{settings["button"]}#{grp_id}',
599 | ),
600 | InlineKeyboardButton(
601 | 'Bᴜᴛᴛᴏɴ' if settings["button"] else 'Tᴇxᴛ',
602 | callback_data=f'setgs#button#{settings["button"]}#{grp_id}',
603 | ),
604 | ],
605 | [
606 | InlineKeyboardButton(
607 | 'Fɪʟᴇ Sᴇɴᴅ Mᴏᴅᴇ',
608 | callback_data=f'setgs#botpm#{settings["botpm"]}#{grp_id}',
609 | ),
610 | InlineKeyboardButton(
611 | 'Mᴀɴᴜᴀʟ Sᴛᴀʀᴛ' if settings["botpm"] else 'Aᴜᴛᴏ Sᴇɴᴅ',
612 | callback_data=f'setgs#botpm#{settings["botpm"]}#{grp_id}',
613 | ),
614 | ],
615 | [
616 | InlineKeyboardButton(
617 | 'Pʀᴏᴛᴇᴄᴛ Cᴏɴᴛᴇɴᴛ',
618 | callback_data=f'setgs#file_secure#{settings["file_secure"]}#{grp_id}',
619 | ),
620 | InlineKeyboardButton(
621 | '✔ Oɴ' if settings["file_secure"] else '✘ Oғғ',
622 | callback_data=f'setgs#file_secure#{settings["file_secure"]}#{grp_id}',
623 | ),
624 | ],
625 | [
626 | InlineKeyboardButton(
627 | 'Iᴍᴅʙ',
628 | callback_data=f'setgs#imdb#{settings["imdb"]}#{grp_id}',
629 | ),
630 | InlineKeyboardButton(
631 | '✔ Oɴ' if settings["imdb"] else '✘ Oғғ',
632 | callback_data=f'setgs#imdb#{settings["imdb"]}#{grp_id}',
633 | ),
634 | ],
635 | [
636 | InlineKeyboardButton(
637 | 'Sᴘᴇʟʟ Cʜᴇᴄᴋ',
638 | callback_data=f'setgs#spell_check#{settings["spell_check"]}#{grp_id}',
639 | ),
640 | InlineKeyboardButton(
641 | '✔ Oɴ' if settings["spell_check"] else '✘ Oғғ',
642 | callback_data=f'setgs#spell_check#{settings["spell_check"]}#{grp_id}',
643 | ),
644 | ],
645 | [
646 | InlineKeyboardButton(
647 | 'Wᴇʟᴄᴏᴍᴇ Msɢ',
648 | callback_data=f'setgs#welcome#{settings["welcome"]}#{grp_id}',
649 | ),
650 | InlineKeyboardButton(
651 | '✔ Oɴ' if settings["welcome"] else '✘ Oғғ',
652 | callback_data=f'setgs#welcome#{settings["welcome"]}#{grp_id}',
653 | ),
654 | ],
655 | [
656 | InlineKeyboardButton(
657 | 'Aᴜᴛᴏ-Dᴇʟᴇᴛᴇ',
658 | callback_data=f'setgs#auto_delete#{settings["auto_delete"]}#{grp_id}',
659 | ),
660 | InlineKeyboardButton(
661 | '10 Mɪɴs' if settings["auto_delete"] else '✘ Oғғ',
662 | callback_data=f'setgs#auto_delete#{settings["auto_delete"]}#{grp_id}',
663 | ),
664 | ],
665 | [
666 | InlineKeyboardButton(
667 | 'Aᴜᴛᴏ-Fɪʟᴛᴇʀ',
668 | callback_data=f'setgs#auto_ffilter#{settings["auto_ffilter"]}#{grp_id}',
669 | ),
670 | InlineKeyboardButton(
671 | '✔ Oɴ' if settings["auto_ffilter"] else '✘ Oғғ',
672 | callback_data=f'setgs#auto_ffilter#{settings["auto_ffilter"]}#{grp_id}',
673 | ),
674 | ],
675 | [
676 | InlineKeyboardButton(
677 | 'Mᴀx Bᴜᴛᴛᴏɴs',
678 | callback_data=f'setgs#max_btn#{settings["max_btn"]}#{grp_id}',
679 | ),
680 | InlineKeyboardButton(
681 | '10' if settings["max_btn"] else f'{MAX_B_TN}',
682 | callback_data=f'setgs#max_btn#{settings["max_btn"]}#{grp_id}',
683 | ),
684 | ],
685 | [
686 | InlineKeyboardButton(
687 | 'ShortLink',
688 | callback_data=f'setgs#is_shortlink#{settings["is_shortlink"]}#{grp_id}',
689 | ),
690 | InlineKeyboardButton(
691 | '✔ Oɴ' if settings["is_shortlink"] else '✘ Oғғ',
692 | callback_data=f'setgs#is_shortlink#{settings["is_shortlink"]}#{grp_id}',
693 | ),
694 | ],
695 | ]
696 |
697 | btn = [[
698 | InlineKeyboardButton("Oᴘᴇɴ Hᴇʀᴇ ↓", callback_data=f"opnsetgrp#{grp_id}"),
699 | InlineKeyboardButton("Oᴘᴇɴ Iɴ PM ⇲", callback_data=f"opnsetpm#{grp_id}")
700 | ]]
701 |
702 | reply_markup = InlineKeyboardMarkup(buttons)
703 | if chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
704 | await message.reply_text(
705 | text="Dᴏ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴏᴘᴇɴ sᴇᴛᴛɪɴɢs ʜᴇʀᴇ ?",
706 | reply_markup=InlineKeyboardMarkup(btn),
707 | disable_web_page_preview=True,
708 | parse_mode=enums.ParseMode.HTML,
709 | reply_to_message_id=message.id
710 | )
711 | else:
712 | await message.reply_text(
713 | text=f"Cʜᴀɴɢᴇ Yᴏᴜʀ Sᴇᴛᴛɪɴɢs Fᴏʀ {title} As Yᴏᴜʀ Wɪsʜ ⚙",
714 | reply_markup=reply_markup,
715 | disable_web_page_preview=True,
716 | parse_mode=enums.ParseMode.HTML,
717 | reply_to_message_id=message.id
718 | )
719 |
720 |
721 |
722 | @Client.on_message(filters.command('set_template'))
723 | async def save_template(client, message):
724 | sts = await message.reply("Checking template")
725 | userid = message.from_user.id if message.from_user else None
726 | if not userid:
727 | return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
728 | chat_type = message.chat.type
729 |
730 | if chat_type == enums.ChatType.PRIVATE:
731 | grpid = await active_connection(str(userid))
732 | if grpid is not None:
733 | grp_id = grpid
734 | try:
735 | chat = await client.get_chat(grpid)
736 | title = chat.title
737 | except:
738 | await message.reply_text("Make sure I'm present in your group!!", quote=True)
739 | return
740 | else:
741 | await message.reply_text("I'm not connected to any groups!", quote=True)
742 | return
743 |
744 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
745 | grp_id = message.chat.id
746 | title = message.chat.title
747 |
748 | else:
749 | return
750 |
751 | st = await client.get_chat_member(grp_id, userid)
752 | if (
753 | st.status != enums.ChatMemberStatus.ADMINISTRATOR
754 | and st.status != enums.ChatMemberStatus.OWNER
755 | and str(userid) not in ADMINS
756 | ):
757 | return
758 |
759 | if len(message.command) < 2:
760 | return await sts.edit("No Input!!")
761 | template = message.text.split(" ", 1)[1]
762 | await save_group_settings(grp_id, 'template', template)
763 | await sts.edit(f"Successfully changed template for {title} to\n\n{template}")
764 |
765 |
766 | @Client.on_message((filters.command(["request", "Request"]) | filters.regex("#request") | filters.regex("#Request")) & filters.group)
767 | async def requests(bot, message):
768 | if REQST_CHANNEL is None or SUPPORT_CHAT_ID is None: return # Must add REQST_CHANNEL and SUPPORT_CHAT_ID to use this feature
769 | if message.reply_to_message and SUPPORT_CHAT_ID == message.chat.id:
770 | chat_id = message.chat.id
771 | reporter = str(message.from_user.id)
772 | mention = message.from_user.mention
773 | success = True
774 | content = message.reply_to_message.text
775 | try:
776 | if REQST_CHANNEL is not None:
777 | btn = [[
778 | InlineKeyboardButton('View Request', url=f"{message.reply_to_message.link}"),
779 | InlineKeyboardButton('Show Options', callback_data=f'show_option#{reporter}')
780 | ]]
781 | reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=f"𝖱𝖾𝗉𝗈𝗋𝗍𝖾𝗋 : {mention} ({reporter})\n\n𝖬𝖾𝗌𝗌𝖺𝗀𝖾 : {content}", reply_markup=InlineKeyboardMarkup(btn))
782 | success = True
783 | elif len(content) >= 3:
784 | for admin in ADMINS:
785 | btn = [[
786 | InlineKeyboardButton('View Request', url=f"{message.reply_to_message.link}"),
787 | InlineKeyboardButton('Show Options', callback_data=f'show_option#{reporter}')
788 | ]]
789 | reported_post = await bot.send_message(chat_id=admin, text=f"𝖱𝖾𝗉𝗈𝗋𝗍𝖾𝗋 : {mention} ({reporter})\n\n𝖬𝖾𝗌𝗌𝖺𝗀𝖾 : {content}", reply_markup=InlineKeyboardMarkup(btn))
790 | success = True
791 | else:
792 | if len(content) < 3:
793 | await message.reply_text("You must type about your request [Minimum 3 Characters]. Requests can't be empty.")
794 | if len(content) < 3:
795 | success = False
796 | except Exception as e:
797 | await message.reply_text(f"Error: {e}")
798 | pass
799 |
800 | elif SUPPORT_CHAT_ID == message.chat.id:
801 | chat_id = message.chat.id
802 | reporter = str(message.from_user.id)
803 | mention = message.from_user.mention
804 | success = True
805 | content = message.text
806 | keywords = ["#request", "/request", "#Request", "/Request"]
807 | for keyword in keywords:
808 | if keyword in content:
809 | content = content.replace(keyword, "")
810 | try:
811 | if REQST_CHANNEL is not None and len(content) >= 3:
812 | btn = [[
813 | InlineKeyboardButton('View Request', url=f"{message.link}"),
814 | InlineKeyboardButton('Show Options', callback_data=f'show_option#{reporter}')
815 | ]]
816 | reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=f"𝖱𝖾𝗉𝗈𝗋𝗍𝖾𝗋 : {mention} ({reporter})\n\n𝖬𝖾𝗌𝗌𝖺𝗀𝖾 : {content}", reply_markup=InlineKeyboardMarkup(btn))
817 | success = True
818 | elif len(content) >= 3:
819 | for admin in ADMINS:
820 | btn = [[
821 | InlineKeyboardButton('View Request', url=f"{message.link}"),
822 | InlineKeyboardButton('Show Options', callback_data=f'show_option#{reporter}')
823 | ]]
824 | reported_post = await bot.send_message(chat_id=admin, text=f"𝖱𝖾𝗉𝗈𝗋𝗍𝖾𝗋 : {mention} ({reporter})\n\n𝖬𝖾𝗌𝗌𝖺𝗀𝖾 : {content}", reply_markup=InlineKeyboardMarkup(btn))
825 | success = True
826 | else:
827 | if len(content) < 3:
828 | await message.reply_text("You must type about your request [Minimum 3 Characters]. Requests can't be empty.")
829 | if len(content) < 3:
830 | success = False
831 | except Exception as e:
832 | await message.reply_text(f"Error: {e}")
833 | pass
834 |
835 | else:
836 | success = False
837 |
838 | if success:
839 | '''if isinstance(REQST_CHANNEL, (int, str)):
840 | channels = [REQST_CHANNEL]
841 | elif isinstance(REQST_CHANNEL, list):
842 | channels = REQST_CHANNEL
843 | for channel in channels:
844 | chat = await bot.get_chat(channel)
845 | #chat = int(chat)'''
846 | link = await bot.create_chat_invite_link(int(REQST_CHANNEL))
847 | btn = [[
848 | InlineKeyboardButton('Join Channel', url=link.invite_link),
849 | InlineKeyboardButton('View Request', url=f"{reported_post.link}")
850 | ]]
851 | await message.reply_text("Your request has been added! Please wait for some time.\n\nJoin Channel First & View Request", reply_markup=InlineKeyboardMarkup(btn))
852 |
853 | @Client.on_message(filters.command("send") & filters.user(ADMINS))
854 | async def send_msg(bot, message):
855 | if message.reply_to_message:
856 | target_id = message.text.split(" ", 1)[1]
857 | out = "Users Saved In DB Are:\n\n"
858 | success = False
859 | try:
860 | user = await bot.get_users(target_id)
861 | users = await db.get_all_users()
862 | async for usr in users:
863 | out += f"{usr['id']}"
864 | out += '\n'
865 | if str(user.id) in str(out):
866 | await message.reply_to_message.copy(int(user.id))
867 | success = True
868 | else:
869 | success = False
870 | if success:
871 | await message.reply_text(f"Your message has been successfully send to {user.mention}.")
872 | else:
873 | await message.reply_text("This user didn't started this bot yet !")
874 | except Exception as e:
875 | await message.reply_text(f"Error: {e}")
876 | else:
877 | await message.reply_text("Use this command as a reply to any message using the target chat id. For eg: /send userid")
878 |
879 | @Client.on_message(filters.command("deletefiles") & filters.user(ADMINS))
880 | async def deletemultiplefiles(bot, message):
881 | chat_type = message.chat.type
882 | if chat_type != enums.ChatType.PRIVATE:
883 | return await message.reply_text(f"Hey {message.from_user.mention}, This command won't work in groups. It only works on my PM !")
884 | else:
885 | pass
886 | try:
887 | keyword = message.text.split(" ", 1)[1]
888 | except:
889 | return await message.reply_text(f"Hey {message.from_user.mention}, Give me a keyword along with the command to delete files.")
890 | k = await bot.send_message(chat_id=message.chat.id, text=f"Fetching Files for your query {keyword} on DB... Please wait...")
891 | files, total = await get_bad_files(keyword)
892 | await k.delete()
893 | #await k.edit_text(f"Found {total} files for your query {keyword} !\n\nFile deletion process will start in 5 seconds !")
894 | #await asyncio.sleep(5)
895 | btn = [[
896 | InlineKeyboardButton("Yes, Continue !", callback_data=f"killfilesdq#{keyword}")
897 | ],[
898 | InlineKeyboardButton("No, Abort operation !", callback_data="close_data")
899 | ]]
900 | await message.reply_text(
901 | text=f"Found {total} files for your query {keyword} !\n\nDo you want to delete?",
902 | reply_markup=InlineKeyboardMarkup(btn),
903 | parse_mode=enums.ParseMode.HTML
904 | )
905 |
906 | @Client.on_message(filters.command("set_shortner"))
907 | async def shortlink(bot, message):
908 | userid = message.from_user.id if message.from_user else None
909 | if not userid:
910 | return await message.reply(f"You are anonymous admin. Turn off anonymous admin and try again this command")
911 | chat_type = message.chat.type
912 | if chat_type == enums.ChatType.PRIVATE:
913 | return await message.reply_text(f"Hey {message.from_user.mention}, This command only works on groups !\n\nFollow These Steps to Connect Shortener:\n\n1. Add Me in Your Group with Full Admin Rights\n\n2. After Adding in Grp, Set your Shortener\n\nSend this command in your group\n\n—> /set_shortner ""{your_shortener_website_name} {your_shortener_api}\n\n#Sample:-\n/set_shortner urlshortx.com aacda989a636df49b60ebd363b56dd5e82095eec\n\nThat's it!!! Enjoy Earning Money 💲\n\n[[[ Trusted Earning Site - https://urlshortx.com/ref/Spidynaik ]]]\n\nIf you have any Doubts, Feel Free to Ask me - @Mr_SPIDYBot")
914 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
915 | grpid = message.chat.id
916 | title = message.chat.title
917 | else:
918 | return
919 | data = message.text
920 | userid = message.from_user.id
921 | user = await bot.get_chat_member(grpid, userid)
922 | if user.status != enums.ChatMemberStatus.ADMINISTRATOR and user.status != enums.ChatMemberStatus.OWNER and str(userid) not in ADMINS:
923 | return await message.reply_text("You don't have access to use this command!\n\nAdd Me to Your Own Group as Admin and Try This Command\n\nFor More PM Me With This Command")
924 | else:
925 | pass
926 | try:
927 | command, shortlink_url, api = data.split(" ")
928 | except:
929 | return await message.reply_text("Command Incomplete :(\n\nGive me a shortener website link and api along with the command !\n\nFormat: /shortlink .com aacda989a636df49b60ebd363b56dd5e82095eec1")
930 | reply = await message.reply_text("Please Wait...")
931 | shortlink_url = re.sub(r"https?://?", "", shortlink_url)
932 | shortlink_url = re.sub(r"[:/]", "", shortlink_url)
933 | await save_group_settings(grpid, 'shortlink', shortlink_url)
934 | await save_group_settings(grpid, 'shortlink_api', api)
935 | await save_group_settings(grpid, 'is_shortlink', True)
936 | await reply.edit_text(f"Successfully added shortlink API for {title}.\n\nCurrent Shortlink Website: {shortlink_url}\nCurrent API: {api}")
937 |
938 | @Client.on_message(filters.command("setshortlinkoff") & filters.user(ADMINS))
939 | async def offshortlink(bot, message):
940 | chat_type = message.chat.type
941 | if chat_type == enums.ChatType.PRIVATE:
942 | return await message.reply_text("I will Work Only in group")
943 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
944 | grpid = message.chat.id
945 | title = message.chat.title
946 | else:
947 | return
948 | await save_group_settings(grpid, 'is_shortlink', False)
949 | # ENABLE_SHORTLINK = False
950 | return await message.reply_text("Successfully disabled shortlink")
951 |
952 | @Client.on_message(filters.command("setshortlinkon") & filters.user(ADMINS))
953 | async def onshortlink(bot, message):
954 | chat_type = message.chat.type
955 | if chat_type == enums.ChatType.PRIVATE:
956 | return await message.reply_text("I will Work Only in group")
957 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
958 | grpid = message.chat.id
959 | title = message.chat.title
960 | else:
961 | return
962 | await save_group_settings(grpid, 'is_shortlink', True)
963 | # ENABLE_SHORTLINK = True
964 | return await message.reply_text("Successfully enabled shortlink")
965 |
966 | @Client.on_message(filters.command("get_info"))
967 | async def showshortlink(bot, message):
968 | userid = message.from_user.id if message.from_user else None
969 | if not userid:
970 | return await message.reply(f"You are anonymous admin. Turn off anonymous admin and try again this command")
971 | chat_type = message.chat.type
972 | if chat_type == enums.ChatType.PRIVATE:
973 | return await message.reply_text(f"Hey {message.from_user.mention}, This Command Only Works in Group\n\nTry this command in your own group, if you are using me in your group")
974 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
975 | grpid = message.chat.id
976 | title = message.chat.title
977 | else:
978 | return
979 | chat_id=message.chat.id
980 | userid = message.from_user.id
981 | user = await bot.get_chat_member(grpid, userid)
982 | # if 'shortlink' in settings.keys():
983 | # su = settings['shortlink']
984 | # sa = settings['shortlink_api']
985 | # else:
986 | # return await message.reply_text("Shortener Url Not Connected\n\nYou can Connect Using /shortlink command")
987 | # if 'tutorial' in settings.keys():
988 | # st = settings['tutorial']
989 | # else:
990 | # return await message.reply_text("Tutorial Link Not Connected\n\nYou can Connect Using /set_tutorial command")
991 | if user.status != enums.ChatMemberStatus.ADMINISTRATOR and user.status != enums.ChatMemberStatus.OWNER and str(userid) not in ADMINS:
992 | return await message.reply_text("Tʜɪs ᴄᴏᴍᴍᴀɴᴅ Wᴏʀᴋs Oɴʟʏ Fᴏʀ ᴛʜɪs Gʀᴏᴜᴘ Oᴡɴᴇʀ/Aᴅᴍɪɴ\n\nTʀʏ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ɪɴ ʏᴏᴜʀ Oᴡɴ Gʀᴏᴜᴘ, Iғ Yᴏᴜ Aʀᴇ Usɪɴɢ Mᴇ Iɴ Yᴏᴜʀ Gʀᴏᴜᴘ")
993 | else:
994 | settings = await get_settings(chat_id) #fetching settings for group
995 | if 'shortlink' in settings.keys() and 'tutorial' in settings.keys():
996 | su = settings['shortlink']
997 | sa = settings['shortlink_api']
998 | st = settings['tutorial']
999 | return await message.reply_text(f"Shortlink Website: {su}\n\nApi: {sa}\n\nTutorial: {st}")
1000 | elif 'shortlink' in settings.keys() and 'tutorial' not in settings.keys():
1001 | su = settings['shortlink']
1002 | sa = settings['shortlink_api']
1003 | return await message.reply_text(f"Shortener Website: {su}\n\nApi: {sa}\n\nTutorial Link Not Connected\n\nYou can Connect Using /set_tutorial command")
1004 | elif 'shortlink' not in settings.keys() and 'tutorial' in settings.keys():
1005 | st = settings['tutorial']
1006 | return await message.reply_text(f"Tutorial: {st}\n\nShortener Url Not Connected\n\nYou can Connect Using /shortlink command")
1007 | else:
1008 | return await message.reply_text("Shortener url and Tutorial Link Not Connected. Check this commands, /shortlink and /set_tutorial")
1009 |
1010 |
1011 | @Client.on_message(filters.command("set_tutorial"))
1012 | async def settutorial(bot, message):
1013 | userid = message.from_user.id if message.from_user else None
1014 | if not userid:
1015 | return await message.reply(f"You are anonymous admin. Turn off anonymous admin and try again this command")
1016 | chat_type = message.chat.type
1017 | if chat_type == enums.ChatType.PRIVATE:
1018 | return await message.reply_text("This Command Work Only in group\n\nTry it in your own group")
1019 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
1020 | grpid = message.chat.id
1021 | title = message.chat.title
1022 | else:
1023 | return
1024 | userid = message.from_user.id
1025 | user = await bot.get_chat_member(grpid, userid)
1026 | if user.status != enums.ChatMemberStatus.ADMINISTRATOR and user.status != enums.ChatMemberStatus.OWNER and str(userid) not in ADMINS:
1027 | return
1028 | else:
1029 | pass
1030 | if len(message.command) == 1:
1031 | return await message.reply("Give me a tutorial link along with this command\n\nCommand Usage: /set_tutorial your tutorial link")
1032 | elif len(message.command) == 2:
1033 | reply = await message.reply_text("Please Wait...")
1034 | tutorial = message.command[1]
1035 | await save_group_settings(grpid, 'tutorial', tutorial)
1036 | await save_group_settings(grpid, 'is_tutorial', True)
1037 | await reply.edit_text(f"Successfully Added Tutorial\n\nHere is your tutorial link for your group {title} - {tutorial}")
1038 | else:
1039 | return await message.reply("You entered Incorrect Format\n\nFormat: /set_tutorial your tutorial link")
1040 |
1041 | @Client.on_message(filters.command("remove_tutorial"))
1042 | async def removetutorial(bot, message):
1043 | userid = message.from_user.id if message.from_user else None
1044 | if not userid:
1045 | return await message.reply(f"You are anonymous admin. Turn off anonymous admin and try again this command")
1046 | chat_type = message.chat.type
1047 | if chat_type == enums.ChatType.PRIVATE:
1048 | return await message.reply_text("This Command Work Only in group\n\nTry it in your own group")
1049 | elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
1050 | grpid = message.chat.id
1051 | title = message.chat.title
1052 | else:
1053 | return
1054 | userid = message.from_user.id
1055 | user = await bot.get_chat_member(grpid, userid)
1056 | if user.status != enums.ChatMemberStatus.ADMINISTRATOR and user.status != enums.ChatMemberStatus.OWNER and str(userid) not in ADMINS:
1057 | return
1058 | else:
1059 | pass
1060 | reply = await message.reply_text("Please Wait...")
1061 | await save_group_settings(grpid, 'is_tutorial', False)
1062 | await reply.edit_text(f"Successfully Removed Your Tutorial Link!!!")
1063 |
1064 | @Client.on_message(filters.command("restart") & filters.user(ADMINS))
1065 | async def stop_button(bot, message):
1066 | msg = await bot.send_message(text="**🔄 𝙿𝚁𝙾𝙲𝙴𝚂𝚂𝙴𝚂 𝚂𝚃𝙾𝙿𝙴𝙳. 𝙱𝙾𝚃 𝙸𝚂 𝚁𝙴𝚂𝚃𝙰𝚁𝚃𝙸𝙽𝙶...**", chat_id=message.chat.id)
1067 | await asyncio.sleep(3)
1068 | await msg.edit("**✅️ 𝙱𝙾𝚃 𝙸𝚂 𝚁𝙴𝚂𝚃𝙰𝚁𝚃𝙴𝙳. 𝙽𝙾𝚆 𝚈𝙾𝚄 𝙲𝙰𝙽 𝚄𝚂𝙴 𝙼𝙴**")
1069 | os.execl(sys.executable, sys.executable, *sys.argv)
1070 |
--------------------------------------------------------------------------------