Spaces:
Sleeping
Sleeping
Merge branch 'main' of https://github.com/Gojo-Bots/Gojo_Satoru
Browse files- Powers/__main__.py +5 -2
- Powers/database/afk_db.py +55 -0
- Powers/database/approve_db.py +2 -0
- Powers/database/autojoin_db.py +50 -0
- Powers/database/captcha_db.py +113 -0
- Powers/plugins/afk.py +167 -0
- Powers/plugins/auto_join.py +147 -0
- Powers/plugins/captcha.py +234 -0
- Powers/plugins/start.py +2 -1
- Powers/utils/admin_check.py +11 -4
- Powers/utils/captcha_helper.py +56 -0
- Powers/utils/custom_filters.py +6 -5
- Powers/utils/string.py +22 -0
- Version/version 2.2.0.md +21 -0
Powers/__main__.py
CHANGED
@@ -1,8 +1,11 @@
|
|
1 |
-
|
|
|
|
|
|
|
2 |
from Powers.bot_class import Gojo
|
3 |
|
4 |
if __name__ == "__main__":
|
5 |
-
|
6 |
Gojo().run()
|
7 |
|
8 |
|
|
|
1 |
+
import uvloop # Comment it out if using on windows
|
2 |
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
3 |
+
|
4 |
+
from Powers import BDB_URI, TIME_ZONE
|
5 |
from Powers.bot_class import Gojo
|
6 |
|
7 |
if __name__ == "__main__":
|
8 |
+
uvloop.install() # Comment it out if using on windows
|
9 |
Gojo().run()
|
10 |
|
11 |
|
Powers/database/afk_db.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers import LOGGER
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
|
8 |
+
|
9 |
+
class AFK(MongoDB):
|
10 |
+
"""Class to store afk users"""
|
11 |
+
db_name = "afk"
|
12 |
+
|
13 |
+
def __init__(self) -> None:
|
14 |
+
super().__init__(self.db_name)
|
15 |
+
|
16 |
+
def insert_afk(self, chat_id, user_id, time, reason, media_type,media=None):
|
17 |
+
with INSERTION_LOCK:
|
18 |
+
curr = self.check_afk(chat_id=chat_id, user_id=user_id)
|
19 |
+
if curr:
|
20 |
+
if reason:
|
21 |
+
self.update({"chat_id":chat_id,"user_id":user_id},{"reason":reason,"time":time})
|
22 |
+
if media:
|
23 |
+
self.update({"chat_id":chat_id,"user_id":user_id},{'media':media,'media_type':media_type,"time":time})
|
24 |
+
return True
|
25 |
+
else:
|
26 |
+
self.insert_one(
|
27 |
+
{
|
28 |
+
"chat_id":chat_id,
|
29 |
+
"user_id":user_id,
|
30 |
+
"reason":reason,
|
31 |
+
"time":time,
|
32 |
+
"media":media,
|
33 |
+
"media_type":media_type
|
34 |
+
}
|
35 |
+
)
|
36 |
+
return True
|
37 |
+
|
38 |
+
def check_afk(self, chat_id, user_id):
|
39 |
+
curr = self.find_one({"chat_id":chat_id,"user_id":user_id})
|
40 |
+
if curr:
|
41 |
+
return True
|
42 |
+
return False
|
43 |
+
|
44 |
+
def get_afk(self, chat_id, user_id):
|
45 |
+
curr = self.find_one({"chat_id":chat_id,"user_id":user_id})
|
46 |
+
if curr:
|
47 |
+
return curr
|
48 |
+
return
|
49 |
+
|
50 |
+
def delete_afk(self, chat_id, user_id):
|
51 |
+
with INSERTION_LOCK:
|
52 |
+
curr = self.check_afk(chat_id,user_id)
|
53 |
+
if curr:
|
54 |
+
self.delete_one({"chat_id":chat_id,"user_id":user_id})
|
55 |
+
return
|
Powers/database/approve_db.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
from threading import RLock
|
|
|
2 |
from Powers import LOGGER
|
3 |
from Powers.database import MongoDB
|
|
|
4 |
INSERTION_LOCK = RLock()
|
5 |
class Approve(MongoDB):
|
6 |
"""Class for managing Approves in Chats in Bot."""
|
|
|
1 |
from threading import RLock
|
2 |
+
|
3 |
from Powers import LOGGER
|
4 |
from Powers.database import MongoDB
|
5 |
+
|
6 |
INSERTION_LOCK = RLock()
|
7 |
class Approve(MongoDB):
|
8 |
"""Class for managing Approves in Chats in Bot."""
|
Powers/database/autojoin_db.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
from time import time
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
|
7 |
+
INSERTION_LOCK = RLock()
|
8 |
+
|
9 |
+
|
10 |
+
class AUTOJOIN(MongoDB):
|
11 |
+
"""class to store auto join requests"""
|
12 |
+
|
13 |
+
db_name = "autojoin"
|
14 |
+
|
15 |
+
def __init__(self) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
|
18 |
+
def load_autojoin(self, chat,mode="auto"):
|
19 |
+
"""
|
20 |
+
type = auto or notify
|
21 |
+
auto to auto accept join requests
|
22 |
+
notify to notify the admins about the join requests
|
23 |
+
"""
|
24 |
+
curr = self.find_one({"chat_id":chat,})
|
25 |
+
if not curr:
|
26 |
+
with INSERTION_LOCK:
|
27 |
+
self.insert_one({"chat_id":chat,"type":mode})
|
28 |
+
return True
|
29 |
+
return False
|
30 |
+
|
31 |
+
def get_autojoin(self,chat):
|
32 |
+
curr = self.find_one({"chat_id":chat})
|
33 |
+
if not curr:
|
34 |
+
return False
|
35 |
+
else:
|
36 |
+
return curr["type"]
|
37 |
+
|
38 |
+
def update_join_type(self,chat,mode):
|
39 |
+
curr = self.find_one({"chat_id":chat})
|
40 |
+
if curr:
|
41 |
+
self.update({"chat_id":chat},{"type":mode})
|
42 |
+
return
|
43 |
+
else:
|
44 |
+
return
|
45 |
+
|
46 |
+
def remove_autojoin(self,chat):
|
47 |
+
curr = self.find_one({"chat_id":chat})
|
48 |
+
if curr:
|
49 |
+
self.delete_one({"chat_id":chat})
|
50 |
+
return
|
Powers/database/captcha_db.py
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers import LOGGER
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
|
8 |
+
|
9 |
+
class CAPTCHA(MongoDB):
|
10 |
+
"""Class to store captcha's info"""
|
11 |
+
db_name = "captcha"
|
12 |
+
|
13 |
+
def __init__(self) -> None:
|
14 |
+
super().__init__(self.db_name)
|
15 |
+
|
16 |
+
def insert_captcha(self, chat, captcha_type:str="qr", captcha_action:str = "mute"):
|
17 |
+
with INSERTION_LOCK:
|
18 |
+
curr = self.is_captcha(chat)
|
19 |
+
if not curr:
|
20 |
+
self.insert_one(
|
21 |
+
{
|
22 |
+
"chat_id":chat,
|
23 |
+
"captcha_type":captcha_type,
|
24 |
+
"captcha_action":captcha_action
|
25 |
+
}
|
26 |
+
)
|
27 |
+
return
|
28 |
+
|
29 |
+
def is_captcha(self, chat):
|
30 |
+
curr = self.find_one({"chat_id": chat})
|
31 |
+
if curr:
|
32 |
+
return True
|
33 |
+
return False
|
34 |
+
|
35 |
+
def update_type(self, chat, captcha_type):
|
36 |
+
with INSERTION_LOCK:
|
37 |
+
curr = self.is_captcha(chat)
|
38 |
+
if curr:
|
39 |
+
self.update({"chat_id":chat},{"captcha_type":captcha_type})
|
40 |
+
return
|
41 |
+
|
42 |
+
def update_action(self, chat, captcha_action):
|
43 |
+
with INSERTION_LOCK:
|
44 |
+
curr = self.is_captcha(chat)
|
45 |
+
if curr:
|
46 |
+
self.update({"chat_id":chat},{"captcha_action":captcha_action})
|
47 |
+
return
|
48 |
+
|
49 |
+
def remove_captcha(self, chat):
|
50 |
+
with INSERTION_LOCK:
|
51 |
+
curr = self.is_captcha(chat)
|
52 |
+
if curr:
|
53 |
+
self.delete_one({"chat_id":chat})
|
54 |
+
return
|
55 |
+
|
56 |
+
def get_captcha(self, chat):
|
57 |
+
curr = self.find_one({"chat_id":chat})
|
58 |
+
if curr:
|
59 |
+
return curr
|
60 |
+
return False
|
61 |
+
|
62 |
+
class CAPTCHA_DATA(MongoDB):
|
63 |
+
"""class to store captcha data"""
|
64 |
+
db_name = "captcha_data"
|
65 |
+
|
66 |
+
def __init__(self) -> None:
|
67 |
+
super().__init__(self.db_name)
|
68 |
+
|
69 |
+
def load_cap_data(self, chat, user, data):
|
70 |
+
curr = self.find_one({"chat_id":chat,"user_id":user})
|
71 |
+
if not curr:
|
72 |
+
with INSERTION_LOCK:
|
73 |
+
self.insert_one({"chat_id":chat,"user_id":user,"data":data})
|
74 |
+
return True
|
75 |
+
else:
|
76 |
+
return
|
77 |
+
|
78 |
+
def get_cap_data(self, chat, user):
|
79 |
+
curr = self.find_one({"chat_id":chat,"user_id":user})
|
80 |
+
if curr:
|
81 |
+
return curr["data"]
|
82 |
+
else:
|
83 |
+
return False
|
84 |
+
|
85 |
+
def remove_cap_data(self, chat, user):
|
86 |
+
curr = self.find_one({"chat_id":chat,"user_id":user})
|
87 |
+
if curr:
|
88 |
+
with INSERTION_LOCK:
|
89 |
+
self.delete_one({"chat_id":chat,"user_id":user})
|
90 |
+
return
|
91 |
+
|
92 |
+
def store_message_id(self, chat, user, message):
|
93 |
+
curr = self.find_one({"chat_id":chat,"user_id":user})
|
94 |
+
if not curr:
|
95 |
+
with INSERTION_LOCK:
|
96 |
+
self.insert_one({"chat_id":chat,"user_id":user,"message_id":message})
|
97 |
+
return
|
98 |
+
else:
|
99 |
+
return
|
100 |
+
|
101 |
+
def is_already_data(self, chat, user):
|
102 |
+
curr = self.find_one({"chat_id":chat,"user_id":user})
|
103 |
+
if curr:
|
104 |
+
return curr["message_id"]
|
105 |
+
else:
|
106 |
+
return False
|
107 |
+
|
108 |
+
def del_message_id(self, chat, user):
|
109 |
+
curr = self.find_one({"chat_id":chat,"user_id":user})
|
110 |
+
if curr:
|
111 |
+
with INSERTION_LOCK:
|
112 |
+
self.delete_one({"chat_id":chat,"user_id":user})
|
113 |
+
return
|
Powers/plugins/afk.py
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from datetime import datetime
|
2 |
+
from random import choice
|
3 |
+
|
4 |
+
from pyrogram import filters
|
5 |
+
from pyrogram.enums import ParseMode as PM
|
6 |
+
from pyrogram.types import Message
|
7 |
+
|
8 |
+
from Powers import LOGGER, PREFIX_HANDLER
|
9 |
+
from Powers.bot_class import Gojo
|
10 |
+
from Powers.database.afk_db import AFK
|
11 |
+
from Powers.plugins import till_date
|
12 |
+
from Powers.utils.cmd_senders import send_cmd
|
13 |
+
from Powers.utils.custom_filters import command
|
14 |
+
from Powers.utils.msg_types import Types, get_afk_type
|
15 |
+
from Powers.vars import Config
|
16 |
+
|
17 |
+
# from traceback import format_exc
|
18 |
+
|
19 |
+
res = [
|
20 |
+
"{first} is resting for a while...",
|
21 |
+
"{first} living his real life, go and live yours.",
|
22 |
+
"{first} is quite busy now-a-days.",
|
23 |
+
"I am looking for {first} too...tell me if you see him/her around",
|
24 |
+
"{first} ran away from the chat...",
|
25 |
+
"{first} is busy in his/her work ||simping||",
|
26 |
+
"{first} is busy saving the world",
|
27 |
+
"{first} is now tired fighting all the curses"
|
28 |
+
]
|
29 |
+
|
30 |
+
back = [
|
31 |
+
"{first} is finally back to life",
|
32 |
+
"{first} welcome back",
|
33 |
+
"{first} the spy is back watch what you talk about"
|
34 |
+
]
|
35 |
+
|
36 |
+
@Gojo.on_message(command(["afk","brb"]) & ~filters.private)
|
37 |
+
async def going_afk(c: Gojo, m: Message):
|
38 |
+
user = m.from_user.id
|
39 |
+
chat = m.chat.id
|
40 |
+
afk = AFK()
|
41 |
+
text, data_type, content = await get_afk_type(m)
|
42 |
+
|
43 |
+
time = str(datetime.now()).rsplit(".",1)[0]
|
44 |
+
|
45 |
+
if len(m.command) == 1:
|
46 |
+
text = choice(res)
|
47 |
+
|
48 |
+
elif len(m.command) > 1:
|
49 |
+
text = m.text.markdown.split(None,1)[1]
|
50 |
+
|
51 |
+
if not data_type:
|
52 |
+
data_type = Types.TEXT
|
53 |
+
|
54 |
+
afk.insert_afk(chat,user,str(time),text,data_type,content)
|
55 |
+
|
56 |
+
await m.reply_text(f"{m.from_user.mention} is now AFK")
|
57 |
+
|
58 |
+
return
|
59 |
+
|
60 |
+
async def get_hours(hour:str):
|
61 |
+
tim = hour.strip().split(":")
|
62 |
+
txt = ""
|
63 |
+
if int(tim[0]):
|
64 |
+
txt += tim[0] + " hours "
|
65 |
+
if int(tim[1]):
|
66 |
+
txt += tim[1] + " minutes "
|
67 |
+
if int(round(float(tim[2]))):
|
68 |
+
txt += str(round(float(tim[2]))) + " seconds"
|
69 |
+
|
70 |
+
return txt
|
71 |
+
|
72 |
+
|
73 |
+
@Gojo.on_message(filters.group,group=-18)
|
74 |
+
async def afk_checker(c: Gojo, m: Message):
|
75 |
+
if not m.from_user:
|
76 |
+
return
|
77 |
+
|
78 |
+
afk = AFK()
|
79 |
+
back_ = choice(back)
|
80 |
+
user = m.from_user.id
|
81 |
+
chat = m.chat.id
|
82 |
+
repl = m.reply_to_message
|
83 |
+
|
84 |
+
if repl and repl.from_user:
|
85 |
+
rep_user = repl.from_user.id
|
86 |
+
else:
|
87 |
+
rep_user = False
|
88 |
+
|
89 |
+
is_afk = afk.check_afk(chat,user)
|
90 |
+
is_rep_afk = False
|
91 |
+
if rep_user:
|
92 |
+
is_rep_afk = afk.check_afk(chat,rep_user)
|
93 |
+
|
94 |
+
if is_rep_afk and rep_user != user:
|
95 |
+
con = afk.get_afk(chat,rep_user)
|
96 |
+
time = till_date(con["time"])
|
97 |
+
media = con["media"]
|
98 |
+
media_type = con["media_type"]
|
99 |
+
tim_ = datetime.now() - time
|
100 |
+
tim_ = str(tim_).split(",")
|
101 |
+
tim = await get_hours(tim_[-1])
|
102 |
+
if len(tim_) == 1:
|
103 |
+
tims = tim
|
104 |
+
elif len(tim_) == 2:
|
105 |
+
tims = tim_[0] + " " + tim
|
106 |
+
reason = f"{repl.from_user.first_name} is afk since {tims}\n"
|
107 |
+
if con['reason'] not in res:
|
108 |
+
reason += f"\nDue to: {con['reason'].format(first=repl.from_user.first_name)}"
|
109 |
+
else:
|
110 |
+
reason += f"\n{con['reason'].format(first=repl.from_user.first_name)}"
|
111 |
+
txt = reason
|
112 |
+
|
113 |
+
if media_type == Types.TEXT:
|
114 |
+
await (await send_cmd(c,media_type))(
|
115 |
+
chat,
|
116 |
+
txt,
|
117 |
+
parse_mode=PM.MARKDOWN,
|
118 |
+
reply_to_message_id=m.id,
|
119 |
+
)
|
120 |
+
else:
|
121 |
+
await (await send_cmd(c,media_type))(
|
122 |
+
chat,
|
123 |
+
media,
|
124 |
+
txt,
|
125 |
+
parse_mode=PM.MARKDOWN,
|
126 |
+
reply_to_message_id=repl.id
|
127 |
+
)
|
128 |
+
|
129 |
+
if is_afk:
|
130 |
+
txt = False
|
131 |
+
try:
|
132 |
+
txt = m.command[0]
|
133 |
+
except Exception:
|
134 |
+
pass
|
135 |
+
|
136 |
+
if txt and txt in ["afk","brb"]:
|
137 |
+
return
|
138 |
+
else:
|
139 |
+
con = afk.get_afk(chat,user)
|
140 |
+
time = till_date(con["time"])
|
141 |
+
tim_ = datetime.now() - time
|
142 |
+
tim_ = str(tim_).split(",")
|
143 |
+
tim = await get_hours(tim_[-1])
|
144 |
+
if len(tim_) == 1:
|
145 |
+
tims = tim
|
146 |
+
elif len(tim_) == 2:
|
147 |
+
tims = tim_[0] + " " + tim
|
148 |
+
txt = back_.format(first=m.from_user.mention) + f"\n\nAfk for: {tims}"
|
149 |
+
await m.reply_text(txt)
|
150 |
+
afk.delete_afk(chat,user)
|
151 |
+
return
|
152 |
+
|
153 |
+
__PLUGIN__ = "afk"
|
154 |
+
|
155 |
+
_DISABLE_CMDS_ = ["afk","brb"]
|
156 |
+
|
157 |
+
__alt_name__ = ["brb"]
|
158 |
+
|
159 |
+
__HELP__ = """
|
160 |
+
**AFK**
|
161 |
+
• /afk (/brb) [reason | reply to a message]
|
162 |
+
|
163 |
+
`reply to a message` can be any media or text
|
164 |
+
"""
|
165 |
+
|
166 |
+
|
167 |
+
|
Powers/plugins/auto_join.py
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.enums import ChatMemberStatus as CMS
|
3 |
+
from pyrogram.types import CallbackQuery, ChatJoinRequest
|
4 |
+
from pyrogram.types import InlineKeyboardButton as ikb
|
5 |
+
from pyrogram.types import InlineKeyboardMarkup as ikm
|
6 |
+
from pyrogram.types import Message
|
7 |
+
|
8 |
+
from Powers.bot_class import Gojo
|
9 |
+
from Powers.database.autojoin_db import AUTOJOIN
|
10 |
+
from Powers.supports import get_support_staff
|
11 |
+
from Powers.utils.custom_filters import admin_filter, command
|
12 |
+
|
13 |
+
SUPPORT_STAFF = get_support_staff()
|
14 |
+
|
15 |
+
@Gojo.on_message(command(["joinreq"]) & admin_filter)
|
16 |
+
async def accept_join_requests(c: Gojo, m: Message):
|
17 |
+
if m.chat.id == m.from_user.id:
|
18 |
+
await m.reply_text("Use it in groups")
|
19 |
+
return
|
20 |
+
|
21 |
+
split = m.command
|
22 |
+
a_j = AUTOJOIN()
|
23 |
+
|
24 |
+
if len(split) == 1:
|
25 |
+
txt = "**USAGE**\n/joinreq [on | off]"
|
26 |
+
await m.reply_text(txt)
|
27 |
+
return
|
28 |
+
else:
|
29 |
+
yes_no = split[1].lower()
|
30 |
+
if yes_no not in ["on","off"]:
|
31 |
+
txt = "**USAGE**\n/joinreq [on | off]"
|
32 |
+
await m.reply_text(txt)
|
33 |
+
return
|
34 |
+
|
35 |
+
else:
|
36 |
+
if yes_no == "on":
|
37 |
+
is_al = a_j.load_autojoin(m.chat.id)
|
38 |
+
|
39 |
+
if is_al:
|
40 |
+
txt = "Now I will approve all the join request of the chat\nIf you want that I will just notify admins about the join request use command\n//joinreqmode [manual | auto]"
|
41 |
+
await m.reply_text(txt)
|
42 |
+
return
|
43 |
+
else:
|
44 |
+
txt = "Auto approve join request is already on for this chat\nIf you want that I will just notify admins about the join request use command\n/joinreqmode [manual | auto]"
|
45 |
+
await m.reply_text(txt)
|
46 |
+
return
|
47 |
+
|
48 |
+
elif yes_no == "off":
|
49 |
+
a_j.remove_autojoin(m.chat.id)
|
50 |
+
txt = "Now I will neither auto approve join request nor notify any admins about it"
|
51 |
+
await m.reply_text(txt)
|
52 |
+
return
|
53 |
+
|
54 |
+
@Gojo.on_message(command("joinreqmode") & admin_filter)
|
55 |
+
async def join_request_mode(c: Gojo, m: Message):
|
56 |
+
if m.chat.id == m.from_user.id:
|
57 |
+
await m.reply_text("Use it in groups")
|
58 |
+
return
|
59 |
+
u_text = "**USAGE**\n/joinreqmode [auto | manual]\nauto: auto approve joins\nmanual: will notify admin about the join request"
|
60 |
+
|
61 |
+
split = m.command
|
62 |
+
a_j = AUTOJOIN()
|
63 |
+
|
64 |
+
if len(split) == 1:
|
65 |
+
await m.reply_text(u_text)
|
66 |
+
return
|
67 |
+
|
68 |
+
else:
|
69 |
+
auto_manual = split[1]
|
70 |
+
if auto_manual not in ["auto","manual"]:
|
71 |
+
await m.reply_text(u_text)
|
72 |
+
return
|
73 |
+
else:
|
74 |
+
a_j.update_join_type(m.chat.id,auto_manual)
|
75 |
+
txt = "Changed join request type"
|
76 |
+
await m.reply_text(txt)
|
77 |
+
return
|
78 |
+
|
79 |
+
|
80 |
+
@Gojo.on_chat_join_request(filters.group)
|
81 |
+
async def join_request_handler(c: Gojo, j: ChatJoinRequest):
|
82 |
+
chat = j.chat.id
|
83 |
+
aj = AUTOJOIN()
|
84 |
+
join_type = aj.get_autojoin(chat)
|
85 |
+
|
86 |
+
if not join_type:
|
87 |
+
return
|
88 |
+
|
89 |
+
user = j.from_user.id
|
90 |
+
userr = j.from_user
|
91 |
+
if join_type == "auto" or user in SUPPORT_STAFF:
|
92 |
+
await c.approve_chat_join_request(chat,user)
|
93 |
+
|
94 |
+
elif join_type == "manual":
|
95 |
+
txt = "New join request is available\n**USER's INFO**\n"
|
96 |
+
txt += f"Name: {userr.first_name} {userr.last_name if userr.last_name else ''}"
|
97 |
+
txt += f"Mention: {userr.mention}"
|
98 |
+
txt += f"Id: {user}"
|
99 |
+
txt += f"Scam: {'True' if userr.is_scam else 'False'}"
|
100 |
+
if userr.username:
|
101 |
+
txt+= f"Username: @{userr.username}"
|
102 |
+
kb = [
|
103 |
+
[
|
104 |
+
ikb("Accept",f"accept_joinreq_uest_{user}"),
|
105 |
+
ikb("Decline",f"decline_joinreq_uest_{user}")
|
106 |
+
]
|
107 |
+
]
|
108 |
+
await c.send_message(chat,txt,reply_markup=ikm(kb))
|
109 |
+
return
|
110 |
+
|
111 |
+
@Gojo.on_callback_query(filters.regex("^accept_joinreq_uest_") | filters.regex("^decline_joinreq_uest_"))
|
112 |
+
async def accept_decline_request(c:Gojo, q: CallbackQuery):
|
113 |
+
user_id = q.from_user.id
|
114 |
+
user_status = (await q.message.chat.get_member(user_id)).status
|
115 |
+
if user_status not in {CMS.OWNER, CMS.ADMINISTRATOR}:
|
116 |
+
await q.answer(
|
117 |
+
"You're not even an admin, don't try this explosive shit!",
|
118 |
+
show_alert=True,
|
119 |
+
)
|
120 |
+
return
|
121 |
+
|
122 |
+
split = q.data.split("_")
|
123 |
+
chat = q.message.chat.id
|
124 |
+
user = int(split[-1])
|
125 |
+
data = split[0]
|
126 |
+
|
127 |
+
if data == "accept":
|
128 |
+
await c.approve_chat_join_request(chat,user)
|
129 |
+
await q.answer(f"APPROVED: {user}",True)
|
130 |
+
elif data == "decline":
|
131 |
+
await c.decline_chat_join_request(chat,user)
|
132 |
+
await q.answer(f"DECLINED: {user}")
|
133 |
+
|
134 |
+
return
|
135 |
+
|
136 |
+
__PLUGIN__ = "auto join"
|
137 |
+
|
138 |
+
__alt_name__ = ["join_request"]
|
139 |
+
|
140 |
+
|
141 |
+
__HELP__ = """
|
142 |
+
**Auto join request**
|
143 |
+
|
144 |
+
**Admin commands:**
|
145 |
+
• /joinreq [on | off]: To switch on auto accept join request
|
146 |
+
• /joinreqmode [auto | manual]: `auto` to accept join request automatically and `manual` to get notified when new join request is available
|
147 |
+
"""
|
Powers/plugins/captcha.py
ADDED
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from random import shuffle
|
2 |
+
from traceback import format_exc
|
3 |
+
|
4 |
+
import pyrogram # don't remove
|
5 |
+
from pyrogram import filters
|
6 |
+
from pyrogram.enums import ChatMemberStatus as CMS
|
7 |
+
from pyrogram.types import CallbackQuery, ChatMemberUpdated, ChatPermissions
|
8 |
+
from pyrogram.types import InlineKeyboardButton as ikb
|
9 |
+
from pyrogram.types import InlineKeyboardMarkup as ikm
|
10 |
+
from pyrogram.types import Message
|
11 |
+
|
12 |
+
from Powers import LOGGER
|
13 |
+
from Powers.bot_class import Gojo
|
14 |
+
from Powers.database.captcha_db import CAPTCHA, CAPTCHA_DATA
|
15 |
+
from Powers.supports import get_support_staff
|
16 |
+
from Powers.utils.captcha_helper import (genrator, get_image_captcha,
|
17 |
+
get_qr_captcha)
|
18 |
+
from Powers.utils.custom_filters import admin_filter, command
|
19 |
+
|
20 |
+
SUPPORT_STAFF = get_support_staff()
|
21 |
+
|
22 |
+
@Gojo.on_message(command("captcha") & admin_filter & ~filters.private)
|
23 |
+
async def start_captcha(c: Gojo, m: Message):
|
24 |
+
captcha = CAPTCHA()
|
25 |
+
split = m.command
|
26 |
+
if len(split) == 1:
|
27 |
+
is_cap = captcha.is_captcha(m.chat.id)
|
28 |
+
if is_cap:
|
29 |
+
txt = "Captcha verification is currently **on** for this chat"
|
30 |
+
else:
|
31 |
+
txt = "Captcha verification is currently **off** for this chat"
|
32 |
+
await m.reply_text(txt)
|
33 |
+
return
|
34 |
+
else:
|
35 |
+
on_off = split[1].lower()
|
36 |
+
if on_off in ["on","yes","enable"]:
|
37 |
+
captcha.insert_captcha(m.chat.id)
|
38 |
+
await m.reply_text("Captcha verification is now **on** for this chat")
|
39 |
+
return
|
40 |
+
elif on_off in ["off","no","disable"]:
|
41 |
+
captcha.remove_captcha(m.chat.id)
|
42 |
+
await m.reply_text("Captcha verification is now **off** for this chat")
|
43 |
+
return
|
44 |
+
else:
|
45 |
+
await m.reply_text("**USAGE**\n/captcha [on | yes | enable | off | no | disable]")
|
46 |
+
return
|
47 |
+
|
48 |
+
@Gojo.on_message(command("captchamode") & admin_filter & ~filters.private)
|
49 |
+
async def set_captcha_mode(c: Gojo, m: Message):
|
50 |
+
split = m.command
|
51 |
+
captcha = CAPTCHA()
|
52 |
+
if len(split) == 1:
|
53 |
+
curr = captcha.get_captcha(m.chat.id)
|
54 |
+
if curr:
|
55 |
+
capatcha_type = curr["captcha_type"]
|
56 |
+
await m.reply_text(f"Current captcha verification methode is {capatcha_type}\nAvailable methodes:\n■ qr\n■ image")
|
57 |
+
return
|
58 |
+
else:
|
59 |
+
await m.reply_text("Captcha verification is off for the current chat")
|
60 |
+
return
|
61 |
+
else:
|
62 |
+
type_ = split[1].lower()
|
63 |
+
if type_ == "qr":
|
64 |
+
captcha.update_type(m.chat.id, "qr")
|
65 |
+
await m.reply_text("Captcha verification is now changed to qr code")
|
66 |
+
return
|
67 |
+
elif type_ == "image":
|
68 |
+
captcha.update_type(m.chat.id,"image")
|
69 |
+
await m.reply_text("Captcha verication is now changed to image")
|
70 |
+
return
|
71 |
+
else:
|
72 |
+
await m.reply_text("**USAGE**\n/captchamode [qr | image]")
|
73 |
+
return
|
74 |
+
|
75 |
+
@Gojo.on_chat_member_updated(filters.group,18)
|
76 |
+
async def joinss(c: Gojo, u: ChatMemberUpdated):
|
77 |
+
chat = u.chat.id
|
78 |
+
|
79 |
+
if (
|
80 |
+
u.new_chat_member
|
81 |
+
):
|
82 |
+
pass
|
83 |
+
else:
|
84 |
+
return
|
85 |
+
|
86 |
+
user = u.new_chat_member.user.id
|
87 |
+
userr = u.new_chat_member.user
|
88 |
+
|
89 |
+
is_qr = CAPTCHA().is_captcha(chat)
|
90 |
+
if not is_qr:
|
91 |
+
return
|
92 |
+
|
93 |
+
captcha = CAPTCHA()
|
94 |
+
cap_data = CAPTCHA_DATA()
|
95 |
+
|
96 |
+
if user in SUPPORT_STAFF:
|
97 |
+
return
|
98 |
+
|
99 |
+
captcha_type = captcha.get_captcha(chat)
|
100 |
+
|
101 |
+
is_already = cap_data.is_already_data(chat, user)
|
102 |
+
|
103 |
+
mess = False
|
104 |
+
try:
|
105 |
+
if is_already:
|
106 |
+
mess = await c.get_messages(chat,int(is_already))
|
107 |
+
except Exception:
|
108 |
+
cap_data.del_message_id(chat,is_already)
|
109 |
+
mess = False
|
110 |
+
is_already = False
|
111 |
+
|
112 |
+
if is_already and not mess:
|
113 |
+
cap_data.del_message_id(chat,is_already)
|
114 |
+
return
|
115 |
+
|
116 |
+
try:
|
117 |
+
await c.restrict_chat_member(chat,user,ChatPermissions())
|
118 |
+
except Exception as e:
|
119 |
+
LOGGER.error(e)
|
120 |
+
LOGGER.error(format_exc())
|
121 |
+
return
|
122 |
+
|
123 |
+
if not is_already:
|
124 |
+
if captcha_type == "qr":
|
125 |
+
pic = await get_qr_captcha(chat, user)
|
126 |
+
cap = f"Please {userr.mention} scan this qr code with your phone to verify that you are human"
|
127 |
+
ms = await c.send_photo(chat,pic,caption=cap)
|
128 |
+
cap_data.store_message_id(chat,user,ms.id)
|
129 |
+
return
|
130 |
+
elif captcha_type == "image":
|
131 |
+
img, code = await get_image_captcha(chat, user)
|
132 |
+
cap = f"Please {userr.mention} please choose the correct code from the one given bellow\nYou have three tries if you get all three wrong u will be kicked from the chat.\nTries left: 3"
|
133 |
+
cap_data.load_cap_data(chat, user, code)
|
134 |
+
rand = [code]
|
135 |
+
while len(rand) != 5:
|
136 |
+
hehe = genrator()
|
137 |
+
rand.append(hehe)
|
138 |
+
|
139 |
+
shuffle(rand)
|
140 |
+
|
141 |
+
ini = f"captcha_{chat}_{user}_"
|
142 |
+
|
143 |
+
kb = ikm(
|
144 |
+
[
|
145 |
+
[
|
146 |
+
ikb(rand[0],ini+rand[0])
|
147 |
+
],
|
148 |
+
[
|
149 |
+
ikb(rand[1],ini+rand[1])
|
150 |
+
],
|
151 |
+
[
|
152 |
+
ikb(rand[2],ini+rand[2])
|
153 |
+
],
|
154 |
+
[
|
155 |
+
ikb(rand[3],ini+rand[3])
|
156 |
+
],
|
157 |
+
[
|
158 |
+
ikb(rand[4],ini+rand[4])
|
159 |
+
]
|
160 |
+
]
|
161 |
+
)
|
162 |
+
await c.send_photo(chat,img,caption=cap,reply_markup=kb)
|
163 |
+
return
|
164 |
+
elif is_already and mess:
|
165 |
+
kb = ikm(
|
166 |
+
[
|
167 |
+
[
|
168 |
+
ikb("Click here to verify",url=mess.link)
|
169 |
+
]
|
170 |
+
]
|
171 |
+
)
|
172 |
+
await c.send_message(f"{userr.mention} your verification is already pending",reply_markup=kb)
|
173 |
+
return
|
174 |
+
else:
|
175 |
+
await c.unban_chat_member(chat,user)
|
176 |
+
return
|
177 |
+
|
178 |
+
@Gojo.on_callback_query(filters.regex("^captcha_"))
|
179 |
+
async def captcha_codes_check(c: Gojo, q: CallbackQuery):
|
180 |
+
split = q.data.split("_")
|
181 |
+
chat = int(split[1])
|
182 |
+
user = int(split[2])
|
183 |
+
code = split[3]
|
184 |
+
|
185 |
+
if q.from_user.id != user:
|
186 |
+
await q.answer("Not for you BAKA!")
|
187 |
+
return
|
188 |
+
|
189 |
+
c_data = CAPTCHA_DATA()
|
190 |
+
code_ = c_data.get_cap_data(chat,user)
|
191 |
+
|
192 |
+
|
193 |
+
if code_ == code:
|
194 |
+
cap = "You guessed the captcha right...Now you can talk in the chat with no restrictions"
|
195 |
+
c_data.remove_cap_data(chat,user)
|
196 |
+
await q.answer(cap,True)
|
197 |
+
try:
|
198 |
+
await q.message.chat.unban_member(user)
|
199 |
+
except Exception as e:
|
200 |
+
await q.message.reply_text(f"Unable to unmute {q.from_user.mention} this user")
|
201 |
+
await q.message.reply_text(e)
|
202 |
+
return
|
203 |
+
await c.send_message(chat,f"{q.from_user.mention} now you are free to talk")
|
204 |
+
await q.message.delete()
|
205 |
+
return
|
206 |
+
else:
|
207 |
+
caps = q.message.caption.split(":")
|
208 |
+
tries = int(caps[1].strip()) - 1
|
209 |
+
caps.pop(-1)
|
210 |
+
caps.append(f" {tries}")
|
211 |
+
new_cap = ":".join(caps)
|
212 |
+
await q.answer(f"Wrong\nTries left: {tries}", True)
|
213 |
+
if not tries:
|
214 |
+
new_cap = f"You have zero tries left now. I am going to kick you know coz you failed to solve captcha...see yaa {q.from_user.mention}"
|
215 |
+
try:
|
216 |
+
await q.message.chat.ban_member(user)
|
217 |
+
except Exception as e:
|
218 |
+
await q.message.reply_text("Failed to kick member")
|
219 |
+
return
|
220 |
+
await q.message.delete()
|
221 |
+
await q.message.reply_text(new_cap)
|
222 |
+
await c.unban_chat_member(chat,user)
|
223 |
+
|
224 |
+
else:
|
225 |
+
await q.edit_message_caption(new_cap,reply_markup=q.message.reply_markup)
|
226 |
+
return
|
227 |
+
|
228 |
+
|
229 |
+
__PLUGIN__ = "captcha"
|
230 |
+
|
231 |
+
__HELP__ = """
|
232 |
+
• /captcha [on|yes|enable|off|no|disable] : To enable or disable captcha verification
|
233 |
+
• /captchamode [qr|image] : To change captcha mode
|
234 |
+
"""
|
Powers/plugins/start.py
CHANGED
@@ -13,11 +13,13 @@ from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
|
|
13 |
from Powers import (HELP_COMMANDS, LOGGER, PYROGRAM_VERSION, PYTHON_VERSION,
|
14 |
UPTIME, VERSION)
|
15 |
from Powers.bot_class import Gojo
|
|
|
16 |
from Powers.utils.custom_filters import command
|
17 |
from Powers.utils.extras import StartPic
|
18 |
from Powers.utils.kbhelpers import ikb
|
19 |
from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, get_help_msg,
|
20 |
get_private_note, get_private_rules)
|
|
|
21 |
from Powers.vars import Config
|
22 |
|
23 |
|
@@ -104,7 +106,6 @@ async def start(c: Gojo, m: Message):
|
|
104 |
quote=True,
|
105 |
)
|
106 |
return
|
107 |
-
|
108 |
try:
|
109 |
cpt = f"""
|
110 |
Hey [{m.from_user.first_name}](http://t.me/{m.from_user.username})! I am Gojo ✨.
|
|
|
13 |
from Powers import (HELP_COMMANDS, LOGGER, PYROGRAM_VERSION, PYTHON_VERSION,
|
14 |
UPTIME, VERSION)
|
15 |
from Powers.bot_class import Gojo
|
16 |
+
from Powers.database.captcha_db import CAPTCHA_DATA
|
17 |
from Powers.utils.custom_filters import command
|
18 |
from Powers.utils.extras import StartPic
|
19 |
from Powers.utils.kbhelpers import ikb
|
20 |
from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, get_help_msg,
|
21 |
get_private_note, get_private_rules)
|
22 |
+
from Powers.utils.string import encode_decode
|
23 |
from Powers.vars import Config
|
24 |
|
25 |
|
|
|
106 |
quote=True,
|
107 |
)
|
108 |
return
|
|
|
109 |
try:
|
110 |
cpt = f"""
|
111 |
Hey [{m.from_user.first_name}](http://t.me/{m.from_user.username})! I am Gojo ✨.
|
Powers/utils/admin_check.py
CHANGED
@@ -3,10 +3,8 @@ from traceback import format_exc
|
|
3 |
from pyrogram.enums import ChatMemberStatus as CMS
|
4 |
from pyrogram.types import CallbackQuery, Message
|
5 |
|
6 |
-
from Powers import
|
7 |
-
|
8 |
-
SUDO_LEVEL = SUDO_USERS + DEV_USERS + [int(OWNER_ID)]
|
9 |
-
DEV_LEVEL = DEV_USERS + [int(OWNER_ID)]
|
10 |
|
11 |
|
12 |
async def admin_check(m: Message or CallbackQuery) -> bool:
|
@@ -16,6 +14,11 @@ async def admin_check(m: Message or CallbackQuery) -> bool:
|
|
16 |
if isinstance(m, CallbackQuery):
|
17 |
user_id = m.message.from_user.id
|
18 |
|
|
|
|
|
|
|
|
|
|
|
19 |
try:
|
20 |
if user_id in SUDO_LEVEL:
|
21 |
return True
|
@@ -66,6 +69,10 @@ async def owner_check(m: Message or CallbackQuery) -> bool:
|
|
66 |
user_id = m.message.from_user.id
|
67 |
m = m.message
|
68 |
|
|
|
|
|
|
|
|
|
69 |
try:
|
70 |
if user_id in SUDO_LEVEL:
|
71 |
return True
|
|
|
3 |
from pyrogram.enums import ChatMemberStatus as CMS
|
4 |
from pyrogram.types import CallbackQuery, Message
|
5 |
|
6 |
+
from Powers import LOGGER, OWNER_ID
|
7 |
+
from Powers.database.support_db import SUPPORTS
|
|
|
|
|
8 |
|
9 |
|
10 |
async def admin_check(m: Message or CallbackQuery) -> bool:
|
|
|
14 |
if isinstance(m, CallbackQuery):
|
15 |
user_id = m.message.from_user.id
|
16 |
|
17 |
+
support = SUPPORTS()
|
18 |
+
|
19 |
+
SUDO_LEVEL = support.get_particular_support("sudo") + support.get_particular_support("dev") + [int(OWNER_ID)]
|
20 |
+
DEV_LEVEL = support.get_particular_support("dev") + [int(OWNER_ID)]
|
21 |
+
|
22 |
try:
|
23 |
if user_id in SUDO_LEVEL:
|
24 |
return True
|
|
|
69 |
user_id = m.message.from_user.id
|
70 |
m = m.message
|
71 |
|
72 |
+
support = SUPPORTS()
|
73 |
+
|
74 |
+
SUDO_LEVEL = support.get_particular_support("sudo") + support.get_particular_support("dev") + [int(OWNER_ID)]
|
75 |
+
|
76 |
try:
|
77 |
if user_id in SUDO_LEVEL:
|
78 |
return True
|
Powers/utils/captcha_helper.py
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from random import choice, randint, randrange
|
2 |
+
|
3 |
+
import qrcode
|
4 |
+
from captcha.image import ImageCaptcha
|
5 |
+
from pyrogram.types import InlineKeyboardButton as IKB
|
6 |
+
from pyrogram.types import InlineKeyboardMarkup as IKM
|
7 |
+
|
8 |
+
from Powers.database.captcha_db import CAPTCHA_DATA
|
9 |
+
from Powers.utils.string import encode_decode
|
10 |
+
from Powers.vars import Config
|
11 |
+
|
12 |
+
initial = f"t.me/{Config.BOT_USERNAME}?start=qrcaptcha_"
|
13 |
+
captchaa = CAPTCHA_DATA()
|
14 |
+
|
15 |
+
async def get_qr_captcha(chat,user):
|
16 |
+
encode = f"{chat}:{user}"
|
17 |
+
encoded = encode_decode(encode)
|
18 |
+
final = initial+encoded
|
19 |
+
qr = qrcode.make(final)
|
20 |
+
name = f"captcha_verification{chat}_{user}.png"
|
21 |
+
qr.save(name)
|
22 |
+
return name
|
23 |
+
|
24 |
+
def genrator():
|
25 |
+
alpha = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
|
26 |
+
rand_alpha = choice(alpha)
|
27 |
+
if_ = randint(0,1)
|
28 |
+
|
29 |
+
if if_:
|
30 |
+
new_alpha = rand_alpha.upper()
|
31 |
+
else:
|
32 |
+
new_alpha = rand_alpha
|
33 |
+
|
34 |
+
list_ = [new_alpha]
|
35 |
+
while len(list_) != 4:
|
36 |
+
xXx = randrange(0,9)
|
37 |
+
list_.append(xXx)
|
38 |
+
|
39 |
+
str_ = ""
|
40 |
+
while len(str_) != 4:
|
41 |
+
OwO = choice(list_)
|
42 |
+
str_ += OwO
|
43 |
+
return str_
|
44 |
+
|
45 |
+
async def get_image_captcha(chat,user):
|
46 |
+
str_ = genrator()
|
47 |
+
captchaa.load_cap_data(chat,user,str_)
|
48 |
+
name = f"captcha_img_{chat}_{user}.png"
|
49 |
+
image = ImageCaptcha(280,90)
|
50 |
+
|
51 |
+
cap = image.generate(str_)
|
52 |
+
image.write(str_,name)
|
53 |
+
|
54 |
+
return name, str_
|
55 |
+
|
56 |
+
|
Powers/utils/custom_filters.py
CHANGED
@@ -9,14 +9,12 @@ from pyrogram.errors import RPCError, UserNotParticipant
|
|
9 |
from pyrogram.filters import create
|
10 |
from pyrogram.types import CallbackQuery, Message
|
11 |
|
12 |
-
from Powers import
|
13 |
from Powers.database.disable_db import Disabling
|
|
|
14 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
15 |
from Powers.vars import Config
|
16 |
|
17 |
-
SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)])
|
18 |
-
DEV_LEVEL = set(DEV_USERS + [int(OWNER_ID)])
|
19 |
-
|
20 |
|
21 |
def command(
|
22 |
commands: Union[str, List[str]],
|
@@ -29,6 +27,8 @@ def command(
|
|
29 |
if not m:
|
30 |
return
|
31 |
|
|
|
|
|
32 |
date = m.edit_date
|
33 |
if date:
|
34 |
return # reaction
|
@@ -61,7 +61,7 @@ def command(
|
|
61 |
if not text:
|
62 |
return False
|
63 |
regex = r"^[{prefix}](\w+)(@{bot_name})?(?: |$)(.*)".format(
|
64 |
-
prefix="|".join(escape(x) for x in
|
65 |
bot_name=Config.BOT_USERNAME,
|
66 |
)
|
67 |
matches = compile_re(regex).search(text)
|
@@ -289,6 +289,7 @@ async def can_pin_message_func(_, __, m):
|
|
289 |
return True
|
290 |
|
291 |
# Bypass the bot devs, sudos and owner
|
|
|
292 |
if m.from_user.id in SUDO_LEVEL:
|
293 |
return True
|
294 |
|
|
|
9 |
from pyrogram.filters import create
|
10 |
from pyrogram.types import CallbackQuery, Message
|
11 |
|
12 |
+
from Powers import OWNER_ID, PREFIX_HANDLER
|
13 |
from Powers.database.disable_db import Disabling
|
14 |
+
from Powers.supports import get_support_staff
|
15 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
16 |
from Powers.vars import Config
|
17 |
|
|
|
|
|
|
|
18 |
|
19 |
def command(
|
20 |
commands: Union[str, List[str]],
|
|
|
27 |
if not m:
|
28 |
return
|
29 |
|
30 |
+
SUDO_LEVEL = get_support_staff("sudo_level")
|
31 |
+
DEV_LEVEL = get_support_staff("dev_level")
|
32 |
date = m.edit_date
|
33 |
if date:
|
34 |
return # reaction
|
|
|
61 |
if not text:
|
62 |
return False
|
63 |
regex = r"^[{prefix}](\w+)(@{bot_name})?(?: |$)(.*)".format(
|
64 |
+
prefix="|".join(escape(x) for x in PREFIX_HANDLER),
|
65 |
bot_name=Config.BOT_USERNAME,
|
66 |
)
|
67 |
matches = compile_re(regex).search(text)
|
|
|
289 |
return True
|
290 |
|
291 |
# Bypass the bot devs, sudos and owner
|
292 |
+
SUDO_LEVEL = get_support_staff("sudo_level")
|
293 |
if m.from_user.id in SUDO_LEVEL:
|
294 |
return True
|
295 |
|
Powers/utils/string.py
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
from datetime import datetime, timedelta
|
2 |
from html import escape
|
3 |
from re import compile as compile_re
|
@@ -192,3 +193,24 @@ async def remove_escapes(text: str) -> str:
|
|
192 |
else:
|
193 |
res += text[counter]
|
194 |
return res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import base64
|
2 |
from datetime import datetime, timedelta
|
3 |
from html import escape
|
4 |
from re import compile as compile_re
|
|
|
193 |
else:
|
194 |
res += text[counter]
|
195 |
return res
|
196 |
+
|
197 |
+
async def encode_decode(string: str,to_do="encode"):
|
198 |
+
"""
|
199 |
+
Function to encode or decode strings
|
200 |
+
string: string to be decoded or encoded
|
201 |
+
to_do: encode to encode the string or decode to decode the string
|
202 |
+
"""
|
203 |
+
if to_do.lower() == "encode":
|
204 |
+
encodee = string.encode("ascii")
|
205 |
+
base64_ = base64.b64encode(encodee)
|
206 |
+
B64 = base64_.decode("ascii")
|
207 |
+
|
208 |
+
elif to_do.lower() == "decode":
|
209 |
+
decodee = string.encode("ascii")
|
210 |
+
base64_ = base64.b64decode(decodee)
|
211 |
+
B64 = base64_.decode("ascii")
|
212 |
+
|
213 |
+
else:
|
214 |
+
B64 = None
|
215 |
+
|
216 |
+
return B64
|
Version/version 2.2.0.md
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# V 2.1.1
|
2 |
+
### Changes made:
|
3 |
+
- Added `AFK` support.
|
4 |
+
- Added `Captcha verification` for new joined members.
|
5 |
+
- Added support for `join request` in the chat.
|
6 |
+
- Now `lock types` will be stored in database.
|
7 |
+
- Improved **youtube support** to provide best quality.
|
8 |
+
- Now you can kang `video sticker` by replying to **videos** and **animations**.
|
9 |
+
- Added few commands for **devs**.
|
10 |
+
- Improved stability and few minor improvements.
|
11 |
+
- Few bug fixes.
|
12 |
+
- Bug known: 0
|
13 |
+
- Deployed and tested locally
|
14 |
+
|
15 |
+
## Report issues [here](https://github.com/Gojo-Bots/Gojo_Satoru/issues/new/choose) if find any.
|
16 |
+
|
17 |
+
## Give ideas [here](https://github.com/Gojo-Bots/Gojo_Satoru/discussions/new?category=ideas) for next update.
|
18 |
+
|
19 |
+
## Trying our best to give the best
|
20 |
+
|
21 |
+
## Regards 🧑💻: [Captain D. Ezio](https://github.com/iamgojoof6eyes)
|